Scipy linear-constrained optimisation out of bounds - python

I am trying to maximize certain logLikelihood function, given trajectory T and parameter tMax, with respect to set o 2d + 2d^2 parameters X, where d is fixed integer.
Each parameter valid range is (0, 10), with exception to parameters with indexes 2*i+1 for i in range(d) (using Python convention). For those, the valid range is (-10, 10). Additionally, I create linear constraints, that for each i in range(d) X[2 * i] + X[2 * i + 1] * (tMax + 1.0) >=0
Here is implementation:
# T given
tMax = 500.0
_d = 2
# part of gradient for constraint X[2 * i] + X[2 * i + 1] * (tMax + 1.0) for i fixed in range(_d)
def grad_for_i(i, d, t_max):
g = np.zeros(2 * d + 2 * d**2)
g[2 * i] = 1.0
g[2 * i + 1] = t_max + 1.0
return g
# array of zeros of lenght l with 1 on index j
def one_on_jth(j, l):
r = [0.0 for _ in range(l)]
r[j] = 1.0
return r
new_lin_const = {
'type': 'ineq',
'fun' : lambda x: np.array(
[x[2 * i] + x[2 * i + 1] * (tMax+ 1.0) for i in range(_d)]
+ [x[j] for j in range(2*_d + 2*_d**2) if j not in [2 * i + 1 for i in range(_d)]]
),
'jac' : lambda x: np.array(
[grad_for_i(i, _d, tMax) for i in range(_d)]
+ [one_on_jth(j, 2*_d + 2*_d**2) for j in range(2*_d + 2*_d**2) if j not in [2 * i + 1 for i in range(_d)]]
)
}
X0 = [1.0 for _ in range(2 * (_d ** 2) + 2 * _d)]
bds = [(0.0, 10.0) for _ in range(2 * (_d ** 2) + 2 * _d)]
for i in range(_d):
bds[2*i + 1] = (-10.0, 10.0)
res = optimize.minimize(lambda x, args: -logLikelihood (x, args[0], args[1]),
constraints=new_lin_const, x0 = X0, args=([T, tMax]), method='SLSQP', options={'disp': True}, bounds=bds)
Procedures converges, but result given is out of linear constraints defined bounds:
print(res.x)
#array([ 1.38771114, -0.72145294, 1.3960635 , -0.22399423, 1.49987397,
# 1.45837707, 1.49958886, 1.45772475, 5.88312636, 5.83211339,
# 5.81175866, 5.67393651])
How is it possible, result is out of bounds?

Related

Compute Fourier Series for a discrete set of points

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.

Plot the multiple values returned by a function

My function returns 2 different values which I want to utilise in 2 different graphs using Matplotlib. How can I achieve it?
def option_value_european_put(T, m, r, sigma, mu, E):
cost_value_at_initial_t_put = []
portfolio_payoff_put = []
for e in E:
delta_t = T / m
u = (1 + (sigma * math.sqrt(delta_t)) * (math.sqrt(1 + ((mu ** 2) * delta_t) / math.pow(sigma, 2))))
v = 2 - u
option_stock_price_matrix_put = np.zeros((m + 1, m + 1))
sum = 0
k = m
start = m
for i in range(m + 1):
option_stock_price_matrix_put[i][start] = max(
(e - stock_price_binomial_model(
mu, sigma, T, m,
S
)[i][start], 0)
)
for j in range(m - 1, -1, -1):
for i in range(0, j + 1):
v_plus = option_stock_price_matrix_put[i][j + 1]
v_minus = option_stock_price_matrix_put[i + 1][j + 1]
v_t = ((((v_plus - v_minus) / (u - v)) * (1 + r * delta_t)) + (u * v_minus - v * v_plus) / (u - v)) / (
1 + r * delta_t)
option_stock_price_matrix_put[i][j] = v_t
cost_value_at_initial_t_put.append(option_stock_price_matrix_put[0][0])
for i in range(0, m+1):
sum = sum + option_stock_price_matrix_put[k][i]
portfolio_return_average = math.average(sum)
portfolio_payoff_put.append(portfolio_return_average-option_stock_price_matrix_put[0][0] )
return cost_value_at_initial_t_put, portfolio_payoff_put
I want to use cost_value_at_initial_t_put in 1 Matplotlib plot and the other value in another plot. How can I use it?
Supposing that cost_value_at_initial_t_put and portfolio_payoff_cut are both lists you can create subplots:
import matplotlib.pyplot as plt
fig, (ax_cost, ax_payoff) = plt.subplots(nrows=2)
ax_cost.plot(cost_value_at_initial_t_put)
ax_payoff.plot(portfolio_payoff_cut)

Overflow and Invalid Values encountered in double scalars - Nonlinear PDE Solving

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])

Crank-Nicolson Method

