How to minimize complex function - python

I have a problem when i'm trying to minimize my complex function using scipy.optimize fmin or scipy.optimize minimize. Indeed it seems like the minimization don't want to take into account the fact that i have a complex function.
I divide my code into two part, the first is a Class and the second is my main program which call the class and solve the minimization.
Here is my Class :
import sys,os
import numpy as np
import random, math
import matplotlib.pyplot as plt
import cmath
class real :
def __init__(self):
self.nmodes = 4
self.L_ch = 1
self.w = 2
def minim(self,eps):
self.T=np.array([[0.0,0.0],[0.00645-0.0012364j,0.0]])
self.Id=np.array([[1,0],[0,1]])
self.disp=np.linalg.det(self.T-self.Id)
return self.disp
Here is my main programm:
import sys,os
import numpy as np
import random, math, cmath
from math import exp
import scipy
from scipy.optimize import fmin
from Carlo import *
#################################
# Call the Class and the function
#################################
A=real()
eps=0.003+0.0042j
C=A.minim(eps)
#################################
# Declare some parameters and list
#################################
Cp=0
track=2
variable=np.arange(track,6,1)
Save=[]
Tau=4.1
Freal=12
Fimag=14j
#################################
# Loop for minimize
#################################
for track in variable:
Cp+=1
print Cp
if Cp==1:
part_real=0.0
part_imag=0.0
else:
part_real=Save[leng-1]/2*3.14*track
part_imag=Save[leng]/2*3.14*track
R_0 = fmin(C,[part_real,part_imag])
print 'La valeur de R_0',R_0
Save.append(Tau)
Save.append(Freal+1)
Save.append(Fimag+1)
leng = len(Save) -1
But i got this error :
Traceback (most recent call last):
File "Main.py", line 40, in <module>
R_0 = fmin(C,[part_real,part_imag])
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/optimize.py", line 360, in fmin
res = _minimize_neldermead(func, x0, args, callback=callback, **opts)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/optimize.py", line 424, in _minimize_neldermead
fsim[0] = func(x0)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/optimize.py", line 268, in function_wrapper
return function(x, *args)
TypeError: 'numpy.complex128' object is not callable
Someone have an idea on what is it happening exactly ?
Thank you.

In the call: R_0 = fmin(C,[part_real,part_imag]) you should send a function as the first argument and it appears that C is not a function (which is why you get the error "object is not callable"):
scipy.linalg.det returns a float or complex Determinant of a matrix, see:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.det.html

Related

strange error python code for definite integral of a matrix

I am trying to compute a definite integral of a 2*10 matrix. I need to compute its definite integral from zero to t as we know the results must coincide to the sinus table.
Here is the code before reaching the goal gives error. The error probably is for the last lines.
I would be so thankful if you guide me please.
import numpy as np
import math
import matplotlib.pyplot as plt
from scipy import integrate
from scipy.integrate import quad
from numpy import linalg as LA
from numpy.linalg import matrix_power
from scipy import linalg
from sympy import *
import scipy.integrate as it
from numpy import vectorize
############
from numba import vectorize, float64
##############################
# Constants
tmax = 20
t = np.arange(0.0, tmax, 1)
t0=0
m=len(t)
#print(t)
etest=np.matrix([[np.sqrt(0),np.sqrt(1),np.sqrt(2) ,np.sqrt(3),np.sqrt(4),np.sqrt(5),np.sqrt(6),np.sqrt(7),np.sqrt(8),np.sqrt(9)],
[np.sqrt(10),np.sqrt(11),np.sqrt(12), np.sqrt(13),np.sqrt(14),np.sqrt(15),np.sqrt(16),np.sqrt(17),np.sqrt(18),np.sqrt (19)]])
pow = np.power( etest, 2 )
pow0=pow[0]
pow1=pow[1]
def norm2etest(xx):
sum= pow0+pow1
return sum
ans2=norm2etest(etest)
print(ans2)
def outerfun(norm2etest):
return np.cos(norm2etest)
def integrandtest(xx):
return outerfun(norm2etest(xx))
ttt=outerfun(norm2etest(etest))
#print(ttt)
for tnow in np.arange(0.0, tmax, 1):
numnow=1*tnow
num=np.array(numnow,dtype=int)
#np.vectorize
def integratetest(i):
def integrandtest(t):
return outerfun(norm2etest(t))[i]
I, ff = quad(integrandtest, t0,tnow)
return I
###########################
INTERVALtest=np.arange(0,10)
ANS1=integratetest(INTERVALtest)
print(INTERVALtest)
#print(ANS1.size)
gives this error
Traceback (most recent call last):
File "C:\Users\user\OneDrive\Desktop\44integral.py", line 58, in <module>
ANS1=integratetest(INTERVALtest)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2163, in __call__
return self._vectorize_call(func=func, args=vargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2241, in _vectorize_call
ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2201, in _get_ufunc_and_otypes
outputs = func(*inputs)
File "C:\Users\user\OneDrive\Desktop\44integral.py", line 54, in integratetest
I, ff = quad(integrandtest, t0,tnow)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\integrate\quadpack.py", line 352, in quad
points)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\integrate\quadpack.py", line 463, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
TypeError: only size-1 arrays can be converted to Python scalars

