在python中计算NxN矩阵的熵

时间:2018-08-17 15:04:30

标签: python numpy matrix sympy entropy

我有一个NxN矩阵,其中所有元素的值都在[-1,1]之间。我可以手动计算香农的熵,但我想要像冯·诺依曼的熵那样的东西。 Numpy / Scipy中有任何内置函数吗? 手动方法也可以。 矩阵的大小通常为100x100。像这样的东西。

[[-0.244608 -0.71395497 -0.36534627]  
[-0.44626849 -0.82385746 -0.74654582]
[ 0.38240205 -0.58970239  0.67858516]]

谢谢。

2 个答案:

答案 0 :(得分:0)

仅查找特征值呢? 未经测试的伪代码

import os
import numpy as np
from mayavi import mlab

data = np.random.uniform(0, 2, (450, 450))
fig = mlab.figure(1)
mlab.clf()
landscape = mlab.imshow(data)
cursor3d = mlab.points3d(0., 0., 0., mode='axes',
                                color=(0, 0, 0),
                                scale_factor=0.5)
mlab.title('click me')
mlab.view(90, 0)

def picker_callback(picker_obj):
    picked = picker_obj.actors
    if landscape.actor.actor._vtk_obj in [o._vtk_obj for o in picked]:
        point2d = picker_obj.mapper_position    
        x_, y_, z_ = point2d
        print(x_,y_,z_) #clicks outside data cells return (0,0,0)

fig.on_mouse_pick(picker_callback)
mlab.show()

更新

在伴侣网站上,您可能会对这个答案感兴趣

https://cs.stackexchange.com/questions/56261/computing-von-neumann-entropy-efficiently

更新

如果您不想遍历特征值/多项式,则可以使用约旦分解获得Jordan normal form of a matrix来计算矩阵的对数(所有其他都是微不足道的)。在python中,可以通过SymPy http://docs.sympy.org/0.7.1/modules/matrices.html#sympy.matrices.matrices.Matrix.jordan_form完成,也请检查Compute Jordan normal form of matrix in Python / NumPy以获得详细信息。

然后可以使用Gantmacher 1959定理从约旦形式计算log(M),请查看本文https://www.ams.org/journals/proc/1966-017-05/S0002-9939-1966-0202740-6/S0002-9939-1966-0202740-6.pdf以获得简化的解释,尤其是等式3.4-3.8

但是我敢打赌,矩阵的一个约旦式甜甜圈普通形式会很复杂。

答案 1 :(得分:0)

您可以按照Nielsen&Chuang在“量子计算和量子信息”中的两种方法之一来定义冯·诺依曼熵。可以根据矩阵的迹线(其负数)乘以其自身的(矩阵)对数来定义...或...可以根据特征值来定义。上面的示例均采用以e为底的对数,但您需要以2为底。为此,您需要在计算中进行一个底数更改。这是Python中可以使用的两个函数,一个用于von Neumann熵定义的每个版本(例如密度运算符):

对于跟踪版本

def von_neumann_entropy(rho):
    import numpy as np
    from scipy import linalg as la
    R = rho*(la.logm(rho)/la.logm(np.matrix([[2]])))
    S = -np.matrix.trace(R)
    return(S)

对于特征值版本

def vn_eig_entropy(rho):
    import numpy as np
    from scipy import linalg as la
    import math as m
    EV = la.eigvals(rho)

    # Drop zero eigenvalues so that log2 is defined
    my_list = [x for x in EV.tolist() if x]
    EV = np.array(my_list)

    log2_EV = np.matrix(np.log2(EV))
    EV = np.matrix(EV)
    S = -np.dot(EV, log2_EV.H)
    return(S)

这些将返回相同的值,因此使用哪个都无所谓。只需使用

之类的东西将这些函数之一输入方矩阵即可
rho = np.matrix([[5/6, 1/6],
                 [1/6, 1/6]])

显然,任何方阵都可以工作,而不仅仅是2x2,这仅是一个例子。如果矩阵的特征值为零,则约定将0 * log(0)项设置为零。这由第二个功能vn_eig_entropy处理。所有密度矩阵都是“非负定数”,因此这是特征值应考虑的唯一问题。我知道这个回应有点晚了,但也许会对别人有所帮助。