I need to write the following pseudocode into Python code:
enter image description here
And here is my code:
import math
def f(x):
v = math.sin(math.pi/2*x)
return v
def zero_matrix(i, j, start_from=1):
matrix = [[-1] * (j+start_from)]
for x in range(i):
line = [-1] * start_from + [0] * j
matrix.append(line)
return matrix
def zero_vector(i, start_from=1):
return [-1] * start_from + [0] * i
def algo_12_3(l, T, alpha, m, N):
"""Crank-Nicolson Method.
Args:
l: endpoint
T: maximum time
alpha: constant
m:
N:
Return:
approximations wi,j to u(xi, tj) for each i=i,...,m-1 and j=1,...,N.
"""
w = zero_matrix(m, N)
z = zero_vector(m-1)
ll = zero_vector(m-1)
u = zero_vector(m-1)
h = l / m
k = T / N
lambda_ = alpha * alpha * k / (h * h)
for i in range(1, m):
w[i][0] = f(i * h)
ll[1] = 1 + lambda_
u[1] = -lambda_/(2*ll[1])
for i in range(2, m-1):
ll[i] = 1 + lambda_ + lambda_ * u[i-1]/2
u[i] = -lambda_/(2 * ll[i])
ll[m-1] = 1 + lambda_ + lambda_ * u[m-2]/2
for j in range(1, N + 1):
t = j * k
z[1] = ((1 - lambda_) * w[1][j-1] + lambda_ / 2 * w[2][j-1]) / ll[1]
for i in range(2, m):
z[i] = ((1 - lambda_) * w[i][j-1] + lambda_ / 2 * (w[i+1][j-1] + w[i-1][j-1] + z[i-1])) / ll[i]
w[m-1][j] = z[m-1]
for i in range(m-2, 0, -1):
w[i][j] = z[i] - u[i] * w[i+1][j]
print('t={}: '.format(t))
for i in range(1, m):
print('({}, {})'.format(i*h, w[i][j]))
algo_12_3(2, 0.1, 1, 4, 2)
My outputs are:
t=0.05:
(0.5, 0.6282614874855517)
(1.0, 0.8822836003342388)
(1.5, 0.5449281541522184)
t=0.1:
(0.5, 0.55687611895338)
(1.0, 0.7741379272219071)
(1.5, 0.5013205633978245)
However, the correct outputs should be:
t=0.05:
(0.5, 0.62884835)
(1.0, 0.88932586)
(1.5, 0.62884835)
t=0.1:
(0.5, 0.59404972)
(1.0, 0.84011317)
(1.5, 0.59404972)
I don't know if it's with the range or with the initial matrix formation. Can anyone help me with it? Thanks a lot!! Appreciate it!

Value Error, Shapes do Not Align Python

Yeah, so this is my code in multiclass logistic regression, but when I run it it gives the error of Value Error, Shapes not aligned or whatever.
import numpy
import matplotlib.pyplot as plt
import math as mt
#normalized and feature scaled
Just loading the data set
def load():
data = numpy.loadtxt(open("housing.data.txt", "rb"), dtype="float")
m, n = data.shape
first_col = numpy.ones((m, 1))
#create new array using new parameters
data = numpy.hstack((first_col, data))
#divide each X with the max in the column
#subtract the mean of X to each element
for l in range(1, n):
max = 0.0
sum = 0.0
for j in range(0, m):
if max < data[j, l]:
max = data[j, l]
sum += data[j, l]
avg = sum / m
for j in range(0, m):
data[j, l] -= avg
data[j, l] /= max
return data
def logistic(z):
z = z[0,0]
z = z * -1
return (1.0 / (1.0 + mt.exp(z)))
def hyp(theta, x):
x = numpy.mat(x)
theta = numpy.mat(theta)
return logistic(theta * x.T)
#cost and derivative functions: TO REWRITE
#regularize using "-1000/m (hyp(theta, data[x, :-1]))"
def derv(theta, data, j):
sum = 0.0
last = data.shape[1] - 1
m = data.shape[0]
for x in range(0, m):
sum += (hyp(theta, data[x, :-1]) - numpy.mat(data[x, last])) +
numpy.mat(data[x, j])
return (sum[0,0] / m)
#regularize using " + 1000/2m(hyp(theta, data[x, :-1]))"
def cost(theta, data):
sum = 0.0
last = data.shape[1] - 1
m = data.shape[0]
for x in range(0, m):
y = data[x, last]
sum += y * mt.log(hyp(theta, data[x, :-1])) + (1 - y) * mt.log(1
- hyp(theta, data[x, :-1]))
return -1 * (sum / m)
data = load()
data1 = data[:, [10]]
data2 = data[:, [13]]
d12 = numpy.hstack((data1, data2))
data3 = data[:, [14]]
pdata = numpy.hstack((d12, data3))
print(pdata)
alpha = 0.01
theta = [10,10,10,10]
ntheta = [0,0,0,0]
delta = 50
x = 0
for l in range(0, 1000):
old_cost = cost(theta, pdata)
for y in range(0, data.shape[1] - 1):
ntheta[y] = theta[y] - alpha * derv(theta, data1, y)
for k in range(0, data.shape[1] - 1):
theta[k] = ntheta[k]
new_cost = cost(theta, data1)
delta = new_cost - old_cost
print("Cost: " + str(new_cost))
print("Delta: " + str(delta))
for r in range(0, data.shape[1]):
if hyp(theta, data1[r, :-1]) >= 0.5:
print("Predicted: 1 Actual: " + str(data1[r, data1.shape[1] - 1]))
else:
print("Predicted: 0 Actual: " + str(data1[r, data1.shape[1] - 1]))
plt.scatter(data1[:, 1], data1[:, 2])
x1 = (-1 * theta[0]) / theta[1]
x2 = (-1 * theta[0]) / theta[1]
x = range(-2, 2)
y = [((-1 * theta[0]) - (theta[1] * z) ) for z in x]
plt.plot(x, y)
plt.show()
I'm guessing it cant be plotted like this or idk

Categories

Resources