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))
Related
I want to store some Data in ASDF-files and want to use non implemented extensions. I want to extend other extensions, so i tried starting with the Astropy extensions.
I know how to write a working Extension for ASDF. But, The key issue is that the ASDF-file should always look like an ASDF-file created by an astropy polynomial. Creating a new extension where numpy polynomials are stored is not my purpose.
On the other side, the asdf file should always output an numpy polynomial.
This is what i started working on:
import asdf
from astropy.modeling import models, fitting
from numpy.polynomial import Polynomial as P
# these 2 polynomials are equal
poly_np = P([0,0,0])
poly_astropy = models.Polynomial1D(degree=2)
# this is the usual way how to save an astropy polynomial
target = asdf.AsdfFile({'astropy_poly':poly_astropy})
# inline is just for readability...
target.write_to('poly_astropy.yaml',all_array_storage='inline')
# does not work since numpy polynomials are not 'known' by asdf
target = asdf.AsdfFile({'numpy_poly':poly_np})
target.write_to('poly_np.yaml',all_array_storage='inline')
I tried to change the class PolynomialType in polynomial.py from astropy so that it will accept the type 'numpy.polynomial.polynomial.Polynomial'. But the issue was still that the object could not be represented. So where do i need to do a change to get my polynomial.py working? Or maybe my way of overwriting the astropy class was wrong?
import numpy as np
from numpy.polynomial import Polynomial as P
from numpy.testing import assert_array_equal
from asdf import yamlutil
from astropy import modeling
from astropy.io.misc.asdf.tags.transform.basic import TransformType
class PolynomialType_np(TransformType):
name = "transform/polynomial"
types = ['astropy.modeling.models.Polynomial1D',
'astropy.modeling.models.Polynomial2D',
'numpy.polynomial.polynomial.Polynomial']
# from asdf file to np polynomial
#classmethod
def from_tree_transform(cls, node, ctx):
coefficients = np.asarray(node['coefficients'])
return P(coefficients)
# from any polynomial to asdf
#classmethod
def to_tree_transform(cls, model, ctx):
# np.polynomial added
if isinstance(model, np.polynomial.polynomial.Polynomial):
coefficients = p.coef
elif isinstance(model, modeling.models.Polynomial1D):
coefficients = np.array(model.parameters)
elif isinstance(model, modeling.models.Polynomial2D):
degree = model.degree
coefficients = np.zeros((degree + 1, degree + 1))
for i in range(degree + 1):
for j in range(degree + 1):
if i + j < degree + 1:
name = 'c' + str(i) + '_' + str(j)
coefficients[i, j] = getattr(model, name).value
node = {'coefficients': coefficients}
return yamlutil.custom_tree_to_tagged_tree(node, ctx)
# astropy classmethod updated with np.arrays
#classmethod
def assert_equal(cls, a, b):
# TODO: If models become comparable themselves, remove this.
TransformType.assert_equal(a, b)
assert (isinstance(a, (modeling.models.Polynomial1D, modeling.models.Polynomial2D, np.polynomial.polynomial.Polynomial)) and
isinstance(b, (modeling.models.Polynomial1D, modeling.models.Polynomial2D, np.polynomial.polynomial.Polynomial)))
if (isinstance(a, (modeling.models.Polynomial1D, modeling.models.Polynomial2D)) and
isinstance(b, (modeling.models.Polynomial1D, modeling.models.Polynomial2D))):
assert_array_equal(a.parameters, b.parameters)
elif (isinstance(a, (modeling.models.Polynomial1D, modeling.models.Polynomial2D)) and
isinstance(b, np.polynomial.polynomial.Polynomial)):
assert_array_equal(a.parameters, b.coeff)
elif (isinstance(b, (modeling.models.Polynomial1D, modeling.models.Polynomial2D)) and
isinstance(a, np.polynomial.polynomial.Polynomial)):
assert_array_equal(a.coeff, b.parameters)
elif (isinstance(a, np.polynomial.polynomial.Polynomial) and
isinstance(b, np.polynomial.polynomial.Polynomial)):
assert_array_equal(a.coeff, b.coeff)
Here are the two solutions #Iguananaut suggested:
Solution 1
This is the solution where you override the PolynomialType registry by force.
# the code from above and then the following
from astropy.io.misc.asdf.extension import AstropyAsdfExtension
from astropy.io.misc.asdf.types import _astropy_asdf_types
_astropy_asdf_types.remove(
astropy.io.misc.asdf.tags.transform.polynomial.PolynomialType)
#this will work now
target = asdf.AsdfFile({'numpy_poly':poly_np},extensions=AstropyAsdfExtension())
target.write_to('poly_np.yaml',all_array_storage='inline')
Solution 2
This is the solution where you create a subclass of PolynomialType where you add the functionality of adding numpy polynomials. Since its not really necessary to read them as numpy polynomials, they are read as astropy polynomials.
import numpy as np
from numpy.polynomial import Polynomial as P
from numpy.testing import assert_array_equal
import asdf
from asdf import yamlutil
from astropy import modeling
from astropy.io.misc.asdf.tags.transform.polynomial import PolynomialType
from astropy.io.misc.asdf.extension import AstropyAsdfExtension
class PolynomialTypeNumpy(PolynomialType):
#classmethod
def to_tree(cls, model, ctx):
coefficients = model.coef
node = {'coefficients': coefficients}
return yamlutil.custom_tree_to_tagged_tree(node, ctx)
# could/should add assert_equal from above
# And then this works.
target = asdf.AsdfFile({'numpy_poly':P([0,0,0])},
extensions=AstropyAsdfExtension())
target.write_to('poly_np.yaml',all_array_storage='inline')
I'm trying to optimize parameters using data for my model with scipy optimize but scipy fails to minimize the function and find values of the parameters. It just returns the initial guess which the user gives as input.Also, it gives the following error: RuntimeWarning: invalid value encountered in reduce.
import pandas as pd
import numpy as np
from math import log10
import math
import scipy.optimize as op
from scipy.integrate import odeint
df1 = pd.read_csv('dataset1.csv')
z=df1.loc[: , "z"]
za=z.as_matrix(columns=None)
mu=df1.loc[: , "mu"]
mua=mu.as_matrix(columns=None)
si=df1.loc[: , "sig"]
sia=si.as_matrix(columns=None)
c = 299792.458;
H0 = 70;
m_t=0.3
d_t=0.7
mu0 = 25 + 5*log10(c/H0);
def model(x,t,m,d):
dydt = 1/(math.sqrt((((1+x)**2)*(1+m*x))-(x*d*(2+x))))
return dydt
def Io(zb,m,d):
return odeint(model,0,zb, args=(m,d))
def lnlike(theta,zb, mub,sib):
m, d = theta
isia2 = 1.0/np.square(sib)
return 0.5*(np.sum(((((5*(np.log10((1+zb)*Io(zb,m,d)))+mu0)-mub)**2)*isia2)- np.log(isia2)))
nll = lambda *args: -lnlike(*args)
result = op.minimize(nll, [m_t, d_t], args=(za, mua,sia))
m_ml, d_ml = result["x"]
print(m_ml, d_ml)
I think scipy is not able to handle illegal values generated due to the square root.If so, how can one bypass the illegal values?
the dataset1 file can be found at the link:https://drive.google.com/file/d/1HDzQ7rz_u9y63ECNkhtB49T2KBvu0qu6/view?usp=sharing
I have matrices where elements can be defined as arithmetic expressions and have written Python code to optimise parameters in these expressions in order to minimize particular eigenvalues of the matrix. I have used scipy to do this, but was wondering if it is possible with NLopt as I would like to try a few more algorithms which it has (derivative free variants).
In scipy I would do something like this:
import numpy as np
from scipy.linalg import eig
from scipy.optimize import minimize
def my_func(x):
y, w = x
arr = np.array([[y+w,-2],[-2,w-2*(w+y)]])
ev, ew=eig(arr)
return ev[0]
x0 = np.array([10, 3.45]) # Initial guess
minimize(my_func, x0)
In NLopt I have tried this:
import numpy as np
from scipy.linalg import eig
import nlopt
def my_func(x,grad):
arr = np.array([[x[0]+x[1],-2],[-2,x[1]-2*(x[1]+x[0])]])
ev, ew=eig(arr)
return ev[0]
opt = nlopt.opt(nlopt.LN_BOBYQA, 2)
opt.set_lower_bounds([1.0,1.0])
opt.set_min_objective(my_func)
opt.set_xtol_rel(1e-7)
x = opt.optimize([10.0, 3.5])
minf = opt.last_optimum_value()
print "optimum at ", x[0],x[1]
print "minimum value = ", minf
print "result code = ", opt.last_optimize_result()
This returns:
ValueError: nlopt invalid argument
Is NLopt able to process this problem?
my_func should return double, posted sample return complex
print(type(ev[0]))
None
<class 'numpy.complex128'>
ev[0]
(13.607794065928395+0j)
correct version of my_func:
def my_func(x, grad):
arr = np.array([[x[0]+x[1],-2],[-2,x[1]-2*(x[1]+x[0])]])
ev, ew=eig(arr)
return ev[0].real
updated sample returns:
optimum at [ 1. 1.]
minimum value = 2.7015621187164243
result code = 4
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
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.