How to calculate complex integral with parameter in Python? (CTFT) - python

I need to calculate CTFT (Continuous Time Fourier Transform) in Python. In other words: I need to calculate an integral with complex number and parameter.
I have function:
def x(t):
return (np.exp(-2*(t**2)+1))
and then I have to calculate integral from:
w is a parameter here.
where my x(t) is like I wrote before:
Do you have any advices how to calculate that?
I tried something like that:
from sympy.abc import x
w=Symbol('w')
f = exp(-(2*x**2-1-(1j)*w*x))
integrate(f, (x, -np.inf, np.inf))
but the result is not good:
thanks for any advices

Related

Python Integration: to calculate area under the curve

I want to find the integral of output power Po in the following code:
Vo = 54.6
# defining a function for duty cycle, output current and output power
def duty_cycle(output_voltage, array_voltage):
duty_cycle = np.divide(output_voltage, array_voltage)
return duty_cycle
def output_current(array_current, duty_cycle):
output_current = np.divide(array_current, duty_cycle)
return output_current
def output_power(output_voltage, output_current):
output_power = np.multiply(output_voltage, output_current)
return output_power
#calculating duty cycle, output current and output power
D = duty_cycle(Vo, array_params['arr_v_mp'])
Io = output_current(array_params['arr_i_mp'], D)
Po = output_power(Vo, Io)
#plot ouput power
plt.ylabel('Output Power [W]')
Po.plot(style='r-')
The code above is just a part of a script. array_params is a pandas time-series data frame. When plotted pandas Series Po, it looks like this:
This is my first time calculating integral using python. After reading through the internet, I think Python's scipy module could be of help but don't really know how and which method to implement. I would appreciate your help in any manner with the above-explained problem.
To compute an integral of the form int y(x) dx from x0 to x1, with an array x_array with values from x0 to x1 and a corresponding y_array of same length, one can use numpy's trapezoidal integration:
integral = np.trapz(y_array, x_array)
which will work also for non-constant spacing x_array[i+1]-x_array[i].
If an indefinite integral (i.e. an integral F(t) = integral f(t) dt) is needed, use scipy.integrate.cumtrapz (instead of numpy.trapz for definite integrals).
integrated = scipy.integrate.cumtrapz(power, dx=timestep)
or
integrated = scipy.integrate.cumtrapz(power, x=timevalues)
To have integrated the same length as power, specify the initial value of the integral, via the optional parameter initial (e.g. initial=0) to scipy.integrate.cumtrapz.

python scipy.integrate inverse ppf

Hello I would like what is the x value that would give me an specific numeric integral.
So far I am using scipy.integrate and works ok, but given a integral value is there a way to know what is the x that gave that result?
let say I have a function f(x) = |2-x| 1<=x<=3
I would like to know what is the x value that give me 0.25 (the first quartile).
What in scipy.stats for normal distribution is norm.ppf(), in this particular case I am using it for PDF (probability density function) but it can be any integral.
Thanks and regards
I use binary search to find answer in logarithmic time (very fast). You can also run code below online here.
import math, scipy.integrate, scipy.optimize
def f(x):
return math.sin(x)
a, b = 0, 10
integral_value = 0.5
res_x = scipy.optimize.bisect(
lambda x: scipy.integrate.quad(f, a, x)[0] - integral_value,
a, b
)
print(
'found point x', res_x, ', integral value at this point',
scipy.integrate.quad(f, a, res_x)[0]
)

Calculating expectation of functions across normal distribution

