Combination of Map and Integration - python

This is the equation that I'm trying to plot, but have not been successful for hours. XA is variable between 0 to 1. I'd like to plot it while I'm varying eA and n constants. I'm still learning Python and this is being too complicated for me. Any help will be very appreciable.
XA = np.linspace(1e-2, 1-1e-2, 20)
from scipy.integrate import quad
def integrand(XA):
return ((1+eA*XA)/(1-XA))**n
p = lambda XA: quad(integrand, 1e-2, XA)[0]
xs = 1-XA
def func(n, eA):
return (XA*((1+eA*XA)/(1-XA))**n)/(p)
n = [1, 1, 2, 2]
eA = [1, 2, 1, 2]
ys = list(map(func, alps, e))
plt.plot(xs, ys)
plt.show()

You need to evaluate the functions in order to use them in further calculations. Also make sure to supply the needed arguments to the functions.
Here would be an example:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
bracket = lambda eA,XA,n: ((1+eA*XA)/(1-XA))**n
p = lambda eA,XA,n: quad(lambda x: bracket(eA,x,n), 1e-2, XA)[0]
func = lambda eA,XA,n: XA*bracket(eA,XA,n)/p(eA,XA,n)
ns = [1, 1, 2, 2]
eAs = [1, 2, 1, 2]
XAs = np.linspace(3e-2, 1-1e-2, 50)
for e,n in zip(eAs,ns):
ys = list(map(lambda x: func(e,x,n), XAs))
plt.plot(XAs, ys, label="n={}, $e_A$={}".format(n,e))
plt.xlabel("$X_A$")
plt.legend()
plt.show()

Related

DFT coefficients are totally different from FFT

I found the Fourier Transform coefficients using the following formula:
I used the following values as a signal:
import matplotlib.pyplot as plt
from math import tau
from scipy.integrate import quad_vec
import numpy as np
signal_x = np.array([1, 2, 3, 4, 5, 5, 5, 4, 3, 2])
signal_y = np.array([5, 5, 5, 5, 5, 4, 3, 3, 3, 3])
plt.plot(signal_x, signal_y)
After that I found the coefficients by transcribing the DFT formula of complex numbers in python
new_x = np.linspace(0, 2*np.pi, len(signal_x))
# LINEAR INTERPOLATION
def f(t, new_x, x, y):
return np.interp(t, new_x, np.array(x) + 1j*np.array(y))
# DFT Complex Number
qt_coeff = 5
coeffs = []
for n in range(-qt_coeff, qt_coeff): # -5 +4 = 10 coeffs
coef = 1/tau * quad_vec(lambda t: f(t, new_x, signal_x, signal_y)*np.exp(t*1j*n), 0, tau)[0]
coeffs.append(coef)
coeffs = np.array(coeffs)
print(coeffs)
# [ 0.04353136+0.02109635j 0.04473849+0.07575828j 0.09004453-0.00688048j
# -0.0256607 +0.13901032j -0.19044464+0.17837592j 3.61111111+4.11111111j
# -1.37786713-0.37885172j -0.17198653+0.00530144j -0.16603542-0.06911041j
# -0.11103156-0.05656161j]
But when using the FFT to gain speed the values of the coefficients are totally different.
# FFT - Fast Fourier transform
signal_complex = signal_x + 1j*signal_y
coeffs_fft = np.fft.fft(signal_complex)
print(coeffs_fft)
#[ 3.40000000e+01+41.j -3.31676888e+00 +1.j -1.00000000e+00 +1.j
# 9.25221011e-01 +1.j -1.00000000e+00 +1.j -4.44089210e-16 +1.j
# -1.00000000e+00 +1.j -1.98094910e+00 +1.j -1.00000000e+00 +1.j
# -1.56275030e+01 +1.j]
Could someone tell me what I'm doing wrong, to be able to use the FFT correctly?

What's meaning of plt.plot(x[0:-1],y/y[0])?

I am plotting an exponential distribution using the information provided by the tutor.
plt.plot(x[:-1],y/y[0])
plt.plot(tvals,pvals)
plt.show()
But, I do not know what's meaning of x[:-1] and y/y[0]?
x[:-1] means all the elements except the last one
y/y[0] is simply dividing the array y by the first value i.e y[0] of the array.
Code Example
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1, 3, 5, 7])
y = np.array([2, 4, 6])
a = x[:-1] # [1, 3, 5]
b = y/y[0] # [1, 2, 3]
plt.plot(a, b)
Output

Reiterative mapping with the previous result

