How to calculate improper integral in python? - python

How can I calculate the value of this integral:
f_tu(t) is given as numpy.array. The graph looks like this:
How can I implement this?
Everything I could find looks something like this
from scipy.integrate import quad
def f(x):
return 1/sin(x)
I = quad(f, 0, 1)
but I have an array there, not a specific function like sin.

How about auc from sklearn.metrics?
import numpy as np
import numpy as np
from scipy.integrate import quad
from sklearn.metrics import auc
x = np.arange(0, 100, 0.001)
y = np.sin(x)
print('auc:', auc(x,y))
print('quad:', quad(np.sin, 0, 100))
auc: 0.13818791291277366
quad: (0.1376811277123232, 9.459751315610276e-09)

Okay, so you have one of those pesky infinity integrals. Here is how I would deal with it:
import numpy as np
from scipy.integrate import quad
def f(x):
return(1/(x**2)) #put your function to integrate here
print(quad(f,0,np.Infinity)) #integrates from 0 to infinity
This returns two values. The first is the estimated value of the integral, and the second is the approximate absolute error of the integral which is useful to know.

If you want to integrate a numpy array here is a simple solution:
import numpy as np
print(np.trapz(your numpy array here))

Related

How could the energy and cos function be in different shapes?

I am trying to write a code that calculates an integral from zero to pi. But it gives an error which I do not understand how to fix. Thank you for your time.
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,300.1,0.1)
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
As is pointed out in the top comment:
Energy.shape == (2980,), but x.shape == (1000,)
so reduce the number of elements in Energy or increase np.cos(x).
Since energy is just a numpy arrage i reduced it to size=1000.
In order to fix this they need to be the same size, so this ,for example, works:
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,102.1,0.1) #<-- changed 300.1 to 102.1
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
This is the result (with the above):
39.39900748229355

how to use solve_ivp solve Partial Differential Equations with spectral method?

I want to use the spectral method to solve partial differential equations. The equations like that, formula,the initial condition is u(t=0,x)=(a^2)*sech(x),u'_t (t=0)=0.
To solve it, I use the python with the spectral method. Following is the code,
import numpy as np
from scipy.integrate import solve_ivp
from scipy.fftpack import diff as psdiff
#RHS of equations
def f(t,u):
uxx= psdiff(u[N:],period=L,order=2)
du1dt=u[:N]
du2dt =a**2*uxx
dudt=np.append(du1dt,du2dt)
return dudt
a=1
amin=-40;bmax=40
L=bmax-amin;N=256
deltax=L/N
x=np.arange(amin,bmax,deltax)
u01 = 2*np.cosh(x)**(-1)
u02=np.zeros(N)
# y0
inital=np.append(u01,u02)
sola1 = solve_ivp(f, t_span=[0,40],y0=inital,args=(a,))
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(x,sola1.y[:N,5])
plt.show()
Following is my expected result,
expected result.
My python code can run,but I can't get the expected result,and can't find the problem.Following is the result from my python code,
my result
-----------------------------Update----------------------------------------------
I also try a new code,but still can't solve
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from scipy.fftpack import diff as psdiff
from itertools import chain
def lambdifide_odes(y,t,a):
# uxx =- (1j)**2*k**2*u[:N]
u1=y[::2]
u2=y[1::2]
dudt=np.empty_like(y)
du1dt=dudt[::2]
du2dt=dudt[1::2]
du1dt=u2
uxx=psdiff(u1,order=2,period=L)
du2dt=a**2*uxx
return dudt
a=1
amin=-40;bmax=40
L=bmax-amin;N=256
deltax=L/N
x=np.arange(amin,bmax,deltax)
u01 = 2*np.cosh(x)**(-1)
u02=np.zeros(N)
initial=np.array(list(chain.from_iterable(zip(u01,u02))))
t0=np.linspace(0,40,100)
sola1 = odeint(lambdifide_odes,y0=initial,t=t0,args=(a,))
fig, ax = plt.subplots()
ax.plot(x,sola1[20,::2])
plt.show()
You have some slight problem with the design of your state vector and using this in the ODE function. The overall intent is that u[:N] is the wave function and u[N:] its time derivative. Now you want the second space derivative of the wave function, thus you need to use
uxx= psdiff(u[:N],period=L,order=2)
at the moment you use the time derivative, making this a mixed third derivative that does not occur in the equation.

Runtime Return array size Error Python

