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.
Related
I'm a noob practicing how to use pylab, matplot lib etc.
Somehow I'm not able to plot this simple branched sin(x) function in pylab/matplotlib.
from math import sin
import pylab as plb
def f(x):
if sin(x) > 0:
return sin(x)
else:
return 0
x = plb.linspace(-4,4,10000)
plb.plot(x,f(x))
plb.show()
The following error outputs when I run the program:
Traceback (most recent call last):
File "C:/Users/...plot.py", line 12, in <module>
plb.plot(x,f(x))
File "C:/Users/......plot.py", line 5, in f
if sin(x) > 0:
TypeError: only size-1 arrays can be converted to Python scalars
Is there anyone who can help me out?
The inbuilt sine function inside math module accepts only a scalar value. You can use numpy sine instead to accomplish your plot as it accepts an array.
import numpy as np
import pylab as plb
def f(x):
sine_ = np.sin(x)
sine_[sine_< 0] = 0
return sine_
x = plb.linspace(-4,4,10000)
plb.plot(x,f(x))
plb.show()
The output is as shown below:
[]
However, as pointed out by Trenton McKinney, this answer states the use of pylab is no longer recommended. So, the alternate solution using matplotlib.pyplot is shown below:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
sine_ = np.sin(x)
sine_[sine_< 0] = 0
return sine_
x = np.linspace(-4,4,10000)
plt.plot(x,f(x))
plt.show()
The output is the same as the image above.
I am trying to integrate the function I, which contains the Legendre polynomial leg_f:
import math
import numpy as np
from mpmath import *
from sympy import *
from scipy.special import legendre
n = 3
c = lambda h_c,z,R : (z**2+h_c**2)**0.5
c_supp = lambda h_c,z,R : (z**2+h_c**2)**(-n)
x = lambda h_x,z,R : -4*R*(R-h_x)/c(h_x,z,R)**2
leg_f = lambda h_l,z,R : legendre(n-1,(1-0.5*x(h_l,z,R))/(1-x(h_l,z,R))**0.5)
f_f_symb = lambda h_v,z,R : hyper((n, 0.5), (1), (-4*R*(R-h_v)/(z**2+h_v**2)))
I = lambda h_i,z_i,R_i : c_supp(h_i,z_i,R_i)*(1-x(h_i,z_i,R_i))**(-n/2)*leg_f(h_i,z_i,R_i)
h_i,z_i,R_i = symbols('h_i z_i R_i')
int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, np.inf))
But I get the error
Traceback (most recent call last):
File "test.py", line 99, in <module>
int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, np.inf))
File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/integrals/integrals.py", line 1276, in integrate
integral = Integral(*args, **kwargs)
File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/integrals/integrals.py", line 75, in __new__
obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
File "/Users/Library/Python/2.7/lib/python/site-packages/sympy/concrete/expr_with_limits.py", line 389, in __new__
obj.is_commutative = function.is_commutative # limits already checked
AttributeError: 'poly1d' object has no attribute 'is_commutative'
What could be the problem? Is it the right way to integrate such function in sympy?
There are some issues with your code that I can see:
You do not need to import legendre function from SciPy. SymPy has its own legendre function which gets imported when you write from sympy import *. Also, if you are interested in symbolic results you should not use SciPy or NumPy at all.
If you want symbolic computations you should not write decimal numbers like 0.5 in your code. Instead you should use Rational(1,2) which is SymPy object that represents the fraction 1/2.
Instead of using NumPy's inf for infinity, you should use Sympy's oo for infinity.
The following code gets rid of the above issues and therefore the original error that you were getting.
from sympy import *
n = 3
c = lambda h_c,z,R : (z**2+h_c**2)**Rational(1,2)
c_supp = lambda h_c,z,R : (z**2+h_c**2)**(-n)
x = lambda h_x,z,R : -4*R*(R-h_x)/c(h_x,z,R)**2
leg_f = lambda h_l,z,R : legendre(n-1,(1-Rational(1,2)*x(h_l,z,R))/(1-x(h_l,z,R))**Rational(1,2))
I = lambda h_i,z_i,R_i : c_supp(h_i,z_i,R_i)*(1-x(h_i,z_i,R_i))**(-n*Rational(1,2))*leg_f(h_i,z_i,R_i)
h_i,z_i,R_i = symbols('h_i z_i R_i')
int_result = integrate(I(h_i,z_i,R_i), (z_i, 0, inf))
Unfortunately, though SymPy cannot quickly integrate the function that you have. Your integrand looks like this
After simplification it becomes a little easier on the eyes but SymPy seems to get stuck trying to evaluate this integral.
Unless symbolic results are absolutely necessary, I would recommend numerical integration for this problem.
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
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.
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.]