Scipy TypeError: only size-1 arrays can be converted to Python scalars when using dogleg in optimize, why?

时间秒杀一切 提交于 2019-12-11 18:04:28

问题


I am using the method dogleg within optimize.minimize tool in Scipy to solve my non-linear 2-equations system.

sol = optimize.minimize(self.myF, self.initialWCEC,rZ,jac=self.myJacobian,hess=self.myJHessian,tol=6e-11, method='dogleg',options={'gtol':1e-12})

I have defined my own hessian and Jacobian functions in order to use this method. They look like

def myJacobian(self,WCEC):
    jacF = numpy.array([[- k - (k**2*EC*WC*(Rs - rZ))/50,- (k**2*EC**2*(Rs - rZ))/100 - (Cmax**2*w**2*(Rs - rZ))/100],
        [2*k**2*EC*(iZ - Ls*w) + (k**2*Ls*EC*w*WC)/100,(Ls*Cmax**2*w**3)/200 + (Ls*k**2*EC**2*w)/200]]);
    return jacF


def myJHessian(self,WCEC):    
    hessF = numpy.array([[ -(k**2*WC*(Rs - rZ))/50                         , 0.0],
        [   2*k**2*(iZ - Ls*w) + (k**2*Ls*w*WC)/100 ,(k**2*Ls*EC*w)/100]])
    return hessF

Running the code shows that

hessF = [[0.20261201 0.        ]
 [0.06653955 0.00095037]]

jacF = [[0.00060601 0.00033435]
 [0.03326977 0.00025093]]

However, I get the following error

    sqrt_discriminant = math.sqrt(b*b - 4*a*c)
TypeError: only size-1 arrays can be converted to Python scalars

being

a
[[-6.61346725e-03 -6.28263166e-05]
 [ 6.78327072e+00  5.78564519e-02]]
b
[[0.12759629 0.00099103]
 [0.05509243 0.00050403]]
c
[[-0.9945422  -0.99985806]
 [-0.98336328 -0.99954252]]
d
[[ 6.77328767e-02  3.22094783e-04]
 [-3.47761293e+01 -2.62788245e-01]]

which I have located in the method get_boundaries_intersections(self, z, d, trust_radius)

Why do I get this error? Am I not setting the right type for the Jacobian and Hessian functions? According to the documentation they both should be an array.

EDIT : adding myF

def myF(self,WCEC,Zin):
        F1 = ((((EC/10)*k)*(WC/100))**2)*(rZ - Rs) +(( Cmax * ( WC/100 ) )**2)*( w**2*(rZ - Rs) ) - (((EC/10)*k)*(WC/100));

        F2 = (EC*k)**2*(iZ - w*Ls) + (EC*k)**2*WC*((w*Ls)/200) + WC*((w*Ls)/200)*(w*Cmax)**2 + (w*Cmax)**2 *(iZ -(w*Ls));

        return F1,F2 

EDIT2: adding my traceback

Traceback (most recent call last):
  File "C:\myself\eclipse\plugins\org.python.pydev.core_7.2.1.201904261721\pysrc\pydevd.py", line 2316, in <module>
    main()
  File "C:\myself\eclipse\plugins\org.python.pydev.core_7.2.1.201904261721\pysrc\pydevd.py", line 2309, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "C:\myself\eclipse\plugins\org.python.pydev.core_7.2.1.201904261721\pysrc\pydevd.py", line 1642, in run
    return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
  File "C:\myself\eclipse\plugins\org.python.pydev.core_7.2.1.201904261721\pysrc\pydevd.py", line 1649, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\myself\eclipse\plugins\org.python.pydev.core_7.2.1.201904261721\pysrc\_pydev_imps\_pydev_execfile.py", line 25, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:\myProjectDir\myProjectFile.py", line 497, in <module>
    getGC(sensor,untilSample=numbSamples) 
  File "C:\myProjectDir\myProjectFile.py", line 478, in getGC
    GLump,CLump,WCLump= pinsAsLine.mysolverFunction(v_mag, v_phs)
  File "C:\myProjectDir\myProjectFile.py", line 267, in mysolverFunction
    sol = optimize.minimize(self.myF, self.initialWCEC,Zin,jac=self.myJacobian,hess=self.myJHessian,tol=6e-11, method='dogleg',options={'gtol':1e-12})#,'initial_trust_radius':,'max_trust_radius':,'eta':,'})
  File "C:\myself\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\optimize\_minimize.py", line 616, in minimize
    callback=callback, **options)
  File "C:\myself\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\optimize\_trustregion_dogleg.py", line 37, in _minimize_dogleg
    **trust_region_options)
  File "C:\myself\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\optimize\_trustregion.py", line 189, in _minimize_trust_region
    p, hits_boundary = m.solve(trust_radius)
  File "C:\myself\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\optimize\_trustregion_dogleg.py", line 121, in solve
    trust_radius)
  File "C:\myself\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\optimize\_trustregion.py", line 83, in get_boundaries_intersections
    sqrt_discriminant = math.sqrt(b*b - 4*a*c)
TypeError: only size-1 arrays can be converted to Python scalars

adding _trustregion snippet to show that import math is used along with math.sqrt within get_boundaries_intersections()

"""Trust-region optimization."""
from __future__ import division, print_function, absolute_import

import math

import numpy as np
import scipy.linalg

.
.
.

def get_boundaries_intersections(self, z, d, trust_radius):
    """
    Solve the scalar quadratic equation ||z + t d|| == trust_radius.
    This is like a line-sphere intersection.
    Return the two values of t, sorted from low to high.
    """
    a = np.dot(d, d)
    b = 2 * np.dot(z, d)
    c = np.dot(z, z) - trust_radius**2
    sqrt_discriminant = math.sqrt(b*b - 4*a*c)

    # The following calculation is mathematically
    # equivalent to:
    # ta = (-b - sqrt_discriminant) / (2*a)
    # tb = (-b + sqrt_discriminant) / (2*a)
    # but produce smaller round off errors.
    # Look at Matrix Computation p.97
    # for a better justification.
    aux = b + math.copysign(sqrt_discriminant, b)
    ta = -aux / (2*a)
    tb = -2*c / aux
    return sorted([ta, tb])

来源:https://stackoverflow.com/questions/57871117/scipy-typeerror-only-size-1-arrays-can-be-converted-to-python-scalars-when-usin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!