I receive the following error for my code below when I try to run curve_fit in Python. "function call is not a proper array of floats". I read that it may be caused by not inputting an array, so I converted my list to array, but I still get the same error.
#Calculate initial price
def initial_price(stocks, V, T, M, N, K, r):
dt = float(T)/M
for i in range(M - 1, 0, -1):
#Define x data
xdata = list()
for k in range(0, N):
xdata.append(stocks[k * M + (i - 1)])
#Convert list into array
xdata = np.asarray(xdata)
#Define y data
ydata = list()
for k in range(0, N):
ydata.append(exp(-r * dt) * V[k * M + i])
#Convert list into array
ydata = np.asarray(ydata)
#get optimal values
popt, pcov = curve_fit(cubic, xdata, ydata)
for k in range(0, N):
V[k * M + (i - 1)] = \
max(C_payoff(stocks[k * M + (i - 1)],
cubic(stocks[k * M + (i - 1)], popt[0],
popt[1], popt[2], popt[3])))
#Compute initial price as discounted weighted average
#over initial prices for all paths
sum = 0.0
for k in range(0, N):
sum = sum + V[k * M]
V0 = exp(-r * dt) * (1.0/N) * sum
return V0
#Define a cubic polynomial function
def cubic(x, a0, a1, a2, a3):
return a0 + a1*x + a2 * x ** 2 + a3 * x ** 3
Related
I am trying to show the monte carlo barrier prices for different number of simultations in the x axis. This is what i tried so far but i'm getting the error -> ValueError: x and y must have same first dimension, but have shapes (10,) and (5,).
I am new to python and as hard as i try i cannot find the error
import numpy as np
import numpy.random as npr
import matplotlib.pyplot as plt
def mc_single_barrier_do(S0, K, T, H, r, vol, N, M):
# Constants
dt = T / N # change in time
nudt = (r - 0.5 * vol ** 2) * dt # deterministic component
volsdt = vol * np.sqrt(dt) # diffusion coefficient
erdt = np.exp(r * dt) # discount factor
# Standard Error Placeholders
sum_CT = 0
sum_CT2 = 0
# Monte Carlo Method
for i in range(M):
# Barrier Crossed Flag
BARRIER = False
St = S0
for j in range(N):
epsilon = np.random.normal()
Stn = St * np.exp(nudt + volsdt * epsilon)
St = Stn
Ptn = np.exp(-2. * (H - St) * (H - Stn) / (St ** 2. * volsdt ** 2.))
Pt = Ptn
if Pt >= npr.uniform():
BARRIER = True
if np.amin(St) > H and BARRIER == False:
CT = np.maximum(St - K, 0)
else:
CT = 0.
sum_CT = sum_CT + CT
sum_CT2 = sum_CT2 + CT * CT
C0_MC = np.exp(-r * T) * sum_CT / M
return C0_MC
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
assert (method in ['MC', 'AV', 'CV'])
mean_payoffs = np.zeros(int(np.ceil(max_sample / 10)))
if method == 'MC':
for n_sample in range(10, max_sample + 1, 10):
payoffs = mc_single_barrier_do(n_sample, S0, K, T, H, r, vol, N)
mean_payoffs[int(n_sample / 10 - 1)] = np.mean(payoffs)
return mean_payoffs
r = 0.1
vol = 0.2
T = 2
N = 20
dt = T / N
S0 = 50
K = 50
H = 45
max_sample = 100
MC_price_estimates = sim_iterator(S0, T, r, vol, K, H, max_sample, N, method='MC')
x_axis1 = range(10, max_sample + 1, 10)
plt.plot(x_axis1, MC_price_estimates)
plt.xlabel("No. of Simulations")
plt.ylabel("Estimated option price")
plt.title("Ordinary Monte Carlo Method")
plt.legend()
plt.show()
in your function definition you used:
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
while when using the function you used:
MC_price_estimates = sim_iterator(S0, T, r, vol, K, H, max_sample, N, method='MC')
python has positional arguments, which means the arguments are mapped according to their position, not their name, so in the first position is mapped to the first argument, which means S0 in the second line was mapped to max_sample in the first line, just fix the arguments arrangement, or use keyword arguments S0=S0.
MC_price_estimates = sim_iterator(S0=S0, T=T, r=r, vol=vol, K=K, H=H, max_sample=max_sample, N=N, method='MC')
this is what your code will look like when you fix all arguments to be keyword arguments.
def mc_single_barrier_do(S0, K, T, H, r, vol, N, M):
# Constants
dt = T / N # change in time
nudt = (r - 0.5 * vol ** 2) * dt # deterministic component
volsdt = vol * np.sqrt(dt) # diffusion coefficient
erdt = np.exp(r * dt) # discount factor
# Standard Error Placeholders
sum_CT = 0
sum_CT2 = 0
# Monte Carlo Method
for i in range(M):
# Barrier Crossed Flag
BARRIER = False
St = S0
for j in range(N):
epsilon = np.random.normal()
Stn = St * np.exp(nudt + volsdt * epsilon)
St = Stn
Ptn = np.exp(-2. * (H - St) * (H - Stn) / (St ** 2. * volsdt ** 2.))
Pt = Ptn
if Pt >= npr.uniform():
BARRIER = True
if np.amin(St) > H and BARRIER == False:
CT = np.maximum(St - K, 0)
else:
CT = 0.
sum_CT = sum_CT + CT
sum_CT2 = sum_CT2 + CT * CT
C0_MC = np.exp(-r * T) * sum_CT / M
return C0_MC
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
assert (method in ['MC', 'AV', 'CV'])
mean_payoffs = np.zeros(int(np.ceil(max_sample / 10)))
if method == 'MC':
for n_sample in range(10, max_sample + 1, 10):
payoffs = mc_single_barrier_do(M=n_sample,S0= S0, K=K, T=T, H=H, r=r, vol=vol, N=N)
mean_payoffs[int(n_sample / 10 - 1)] = np.mean(payoffs)
return mean_payoffs
r = 0.1
vol = 0.2
T = 2
N = 20
dt = T / N
S0 = 50
K = 50
H = 45
max_sample = 100
MC_price_estimates = sim_iterator(S0=S0, T=T, r=r, vol=vol, K=K, H=H, max_sample=max_sample, N=N, method='MC')
x_axis1 = range(10, max_sample + 1, 10)
plt.plot(x_axis1, MC_price_estimates)
plt.xlabel("No. of Simulations")
plt.ylabel("Estimated option price")
plt.title("Ordinary Monte Carlo Method")
plt.legend()
plt.show()
I'm trying to compute the continuous function hidden behind the points, but it shows a graph that looks like it actually coutns the points in-between as zeros.
Here's the plot that shows up (100 vectors, red dots - data set, blue plot - my Fourier series):
Here's the python code:
import matplotlib.pyplot as plt
import numpy as np
import math
step = (np.pi * 2) / 5
start = -np.pi
xDiscrete = [start, start + step, start + 2 * step, start + 3 * step, start + 4 * step, np.pi]
yDiscrete = [2.88, 2.98, 3.24, 3.42, 3.57, 3.79]
ak = []
bk = []
a0 = 0
precisionSize = 0.001
n = 100
avgError = 0
def getAN(k):
sum = 0
for ind in range(1, len(yDiscrete)):
sum += yDiscrete[ind] * math.cos(k * xDiscrete[ind])
an = (2.0 / n) * sum
print('a' + str(k) + ' = ' + str(an))
return an
def getBN(k):
sum = 0
for ind in range(1, len(yDiscrete)):
sum += yDiscrete[ind] * math.sin(k * xDiscrete[ind])
bn = (2.0 / n) * sum
print('b' + str(k) + ' = ' + str(bn))
return bn
def getA0():
sum = 0
for ind in range(1, len(yDiscrete)):
sum += yDiscrete[ind]
a0 = (2.0 / n) * sum
print('a0 = ' + str(a0))
return a0
def getFourierOneSum(x, i):
return ak[i - 1] * math.cos(i * x) + bk[i - 1] * math.sin(i * x)
def getFourierAtPoint(x):
sum = a0 / 2
for i in range(1, n + 1):
sum += getFourierOneSum(x, i)
return sum
for i in range(1, n + 1):
ak.append(getAN(i))
bk.append(getBN(i))
a0 = getA0()
x2 = np.arange(-np.pi, np.pi, precisionSize)
y2 = []
for coor in x2:
y2.append(getFourierAtPoint(coor))
plt.plot(xDiscrete, yDiscrete, 'ro', alpha=0.6)
plt.plot(x2, y2)
plt.grid()
plt.title('Approximation')
plt.show()
I've checked where is the problem, and I'm pretty sure it's with the coefficients (functions getAN, getBN, getA0), but I'm not sure how to fix it.
I am seeking to find a finite difference solution to the 1D Nonlinear PDE
u_t = u_xx + u(u_x)^2
Code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import math
'''
We explore three different numerical methods for solving the PDE, with solution u(x, t),
u_t = u_xx + u(u_x)^2
for (x, t) in (0, 1) . (0, 1/5)
u(x, 0) = 40 * x^2 * (1 - x) / 3
u(0, t) = u(1, t) = 0
'''
M = 30
dx = 1 / M
r = 0.25
dt = r * dx**2
N = math.floor(0.2 / dt)
x = np.linspace(0, 1, M + 1)
t = np.linspace(0, 0.2, N + 1)
U = np.zeros((M + 1, N + 1)) # Initial array for solution u(x, t)
U[:, 0] = 40 * x**2 * (1 - x) / 3 # Initial condition (: for the whole of that array)
U[0, :] = 0 # Boundary condition at x = 0
U[-1, :] = 0 # Boundary condition at x = 1 (-1 means end of the array)
'''
Explicit Scheme - Simple Forward Difference Scheme
'''
for q in range(0, N - 1):
for p in range(0, M - 1):
b = 1 / (1 - 2 * r)
C = r * U[p, q] * (U[p + 1, q] - U[p, q])**2
U[p, q + 1] = b * (U[p, q] + r * (U[p + 1, q + 1] + U[p - 1, q + 1]) - C)
T, X = np.meshgrid(t, x)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(T, X, U)
#fig.colorbar(surf, shrink=0.5, aspect=5) # colour bar for reference
ax.set_xlabel('t')
ax.set_ylabel('x')
ax.set_zlabel('u(x, t)')
plt.tight_layout()
plt.savefig('FDExplSol.png', bbox_inches='tight')
plt.show()
The code I use produces the following error:
overflow encountered in double_scalars
C = r * U[p, q] * (U[p + 1, q] - U[p, q])**2
invalid value encountered in double_scalars
U[p, q + 1] = b * (U[p, q] + r * (U[p + 1, q + 1] + U[p - 1, q + 1]) - C)
invalid value encountered in double_scalars
C = r * U[p, q] * (U[p + 1, q] - U[p, q])**2
Z contains NaN values. This may result in rendering artifacts.
surf = ax.plot_surface(T, X, U)
I've looked up these errors and I assume that the square term generates values too small for the dtype. However when I try changing the dtype to account for a larger range of numbers (np.complex128) I get the same error.
The resulting plot obviously has most of its contents missing. So, my question is, what do I do?
Discretisation expression was incorrect.
Should be
for q in range(0, N - 1):
for p in range(0, M - 1):
U[p, q + 1] = r * (U[p + 1, q] - 2 * U[p, q] + U[p - 1, q]) + r * U[p, q] * (U[p + 1, q] - U[p, q])
Dose anyone know how the Confidence interval for the standard deviation is calculated in normfit function in Matlab? I need a python code to calculate such a parameter. In MATLAB, normfit returns 4 parameter, mean, std and Confidence interval of mean (muCI) and Confidence interval of standard deviation (sigmaCI).
[muHat,sigmaHat,muCI,sigmaCI] = normfit(x)
The python code below gives three parameters, muHat, sigmaHat and muCI. But I need the confidence interval of std (sigmaCI) in Python.
def function(data, confidence= 0.95):
a = 1.0 * np.array(data)
n = len(a)
m ,se = np.mean(a), scipy.stats.sem(a)
h = se * scipy.stats.t.ppf((1 + confidence) / 2., n - 1)
sigma = np.std(data, ddof=1)
return m, sigma, [m - h, m + h]
Here is the normfit function in Python.
def normfit(self, data, confidence=0.95):
a = 1.0 * np.array(data)
n = len(a)
m, se = np.mean(a), scipy.stats.sem(a)
h = se * scipy.stats.t.ppf((1 + confidence) / 2., n - 1)
var = np.var(data, ddof=1)
varCI_upper = var * (n - 1) / (scipy.stats.chi2.ppf((1-confidence) / 2, n - 1))
varCI_lower = var * (n - 1) / (scipy.stats.chi2.ppf(1-(1-confidence) / 2, n - 1))
sigma = np.sqrt(var)
sigmaCI_lower = np.sqrt(varCI_lower)
sigmaCI_upper = np.sqrt(varCI_upper)
return m, sigma, [m - h, m + h], [sigmaCI_lower, sigmaCI_upper]
I have written the following code for a chemical reaction kinetics assignment. The problem actually involves rabbits being born and leaving a farm instead of reactions. I'm asked to develop an Explicit Euler method program to model the rabbit population.
My program was running fine (i.e. I wasn't receiving any errors but wasn't getting the results I wanted) until just recently where I've been getting the ValueError (ValueError: setting an array element with a sequence.) message. I'm unsure of what I did to my code to prompt the error.
Any help would be appreciated.
def explicit_euler(df, x0, h, n):
# df - ODE that you wish to solve numerically
# x0 - initials values for ODE
# h - step size
# n - number of steps
for i in range(0, len(x0)):
N = np.zeros((len(x0), n))
t = 0
N[i, 0] = x0[i]
for j in range(0, n - 1):
N[i, j + 1] = N[i, j] + h * df(t, N[i, j])
t += h
return N
def df(t, N):
return [(k2 - k5) * t * N,
(k3 - k4) * t * N,
(k1 - k2 - k3 - (k6 * N)) * t * N]
N0 = [2., 10., 0.] # initial number of rabbits [Male, Female, Baby]
# "Reaction rate" coefficients
k1 = 3.5 # [events/rabbits month]
k2 = k3 = 0.15 # [events/rabbits month]
k4 = 0.1 # [events/rabbits month]
k5 = 0.5 # [events/rabbits month]
k6 = 0.1 # [events/rabbits^2 month]
h = 1 # time steps [month]
tspan = 120 # length of time [month]
n = int(tspan / h) # number of time steps
N = explicit_euler(df, N0, h, n)
t = np.linspace(0, tspan, n)
plot1, = plt.plot(t, N[0, :])
plot2, = plt.plot(t, N[1, :])
plot3, = plt.plot(t, N[2, :])
plt.xlabel('Time [months]')
plt.ylabel('Rabbits')
plt.legend((plot1, plot2, plot3), ('Male', 'Female', 'Babies'))
plt.show()
print(N)
EDIT: Forgot to include the error traceback.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-d31ce8d859bf> in <module>()
39 n = int(tspan / h) # number of time steps
40
---> 41 N = explicit_euler(df, N0, h, n)
42 t = np.linspace(0, tspan, n)
43
<ipython-input-4-d31ce8d859bf> in explicit_euler(df, x0, h, n)
14 for j in range(0, n - 1):
15
---> 16 N[i, j + 1] = N[i, j] + h * df(t, N[i, j])
17 t += h
18
ValueError: setting an array element with a sequence.