Python - Different regular/analytic functions - python

To perform the derivative, I have developed the following code:
import matplotlib.pyplot as plt
import numpy as np
from math import *
xi = jnp.linspace(-3,3)
def f(x):
a = x**3+5
return a
g1i = jax.vmap(jax.grad(f))(xi)
g2i = jax.vmap(jax.grad(jax.grad(f)))(xi)
g3i = jax.vmap(jax.grad(jax.grad(jax.grad(f))))(xi)
plt.plot(xi,yi, label = "f")
plt.plot(xi,g1i, label = "f'")
plt.plot(xi,g2i, label = "f''")
plt.plot(xi,g3i, label = "f'''")
plt.legend()
This code works, but now I am interested in apply the following code to compute the first derivative of a Call price, with respect to the underlying asset (i.e. delta), trying with the following, but it does not works:
import scipy.stats as si
import sympy as sy
import sys
xi = jnp.linspace(1,1.5)
def analytical_call(s0):
T=1.
q=0.
r=0.
k=1.
sigma=0.4
Kt = k*exp((q-r)*T)
d = (log(Kt/s0)+(sigma**2)/2*T)/sigma
result = (Kt * si.norm.cdf((d / sqrt(T)), 0.0, 1.0) - s0 * si.norm.cdf(((d - sigma * T) / sqrt(T)), 0.0, 1.0) ) * exp(-q * T) + exp(-q * T) * (s0 - Kt)
return result
print(analytical_call(1))
g1i = jax.vmap(jax.grad(analytical_call))(xi)
g2i = jax.vmap(jax.grad(jax.grad(analytical_call)))(xi)
plt.plot(xi,yi, label = "f")
plt.plot(xi,g1i, label = "f'")
plt.legend()
Have you some hints? Thanks in advance!

As already mentioned in the comments, you can't use methods outside the jax library like scipy.stats.norm.cdf. Use jax.scipy.stats instead. Similarly, replace exp and sqrt with their jax equivalents jnp.exp and jnp.sqrt:
from jax import jit, grad, vmap
import jax.numpy as jnp
from jax.scipy.stats.norm import cdf
def analytical_call(s0):
T, q, r, k, sigma = 1.0, 0.0, 0.0, 1.0, 0.4
Kt = k*jnp.exp((q-r)*T)
d = (jnp.log(Kt/s0)+(sigma**2)/2*T)/sigma
result = (Kt * cdf((d / jnp.sqrt(T)), 0.0, 1.0) - s0 * cdf(((d - sigma * T) / jnp.sqrt(T)), 0.0, 1.0) ) * jnp.exp(-q * T) + jnp.exp(-q * T) * (s0 - Kt)
return result
g = vmap(grad(analytical_call))
h = vmap(grad(grad(analytical_call)))
xi = jnp.linspace(1,1.5)
Then, you can evaluate g(xi) and h(xi).

Related

What is my problem with the implementation of multivariate_gauss pdf?

