How to set the bounds of scipy.optimize.minimize()? - python

Im trying to minimize function(T) by scipy.optimize.minimize().
With 0 < T < 1.
My code is the following:
import scipy
import math
def function(T):
'''
U = (1- sqrt(T)^(-2)
1 - T^3 * (1 - T - U) ^ 5 * U ^ 10
'''
return 1 - T**3 * (1-T - (T + 1 + 2 * math.sqrt(T))/(T-1)**2) ** 5 * ((T + 1 + 2 * math.sqrt(T))/(T-1)**2)**10
# minimization
res = scipy.optimize.minimize(function, 1, bounds= [(0,1)])
w = res.x
When I run the code it shows the error messege:
RuntimeWarning: divide by zero encountered in true_divide
return 1 - T**x[0] * (1-T - (T + 1 + 2 * math.sqrt(T))/(T-1)**2) ** x[1] * ((T + 1 + 2 * math.sqrt(T))/(T-1)**2)**x[2]
RuntimeWarning: overflow encountered in multiply
return 1 - T**x[0] * (1-T - (T + 1 + 2 * math.sqrt(T))/(T-1)**2) ** x[1] * ((T + 1 + 2 * math.sqrt(T))/(T-1)**2)**x[2]
What is going on? Thanks.
PS: what does the error messages mean?

Related

TypeError: f_p() argument after * must be an iterable, not numpy.float64

I'm coding an algorithm that takes the inverse of a Laplace transform, iterates it until it converges and live-plots the graph. I've dealt with a bunch of errors so far and solved them all but on this one, I'm stumped. Here's the function f_p() that I'm getting the error from. For context, it contains 6 Laplace transforms that I painstakingly derived by hand to eliminate the imaginary component:
def f_p(u, omega, m):
a = gamma
b = (omega + k * math.pi) / u
if m == 1:
f = a * (1 / (a ** 2 + (b + 1) ** 2) + 1 / (a ** 2 + (b - 1) ** 2))
return f * math.cos(omega)
elif m == 2:
f = a / (a ** 2 + b ** 2)
return f * math.cos(omega)
elif m == 3:
f = math.e ** (-a / (a ** 2 + b ** 2)) * (a ** 2 + b ** 2) ** (1 / 4) * math.cos(
(math.atan2(b, a) + 2 * n * math.pi) / 2) * math.cos(b / (a ** 2 + b ** 2)) / (
math.sqrt(a ** 2 + b ** 2) * (math.cos((math.atan2(b, a) + 2 * n * math.pi) / 2) ** 2 + math.sin(
(math.atan2(b, a) + 2 * n * math.pi) / 2)))
return f * math.cos(omega)
elif m == 4:
a = math.e
f = -(a * math.log(a ** 2 + b ** 2) + a ** 2) / (a ** 2 + b ** 2)
return f * math.cos(omega)
elif m == 5:
f = a * (math.e ** (-a) * math.cos(b) - math.e ** (-2 * a) * math.cos(2 * b)) / (a ** 2 + b ** 2)
return f * math.cos(omega)
elif m == 6:
f = math.sqrt((a ** 2 - b ** 2 + 1) ** 2 + (2 * a * b) ** 2) * math.cos(
(math.atan2(2 * a * b, a ** 2 - b ** 2 + 1) + 2 * n * math.pi) / 2) / (
((a ** 2 - b ** 2 + 1) ** 2 + (2 * a * b) ** 2) * (
math.cos((math.atan2(2 * a * b, a ** 2 - b ** 2 + 1) + 2 * n * math.pi) / 2) ** 2 + math.sin(
(math.atan2(2 * a * b, a ** 2 - b ** 2 + 1) + 2 * n * math.pi) / 2) ** 2))
return f * math.cos(omega)
else:
return 0
This function feeds into another function f_u(), which contains the algorithm itself, which integrates over omega, removing it as a variable. The remaining variable is u, which I need to iterate until the function converges. Here's the execution of the algorithm:
u = np.linspace(0.000001, 100, 100000)
if __name__ == '__main__':
pool = Pool(processes=4)
for m in range(1, 7):
if m == 4:
gamma = math.e
else:
gamma = 10
pool.map(f_u, u)
Maybe it could be a syntax problem? I don't know. Any help would be much appreciated.

Integrate Over Multiple Columns in 1 List to Fill Additional List With Same Number Of Columns

