Input: Defines the model and constraints


In [2]:
from dcprogs import read_idealized_bursts
from dcprogs.likelihood import QMatrix

name   = 'CH82'
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.


In [5]:
from scipy.optimize import minimize
from numpy import NaN, zeros, arange
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 xrange(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


In [8]:
method = 'COBYLA'
x = random_starting_point()
maxx = (x.copy(), reduced(x))
for i in xrange(2):
  result = minimize( does_not_throw,
                     x,
                     method=method,
                     constraints=constraints,
                     options={'maxiter': 1000, 'disp':True}) 

  print result
  if not 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 any(isnan(x)): x = random_starting_point()
  method = 'SLSQP'                     
print maxx[0]
print maxx[1]


-3948.20229758 [[-7920.3875  0.92486365  7919.4627  0.0  0.0]
 [ 0.55517582 -0.80095681  0.0  0.24578098  0.0]
 [ 0.56113845  0.0 -1041.4415  1040.6404  0.23995299]
 [ 0.0  6264.7974  0.65518461 -6265.4526  0.0]
 [ 0.0  0.0  0.59567264  0.0 -0.59567264]]
  status: 1
    nfev: 472
   maxcv: 0.0
 success: True
     fun: -475.89790397458853
       x: array([  8.36271279e-01,   7.91969309e+03,   4.39549095e+01,
         9.82362014e-01,   7.57945647e+00,   1.03931041e+03,
         2.80566914e+01,   6.26417165e+03,   2.53552953e+00,
         5.90324742e-05])
 message: 'Optimization terminated successfully.'
-1320.28566922 [[-0.85151686  0.62548723  0.22602963  0.0  0.0]
 [ 0.022396727 -0.062215884  0.0  0.039819157  0.0]
 [ 0.18419027  0.0 -0.84143056  0.48693936  0.17030094]
 [ 0.0  0.79020791  2406.581 -2407.3713  0.0]
 [ 0.0  0.0  3447.9226  0.0 -3447.9226]]
Positive directional derivative for linesearch    (Exit mode 8)
            Current function value: -3220.84235128
            Iterations: 21
            Function evaluations: 239
            Gradient evaluations: 17
  status: 8
 success: False
    njev: 17
    nfev: 239
     fun: -3220.84235127546
       x: array([ -1.81880694e-07,   2.75946817e+03,   7.39666756e+03,
         6.86623309e+02,   7.82140937e+03,   3.14601044e+01,
         9.01589486e+03,   8.93304073e+03,  -5.43645200e-07,
         4.97340622e-08])
 message: 'Positive directional derivative for linesearch'
     jac: array([ -2.84118652e-01,   8.08013916e-01,   1.83105469e-04,
         9.15527344e-05,  -1.32110596e-01,  -7.59887695e-03,
         3.45153809e-02,   9.15527344e-05,   3.35693359e-04,
         7.00870855e+06,   0.00000000e+00])
     nit: 21
1497.81512604 [[-1.1363394  0.78958595  0.34675343  0.0  0.0]
 [ 0.34962076 -6983.2469  0.0  6982.8973  0.0]
 [ 0.99531441  0.0 -344.45332  0.86158618  342.59642]
 [ 0.0  0.8029179  0.59347518 -1.3963931  0.0]
 [ 0.0  0.0  0.33958842  0.0 -0.33958842]]
[  9.24863649e-01   7.91946268e+03   5.55175822e-01   2.45780984e-01
   5.61138451e-01   1.04064037e+03   2.39952989e-01   6.26479744e+03
   6.55184611e-01   5.95672644e-01]
-3948.20229758