CH82 – optimization¶
Input: Defines the model and constraints
from dcprogs import read_idealized_bursts
from dcprogs.likelihood import QMatrix
name = "CH82.scn"
tau = 1e-4
tcrit = 4e-3
graph = [["V", "V", "V", 0, 0],
["V", "V", 0, "V", 0],
["V", 0, "V", "V", "V"],
[ 0, "V", "V", "V", 0],
[ 0, 0, "V", 0, "V"]]
nopen = 2
qmatrix = QMatrix([[ -3050, 50, 3000, 0, 0 ],
[ 2./3., -1502./3., 0, 500, 0 ],
[ 15, 0, -2065, 50, 2000 ],
[ 0, 15000, 4000, -19000, 0 ],
[ 0, 0, 10, 0, -10 ] ], 2)
bursts = read_idealized_bursts(name, tau=tau, tcrit=tcrit)
Creates the constraints, the likelihood function, as well as a function to create random Q-matrix.
from scipy.optimize import minimize
from numpy import NaN, zeros, arange
import numpy as np
from dcprogs.likelihood.random import qmatrix as random_qmatrix
from dcprogs.likelihood import QMatrix, Log10Likelihood
from dcprogs.likelihood.optimization import reduce_likelihood
likelihood = Log10Likelihood(bursts, nopen, tau, tcrit)
reduced = reduce_likelihood(likelihood, graph)
x = reduced.to_reduced_coords( random_qmatrix(5).matrix )
constraints = []
def create_inequality_constraints(i, value=0e0, sign=1e0):
f = lambda x: sign * (x[i] - value)
def df(x):
a = zeros(x.shape)
a[i] = sign
return a
return f, df
for i in range(len(x)):
f, df = create_inequality_constraints(i)
constraints.append({'type': 'ineq', 'fun': f, 'jac': df})
f, df = create_inequality_constraints(i, 1e4, -1)
constraints.append({'type': 'ineq', 'fun': f, 'jac': df})
def random_starting_point():
from numpy import infty, NaN
from dcprogs.likelihood.random import rate_matrix as random_rate_matrix
for i in range(100):
matrix = random_rate_matrix(N=len(qmatrix.matrix), zeroprob=0)
x = reduced.to_reduced_coords( matrix )
try:
result = reduced(x)
print(result, reduced.to_full_coords(x))
except:
pass
else:
if result != NaN and result != infty and result != -infty: break
else: raise RuntimeError("Could not create random matrix")
return x
def does_not_throw(x):
try: return -reduced(x)
except: return NaN
Performs the minimization
import math
methods = ['COBYLA', 'SLSQP']
x = random_starting_point()
print ('x=', x)
maxx = (x.copy(), reduced(x))
for i in range(len(methods)):
result = minimize(does_not_throw,
x,
method=methods[i],
constraints=constraints,
options={'maxiter': 1000, 'disp':True})
print(result)
if not math.isnan(result.fun):
if result.fun < maxx[1]: maxx = (x.copy(), result.fun)
if result.success and i > 4: break
x += random_starting_point() * 1e-2
if np.all(np.isnan(x)): x = random_starting_point()
print(maxx[0])
print(maxx[1])
-795.0079187129502 [[ -7.31733927e-01 5.73608232e-01 1.58125695e-01 0.00000000e+00
0.00000000e+00]
[ 5.13099956e+03 -5.13147159e+03 0.00000000e+00 4.72028553e-01
0.00000000e+00]
[ 5.34657910e-01 0.00000000e+00 -4.57912950e+03 2.82462703e+02
4.29613214e+03]
[ 0.00000000e+00 8.45220269e-01 2.92597166e-02 -8.74479986e-01
0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 1.57421312e-01 0.00000000e+00
-1.57421312e-01]]
x= [ 5.73608232e-01 1.58125695e-01 5.13099956e+03 4.72028553e-01
5.34657910e-01 2.82462703e+02 4.29613214e+03 8.45220269e-01
2.92597166e-02 1.57421312e-01]
fun: -2150.8720254173086
maxcv: 5.1878344877524985e-16
message: 'Maximum number of function evaluations has been exceeded.'
nfev: 1000
status: 2
success: False
x: array([ 3.01358997e+00, 1.89327366e+02, 5.12972462e+03,
2.44890905e+01, 8.00417955e+02, 2.37558925e+02,
4.24260764e+03, -5.18783449e-16, 3.93011670e+01,
1.32532752e+01])
-2231.1152175140232 [[ -1.11438201e+00 8.32376148e-01 2.82005864e-01 0.00000000e+00
0.00000000e+00]
[ 4.43631622e-01 -1.20756270e+00 0.00000000e+00 7.63931076e-01
0.00000000e+00]
[ 9.51457047e-01 0.00000000e+00 -1.29672622e+03 1.29508725e+03
6.87511017e-01]
[ 0.00000000e+00 7.89527185e+03 9.51068931e-01 -7.89622292e+03
0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 7.13307027e+03 0.00000000e+00
-7.13307027e+03]]
Iteration limit exceeded (Exit mode 9)
Current function value: nan
Iterations: 1001
Function evaluations: 21639
Gradient evaluations: 1001
fun: nan
jac: array([ nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.])
message: 'Iteration limit exceeded'
nfev: 21639
nit: 1001
njev: 1001
status: 9
success: False
x: array([ nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
-11800.651476936484 [[ -8.76004244e+03 2.96504216e-01 8.75974593e+03 0.00000000e+00
0.00000000e+00]
[ 7.01352194e+03 -7.01410216e+03 0.00000000e+00 5.80220290e-01
0.00000000e+00]
[ 6.83310821e-01 0.00000000e+00 -1.59395396e+00 6.06206268e-01
3.04436871e-01]
[ 0.00000000e+00 2.14009497e-01 8.70868111e-01 -1.08487761e+00
0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 3.72315643e+03 0.00000000e+00
-3.72315643e+03]]
[ 5.73608232e-01 1.58125695e-01 5.13099956e+03 4.72028553e-01
5.34657910e-01 2.82462703e+02 4.29613214e+03 8.45220269e-01
2.92597166e-02 1.57421312e-01]
-2150.87202542