I am intending to take a list of random variables and alter a previous list in each column by said random variables. However, for the purpose of my function, each variable must be used in a Gamma function as well as integrated.
x[t] = c * (1 / (2 ** (v / 2) + test[t - 1]) * (gamma((v / 2) + test[t - 1]))) * integrate.\
quad(lambda h: np.exp(-h / 2) * h ** ((v / 2) + test[t - 1] - 1), 0, np.inf)
x[ t ] is an np.zeros((x , y)) list, and test[t - 1] is an np.zeros((x - 1, y)) list
I have filled test[ ] with the appropriate random variables, but I am unable to pass them through this equation to complete the columns of row [ t ] in x
When I try to run my current code, I receive:
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\scipy\integrate\quadpack.py", line 450, in _quad
return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
TypeError: only size-1 arrays can be converted to Python scalars
Is there a different special function which allows me to use each column's variable to solve for my desired x[ t ]?
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import stats
import mpmath as mp
import scipy.integrate as integrate
from scipy.special import gamma
T = 1
beta = 0.5
x0 = 0.05
q = 0
mu = x0 - q
alpha = - (2 - beta) * mu
sigma0 = 0.1
sigma = (2 - beta) * sigma0
b = - ((1 - beta) / (2 * mu) * (sigma0 ** 2))
simulations = 100
M = 50
dt = T / M
def srd_sampled_nxc2():
x = np.zeros((M + 1, simulations))
x[0] = x0
test = np.zeros((M, simulations))
for t in range(1, M + 1):
v = 4 * b * alpha / sigma ** 2
c = (sigma ** 2 * (1 - np.exp(-alpha * dt))) / (4 * alpha)
nc = np.exp(-alpha * dt) / c * x[t - 1]
if v > 1:
x[t] = c * ((np.random.standard_normal(simulations) + nc ** 0.5) ** 2 + mp.nsum(
lambda i: np.random.standard_normal(simulations) ** 2, [0, v - 1]))
else:
max_array = []
nc_over_2 = [l / 2 for l in nc]
for p in range(simulations):
sump = []
poisson_start = 0
while poisson_start <= 1:
x_i = sum(-np.log(np.random.uniform(0, 1, simulations)) / nc_over_2)
sump.append(
x_i
)
poisson_start += x_i
x_n = max(sump)
max_array.append(
x_n
)
sump = []
test[t - 1] = max_array
x[t] = c * (1 / (2 ** ((v / 2) + test[t - 1])) * (gamma((v / 2) + test[t - 1]))) * integrate.\
quad(lambda h: np.exp(-h / 2) * h ** ((v / 2) + test[t - 1] - 1), 0, np.inf)
max_array = []
return x
Ultimately ended up finding a workaround which is simple to implement:
else:
max_array = []
for p in range(simulations):
k = nc[t - 1, p]
lam = k / 2
poisson_samp = 0
while poisson_samp <= 1:
x_i = -math.log(np.random.uniform(0, 1)) / lam
max_array.append(
x_i
)
poisson_samp += x_i
test[t - 1, p] = len(max_array) - 1
max_array.clear()
for f in range(simulations):
n = test[t - 1, f]
z = integrate.quad(lambda h: np.exp(-h / 2) * h ** ((v / 2) + n - 1), 0, 1)
new[t - 1, f] = z[0]
x[t] = c * (1 / (2 ** ((v / 2) + test[t - 1]) * (gamma((v / 2) + test[t - 1]))) * new[0])
The only real problem is the shrinkage of x[t] which leads to dividing by zero--just a formula problem.

Simultaneous equation solver, 4 equations 4 unknowns