I want to compute the expectation of certain functions across a normal distribution.
An example:
mu = 100
k = 100
sigma = 10
val, err = quad(lambda x: norm.pdf((x - mu) / sigma) * x if x > k else 0, -math.inf, math.inf)
print(val)
This prints 4.878683842492743e-288 which is clearly not the correct answer.
I assume this is happening because SciPy is unable to integrate the Gaussian. How can I solve this? Ideally, I'd want a method that'd allows one to integrate all sorts of functions across Gaussian and is not specific to the example I have put in.
Thanks!
I think this is a problem with the quadrature (sometimes it doesn't really adapt), and doesn't like the if statement.
So I would suggest something like this (integrate from k to infinity):
def f(x):
return 1/sigma*norm.pdf((x - mu) / sigma)*x
val, err = quad(f, k, math.inf)
Notice, as implied by Jimmy, the correct form of the Gaussian needs 1/sigma.
Another way to do this integral would be to force quad to be careful at some points. My favorite way is to do something like
import numpy as np
from scipy.integrate import quad
#this is the Gaussian. Note that *0.5*(np.sign(x-k)+1) is 0 for x<k and 1 otherwise.
def f(x):
return 1/(np.sqrt(2*np.pi)*sigma)*np.exp(- 0.5*( (x-mu)/sigma )**2 ) *x*0.5*(np.sign(x-k)+1)
#use this to integrate from in (-1,1)
def G(u):
x=u/(1-u**2)
return f(x)*(1+u**2)/(1-u**2)**2
quad(G,-1,1,points=np.linspace(-0.999,0.999,25))
I would suggest to read this in order to get how you can optimize such integrals.

Numerical integration with singularities in python (principal value)

I'm trying to integrate a function with singularities using the quad function in scipy.integrate but I'm not getting the desired answer. Here is the code:
from scipy.integrate import quad
import numpy as np
def fun(x):
return 1./(1-x**2)
quad(fun, -2, 2, points=[-1, 1])
This results in IntegrationWarning and return value about 0.4.
The poles for the function are [-1,1]. The answer should be of roughly 1.09 (calculated using pen and paper).
The option weight='cauchy' can be used to efficiently compute the principal value of divergent integrals like this one. It means that the function provided to quad will be implicitly multiplied by 1/(x-wvar), so adjust that function accordingly (multiply it by x-wvar where wvar is the point of singularity).
i1 = quad(lambda x: -1./(x+1), 0, 2, weight='cauchy', wvar=1)[0]
i2 = quad(lambda x: -1./(x-1), -2, 0, weight='cauchy', wvar=-1)[0]
result = i1 + i2
The result is 1.0986122886681091.
With a simple function like this, you can also do symbolic integration with SymPy:
from sympy import symbols, integrate
x = symbols('x')
f = integrate(1/(1-x**2), x)
result = (f.subs(x, 2) - f.subs(x, -2)).evalf()
Result: 1.09861228866811. Without evalf() it would be log(3).
I also couldn't get it to work with the original function. I came up with this to evaluate the principal value in scipy:
def principal_value(func, a, b, poles, eps=10**(-6)):
#edges
res = quad(func,a,poles[0]-eps)[0]+quad(func,poles[-1]+eps,b)[0]
#inner part
for i in range(len(poles)-1):
res += quad(func, poles[i]+eps, poles[i+1]-eps)[0]
return res
Where func is your function handle, a and b are the limits, poles is a list of poles and eps is how near you want to approach the poles. You can make eps smaller and smaller to get a better result, but maybe sympy will be better for a problem like this.
With this function and the standard eps I get 1.0986112886023367 as a result, which is almost the same as wolframalpha gives.

Manually integrating to get inverse Laplace transform

I wanted to compute the inverse Laplace transform manually without resorting to any library. Specifically, I wanted to compute a bilateral laplace inverse transform. I wanted to check my understanding and tried the following manually, but not able to match the answer. Where am I going wrong?
I want to compute laplace transform of 1/(s-a). I know the answer is eat. My attempt:
a = 2
t = 0.5
f = lambda s: 1/(s-a)
def g(u):
gammah=1
s = complex(real=gammah,imag=u)
return (f(s)).real*np.cos(s.imag*t) * 2*np.exp(s.real*t)/pi
import spicy as sp
import numpy as np
sp.integrate(g,0,np.inf,limit=10000)
gives me -0.9999999
but I know the answer is exp = 2.71...
The main error is mathematical. As Wikipedia says,
integration is done along the vertical line Re(s) = γ in the complex plane such that γ is greater than the real part of all singularities of F(s)
The function F(s) = 1/(s-a) has a singularity at a, which is 2 in your example. So γ needs to be greater than 2. For example, with γ=3 the output of quad is
(2.718278877362764, 2.911191228083254e-06)
as expected. By the, your import spicy etc can't possibly work, correct import syntax would be
from scipy.integrate import quad
# ....
quad(g, 0, np.inf, limit=10000)

Categories