Python 关于单个numpy数组中多个numpy数组的维度初始化的问题

Python 关于单个numpy数组中多个numpy数组的维度初始化的问题,python,python-3.x,numpy,numpy-ndarray,quantum-computing,Python,Python 3.x,Numpy,Numpy Ndarray,Quantum Computing,假设我们有3个,每个尺寸为2x2。如下图所示: X = np.array([[0, 1], [1, 0]], dtype=complex) Y = np.array([[0, -1j], [1j, 0]], dtype=complex) Z = np.array([[1, 0], [0, -1]], dtype=complex) 现在,如果我把每个单独的2x2矩阵作为另一个2x2矩阵的条目。说: A = np.array([[X, 0], [0, Y]]) B = np.array([[X,

假设我们有3个,每个尺寸为2x2。如下图所示:

X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)
现在,如果我把每个单独的2x2矩阵作为另一个2x2矩阵的条目。说:

A = np.array([[X, 0], [0, Y]])
B = np.array([[X, X], [Y, Y]])
奇怪的是,A的dim为2x2,这是我理想的尺寸,而B的dim为2,2,2,2,无论这是什么,如下所示

A = np.array([[X, 0], [0, Y]])

A.shape
Out[131]: (2, 2)

B = np.array([[X, X], [Y, Y]])

B.shape
Out[133]: (2, 2, 2, 2)
另一方面,假设C是1x3矩阵,D是1x2矩阵,例如

C = np.array([[X, Y, 0]])
D = np.array([[X, Y]])
同样,如果我们看一下初始化矩阵的维数

C = np.array([[X, Y, 0]])

C.shape
Out[136]: (1, 3)

D = np.array([[X, Y]])

D.shape
Out[138]: (1, 2, 2, 2)
因此,似乎每当我在这样的数组中初始化数组时,如果有混合的数据类型作为条目,如AandC中的矩阵和整数,它会给出我想要的合理形状,即维度2,2,每个条目的隐藏维度为2x2。但是,只要条目是严格的矩阵,就像在BandD中一样,它就给了我不敏感的维度,比如2,2,2,2。所以我的问题是:

我如何用严格的2,2个矩阵作为条目初始化一个n,n numpy数组矩阵,并且仍然保持它的n,n维,也就是说,不给我一些奇怪的numpy维w,x,y,z

我之所以要这样做,是因为我用量子力学中的算符进行计算,用这些泡利矩阵,比如X,Y和Z,作为量子计算中的量子门。如果我有一些状态ρ,它也是一个2x2矩阵。让

rho = np.array([[1, 0],
                [0, 0]])
设ρ为2x2对角矩阵,其项为2x2ρ矩阵

RHO = np.array([[rho, 0],
                [0, rho]])
我希望计算类似于np.dotD,RHO的东西,这样它就可以

np.array([np.dot(X, rho), 0],
         [0, np.dot(Y, rho)])
我在python上检查了两个2x2矩阵的点积,其中2x2矩阵作为条目,它的条目乘法也都是点积

我在上面提到的所有东西的动机是,我希望使用这些属性作为对我的算法进行矢量化的手段。目前,我的算法的一个非常粗糙的示例如下所示:

for i in (integer_1):
    for j in (integer_2):
        #do something that involves operations with sums of dot products of many matrices#
并将其矢量化,使其可能成为

for i in (integer_1):
        #do something that involves operations with multiples of matrices with dot product of matrices as its entries#
这可能有效,也可能无效!但我很好奇,看看我的这种方法是否会产生加速。 我希望我已经很好地解释了我的问题。 提前谢谢

编辑1

def计算通道操作RHO,操作员: 给定一个量子态的密度函数rho,则 此状态下的频道为: rho->sum{i=1}^n E_i*rho*E_i^匕首 Args: rho 2x2矩阵:密度函数 运算符列表:运算符矩阵列表 返回: 编号:应用运算符列表的结果 操作=[E@rho@E.conj.T表示i,E在枚举运算符中] 返回np.SUM操作,轴=0 这里的问题是K,这里应该是任意1xn维的列表,即[i]或[i,X]或[i,X,Y]或[i,X,Y,Z]。我知道这里X=X^{\dagger},Y和Z也是如此,但我在模拟中会遇到一些情况,情况并非如此

我希望我现在已经解释清楚了。2,2,2,2不是一个奇怪的维度,它只是一个2X2形状的4D张量

为A和B设置不同形状的原因是,将A设置为标量0,而不是2x2零矩阵。换成

A = np.array([[X, np.zeros((2, 2))], [np.zeros((2, 2)), Y]])
B = np.array([[X, X], [Y, Y]])
C = np.vstack([
    np.hstack([X, np.zeros((2, 2))]),
    np.hstack([np.zeros((2, 2)), Y])
])
D = np.vstack([
    np.hstack([X, X]),
    np.hstack([Y, Y])
])
你们会得到两个的2x2张量

或者改成

A = np.array([[X, np.zeros((2, 2))], [np.zeros((2, 2)), Y]])
B = np.array([[X, X], [Y, Y]])
C = np.vstack([
    np.hstack([X, np.zeros((2, 2))]),
    np.hstack([np.zeros((2, 2)), Y])
])
D = np.vstack([
    np.hstack([X, X]),
    np.hstack([Y, Y])
])
你会得到4x4矩阵

RHO = np.array([[rho, 0],
                [0, rho]])
您还可以使用从一种形式转换到另一种形式

E = A.transpose(0, 2, 1, 3).reshape(4, 4)
F = B.transpose(0, 2, 1, 3).reshape(4, 4)

np.allclose(C, E)  # True
np.allclose(D, F)  # True
回来

G = E.reshape(2, 2, 2, 2).transpose(0, 2, 1, 3)
H = F.reshape(2, 2, 2, 2).transpose(0, 2, 1, 3)

np.allclose(A, G)  # True
np.allclose(B, H)  # True
编辑:关于函数compute\u channel\u操作,如果不执行列表理解,而是对操作进行矢量化,并在所有操作中传递3D张量,则可以大大加快运算速度

rho = np.random.rand(2, 2)
operators = [np.random.rand(2, 2) for _ in range(1000)]
operators_tensor = np.asarray(operators)  # same as np.random.rand(1000, 2, 2)

def compute_channel_operation(rho, operators):
    operation = [E@rho@E.conj().T for i, E in enumerate(operators)]
    return np.sum(operation, axis=0)

def compute_channel_operation2(rho, operators):
    return np.sum(operators @ rho @ operators.transpose(0, 2, 1).conj(), axis=0)

A = compute_channel_operation(rho, operators)
B = compute_channel_operation(rho, operators_tensor)
C = compute_channel_operation2(rho, operators_tensor)

np.allclose(A, B) # True
np.allclose(A, C) # True

%timeit compute_channel_operation(rho, operators)
# 6.95 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit compute_channel_operation(rho, operators_tensor)
# 7.53 ms ± 141 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit compute_channel_operation2(rho, operators_tensor)
# 416 µs ± 12 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
np.array尝试生成多维数字数组,如果失败,将生成对象数据类型数组或引发错误

In [347]: np.array([X,0])                                                                                       
Out[347]: 
array([array([[0.+0.j, 1.+0.j],
       [1.+0.j, 0.+0.j]]), 0], dtype=object)
这个数组基本上与列表[X,0]相同——它包含指向对象X和数字0的指针或引用

但给定2个或更多大小匹配的数组,它将生成更高维的数值数组。例如,具有复杂数据类型的2,2,2数组

In [348]: np.array([X,Y])                                                                                       
Out[348]: 
array([[[ 0.+0.j,  1.+0.j],
        [ 1.+0.j,  0.+0.j]],

       [[ 0.+0.j, -0.-1.j],
        [ 0.+1.j,  0.+0.j]]])
块或连接/堆栈的某些组合可以构成二维数组。例如,2,4复杂阵列:

In [349]: np.block([X,Y])                                                                                       
Out[349]: 
array([[ 0.+0.j,  1.+0.j,  0.+0.j, -0.-1.j],
       [ 1.+0.j,  0.+0.j,  0.+1.j,  0.+0.j]])
要生成包含X和Y的对象数据类型数组,我可以执行以下操作:

In [356]: xy = np.empty((2,), object)                                                                           
In [357]: xy[0]= X                                                                                              
In [358]: xy[1]= Y                                                                                              
In [359]: xy                                                                                                    
Out[359]: 
array([array([[0.+0.j, 1.+0.j],
       [1.+0.j, 0.+0.j]]),
       array([[ 0.+0.j, -0.-1.j],
       [ 0.+1.j,  0.+0.j]])], dtype=object)
这种先空后单独赋值的方法是构建对象数据类型数组的最可靠的方法。它得到了Out[348]中所示的多维结果

我不知道这些方法是否有助于你的计算目标。我对你的描述研究得不够。但请记住,fast numpy代码适用于多维数值数组,包括复杂数组,如Out[348]。使用对象数据类型数组的数学运算是命中或未命中的,而且几乎总是较慢


@矩阵乘法适用于X、Y、Out[348]和rho等,但不适用于Out[347]或rho+使用对象数据类型数组,前提是元素本身支持加法。

您希望A和B是4x4矩阵还是2x2张量?我希望我的B与A的2,2,2,2具有相同的dim。或
它们基本上有相同的维数吗?但是你把矩阵作为另一个矩阵的条目是什么意思?你想创建一个块矩阵,还是真正的矩阵矩阵?在NumPy中,对象的2,2矩阵不是很有用,因为大多数数学运算都会停止工作。。。也许您可以给出一些示例输入数据,一些您想要执行的操作,以及所需的输出数据?请参阅我上面的编辑。谢谢:我已经修改了密度运算符2x2矩阵rho=np.数组[[1,0],[0,0]]的函数加速解决方案,有没有一种快速生成以rho作为对角项的nxn对角张量的方法?例如,对于2x2或2,2,2,2张量=np.数组[[rho,0],[0,rho]]或对于3x3或3,3,2,2张量=np.数组[[rho,0,0],[0,0],[0,0,rho]]是的,scipy.linalg.block_diag。但是请记住,对于大型矩阵,您的计算将变得非常低效。您的代码正是我想要的,因此我将正式接受它,所以谢谢您!!但我意识到,只有在运算符的大小较大的情况下(即1100),速度才会显著,在我的情况下,我的代码将只是一个数组wmax dim为1,4。所以现在我很明显,为了我想要的加速,我应该对前面提到的2个I和j循环进行矢量化,我在我的compute\u channel\u操作上运行这些循环,但是我不确定我如何做到这一点,我也不完全适合在这里发布我的全部代码。如果你仍然感兴趣,你可以看看private?compute_channel_operation2是函数的矢量化解决方案。但如果这不能解决您的问题,只需创建另一个问题,并可选地将其链接到此处。这里就是