scipy curve_fit with arrays TypeError:只有length-1数组可以转换为Python标量

时间:2018-02-07 10:24:50

标签: arrays python-2.7 numpy scipy

我正在尝试用scipy创建与4x4哈密顿矩阵计算的能量本征值的曲线拟合。在下面的错误中,“energy”对应于我定义哈密顿量的函数,“xdata”是在函数之后给出的数组,对应于k,“e”是得到的能量本征值。 该错误似乎是哈密顿矩阵。但是,如果我在没有curve_fit的情况下运行代码,一切正常。 我也尝试过根据我在这里找到的其他问题使用np.array但是它再次起作用。 如果在曲线拟合中给出一个特定的xdata,比如xdata [0],那么代码可以工作,但是由于我希望使用所有值来拟合,所以它对我没什么帮助。 有谁知道这是什么问题?提前谢谢大家!

Traceback (most recent call last):
     File "fitest.py", line 70, in <module>
     popt, pcov = curve_fit(energies,xdata, e)#,
  File "/eb/software/Python/2.7.12-intel-2016b/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 651, in curve_fit
    res = leastsq(func, p0, args=args, full_output=1, **kwargs)
  File "/eb/software/Python/2.7.12-intel-2016b/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 377, in leastsq
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
  File "/eb/software/Python/2.7.12-intel-2016b/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 26, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
  File "/eb/software/Python/2.7.12-intel-2016b/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 453, in _general_function
    return function(xdata, *params) - ydata
  File "fitest.py", line 23, in energies
    [         0.0,              0.0,                      0.0,     ep-2*V4*cos(kpt*d) ]],dtype=complex)
TypeError: only length-1 arrays can be converted to Python scalars

代码:

from numpy import sin, cos, array

from scipy.optimize import curve_fit

from numpy import *

from numpy.linalg import *


def energies(kpt, a=1.0, b=2.0, c=3.0, f=4.0):

   e1=-15.0
   e2=-10.0

   d=1.0
   v0=(-2.0/d**2) 
   V1=a*v0
   V2=b*v0
   V3=c*v0
   V4=d*v0

   basis=('|S, s>', '|S,px>', '|S, py>', '|S,pz>')
   h=array([[ e1-2*V1*cos(kpt*d), -2*V2*1j*sin(kpt*d),   0.0,                   0.0 ], 
     [    2*V2*1j*sin(kpt*d), e2-2*V3*cos(kpt*d),       0.0,                        0.0],  
    [         0.0,              0.0,           e2-2*V4*cos(kpt*d),                 0.0],            
   [         0.0,              0.0,                      0.0,     e2-2*V4*cos(kpt*d) ]],dtype=complex) 

   e,psi=eigh(h)


   return e

print energies(kpt=0.0)
k2=0.4*2*pi/2.05
print energies(kpt=k2)


xdata = array([0.0,k2])
print xdata

popt, pcov = curve_fit(energies, xdata, e)


print " "
print popt
print " "

1 个答案:

答案 0 :(得分:1)

你的问题与你的健康无关,你遇到同样的问题,如果你执行

print energies(xdata)

此错误消息的原因是您将数组kpt作为数组元素放入h,然后告诉numpy将此数组kpt转换为复数。 Numpy非常友好地将长度为1的数组转换为标量,然后可以将其转换为复数。这解释了为什么您没有收到xdata[0]的错误消息。您可以像这样轻松地重现您的问题

import numpy as np
#all fine with an array of length one
xa = np.asarray([1])
a = np.asarray([[xa, 2, 3], [4, 5, 6]])
print a
print a.astype(complex)

#can't apply dtype = complex to an array with two elements
xb = np.asarray([1, 2])
b = np.asarray([[xb, 2, 3], [4, 5, 6]])
print b
print b.astype(complex)

Idk,你用你的能量函数想要达到的目标,所以在构造h数组时我只能推测你的目标。也许像这样的3D阵列?

kpt = np.asarray([1, 2, 3])

h = np.zeros(16 * len(kpt), dtype = complex).reshape(len(kpt), 4, 4)
h[:, 0, 0] = 2 * kpt + 1
h[:, 0, 1] = kpt ** 2
h[:, 3, 2] = np.sin(kpt)
print h