2016-02-18 61 views
7

Python'da karmaşık bir matrisi üstelleştirmeye çalışıyorum ve bazı sıkıntılarla karşılaşıyorum. Ben scipy.linalg.expm fonksiyonunu kullanıyorum ve ben aşağıdaki kodu deneyin oldukça garip hata mesajı yaşıyorum: İkinci deney çalıştırıldığındaPython'da matris üssüleşmesi

import numpy as np 
from scipy import linalg 

hamiltonian = np.mat('[1,0,0,0;0,-1,0,0;0,0,-1,0;0,0,0,1]') 

# This works 
t_list = np.linspace(0,1,10) 
unitary = [linalg.expm(-(1j)*t*hamiltonian) for t in t_list] 

# This doesn't 
t_list = np.linspace(0,10,100) 
unitary = [linalg.expm(-(1j)*t*hamiltonian) for t in t_list] 

hatadır:

This works! 
Traceback (most recent call last): 
    File "matrix_exp.py", line 11, in <module> 
    unitary_t = [linalg.expm(-1*t*(1j)*hamiltonian) for t in t_list] 
    File "/usr/lib/python2.7/dist-packages/scipy/linalg/matfuncs.py",  line 105, in expm 
    return scipy.sparse.linalg.expm(A) 
    File "/usr/lib/python2.7/dist- packages/scipy/sparse/linalg/matfuncs.py", line 344, in expm 
    X = _fragment_2_1(X, A, s) 
    File "/usr/lib/python2.7/dist- packages/scipy/sparse/linalg/matfuncs.py", line 462, in _fragment_2_1 
    X[k, k] = exp_diag[k] 
TypeError: only length-1 arrays can be converted to Python scalars 

Bu gerçekten görünüyor Ben değiştiğimden beri garip kullanıyorum t aralığı oldu. Hamiltoniyen diyagonal olduğundan mı? Genel olarak, Hamiltonlular olmayacak, ama ben de köşegen olanlar için çalışmasını istiyorum. Ben gerçekten expm tekniklerini bilmiyorum, bu yüzden herhangi bir yardım büyük takdir edilecektir.

+0

Hesaplamayı, liste anlaşması yerine bir for döngüsüne taşımayı deneyebilirsiniz. O zaman en azından hangi değerin başarısız olduğunu anlayabilirsiniz. – Elliot

+1

Programın başarısız olduğu ilk sayı 't = 2.12121212121''dir. Tamamen keyfi görünüyor ... Program 't = 2.ax'' a '0' için çalışmıyor. Ve 't = 3.x' için işe yaramıyor ... – anar

cevap

3

Bu ilginç. Söyleyebileceğim tek şey, sorunun np.matrix alt sınıfına özgü olmasıdır. Örneğin, aşağıdaki çalışıyor: traceback içine biraz daha derin kazmak

h = np.array(hamiltonian) 
unitary = [linalg.expm(-(1j)*t*h) for t in t_list] 

, istisna scipy.sparse.linalg.matfuncs.py yılında _fragment_2_1 büyüdü ediliyor, özellikle these lines:

n = X.shape[0] 
diag_T = T.diagonal().copy() 

# Replace diag(X) by exp(2^-s diag(T)). 
scale = 2 ** -s 
exp_diag = np.exp(scale * diag_T) 
for k in range(n): 
    X[k, k] = exp_diag[k] 

hata mesajı

exp_diag[k] bir skaler olmalı, ancak bunun yerine bir vektör döndürüyor (ve bir skaler olan X[k, k]'a bir vektör atayamazsınız).

ipdb> l 
    751  # Replace diag(X) by exp(2^-s diag(T)). 
    752  scale = 2 ** -s 
    753  exp_diag = np.exp(scale * diag_T) 
    754  for k in range(n): 
    755   import ipdb; ipdb.set_trace() # breakpoint e86ebbd4 // 
--> 756   X[k, k] = exp_diag[k] 
    757 
    758  for i in range(s-1, -1, -1): 
    759   X = X.dot(X) 
    760 
    761   # Replace diag(X) by exp(2^-i diag(T)). 

ipdb> exp_diag.shape 
(1, 4) 
ipdb> exp_diag[k].shape 
(1, 4) 
ipdb> X[k, k].shape 
() 

altta yatan sorun exp_diag 1D veya bir sütun vektördür bir np.matrix nesnenin çapraz olduğu varsayılır olmasıdır a,:

bir kesme noktası ayarlama ve bu değişkenlerin şekilleri incelenmesi, bu teyit satır vektörü. Bu, np.matrix'un genellikle np.ndarray'dan daha az desteklendiği daha genel bir noktayı vurgular, bu nedenle çoğu durumda bu ikincisini kullanmak daha iyidir.

bir 1D np.ndarray içine diag_T düzleştirmek için np.ravel() kullanmak olası bir çözüm olacaktır:

diag_T = np.ravel(T.diagonal().copy()) 

np.matrix Ben cenneti ilişkin diğer sorunlar olabileceğini ancak bu, karşılaştığınız sorunu çözmek gibi görünüyor henüz fark edilmedi.


Bir çekme isteği açtım here.

+0

Bunun için çok teşekkür ederim! Sanırım sadece mat yerine 'ndarray' ile çalışabilirim ve eğer ihtiyacım olursa işleri matrislere dökebilirim. Sanırım iki sınıfın iç işleyişi hakkında yeterince bilgim yok. İlişkisiz, ancak Python'da kesme noktalarını nasıl belirlersiniz? Belirli bir IDE kullanıyor musunuz veya bunu emacs, vb. Yapabilir misiniz? – anar

+1

Kesme noktalarını ayarlamak için IDE'ye ihtiyacınız yoktur. ['Ipdb'] (https://pypi.python.org/pypi/ipdb) kullanıyorum, ancak standart Python hata ayıklayıcı,' pdb' kullanabilirsiniz. SublimeText3'ü, kesme noktalarını uygun bir şekilde ayarlamak için bir uzantıya sahip bir editör olarak kullanıyorum, ancak Emacs'e eşdeğer bir ... –