Trying to solve a system of 4 equations and 4 unknowns. Keep getting errors for "result from function call is not a proper array of floats". I am new to python so I think the issue is in my def of the equations.
I have tried fsolve, sympy.solve, and with and without a definition.
L0_fcc = 5200
L0_bct = 12000
L0_l = 4700
R = 8.3144
def equations(p):
t, XSnl, XSnfcc, XSnbct = p
GPb_fcc_bct = 489 + 3.52 * t
GPb_fcc_l = 4810 - 8.017 * t
GSn_bct_fcc = 5510 - 8.46 * t
GSn_bct_l = 7179 - 14.216 * t
GSn_fcc_l = 1661 - 5.756 * t
E1 = sp.Eq(GPb_fcc_l + R * t * sp.log((1-XSnl)/(1-XSnfcc)) + L0_l * (XSnl**2) - L0_fcc * (XSnfcc**2))
E2 = sp.Eq(GPb_fcc_bct + R * t * sp.log((1-XSnbct)/(1-XSnfcc)) + L0_bct * (XSnbct**2) - L0_fcc * (XSnfcc**2))
E3 = sp.Eq(GSn_fcc_l + R * t * sp.log(XSnl/XSnfcc) + L0_l * ((1-XSnl)**2) - L0_fcc * ((1-XSnfcc)**2))
E4 = sp.Eq(GSn_bct_l + R * t * sp.log(XSnl/XSnbct) + L0_l * ((1-XSnl)**2) - L0_bct * ((1-XSnbct)**2))
return (E1, E2, E3, E4)
x0 = [300, 0, 0, 0]
t, XSnl, XSnfcc, XSnbct = fsolve(equations, x0)
print(t, XSnl, XSnfcc, XSnbct)`
It should come out with 4 values, 3 of which should be between 0 and 1. I am getting the "Result from function call is not a proper array of floats"
I'm not sure why you would expect sympy objects to interact with scipy solvers, they are completely different libraries. The former is symbolic objects and the latter is numerical analysis.
The solution is to simply change the following lines to:
E1 = (GPb_fcc_l + R * t * np.log((1-XSnl)/(1-XSnfcc)) + L0_l * (XSnl**2) - L0_fcc * (XSnfcc**2))
E2 = (GPb_fcc_bct + R * t * np.log((1-XSnbct)/(1-XSnfcc)) + L0_bct * (XSnbct**2) - L0_fcc * (XSnfcc**2))
E3 = (GSn_fcc_l + R * t * np.log(XSnl/XSnfcc) + L0_l * ((1-XSnl)**2) - L0_fcc * ((1-XSnfcc)**2))
E4 = (GSn_bct_l + R * t * np.log(XSnl/XSnbct) + L0_l * ((1-XSnl)**2) - L0_bct * ((1-XSnbct)**2))
return (E1, E2, E3, E4)
Now this results in a RuntimeWarning: invalid value encountered in long_scalars and a RuntimeWarning: divide by zero encountered in double_scalars and finally a RuntimeWarning: The iteration is not making good progress, as measured by the improvement from the last ten iterations. but that's an algorithmic error which you will have to figure out on your own.
(It's almost certainly bad starting conditions since there is a XSnl/XSnfcc == 0/0 term on the first iteration)
Finding numerical solutions to equations if often more an art than a science.

non linear system of differential equations

i'm trying to solve the following non linear system of differential equations
but i don't understand where is the problem in the code that i wrote.
The system is non linear with complex coefficients and complex domain.
from pylab import *
from scipy.integrate import ode
#------initial parameters------
c = 3 * 10 ** 8
h = 6.626 / (2 * pi) * 10 ** -34
kb = 1.3806 * 10 ** -23
TT = 0.1
mm = 1.50 * 10 ** -10
wM = 2 * pi * 10 ** 6
gM = 2 * pi * 10 ** 2
ll = 1064 * 10 ** -9
PL = 100 * 10 ** -4
L = 0.025
k = 1.340 * 10 ** 7
D0 = wM
Ns = 2083
wL = 2 * pi * c / ll
wC = D0 + wL
aL = sqrt((2 * k * PL) / (h * wL))
G0 = wC / L * sqrt(h / (mm * wM))
tau = 1 / k
tciclo = 3 * pi / wM
tauP = 0.5 * pi / wM
tauNP = tciclo - tauP
dtau = 1 / (10 * k)
def fun(t, y, wM,gM,G0,k,D0,aL):
return [wM * y[1],
-wM * y[0] - gM * y[1] + G0 * y[2]*y[2].conjugate(),
-(k + 1j * D0) * y[2] + 1j * G0 * y[0] * y[2]+aL]
y0 = [0.0, 0.0, 0.0]
r = ode(f).set_integrator('zvode', method='bdf')
r.set_initial_value(y0, 0).set_f_params(2.0)
tt = []
yy = []
while r.successful() and r.t < tauP:
r.integrate(r.t + dtau)
tt.append(r.t)
yy.append(r.y)
plot(tt, yy)
show()
Always include the error message in your question. If you don't have any errors, include the output that you got, and explain why it is not what you expected.
Having said that... I see at least one problem with your code. fun has the standard t and y arguments, followed by the parameters wM,gM,G0,k,D0,aL. You must specify a value for each of these parameters in the call to set_f_params(). You currently have set_f_params(2.0), but that call needs six arguments to match the extra parameters of fun.
In a comment, #pv. has pointed out a second problem: ode(f) should be ode(fun).

Solving an equation with Sympy symbols

Is the following code not solvable by Sympy? I've executed this code a couple of minutes ago, but it printed n = 5 on the screen and it stuck.
import sympy
Wmin = 31
m = 8
p = sympy.symbols('p')
for n in range(5, 10):
print 'n = %3d' % n
denominator = (1 + Wmin + p * Wmin * ((1 - (2 * p) ** m) / (1 - 2 * p)))
right = 1 - (1 - 2 / denominator) ** (n - 1)
p_solve = sympy.solve(sympy.Eq(p, right))
print p_solve
Actually, I've solved the equation with bisection method in MATLAB and I'm currently modifying without bisection method and porting in Python.
You could use nsolve to solve a problem like this -- but you need a guess as to where the solution(s) might be:
>>> for n in range(5, 10):
... print 'n = %3d' % n
... denominator = (1 + Wmin + p * Wmin * ((1 - (2 * p) ** m) / (1 - 2 * p)))
... right = 1 - (1 - 2 / denominator) ** (n - 1)
... p_solve = nsolve(sympy.Eq(p, right),p,0)
... print p_solve
...
n = 5
0.181881594898608
n = 6
0.210681675044646
n = 7
0.235278433487669
n = 8
0.256480923202426
n = 9
0.27492972759045

Categories

Resources