I am trying to solve a simple differential equation using odeint function. It is giving an error with matching size of array. I think my initial_condi is not matching with the equation function. I can't figure it out where actually the error is. Blow is the error and code. Any help would be greatly appreciated.
RuntimeError: The size of the array returned by func (1) does not match the size of y0 (3)
from scipy import *
from scipy.integrate import odeint
from operator import itemgetter
import matplotlib as plt
from matplotlib.ticker import FormatStrFormatter
from pylab import *
from itertools import product
import itertools
from numpy import zeros_like
import operator
initial_condi = [1, 1, 1]
t_range = arange(0.0,60.0,1.0)
def equation(w, t):
T,I,V = w
dT= V*I*10.24-T*1.64
return dT
result_init = odeint(equation, initial_condi, t_range)
plt.plot(t, result_init[:, 0])
plt.show()
As your state vector has 3 components, the return value of the ODE function also needs to have 3 components, the derivatives of T,I,V. You only provided dT, but should return [dT, dI, dV ].

Python fmin(find minimum) for a vector function

I would like to find the minimum of 3dvar function defined as:
J(x)=(x-x_b)B^{-1}(x-x_b)^T + (y-H(x)) R^{-1} (y-H(x))^T (latex code)
with B,H,R,x_b,y given.
I would like to find the argmin(J(x)). However it seems fmin in python does not work. (the function J works correctly)
Here is my code:
import numpy as np
from scipy.optimize import fmin
import math
def dvar_3(x):
B=np.eye(5)
H=np.ones((3,5))
R=np.eye(3)
xb=np.ones(5)
Y=np.ones(3)
Y.shape=(Y.size,1)
xb.shape=(xb.size,1)
value=np.dot(np.dot(np.transpose(x-xb),(np.linalg.inv(B))),(x-xb)) +np.dot(np.dot(np.transpose(Y-np.dot(H,x)),(np.linalg.inv(R))),(Y-np.dot(H,x)))
return value[0][0]
ini=np.ones(5) #
ini.shape=(ini.size,1) #change initial to vertical vector
fmin(dvar_3,ini) #start at initial vector
I receive this error:
ValueError: operands could not be broadcast together with shapes (5,5) (3,3)
How can I solve this problem? Thank you in advance.
reshape argument x in the function dvar_3, the init argument of fmin() needs a one-dim array.
import numpy as np
from scipy.optimize import fmin
import math
def dvar_3(x):
x = x[:, None]
B=np.eye(5)
H=np.ones((3,5))
R=np.eye(3)
xb=np.ones(5)
Y=np.ones(3)
Y.shape=(Y.size,1)
xb.shape=(xb.size,1)
value=np.dot(np.dot(np.transpose(x-xb),(np.linalg.inv(B))),(x-xb)) +np.dot(np.dot(np.transpose(Y-np.dot(H,x)),(np.linalg.inv(R))),(Y-np.dot(H,x)))
return value[0][0]
ini=np.ones(5) #
fmin(dvar_3,ini) #start at initial vector

Definite integral over one variable in a function with two variables in Scipy

I am trying to calculate the definite integral of a function with multiple variables over just one variable in scipy.
This is kind of like what my code looks like-
from scipy.integrate import quad
import numpy as np
def integrand(x,y):
return x*np.exp(x/y)
quad(integrand, 1,2, args=())
And it returns this type error:
TypeError: integrand() takes exactly 2 arguments (1 given)
However, it works if I put a number into args. But I don't want to, because I want y to remain as y and not a number. Does anyone know how this can be done?
EDIT: Sorry, don't think I was clear. I want the end result to be a function of y, with y still being a symbol.
Thanks to mdurant, here's what works:
from sympy import integrate, Symbol, exp
from sympy.abc import x
y=Symbol('y')
f=x*exp(x/y)
integrate(f, (x, 1, 2))
Answer:
-(-y**2 + y)*exp(1/y) + (-y**2 + 2*y)*exp(2/y)
You probably just want the result to be a function of y right?:
from scipy.integrate import quad
import numpy as np
def integrand(x,y):
return x*np.exp(x/y)
partial_int = lambda y: quad(integrand, 1,2, args=(y,))
print partial_int(5)
#(2.050684698584342, 2.2767173686148355e-14)
The best you can do is use functools.partial, to bind what arguments you have for the moment. But one fundamentally cannot numerically integrate a definite integral if you havnt got the entire domain specified yet; in that case the resulting expression will necessarily still contain symbolic parts, so the intermediate result isn't numerical.
(Assuming that you are talking about computing the definite integral over x given a specific, fixed value of y.)
You could use a lambda:
quad(lambda x:integrand(x, 10), 1, 2, args=())
or functools.partial():
quad(functools.partial(integrand, y=10), 1, 2, args=())
from scipy.integrate import quad
import numpy as np
def integrand(x,y):
return x*np.exp(x/y)
vec_int = np.vectorize(integrand)
y = np.linspace(0, 10, 100)
vec_int(y)

Categories

Resources