Gradient using autograd function error python

I am trying to compute the gradient of some function using autograd but fails and shows the below error
from autograd import grad
def f(a):
return a[0]*np.sin(2*np.pi*a[1]) + a[2]*np.sin(2*np.pi*a[3])
a=[1.0,1.0,1.0,1.0]
gr = grad(f,0)
print(gr(a))
File "C:\Users\user\Desktop\auto.py", line 23, in f
return a[0]*np.sin(2*np.pi*a[1]) + a[2]*np.sin(2*np.pi*a[3])
TypeError: loop of ufunc does not support argument 0 of type ArrayBox which has no callable sin method
I had the same issue. I think this a problem with autograd. You have to import numpy from autograd! Add at the beginning : import autograd.numpy as np
from autograd import grad
import autograd.numpy as np ; <-----------
def f(a):
return a[0]*np.sin(2*np.pi*a[1]) + a[2]*np.sin(2*np.pi*a[3])
a=[1.0,1.0,1.0,1.0]
gr = grad(f,0)
print(gr(a))

Python matplotlib error: Supplied function does not return a valid float

from __future__ import division
import functools
import warnings
import numpy as np
import scipy as sp
from scipy import integrate
from numpy import exp, pi
import matplotlib.pyplot as plt
warnings.simplefilter("ignore", np.ComplexWarning)
def legendrePoly(a,n):
def integrand(t):
return ( ((a + exp(2j*pi*t))**2 - 1)/(2*exp(2j*pi*t)) )**n
return sp.integrate.quad(integrand,0,1)[0]
basisDim = 6
legendreBasis = [functools.partial(legendrePoly, n=i) for i in range(basisDim)]
integrand = [lambda x,i=i: exp(x) * legendreBasis[i](x) for i in range(basisDim)]
normalizingConst = [lambda x,i=i: legendreBasis[i](x)**2 for i in range(basisDim)]
basisCoeff = [sp.integrate.quad(integrand[i],-1,1)[0]
/sp.integrate.quad(normalizingConst[i],-1,1)[0] for i in range(basisDim)]
approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))
t = np.arange(-1, 1, 1e-3)
plt.plot(t,exp(t),'b')
plt.plot(t,approxPoly(t),'r')
plt.show()
I'm using Legendre polynomials as a basis for a polynomial approximation to the exponential function. I'm also using Cauchy's Integral Formula to evaluate them, rather than importing them directly from numpy.
Everything runs fine up to and including defining approxPoly, and approxPoly returns the expected value for any input I enter. But for some reason when I try to plot approxPoly(t), it returns the error: Supplied function does not return a valid float.
This error seems to suggest that when my functions in legendreBasis call to scipy.integrate.quad, that something goes wrong there, but if that was the case then approxPoly wouldn't work, yet if you evaluate it at 2000 points between -1 and 1 manually, and plot these points, everything works fine, but is that not exactly what plt.plot doing when it tries to graph my function?
Traceback:
Traceback (most recent call last):
File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 34, in <module>
plt.plot(t,approxPoly(t),'r')
File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 29, in <lambda>
approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))
File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 29, in <genexpr>
approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))
File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 18, in legendrePoly
return sp.integrate.quad(integrand,0,1)[0]
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/integrate/quadpack.py", line 247, in quad
retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/integrate/quadpack.py", line 312, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
quadpack.error: Supplied function does not return a valid float.
logout
scipy.integrate.quad doesn't integrate functions that return arrays. That means when you try to call approxPoly(t), t gets passed around until it ends up in this function:
def legendrePoly(a,n):
def integrand(t):
return ( ((a + exp(2j*pi*t))**2 - 1)/(2*exp(2j*pi*t)) )**n
return sp.integrate.quad(integrand,0,1)[0]
integrand returns an array, and sp.integrate.quad chokes. The same problem occurs a number of times in your code. Everything seems to be written assuming scalar arguments.
You can probably fix this by calling vectorize on approxPoly:
plt.plot(t,np.vectorize(approxPoly)(t),'r')
NumPy will then call approxPoly on each element of t separately.

Use of fsolve and numpy

I have an issu when i'm trying to minimize my (complex matrix) function using fsolve or scipy.optimize.newton but both of them didn't worked. Indeed, my function is 2*2 matrix with complex value. First, I defined my function in a Class i called real() and it is called by my main program MAin.py:
import sys,os
import numpy as np
import random, math
from scipy.optimize import fsolve
from scipy import optimize
class real :
def __init__(self):
self.w = 2
def func1(self,eps):
self.k_ch=2.5*np.exp(eps)
f=np.array([[0,eps*3*self.k_ch+0.032],[0,self.w]])
return f
And my Main program is:
import sys,os
import numpy as np
import random, math, cmath
from scipy.optimize import fsolve
from Carlo import *
A=real()
eps=0.003+0.0042j
C=A.func1(eps)
Cp=0
track=1e-03
variable=np.arange(track,0.1,1)
for track in variable:
Cp=Cp+1
if Cp==1:
eps_real=0
elif Cp==1:
fray=np.array([Cp-1,2])
eps_real=fray/2*3.14*track
R_0= fsolve(C,eps.real)
print R_0
if xtol<=1e-04:
value_stock= np.array([Cp-1,2])
print 'R_0 value is', R_0
But I got this error:
Traceback (most recent call last):
File "Main.py", line 29, in <module>
R_0= fsolve(C,eps.real)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/minpack.py", line 127, in fsolve
res = _root_hybr(func, x0, args, jac=fprime, **options)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/minpack.py", line 183, in _root_hybr
_check_func('fsolve', 'func', func, x0, args, n, (n,))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/optimize/minpack.py", line 14, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
TypeError: 'numpy.ndarray' object is not callable
Since i'm a new beginner with python, I don't know how to deal with it. Can you help me please if you have any idea. It seems like maybe fsolve does not like complex value but I got the same error using scipy.optimize.newton.
Thank you.
fsolve needs a function in the first argument. You provided C which is a numpy.ndarray, not a function.
I wonder why you use fsolve while you state you want to minimize a function? In case minimization is what you want, this example straight from the scipy.optimize tutorial might set you on track:
import numpy as np
from scipy.optimize import minimize
def rosen(x):
"""The Rosenbrock function"""
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(rosen, x0, method='nelder-mead',
options={'xtol': 1e-8, 'disp': True})
print(res.x)
[ 1. 1. 1. 1. 1.]

Python AttributeError:cos

I'm trying to solve numerically an equation using Python2.7. This is the whole code:
from sympy import *
from sympy import Symbol
from sympy.solvers import nsolve
from scipy import *
from pylab import *
import numpy as np
# Symbols
theta = Symbol('theta')
phi = Symbol('phi')
phi0 = Symbol('phi0')
H0 = Symbol('H0')
# Constants
a = 0.05
b = 0.05**2/(8*pi*1e-7)
c= 0.001/(4*pi*1e-7)
phi0 = 60*pi/180
H0 = -0.03/(4*pi*1e-7)
def m(theta,phi):
return np.array([sin(theta)*cos(phi), sin(theta)*cos(phi), cos(phi)])
def h(phi0):
return np.array([cos(phi0), sin(phi0), 0])
def k(theta,phi,phi0):
return np.vdot(m(theta,phi),h(phi0))
def F(theta,phi,phi0,H0):
return -(a*H0)*k(theta,phi,phi0)+b*(cos(theta)**2)+c*(sin(2*theta)**2)+sin(theta)**4*sin(2*phi)**2
def F_phi(theta,phi,phi0,H0):
return simplify(diff(F(theta,phi,phi0,H0),phi))
def G(phi):
return F_phi(pi/2,phi,phi0,H0)
solution = nsolve(G(phi), phi)
print solution
and this is the traceback that I have:
Traceback (most recent call last):
File "Test.py", line 33, in <module>
solution = nsolve(G(phi), phi)
File "Test.py", line 32, in G
return F_phi(pi/2,phi,phi0,H0)
File "Test.py", line 30, in F_phi
return simplify(diff(F(theta,phi,phi0,H0),phi))
File "Test.py", line 28, in F
return -(a*H0)*k(theta,phi,phi0)+b*(cos(theta)**2)+c*(sin(2*theta)**2)+sin(theta)**4*sin(2*phi)**2
File "Test.py", line 26, in k
return np.vdot(m(theta,phi),h(phi0))
File "Test.py", line 22, in m
return np.array([sin(theta)*cos(phi), sin(theta)*cos(phi), cos(phi)])
AttributeError: cos
I am using the sympy, numpy and pylab libraries. So, I don't get a problem with the cos function. Any help?
The problem is using star imports instead of importing each package under a different namespace.
This imports function sympy.functions.elementary.trigonometric.cos under the cos name:
from sympy import *
After that, you import <ufunc 'cos'> under the name cos, overwriting the previous definition:
from scipy import *
Then, it overwrites the previous cos function by another copy of exactly the same function (from the matplotlib package):
from pylab import *
This also imports the same <ufunc 'cos'> but under the np.cos name. This is the proper way to import things:
import numpy as np
In the end, you're left with a copy of the cos function that knows how to apply itself to floats, not sympy objects. When you try to apply that function to sympy objects like phi you get the AttributeError. All in all, the solution to this particular problem is to fix the imports and know if you want the functions from sympy or the ones from numpy.
Did you import the cos function? It's in the math module
from math import cos
Same thing for sin.

Categories