I need to solve an integral equation by python 3.2 in win7.
I want to find an initial guess solution first and then use "fsolve()" to solve it in python.
This is the code:
import numpy as np
from scipy.optimize.minpack import fsolve
from cmath import cos, exp
from scipy.integrate.quadpack import quad
def integrand2(x, b):
return exp(-x)/b
def intergralFunc2(b):
integral,err = quad(integrand2, 0, 10, args=(b)) // **error here**
return 0.01 - integral
import matplotlib.pyplot as plt
def findGuess():
vfunc = np.vectorize(intergralFunc2)
f = np.linspace(-20, 20,10)
plt.plot(f, vfunc(f))
plt.xlabel('guess value')
plt.show()
def solveFunction():
y= fsolve(intergralFunc2, 10)
return y
if __name__ == '__main__':
findGuess()
solution = solveFunction()
print("solution is ", solution)
I got error:
quadpack.error: Supplied function does not return a valid float.
Any help would be appreciated.
Just made the following change and it should work (it worked for me).
remove:
from cmath import exp, cos
include:
from numpy import exp, cos
as explained in the comments, the cmath functions accept only float inputs, not arrays.
Related
So I tried to get the limits to infinity of an expression which has a function argument through this code and I got this. Help.
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from scipy import integrate
T=2
t=sp.symbols('t')
x=sp.Piecewise((1,t%T<=T/2),(0,t%T>T/2))
n=sp.symbols('n')
xnum=sp.lambdify(t,x)
def realintegrand(t,f):
w0=2*np.pi/T
trig=np.cos(n*w0*t)
return f(t)*trig/T
def imagintegrand(t,f):
w0=2*np.pi/T
trig=np.sin(n*w0*t)
return f(t)*trig/T
def limitfunc(f):
realans, errreal = integrate.quad(realintegrand, 0, T,args=(f,))
imagans, errimag = integrate.quad(imagintegrand, 0, T,args=(f,))
return sp.limit(realans-1.0j*imagans,n,float('inf'),'+')
k=limitfunc(xnum)
TypeError:
loop of ufunc does not support argument 0 of type Mul which has no callable cos method
How to do zero-skewness log transform in Python?
For example in Stata it is implemented in lnskew0 (see https://www.stata.com/manuals13/rlnskew0.pdf).
I didn't find an implementation in Python. Is anyone aware of an implementation?
Otherwise, a first try would be:
from scipy.stats import skew
import numpy as np
from scipy.optimize import root_scalar
def lnskew0(x):
def skew_ln(k):
return skew(np.log(x - k))
res = root_scalar(
skew_ln,
bracket=[-x.min(), x.max()*0.99999],
method='bisect'
)
return np.log(x - res.root)
Works fine on numpy arrays with only positive numbers. How is Stata's lnskew0 implemented that it works with negative numbers as well?
I gave it another try so that it works with negative numbers as well:
from scipy.stats import skew
import numpy as np
from scipy.optimize import root_scalar
def lnskew0(x):
x0 = x + 1
def skew_ln_pos(k):
with np.errstate(all='ignore'):
return skew(np.log(x0 - k))
res_pos = root_scalar(
skew_ln_pos,
bracket=[-150, 150],
method='bisect'
)
def skew_ln_neg(k):
with np.errstate(all='ignore'):
return skew(np.log(-x0 - k))
res_neg = root_scalar(
skew_ln_neg,
bracket=[-150, 150],
method='bisect'
)
res = (res_pos.root - 1, res_neg.root + 1)
lnskew0_res = (
np.log(x - res[0]),
np.log(-x - res[1])
)
whichmin = np.nanargmin([abs(skew(x)) for x in lnskew0_res])
return lnskew0_res[whichmin]
Note: It still has one issue. The bracket of the root_scalar needs to be choosen manually.
I want to calculate a convolution in Python by explicitly evaluating the integral
and comparing the result with what I get from fftconvolve. The integral would be calculated using quad:
import numpy as np
from scipy.integrate import quad
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
from sympy import symbols
def f(x,a,b):
return np.exp(-(x-a)**2/b)
def g(x,a,b):
return np.exp(-(x-np.pi*a)**2/(2.9*b))
x = symbols('x')
a = 1.2
b = 4.7
t = np.linspace(-100,100,int(1e4))
dt = t[1] - t[0]
h1 = fftconvolve(f(t,a,b),g(t,a,b),mode='same')*dt
h2,_ = quad(f(t,a,b)*g(x-t,a,b),-np.inf,np.inf,epsabs=0,epsrel=1e-6,args=(a,b))
x = np.linspace(-100,100,int(1e4))
plt.figure()
plt.plot(t,h1,label='fftconvolve')
plt.plot(x,h2,label='brute force')
plt.legend()
plt.show()
I keep getting the error AttributeError: 'Mul' object has no attribute 'exp' which refers to the line h2,_ = quad(... when it is called by quad.
What does this error mean and is this an appropriate way to use quad to evaluate the integral?
I saw there are some similar questions around here but none of them seems to really get to my problem.
This is my code:
import numpy as np
from matplotlib import pyplot as mp
from scipy.integrate import *
deltat = 30.0e-6
ku = 50.0e-12
pant = 0.05
csc = 200.0e-12
tausc = 150.0e-6
def int1(tp, tausc, csc, t):
return (1/csc)*(np.exp(-tp/tausc))
def deltafisc(t):
return quad(int1, 0, np.inf, args=(tausc, csc, t))
t = np.linspace(-2.0, 2.0, num=100)*1e-4
mp.plot(t,deltafisc(t))
mp.show()
The function works, but when I try to plot it report a mistake.
I would like to solve a nonlinear first order differential equation using Python.
For instance,
df/dt = f**4
I wrote the following program, but I have an issue with matplotlib, so I don't know if the method I used with scipy is correct.
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
derivate=lambda f,t: f**4
f0=10
t=np.linspace(0,2,100)
f_numeric=scipy.integrate.odeint(derivate,f0,t)
print(f_numeric)
plt.plot(t,f_numeric)
plt.show()
Which results in the following error:
AttributeError: 'float' object has no attribute 'rint'
In this case, you might be better of using Sympy, which allows you to obtain the closed form solutions:
from IPython.display import display
import sympy as sy
from sympy.solvers.ode import dsolve
import matplotlib.pyplot as plt
import numpy as np
sy.init_printing() # LaTeX like pretty printing for IPython
t = sy.symbols("t", real=True)
f = sy.symbols("f", function=True)
eq1 = sy.Eq(f(t).diff(t), f(t)**4) # the equation
sls = dsolve(eq1) # solvde ODE
# print solutions:
print("For ode")
display(eq1)
print("the solutions are:")
for s in sls:
display(s)
# plot solutions:
x = np.linspace(0, 2, 100)
fg, axx = plt.subplots(2, 1)
axx[0].set_title("Real part of solution of $\\frac{d}{dt}f(t)= (f(t))^4$")
axx[1].set_title("Imag. part of solution of $\\frac{d}{dt}f(t)= (f(t))^4$")
fg.suptitle("$C_1=0.1$")
for i, s in enumerate(sls, start=1):
fn1 = s.rhs.subs("C1", .1) # C_1 -> 1
fn2 = sy.lambdify(t, fn1, modules="numpy") # make numpy function
y = fn2(x+0j) # needs to be called with complex number
axx[0].plot(x, np.real(y), label="Sol. %d" % i)
axx[1].plot(x, np.imag(y), label="Sol. %d" % i)
for ax in axx:
ax.legend(loc="best")
ax.grid(True)
axx[0].set_ylabel("Re$\\{f(t)\\}$")
axx[1].set_ylabel("Im$\\{f(t)\\}$")
axx[-1].set_xlabel("$t$")
fg.canvas.draw()
plt.show()
In an IPython shell, you should see the following: