I was wondering if is there is a way to define a function that is a derivative of a function. I'm new to python so I don't no much, I tired looking up stuff that might be similar but nothing has worked so far. This is what I have for my code right now.
import sympy as sp
import math
x = sp.Symbol('x')
W = 15 #kN/m
E = 70 # Gpa
I = 52.9*10**(-6) #m**4
L = 3 #m
e = 0.01
xi = 1.8
y = 9
def f(x):
return ( ( y*3*(math.pi**4)*E*I/(W*L) ) - ( 48*(L**3)*math.cos(math.pi*x/(2*L)) ) + ( 48*(L**3) ) + ( (math.pi**3)*(x**3) ) )/(3*L*(math.pi**3))**(1/2)
def derv(f,x):
return sp.diff(f)
print (derv(f,x))
Also, I don't understand whatx = sp.Symbol('x') does, so if someone could explain that, that would be awesome.
Any help is appreciated.
You are conflating two different things: python functions like f and math functions, which you can express with sympy like y = π * x/3. f is a python function that returns a sympy expression. sympy lets you stay in the world of symbolic math functions by defining variables like x = sp.Symbol('x') So calling f() produces a symbolic math function like:
You can use sympy to find the derivative of the symbolic function returned by f() but you need to define it with the sympy versions of the cos() function (and sp.pi if you want to keep it symbolic).
For example:
import sympy as sp
x = sp.Symbol('x')
W = 15 #kN/m
E = 70 # Gpa
I = 52.9*10**(-6) #m**4
L = 3 #m
e = 0.01
xi = 1.8
y = 9
def f(x):
return ( ( y*3*(sp.pi**4)*E*I/(W*L) ) - ( 48*(L**3)*sp.cos(sp.pi*x/(2*L)) ) + ( 48*(L**3) ) + ( (sp.pi**3)*(x**3) ) )/(3*L*(sp.pi**3))**(1/2)
def derv(f,x):
return sp.diff(f(x)) # pass the result of f() which is a sympy function
derv(f,x)
You've programmed the function. it appears to be a simple function of two independent variables x and y.
Could be that x = sp.Symbol('x') is how SymPy defines the independent variable x. I don't know if you need one or another one for y.
You know enough about calculus to know that you need a derivative. Do you know how to differentiate a function of a single independent variable? It helps to know the answer before you start coding.
y*3*(math.pi**4)*E*I/(W*L) ) - ( 48*(L**3)*math.cos(math.pi*x/(2*L)) ) + ( 48*(L**3) ) + ( (math.pi**3)*(x**3) ) )/(3*L*(math.pi**3))**(1/2)
Looks simple.
There's only one term with y in it. The partial derivative w.r.t. y leaves you with 3*(math.pi**4)*E*I/(W*L) )
There's only one term with Cx**3 in it. That's easy to differentiate: 3C*x**2.
What's so hard? What's the problem?
In traditional programming, each function you write is translated to a series of commands that are then sent to the CPU and the result of the calculation is returned. Therefore, symbolic manipulation, like what we humans do with algebra and calculus, doesn't make any sense to the computer. Sympy gets around this by overriding Python's normal arithmetic operators, allowing you to do generate algebraic functions that can be manipulated similarly to how we humans do math. That's what sp.Symbols('x') is doing: providing you with a symbolic variable you can work with (you're also naming it in sympy).
If you want to evaluate your derivative, simply call evalf with the numerical value you want to assign to x.
I am trying to use the symbolic libraries of the python Symp. I am getting lots of errors. How to overcome this. every time I don't want to type sym.symobls for defining some thing new.
from sympy import *
from math import *
W1, W2, W3,z1, z2, b, a,g,l = symbols('W1 W2 W3 z1 z2 b a g l')
l = b**2(g/sqrt(a));
#Beam Functions
W1 = simplify(c1*cos(b*x) + c2*sin(b*x) + c3*cosh(b*x) + c4*sinh(b*x));
The expression l = b**2(g/sqrt(a)) isn't valid. You need e.g. a * between the 2 and the opening bracket. Also note that after the assignment, l isn't a symbol anymore, but a symbolic expression.
You can avoid declaring many variables by using sympify(). That function gets a string as input and creates symbolic variables on the fly. With sympify a lot of standard functions also get their correct symbolic version.
As mentioned in the comments, from sympy import * can be problematic, especially if you also work with other libraries. For convenience, a lot of examples in the docs do use import *, but only for short programs which don't use other libraries.
Here is a simple standalone example which assigns a symbolic expression to l and shows the internal representation (note that the expression is placed into quotes):
from sympy import sympify, srepr
l = sympify("b**2*(g/sqrt(a))")
print(srepr(l))
W1 = sympify("simplify(c1*cos(b*x) + c2*sin(b*x) + c3*cosh(b*x) + c4*sinh(b*x))")
print(srepr(W1))
Output:
Mul(Pow(Symbol('a'), Rational(-1, 2)), Pow(Symbol('b'), Integer(2)), Symbol('g'))
Add(Mul(Symbol('c1'), cos(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c2'), sin(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c3'), cosh(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c4'), sinh(Mul(Symbol('b'), Symbol('x')))))
Often, routines will allow string input so you can just refer to variables created automatically through sympifying an expression with a string:
>>> from sympy import S
>>> S('x')
x
>>> _.subs('x',42)
42
>>> S('2*x').coeff('x')
2
If all you are doing is working with single letter symbols and SymPy functions (and no other libraries) you can (and this is how I always start my sessions):
>>> from sympy.abc import *
>>> from sympy import *
I put the second import there so I get S as the shortcut to sympify rather than as symbol S.
I am trying to differentiate this equation using SymPy:
What I wanted to achieve is this result:
But when I type this code into to execute, it gives me this result:
Here is my current code:
import sympy as sp
# declare symbols
t = sp.Symbol('t')
deriv = sp.diff((t*(sp.cos(t)))/(1-t)**2)
# Find the derivative
sp.simplify(deriv)
Is there a way to achieve the desired result?
That is the same result. Break the result you get on the "+" and you get the same thing
Looking for the "simplest" form is not a well-defined problem and sympy can't guess which form you are looking for. You can always call sp.simplify on both the result you get and the desired answer. sympy will derive the same expression for both. In your case
result = sp.simplify(deriv)
desired = sp.simplify((-2 * t * sp.cos(t))/(t - 1)**3 + (-t * sp.sin(t) + sp.cos(t))/(t - 1)**2)
# result == desired
I would like to find minimum of equations given in these script. It is looking very messy(but deep undestanding of equation is not needed- I suppose). At the end of def is the expression to minimize:
vys1=-Qd-40*sqrt(5)*sqrt((ch+cm)*ep*kb*Na*T)*w1
vys2=fi0-fib-Q0/cq
vys3=fib-fid+Qd/cq1
vysf= np.array([vys1,vys2,vys3])
return vysf
I write this script in matlab using lsqnonlin to compare the results. Matlab results seems much accurate. Result are (fi0,fib,fid)
Python
[-0.14833481 -0.04824387 -0.00942132] Sum(value) ~1e-3.
Matlab
[-0,13253 -0,03253 -0,02131 ] Sum(value)~1e-15
Note that script has a check for typos in equation(if they are identical in python and matlab)
for [fi0,fib,fid]=[-0.120, -0.0750 ,-0.011] the result are the same [vys1,vys2,vys3]-
python [0.00069376 0.05500097 -0.06179421]
matlab [0.0006937598,0.05500096 -0.06179421]
Are there any options in least_squares to improve results? Thanks for any help(sorry for misunderstanding english )
Python
import scipy as sc
import numpy as np
from math import sinh
import matplotlib as plt
from numpy import exp, sqrt
from scipy.optimize import leastsq,least_squares
def q(par,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch,cm):
fi0,fib,fid=np.array([par[0],par[1],par[2]])
AlOH= gamaal*k1*exp(e*fi0/(T*kb))/(ch + k1*exp(e*fi0/(T*kb)))
AlOH2= ch*gamaal/(ch + k1*exp(e*fi0/(T*kb)))
SiO= gamasi*k2*exp(e*fi0/(T*kb))/(ch + k2*exp(e*fi0/(T*kb)))
SiOH= ch*gamasi/(ch + k2*exp(e*fi0/(T*kb)))
X= gamax*k3*k4*exp(e*fib/(T*kb))/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/ (T*kb)))
XH= ch*gamax*k4/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/(T*kb)))
Xm= cm*gamax*k3/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/(T*kb)))
Q0=e*(0.5*(AlOH2+SiOH-AlOH-SiO)-gamax)
Qb=e*(XH+Xm)
Qd=-Q0-Qb
w1=sc.sinh(0.5*e*fid/kb/T)
vys1=-Qd-40*sqrt(5)*sqrt((ch+cm)*ep*kb*Na*T)*w1
vys2=fi0-fib-Q0/cq
vys3=fib-fid+Qd/cq1
vysf= np.array([vys1,vys2,vys3])
return vysf
kb=1.38E-23;T=300;e=1.6e-19;Na=6.022e23;gamaal=1e16;gamasi=1e16
gamax=1e18;k1=1e-4;k2=1e5;k3=1e-4;k4=1e-4;cq=1.6;cq1=0.2
cm=1e-3;ep=80*8.8e-12
ch1=np.array([1e-3,1e-5,1e-7,1e-10])
# Check the equations, if they are same
x0=np.array([-0.120, -0.0750 ,-0.011])
val=q(x0,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch1[0],cm)
print(val)
w1=least_squares(q,x0, args=(kb,ep,Na,T,e,gamaal,gamasi,gamax,k1,k2,k3,
k4,cq,cq1,ch1[0],cm))
print(w1['x'])
matlab
function[F1,poten,fval]=test()
kb=1.38E-23;T=300;e=1.6e-19;Na=6.022e23;gamaal=1e16;gamasi=1e16;gamax=1e18;
k1=1e-4;k2=1e5;k3=1e-4;k4=1e-4;cq=1.6;cq1=0.2;ch=[1e-3];cm=1e-3;ep=80*8.8e- 12;
% Test if equation are same
x0=[-0.120, -0.0750 ,-0.011];
F1=rovnica(x0,ch) ;
[poten,fval]= lsqnonlin(#(c) rovnica(c,ch(1)),x0);
function[F]=rovnica(c,ch)
fi0=c(1);
fib=c(2);
fid=c(3);
aloh=exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*gamaal.*k1.*(ch+exp(1).^(e.* ...
fi0.*kb.^(-1).*T.^(-1)).*k1).^(-1);
aloh2=ch.*gamaal.*(ch+exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*k1).^(-1);
sioh=ch.*gamasi.*(ch+exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*k2).^(-1);
sio=exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*gamasi.*k2.*(ch+exp(1).^(e.* ...
fi0.*kb.^(-1).*T.^(-1)).*k2).^(-1);
Xm=cm.*gamax.*k3.*(cm.*k3+ch.*k4+exp(1).^(e.*fib.*kb.^(-1).*T.^(-1)) ...
.*k3.*k4).^(-1);
XH=ch.*gamax.*k4.*(cm.*k3+ch.*k4+exp(1).^(e.*fib.*kb.^(-1).*T.^(-1)) ...
.*k3.*k4).^(-1);
Q0=e*(0.5*(aloh2+sioh-aloh-sio)-gamax);
Qb=e*(XH+Xm);
Qd=-Q0-Qb;
F=[-Qd+(-40).*5.^(1/2).*((ch+cm).*ep.*kb.*Na.*T).^(1/2).*sinh((1/2).*e.* ...
fid.*kb.^(-1).*T.^(-1));...
fi0-fib-Q0/cq;...
(fib-fid+Qd/cq1)];
end
end
There is a mistake in this line:
w1=least_squares(q,x0, args=(kb,ep,Na,T,e,gamaal,gamasi,gamax,k1,k2,k3,
k4,cq,cq1,ch1[0],cm))
You have the argument kb in the wrong spot. The signature of q is:
def q(par,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch,cm):
The argument kb is between Na and T. If you fix the args argument in the least_squares call:
w1 = least_squares(q, x0, args=(ep, Na, kb, T, e, gamaal, gamasi, gamax,
k1, k2, k3, k4, cq, cq1, ch1[0], cm))
then the output of the Python script is
[ 0.00069376 0.05500097 -0.06179421]
[-0.13253313 -0.03253254 -0.02131043]
which agrees with the Matlab output.
I am trying to implement an algorithm in the following paper (method 5) http://dx.doi.org/10.1016%2FS0076-6879(05)09012-9 in python2.7 to improve my programming skill. Implementations can be found at these locations: Apparently I cannot post so many links. If my reputation goes up, I will post the links here.
Essentially, the algorithm is used for biological research, and finds the mutation rate of cells under some condition. Here is my attempt, which has errors (NOTE: I updated this code to remove an error however I am still not getting the right answer):
import numpy as np
import sympy as sp
from scipy.optimize import minimize
def leeCoulson(nparray):
median=np.median(nparray)
x=sp.Symbol('x')
M_est=sp.solve(sp.Eq(-x*sp.log(x) - 1.24*x + median,0),x)
return M_est
def ctArray(nparray,max):
list=[0] * int(max+1)
for i in range(int(max)+1):
list[i]=nparray.count(i)
return list
values='filename1.csv'
data=np.genfromtxt(values,delimiter=',')
mVal=int(max(data))
ctArray_=ctArray(np.ndarray.tolist(data),mVal)
ef mssCalc(estM,max=mVal,count=ctArray_):
def rec(pi,r):
pr=(estM/r)+sum([(pi[i]/(r-i+1)) for i in range(0,r-1)])
return pr
prod=1
pi=[0]*max
pi[0]=np.exp(-1*estM)
for r in range(1,max):
pi[r]=rec(pi,r)
prod=prod*(pi[r]**count[r])
return -1*prod
finalM=minimize (mssCalc,leeCoulson(data),method='nelder-mead',options={'xtol':1e-3,'disp':True})
print finalM
This code gives the following errors:
mss-mle_calc.py:37: RuntimeWarning: overflow encountered in multiply
prod=prod*(pi[r]**count[r])
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/optimize.py:462: RuntimeWarning: invalid value encountered in subtract
numpy.max(numpy.abs(fsim[0] - fsim[1:])) <= ftol):
Warning: Maximum number of function evaluations has been exceeded.
Please help me make this code better if you have some time.
Thanks for looking, there were a couple stupid mistakes in my code. Here is the working code (as far as I can tell):
import numpy as np
import sympy as sp
from scipy.optimize import minimize
def leeCoulson(nparray):
median=np.median(nparray)
x=sp.Symbol('x')
M_est=sp.solve(sp.Eq(-x*sp.log(x) - 1.24*x + median,0),x)
return float(M_est[0])
def ctArray(nparray,max):
list=[0] * int(max+1)
for i in range(int(max)+1):
list[i]=nparray.count(i)
return list
values='filename1.csv'
data=np.genfromtxt(values,delimiter=',')
mVal=int(max(data))
ctArray_=ctArray(np.ndarray.tolist(data),mVal)
def mssCalc(estM,max=mVal,count=ctArray_):
def rec(pi,r):
pr=(estM/r)*sum([(pi[i]/(r-i+1)) for i in range(0,r)])
return pr
prod=1
pi=[0]*(max+1)
pi[0]=np.exp(-1.0*estM)
for r in range(1,max+1):
pi[r]=rec(pi,r)
prod=prod*(pi[r]**count[r])
return -1*prod
finalM=minimize (mssCalc,leeCoulson(data),method='nelder-mead',options={'xtol':1e-3,'disp':True})
print finalM