def wrapper_minimization(HM, starting_pars, parameterIndex=0, problem='hill_min', list_of_constraints=None): # this function takes as input a Hill Model, initial parameter values and the index of the parameter and maximises # the hysteresis parameters # INPUTS # HM Hill model # starting_pars starting parameters for minimization # parameterIndex=1 which parameter is the spacial one in the problem # problem='hysteresis' what problem is to solve # list_of_constraints are there any special constraints? Default = 'hysteresis' and 'norm_param' if list_of_constraints is None: list_of_constraints = ['saddle_node', 'norm_param'] SN = SaddleNode(HM) # find starting point jSearchNodes = np.linspace(starting_pars[parameterIndex] / 10, 10 * starting_pars[parameterIndex], 25) starting_values = SN.find_saddle_node(parameterIndex, starting_pars, freeParameterValues=jSearchNodes, flag_return=1) # restructuring starting values in the right format # the right format: [lambda1, x1, v1, lambda2, x2, v2, other_pars] if starting_values.shape[0] > 1: raise Exception("We found more than 1 saddle node: " + str(starting_values.shape[0])) elif starting_values.shape[0] < 1: raise Exception("We couldn't find 1 saddle node") non_special_starting_pars = ezcat(starting_pars[:parameterIndex], starting_pars[parameterIndex + 1:]) all_starting_values = ezcat(starting_values[0, :], starting_values[1, :], non_special_starting_pars) # create constraints all_constraints = list() if 'saddle_node' in list_of_constraints + [problem]: all_constraints = all_constraints + saddle_node_constraint(SN, parameterIndex) # if 'norm_param' in list_of_constraints: # all_constraints = all_constraints + parameter_norm_constraint(all_starting_values) # create minimizing function if problem is 'saddle_node': min_function, jac_func, hessian_func = hill_coefficient_min() else: raise Exception("Not coded yet = only hysteresis considered") print(all_starting_values) results_min = minimize(min_function, all_starting_values, method='trust-constr', jac=jac_func, constraints=all_constraints, hess=hessian_func) return results_min
if orthogonal: orthogParm_hess = np.zeros([13, 13]) orthogParm_hess[np.ix_(np.arange(5, 9), np.arange(9, 13))] = np.eye(4) orthogParm_hess[np.ix_(np.arange(9, 13), np.arange(5, 9))] = np.eye(4) return np.einsum('ijk, i', D2g, h[:-1]) + h[-1] * orthogParm_hess else: return np.einsum('ijk, i', D2g, h) return saddle_node_problem, saddle_node_jac, saddle_node_hess decay = np.array([np.nan, np.nan], dtype=float) # gamma p1 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_1, delta_1, theta_1) p2 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_2, delta_2, theta_2) f = ToggleSwitch(decay, [p1, p2]) SN = SaddleNode(f) # set up the minimization problem loss, lossJacobian, lossHessian = minimize_hill(SN, punish_degenerate=True) # minimization problem xBounds = [[0, 10], [0, 10]] # phase space bounds for saddle node equilibria points vBounds = [[-5, 5], [-5, 5]] # tangent vector coordinate bounds hillBounds = [[1, 10]] # hill coefficient bounds parameterBounds = [[0, 10] for i in range(8)] # bounds on remaining variable parameters bounds = Bounds(*list(zip(*(xBounds + vBounds + hillBounds + parameterBounds)))) constraintFunction, constraintJacobian, constraintHessian = saddle_node_constraint(SN, orthogonal=False) saddleNodeConstraint = NonlinearConstraint(constraintFunction, 0, 0, jac=constraintJacobian, hess=constraintHessian) # saddleNodeConstraint = NonlinearConstraint(constraintFunction, 0, 0, jac=constraintJacobian, hess=BFGS()) def find_min_hill(hill, parameter): """Gradient descent of the loss function using SciPy optimize"""
import numpy as np import matplotlib.pyplot as plt import time from hill_model import * from saddle_node import SaddleNode from models import ToggleSwitch # set some parameters to test using MATLAB toggle switch for ground truth decay = np.array([np.nan, np.nan], dtype=float) # gamma p1 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_1, delta_1, theta_1) p2 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_2, delta_2, theta_2) f = ToggleSwitch(decay, [p1, p2]) SN = SaddleNode(f) # # =========== NON-DIMENSIONALIZED UNIFORM: 23.36 percent, 5,545 max Hill, 3.393 mean Hill # saveFile = 'tsDataCenter' # hillInitialData = np.linspace(2, 20, 10) # hill = 3 # # # def sample_center(): # """Return a sample point in the DSGRN central region""" # theta_1 = theta_2 = gamma_1 = 1. # set fixed parameters for from non-dimensionalization # ell_1 = np.random.random_sample() # sample in (0, 1) # u_1 = 1. + np.random.random_sample() # sample ell_1 + delta_1 in (1,2) # delta_1 = u_1 - ell_1 # # gamma_2 = 0.1 + 9.9 * np.random.random_sample() # set gamma_2 in (0.1, 10)
decay = np.array([np.nan, np.nan], dtype=float) # gamma p1 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_1, delta_1, theta_1) p2 = np.array([np.nan, np.nan, np.nan], dtype=float) # (ell_2, delta_2, theta_2) f = ToggleSwitch(decay, [p1, p2]) f1 = f.coordinates[0] f2 = f.coordinates[1] H1 = f1.components[0] H2 = f2.components[0] p0 = np.array( [1, 1, 5, 3, 1, 1, 6, 3], dtype=float ) # (gamma_1, ell_1, delta_1, theta_1, gamma_2, ell_2, delta_2, theta_2) SN = SaddleNode(f) # ==== find saddle node for a parameter choice rho = 4.1 p = np.array([1, 1, 5, 3, 1, 1, 6, 3], dtype=float) # x0Sol, v0Sol, rhoSol = [u0Sol.x[idx] for idx in [[0, 1], [2, 3], [4]]] # # compare to rhoSol = [ 4.55637172, 2.25827744, 0.82199933, -0.56948846, 3.17447061] # plot nullclines and equilibria plt.close('all') plt.figure() f.plot_nullcline(rho, p) plt.title('Initial parameters: \n' + np.array2string(ezcat(rho, p))) fig = plt.figure(tight_layout=True, figsize=(15., 9.))