I use python to calculate the multivariate_gauss distribution, but I don't know what's wrong.
The code is here
# calculate multi-d gaussian pdf
def mul_gauss(x, mu, sigma) -> float:
d = len(x[0])
front = 1 / math.sqrt(((2 * math.pi) ** d) * np.linalg.det(sigma))
tmp = (np.array(x) - np.array(mu))
tmp_T = np.transpose(tmp)
back = -0.5 * (np.matmul(np.matmul(tmp, np.linalg.inv(sigma)), tmp_T))[0][0]
return front * math.exp(back)
I compared the result with scipy.stats.multivariate_normal(x,mu,sigma)
x = [[2,2]]
mu = [[4,4]]
sigma = [[3,0],[0,3]]
ret_1 = mul_gauss(x, mu, sigma)
ret_2 = scipy.stats.multivariate_normal(x[0], mu[0], sigma).pdf(x[0])
print('ret_1=',ret1)
print('ret_2=',ret2)
and output is
ret_1=0.013984262505331654
ret_2=0.03978873577297383
Could anyone help me?
In line 5 of your main you call the .pdf() on the object instead as a method.
Here is a fix:
# calculate multi-d gaussian pdf
import math
import numpy as np
from scipy import stats
def mul_gauss(x, mu, sigma) -> float:
d = x[0].shape[0]
coeff = 1/np.sqrt((2 * math.pi) ** d * np.linalg.det(sigma))
tmp = x - mu
exponent = -0.5 * (np.matmul(np.matmul(tmp, np.linalg.inv(sigma)), tmp.T))[0][0]
return coeff * math.exp(exponent)
x = np.array([[2,2]])
mu = np.array([[4,4]])
sigma = np.array([[3,0],[0,3]])
ret_1 = mul_gauss(x, mu, sigma)
ret_2 = stats.multivariate_normal.pdf(x[0], mu[0], sigma)
print('ret_1=',ret_1)
print('ret_2=',ret_2)
Output:
ret_1= 0.013984262505331654
ret_2= 0.013984262505331658
Cheers.

why doesn't my gaussian pdf integrate to one?

normal pdf:
import numpy as np
import scipy
def gaussian(x, mu = 0, sigma = 1):
return 1/(np.sqrt(2*np.pi*sigma)) * np.exp(-(x-mu)**2 / (0.5*sigma)**2)
integrate over entire support:
scipy.integrate.quad(gaussian, -np.inf, np.inf)
returns
(0.3535533905932738, 1.4635936470160148e-11)
I know I messed up somewhere in the pdf but i've been starting at it for an hour and i can't see it
Your gaussian function is incorrect. It should be:
def gaussian(x, mu = 0, sigma = 1):
return (1/(sigma * np.sqrt(2 * np.pi))) * np.exp((-(x-mu)**2) / (2 * sigma ** 2))

Can't find the cause of a SyntaxError in matplotlib

