what is this error: 'matrix' object has no attribute 'diff' - python

when i am trying to run this program it gives Attribute error.
I am new to python so please forgive if i miss anything.Thanks
import math
import numpy as np
from sympy import *
from sympy import diff
import sympy as sp
p=np.matrix([[0],[0],[0],[1]])
pdash=p
zi=Matrix(2, 1, lambda i,j: Symbol('z%d' % (i+1)))
xi=Matrix(2, 1, lambda i,j: Symbol('x%d' % (i+1)))
alphai=Matrix(2,1, lambda i,j: Symbol('a%d' % (i+1)))
thetai=Matrix(2,1, lambda i,j: Symbol('t%d' % (i+1)))
transformed=np.matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])
def transformation_fn(zi,xi,thetai,alphai):
ca=cos((alphai))
sa=sin((alphai))
ct=cos((thetai))
st=sin((thetai))
transformation=np.matrix([[ct,-st*ca,st*sa,xi*ct],
[st,ct*ca,-ct*sa,xi*st],
[0,sa,ca,zi],
[0,0,0,1]])
return transformation
for z,x,t,a in zip(zi,xi,thetai,alphai):
transformed=transformed*transformation_fn(z,x,t,a)
e=transformed*p
jacobian=e.diff(t1)
print jacobian
I also tried with a sample code if the diff() works or not it worked in this case
import math
import numpy as np
from sympy import *
from sympy import diff
import sympy as sp
x, y, e1 = symbols('x y e1')
e=Matrix(2,1,lambda i,j:Symbol('e%d'%(i+1)))
I=np.matrix([[1 ,0 ],
[0 ,1 ]])
k=I*e
print k.diff(e1)

As was said in comments, symbolic differentiation cannot be applied to a SymPy matrix object. Apply it to each entry separately. Example:
t1 = Symbol('t1')
jacobian = Matrix(*e.shape, lambda i,j: e[i,j].diff(t1))
The second line constructs a matrix of the same shape as e, in which the entries are the derivatives of the entries of e with respect to t1.
(You never actually defined t1 in the code, which made the first line here necessary.)

Related

How to use math function in Python

How to execute this code:
import numpy as np
import math
x = np.arange(1,9, 0.5)
k = math.cos(x)
print(x)
I got an error like this:
TypeError: only size-1 arrays can be converted to Python scalars
Thank you in advance.
So this is happening because math.cos doesn't accept numpy arrays larger than size 1. That's why if you had a np array of size 1, your approach would still work.
A simpler way you can achieve the result is to use np.cos(x) directly:
import numpy as np
x = np.arange(1,9, 0.5)
k = np.cos(x)
print(x)
print(k)
If you have to use the math module, you can try iterating through the array and applying math.cos to each member of the array:
import numpy as np
import math
x = np.arange(1,9,0.5)
for item in x:
k = math.cos(item)
print(k) # or add to a new array/list
You're looking for something like this?
import numpy as np
import math
x = np.arange(1,9, 0.5)
for ang in x:
k = math.cos(ang)
print(k)
You are trying to pass ndarray (returned by arange) to a function, which expects just real number. Use np.cos instead.
If you want pure-Python:
You can use math.fun in map like below:
import math
x = range(1,9)
print(list(map(math.cos, x)))
Output:
[0.5403023058681398, -0.4161468365471424, -0.9899924966004454, -0.6536436208636119, 0.2836621854632263, 0.9601702866503661, 0.7539022543433046, -0.14550003380861354]

How is it possible to define a equation, differentiate and plot it, using Sympy in Jupyter Nootebook?

In Jupyter Notebook i would like to define a equation, differentiate and plot the equation.
import sympy as sp
from IPython.display import display
sp.init_printing()
import matplotlib.pyplot as plt
import numpy as np
x = sp.symbols('x')
def func(x):
a= sp.sympify("4/5")
return (x**3+a*x**2)
display(func(x))
def dfunc(x):
a = sp.diff(func(x),x)
return a
display(dfunc(x))
x = np.linspace(-10,10,20)
plt.plot(x,func(x))
plt.plot(x,dfunc(x)) # doesn't work
display(dfunc(x)) shows the wanted function but plt.plot(x,dfunc(x)) returns the error message ValueError: cannot derive by this array
Does anyone know how to get the plot?
(It also doesn't work with sp.integrate(func(x),x) instead of sp.diff(func(x),x). Just another error message is returned ValueError: Invalid limits given: ...)
Many thanks in advance.
Matthias
You can use the SymPy plot function rather than the matplotlib one. The matplotlib plot function expects arrays as inputs whereas the sympy one accepts sympy expressions (and then calculates values to make the arrays for matplotlib):
In [36]: import sympy as sym
In [37]: a = sym.Rational(4, 5)
In [38]: x = sym.Symbol('x')
In [39]: f = x**3 + a*x**2
In [40]: f
Out[40]:
2
3 4⋅x
x + ────
5
In [41]: f.diff(x)
Out[41]:
2 8⋅x
3⋅x + ───
5
In [42]: sym.plot(f.diff(x))

solve complicated ODE groups using spicy.integrate solve_bvp unsuccessfully

When I run my code sentence by sentence, no errors exist. However, when I check out the results of AA (bvp solution in my code), it displays that I solve this ODE group falsely.
How can I run this code correctly?
import numpy as np
import scipy.integrate
from scipy.integrate import solve_bvp
import matplotlib.pyplot as plt
k=0.06
Theta=20
p=0.4 #porosity of the electrode
pi=3.14
L=4 #cm
R=8.314
F=96485
t2=0.78
C0=1
T=298.15
vs=1
aa=0.5
ac=0.5
a=23300
i0=2e-2
Dad=0.5
I=2
Da=900
B=(1/k*(p**(1.5)))+1/Theta
C=I/(2*pi*L*Theta)
D=2*R*T/F
E=Da*p**(1.5)
def battery(r,y):
A=np.exp((aa*F*y[0])/(R*T))-np.exp((-ac*F*y[0])/(R*T))
return np.vstack((y[1]*B-C/r+(D*y[3]/y[2])*(0.22+y[2]),
A/((1/a*i0)+A/Dad),
y[3],
((1-E)/E)*y[3]+(0.22/(E*F))*(A/((1/a*i0)+A/Dad))))
def boundary(ya,yb):
return [ya[1]-2/(2*3.14*4*10*4.2),yb[1],ya[2]-9,yb[3]]
n = 25
r = np.linspace(4.2, 6.9, n)
y = np.ones((4,r.size))
AA=solve_bvp(battery,boundary,r,y)
The results are below:
sol: <scipy.interpolate.interpolate.PPoly object at 0x11303f728>
status: 2
success: False

scipy can't optimize parameters gives error- RuntimeWarning: invalid value encountered in reduce

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

NLopt minimize eigenvalue, Python

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

Categories