I'm trying to reiterate calculation using the previous result via using map function. I have a code work, but looks ugly. If you have insights, so that a code can be written elegantly, please, teach me. Any help will be very appreciable.
The reiterating process is described as you see in the figure below.
I have put my ugly code and also my trial with map function. I appreciate your help in advance.
The ugly one
import numpy as np
ys=np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
xs=ys
from scipy.interpolate import interp1d
g = interp1d(xs, ys, fill_value='extrapolate')
x0=ys[0]
s1=-4
def func(x1):
return -g(x1)/(x0-x1)-s1
from scipy.optimize import fsolve
initial_guess = 5
x1=fsolve(func, initial_guess)[0]
print(x1)
s2=-2
def func(x2):
return -g(x2)/(x1-x2)-s2
from scipy.optimize import fsolve
initial_guess = 5
x2=fsolve(func, initial_guess)[0]
print(x2)
s3=-0.67
def func(x3):
return -g(x3)/(x2-x3)-s3
from scipy.optimize import fsolve
initial_guess = 5
x3=fsolve(func, initial_guess)[0]
print(x3)
My trial with map function
import numpy as np
ys=np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
xs=ys
from scipy.interpolate import interp1d
g = interp1d(xs, ys, fill_value='extrapolate')
x0=ys[0]
s=[-4,-2,-0.67]
def func(x):
return -g(x)/(x0-x)-s
xall=list(map(func, s))
from scipy.optimize import fsolve
initial_guess = 5*np.ones(s.size)
xi=fsolve(xall, initial_guess)[0]
print(xi)
Maybe you want to use a lambda function as input to fsolve. Something like this:
import numpy as np
from scipy.optimize import fsolve
from scipy.interpolate import interp1d
ys = np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
xs = ys
g = interp1d(xs, ys, fill_value='extrapolate')
x0 = ys[0]
s = [-4, -2, -0.67]
initial_guess = 5
for si in s:
x0 = fsolve(lambda x1: -g(x1)/(x0 - x1) - si, initial_guess)[0]
print(x0)

python 3 empty graph

I have a problem showing data in a graph. The graph frame appears, but no graph is to be seen. Can you please help ?
I made sure that the dimension of the x axis and the data is the same ... I simply cannot find out why I do not get a graph in return.
Thank you very much in advance.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
n = 1000
theta = 0.8
d = np.sqrt(1-theta**2)
def p(x,y):
"Stochastic kernel for the TAR model"
return norm().pdf((y-theta*np.abs(x))/d)/d
Z = norm().rvs(n)
X = np.empty(n)
for t in range(n-1):
X[t+1] = theta*np.abs(X[t])+d*Z[t+1]
n = len(X)
X = X.reshape((n, 1))
ys = np.linspace(-3,3,200)
k = len(ys)
ys = ys.reshape((1,k))
v = p(X,ys)
kernel = np.mean(v, axis=0)
h = len(kernel)
kernel = kernel.reshape((1,h))
fig, ax = plt.subplots(figsize=(10,7))
ax.plot(ys,kernel, 'b-', lw=2,alpha=0.6, label='look ahead estimate')
plt.show()
The problem is, that through reshaping the two 1-dimensional arrays ys and kernel to a 1xk or 1xh array respectively you get 2-dimensional arrays, where the first dimension is 1. The plot function apparently only iterates through the first dimension, which is why the plot doesn't show anything.
I can think of two easy options to fix that:
Do not reshape the variables kernel and ys:
# ... continuing your code ...
ys = np.linspace(-3,3,200)
k = len(ys)
#ys = ys.reshape((1,k))
v = p(X,ys)
kernel = np.mean(v, axis=0)
h = len(kernel)
#kernel = kernel.reshape((1,h))
fig, ax = plt.subplots(figsize=(10,7))
ax.plot(ys,kernel, 'b-', lw=2,alpha=0.6, label='look ahead estimate')
plt.show()
Call your plot function like this:
ax.plot(ys[0],kernel[0], 'b-', lw=2, alpha=0.6, label='look ahead estimate')
I hope this solves your problem.
To understand why you still have to reshape X:
Let's first understand your function p(x,y) in terms of dimensions:
def p(x,y):
"Stochastic kernel for the TAR model"
"""If x is not reshaped, you substract two one-dimensional arrays from each other,
which have not the same dimensions (dim(x) == 1000, dim(y) == 200 in your case).
This throws an error.
If you reshape X before passing to this function, the y array is substracted
element-wise by each of the values of X, which gives you a matrix with dimension
dim(x) x dim(y).
"""
return norm().pdf((y-theta*np.abs(x))/d)/d
For illustration what happens here dimension-wise:
>>> X = np.array([[1], [2], [3], [4]])
>>> Y = np.array([1, 2, 3])
>>> Y-X
array([[ 0, 1, 2],
[-1, 0, 1],
[-2, -1, 0],
[-3, -2, -1]])
Now we take a look what happens with the matrix returned by p(x,y):
The calculation of the kernel with np.mean(v, axis=0), where v is the returned matrix from p(X,ys), works such, that np.mean iterates over the lines of the matrix v and calculates the mean value of each "line vector" in the matrix. This gives you an one dimensional array (dimension of ys) which you can plot over ys.

Integrating over an interpolate function (interp1d) in python

I am trying to do double integration over an interpolated function, in which r = r(x,y).
from scipy import interpolate
import scipy as sp
r = [0, 1, 2]
z = [0, 1, 2]
def cartesian(x, y, f):
r = sp.sqrt(x**2 + y**2)
return f(r)
interp = interpolate.interp1d(r, z)
print(cart(1,1,interp))
a = sp.integrate.dblquad(cart, 0, 1, lambda x: 0, lambda x: 1, args=(interp))
print(a)
Executing the Cartesian function once produces the correct answer. However the integral gives the the following error:
TypeError: integrate() argument after * must be an iterable, not interp1d
I don't understand why my function isn't iterable and do not know how to convert it into an iterable form. Many thanks for any help.
args is supposed to be a sequence of arguments, so:
sp.integrate.dblquad(cart, 0, 1, lambda x: 0, lambda x: 1, args=(interp,))
The comma after interp is critical: in Python, (x) is just x, but (x,) is a tuple (i.e. a sequence).

Categories