I'm currently trying to plot an integral equation in Python. It suposed to give the of the functions for three different values of parameter gama. There is gama depedency of the parameter beta and in the wave function itself. Here is the code:
from scipy.integrate import quad
import numpy as np
from scipy.special import gamma
from scipy.constants import alpha
import matplotlib.pyplot as plt
#Constants
epsilon = 13.1 #dielectric constant of the material
gamma_C = 0.5 # donor impurity linewidth
nr = 3.2 #refractive index of semiconductor
flux = 0.0 # Phi in eqn 8 magnetic flux
R = 5.0 #radius of the quantum ring in nm
r = np.linspace(0, 6 * R)
rho = r / R
m_0 = 0.0067*0.511 # electron effective mass
h = 4.13e-15 # Planck constant in eV
hbar = 6.58e-16 # reduced Planck constant in eV
#Photon energy
hnu = np.linspace(0, 100) #in eV
#Function that calculates the integrand
def func(rho, theta):
betai = gama**2/2
betaf = np.sqrt(1+gama**4/2)
return (R *(gama * rho)**(betai + betaf) *
np.exp(-1/2*(gama * rho)**2) *
(gama*rho)**2/2 )
def cross_section(hnu, gama):
#function that calculates the photoionisation cross section
betai = gama**2/2
betaf = np.sqrt(1+gama**4/2)
Ei = gama**2*(1+betai)-gama**4/2
Ef = gama**2*(3+betaf)-gama**4/2
delta = hbar * gamma_C/(Ef - Ei - hnu)**2 + ( hbar * gamma_C)**2
return (nr/epsilon * 4*np.pi/3 * alpha * hnu *
(abs( np.sqrt(1/2**betai*gamma(betai + 1))*
np.sqrt(1/2**betaf*gamma(betaf + 2)) *
quad(func, 0, np.infty) [0] * delta))
#Plot
plt.figure();plt.clf()
for gama in [1.0, 1.5, 2.0]:
plt.plot(hnu, (cross_section(hnu, gama))
plt.legend(['$\gamma = 1.0$', '$\gamma = 1.5$', '$\gamma = 2.0$'] )
plt.ylabel('Photoionization cross\n section $\sigma (10^{-14}cm^{2}$)')
plt.xlabel('Photon energy $h\\nu (meV)$ ')
But I'm getting a unexpected syntax error on a line of the code:
runfile('/home/daniel/Arquivos_Python/crosssection.py', wdir='/home/daniel/Arquivos_Python')
File "/home/daniel/Arquivos_Python/crosssection.py", line 49
plt.figure();plt.clf()
^
SyntaxError: invalid syntax
Its because your bracket at return of the Cross_section
I've run it and got another error XD
func() missing 1 required positional argument: 'theta'
, at least the Syntax error are known and resolve
here is your edited code:
from scipy.integrate import quad
import numpy as np
from scipy.special import gamma
from scipy.constants import alpha
import matplotlib.pyplot as plt
#Constants
epsilon = 13.1 #dielectric constant of the material
gamma_C = 0.5 # donor impurity linewidth
nr = 3.2 #refractive index of semiconductor
flux = 0.0 # Phi in eqn 8 magnetic flux
R = 5.0 #radius of the quantum ring in nm
r = np.linspace(0, 6 * R)
rho = r / R
m_0 = 0.0067*0.511 # electron effective mass
h = 4.13e-15 # Planck constant in eV
hbar = 6.58e-16 # reduced Planck constant in eV
#Photon energy
hnu = np.linspace(0, 100) #in eV
#Function that calculates the integrand
def func(rho, theta):
betai = gama**2/2
betaf = np.sqrt(1+gama**4/2)
return (R *(gama * rho)**(betai + betaf) *
np.exp(-1/2*(gama * rho)**2) *
(gama*rho)**2/2 )
def cross_section(hnu, gama):
#function that calculates the photoionisation cross section
betai = gama**2/2
betaf = np.sqrt(1+gama**4/2)
Ei = gama**2*(1+betai)-gama**4/2
Ef = gama**2*(3+betaf)-gama**4/2
delta = hbar * gamma_C/(Ef - Ei - hnu)**2 + ( hbar * gamma_C)**2
return (nr/epsilon * 4*np.pi/3 * alpha * hnu *
(abs( np.sqrt(1/2**betai*gamma(betai + 1))*
np.sqrt(1/2**betaf*gamma(betaf + 2)) *
quad(func, 0, np.infty) [0] * delta)))
#Plot
plt.figure()
plt.clf()
for gama in [1.0, 1.5, 2.0]:
plt.plot(hnu, (cross_section(hnu, gama)))
plt.legend(['$\gamma = 1.0$', '$\gamma = 1.5$', '$\gamma = 2.0$'] )
plt.ylabel('Photoionization cross\n section $\sigma (10^{-14}cm^{2}$)')
plt.xlabel('Photon energy $h\\nu (meV)$ ')

Maximum likelihood estimation in python

I want to solve this function.
I want to estimate the parameter in the pin model. The Log converted likelihood function is the same as the attached photo. The parameters to be estimated are (α, δ, μ, εB, εS). I code the 3-steps-for-statement to set initial value. I try to use statsmodel or scipy.minimize to estimate the parameter by applying maximum likelihood estimation. I do not know what parameters to put in detail. Give me an idea..
import timeimport random
import sqlite3
from openpyxl import Workbook
import numpy as np
import scipy.optimize
def cal_likelihood(mean_selling, mean_buying, selling_array, buying_array):
final_param = []
for ini_a in [0.1, 0.3, 0.5, 0.7, 0.9]:
for ini_h in [0.1, 0.3, 0.5, 0.7, 0.9]:
for z in [0.1, 0.3, 0.5, 0.7, 0.9]:
ini_eB = z * mean_buying
cal_u = (mean_buying - ini_eB) / (ini_a * (1-ini_h))
ini_eS = mean_selling - (ini_a * ini_h * cal_u)
i = 0
for i in range(0, len(buying_array)):
k1 = ((-1.0)*(cal_u) - buying_array[i] * scipy.log10(1 + (cal_u/ini_eB)))
k2 = ((-1.0)*(cal_u) - selling_array[i] * scipy.log10(1 + (cal_u/ini_eS)))
k3 = (-1) * buying_array[i] * scipy.log10(1 + (cal_u/ini_eB)) - selling_array[i] * scipy.log10(1 + (cal_u/ini_eS))
kmi = max(k1, k2, k3)
ini_L = ini_a * ini_h * scipy.exp(k1 - kmi) + ini_a * (1 - ini_h) * scipy.exp(k2 - kmi) + (1 - ini_a) * scipy.exp(k3 - kmi) + (buying_array[i] * scipy.log10(ini_eB + ini_h) + selling_array[i] * scipy.log10(ini_eS + ini_h) - (ini_eB + ini_eS) + kmi)

Fitting two Gaussians with python

I'm working on the analysis of some data. Theoretically, there should be two gaussians, that overlap more or less. I found out that fitting the data works best if you don't fit the two gaussians but their distribution function. Actually, this fit seems to work rather well, but if i go back to the density representation of the data it looks somehow wired. The pictures attached speak for them self. Any idea what goes wrong there?
Here is my code:`
import numpy as np
import scipy
import scipy.special
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.optimize import leastsq
from scipy.special import erf
def fitfunction(params,Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio * 0.5 * (1 + erf((Bins -mu)/np.sqrt(2*sigma1**2))) + (1-amp_ratio)* 0.5 * (1 + erf((Bins - (mu + Delta))/np.sqrt(2*sigma2**2)))
def errorfunction(params, Reale_werte, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
if(amp_ratio > 0) and (amp_ratio < 1):
return (Reale_werte - fitfunction(params, Bins))
else:
return (Reale_werte - fitfunction(params, Bins))*100
def Gaussians(params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio/np.sqrt(2*np.pi*sigma1*sigma1) * np.exp(-((Bins-mu)**2) / np.sqrt(2*np.pi*sigma1*sigma1)) + (1-amp_ratio)/np.sqrt(2*np.pi*sigma2*sigma2) * np.exp(-((Bins-(mu + Delta))**2) / np.sqrt(2*np.pi*sigma2*sigma2))
def Gaussian1(params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio/np.sqrt(2*np.pi*sigma1*sigma1) * np.exp(-((Bins-mu)**2) / np.sqrt(2*np.pi*sigma1*sigma1))
def Gaussian2(params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return (1-amp_ratio)/np.sqrt(2*np.pi*sigma2*sigma2) * np.exp(-((Bins-(mu + Delta))**2) / np.sqrt(2*np.pi*sigma2*sigma2))
params = 0.25,1,10,1,5
params_init = 0.75, 0.8, 2.5, 1.2, 4
Bins = np.linspace(-4,18,1024)
data = Gaussians(params, Bins)
summe = np.zeros_like(Bins)
for i in range(Bins.shape[0]-1):
summe[i+1] = summe[i] + data[i]
summe = summe/summe[Bins.shape[0]-1]
params_result = leastsq(errorfunction, params_init, args=(summe, Bins))
plt.plot(Bins,fitfunction(params_result[0], Bins))
plt.plot(Bins, summe, 'x')
plt.savefig("Distribution.png")
plt.show()
print params_result[0]
plt.plot(Bins,Gaussians(params_result[0], Bins))
plt.plot(Bins, data, 'x')
plt.savefig("Gaussian.png")
plt.show()`
I was wondering whether kernel density estimation works in your case:
from scipy.stats import kde
import matplotlib.pyplot as plt
density = kde.gaussian_kde(x) # your data
xgrid = np.linspace(x.min(), x.max(), 1024)
plt.plot(xgrid, density(xgrid))
plt.show()

Categories

Resources