def mm_sloppy_plot(): """Plots trajectories of 'P' at different parameter values: a visual confirmation of parameter sloppiness""" # set up base system params = OrderedDict((('K',2.0), ('V',1.0), ('St',2.0), ('epsilon',1e-3), ('kappa',10.0))) # from Antonios' writeup true_params = np.array(params.values()) nparams = true_params.shape[0] transform_id = 't2' # set init concentrations S0 = params['St']; C0 = 0.0; P0 = 0.0 # init concentrations Cs0 = np.array((S0, C0, P0)) # set times at which to collect data tscale = (params['St'] + params['K'])/params['V'] # timescale of slow evolution npts = 20 times = tscale*np.linspace(1,npts,npts)/5.0 # use these params, concentrations and times to define the MM system MM_system = MM.MM_System(Cs0, times, true_params, transform_id) # define variables to test param1_name = 'epsilon' # nparam1s = 2 param1s = [0.01, 0.000001]#np.logspace(-1, -0.5, nparam1s) # # nparam2s = 1 param2_name = 'kappa' param2s = [10.0]#np.logspace(-2, 2, nparam2s) # param1_name = 'K' # # nparam1s = 3 # param1s = np.array((100,))#2*np.logspace(0, 3, nparam1s) # param2_name = 'V' # param2s = 3.0*param1s/10.0 + np.array((10, 0)) # set up figure, add true trajectory fig = plt.figure() ax = fig.add_subplot(111) ax.hold(True) ax.plot(times, MM_system.gen_profile(Cs0, times, true_params)[:,2], label='true params') markers = ['.', 'o', 'v', '^', 's', 'p', '*', 'x', '+', '_', 'D'] count = 0 # true_traj_squared_norm = np.power(np.linalg.norm(MM_system.gen_profile(Cs0, times, true_params)[:,2]), 2) # for recording relative as error, scale of_eval by this norm for param1 in param1s: for param2 in param2s: # update values params[param1_name] = param1 params[param2_name] = param2 # params['V'] = params['K']*3.0/10.0 S0 = params['St']; C0 = 0.0; P0 = 0.0 # init concentrations Cs0 = np.array((S0, C0, P0)) ax.plot(times, MM_system.gen_profile(Cs0, times, np.array(params.values()))[:,2], label=param1_name + '=' + str(param1) + ', ' + param2_name + '=' + str(param2) + ',error=' + str("%1.2e" % (np.power(MM_system.of(params.values()), 0.5)/npts)), marker=markers[count]) count = count + 1 ax.set_xlabel('time') ax.set_ylabel('P') # ax.set_title(r'$\frac{K}{V} = \frac{10}{3}$') ax.legend(fontsize=24, loc='lower right') plt.show()
def check_sloppiness(): """Checks for sloppiness in the model by printing the Hessian's eigenvalues when evaluated at the minimum of least-squares objective fn.""" # set parameters as per suggestions in paper # K = 1.0; V = 1.0; sigma = 1.0; epsilon = 1e-2; kappa = 10.0 # used in first param. transform/ation, now use St instead of sigma # params = np.array((K, V, sigma, epsilon, kappa)) # again, from old transformation # transform_id = 't1' K = 2.0; V = 1.0; St = 2.0; epsilon = 1e-3; kappa = 10.0 # from Antonios' writeup params = np.array((K, V, St, epsilon, kappa)) transform_id = 't2' sigma = St/K # set init concentrations S0 = K*sigma; C0 = 0.0; P0 = 0.0 # init concentrations Cs0 = np.array((S0, C0, P0)) # set times at which to collect data tscale = (sigma + 1)*K/V # timescale of slow evolution npts = 20 times = tscale*np.linspace(1,npts,npts)/5.0 # use these params, concentrations and times to define the MM system MM_system = MM.MM_System(Cs0, times, params, transform_id) # test stepsize's effect on hessian approx as the calculation seems prone to numerical errors nhvals = 20 hvals = np.logspace(-7,-4, nhvals) # numerical delta_h values that will be used in the finite-difference approximations m = 3 # the number of parameters of interest, i.e. '3' if only looking at the effects of K, V and sigma, otherwise '5' to look at effects of all parameters on the obj. fn. eigs = np.empty((nhvals, m)) for i in range(nhvals): hessian_eval = hessian(MM_system.of, params, h=hvals[i]) eigs[i] = np.sort(np.linalg.eigvalsh(hessian_eval[:m,:m])) # plot output fig = plt.figure() ax = fig.add_subplot(111) for i in range(m): ax.cla() ax.plot(hvals, eigs[:,i]) ax.yaxis.get_children()[1].set_size(16) ax.yaxis.get_major_formatter().set_powerlimits((0, 2)) ax.set_xscale('log') ax.set_ylabel('Eigenvalue ' + str(i + 1), fontsize=18) ax.set_xlabel('Finite difference approximation stepsize', fontsize=16) plt.tight_layout() # save in special directory if exists if os.path.isdir('./figs/hessian'): plt.savefig('./figs/hessian/all_eigs' + str(i) + '.png') else: plt.savefig('./all_eigs' + str(i) + '.png')
def sample_sloppy_params_ii(): """Uses mpi4py to parallelize the collection of sloppy parameter sets. The current, naive method is to sample over a noisy grid of points, discarding those whose objective function evaluation exceeds the set tolerance. The resulting sloppy parameter combinations are saved in './data/input'""" # init MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() nprocs = comm.Get_size() # set up true system, basis for future objective function evaluations K_true = 2.0; V_true = 1.0; St_true = 4.0; epsilon_true = 1e-3; kappa_true = 10.0 # from Antonios' writeup sigma_true = St_true/K_true true_params = np.array((K_true, V_true, sigma_true, epsilon_true, kappa_true)) nparams = true_params.shape[0] transform_id = 't1' # set init concentrations S0_true = St_true; C0_true = 0.0; P0_true = 0.0 # init concentrations concs0_true = np.array((S0_true, C0_true, P0_true)) # set times at which to collect data tscale = (sigma_true + 1)*kappa_true/V_true # timescale of slow evolution print tscale npts = 10 times = np.linspace(tscale, 4*tscale, npts) # use these params, concentrations and times to define the MM system MM_system = MM.MM_System(concs0_true, times, true_params, transform_id) # visualize concentration profiles conc_profiles = MM_system.gen_profile(concs0_true, times, true_params) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(times, conc_profiles[:,0], label='S') ax.plot(times, conc_profiles[:,1], label='C') ax.plot(times, conc_profiles[:,2], label='P') # ax.plot(times, MM_system._data[:,0], label='S') # ax.plot(times, MM_system._data[:,1], label='C') # ax.plot(times, MM_system._data[:,2], label='P') ax.set_xlabel('times') ax.set_ylabel('concentration (potentially dimensionless)') ax.legend(loc=2) plt.show(fig)
def sample_sloppy_params(): """Uses mpi4py to parallelize the collection of sloppy parameter sets. The current, naive method is to sample over a noisy grid of points, discarding those whose objective function evaluation exceeds the set tolerance. The resulting sloppy parameter combinations are saved in './data/input'""" # init MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() nprocs = comm.Get_size() # set up true system, basis for future objective function evaluations K = 2.0; V = 1.0; St = 2.0; epsilon = 1e-3; kappa = 10.0 # from Antonios' writeup true_params = np.array((K, V, St, epsilon, kappa)) nparams = true_params.shape[0] transform_id = 't2' sigma = St/K # set init concentrations S0 = St; C0 = 0.0; P0 = 0.0 # init concentrations Cs0 = np.array((S0, C0, P0)) # set times at which to collect data tscale = (sigma + 1)*K/V # timescale of slow evolution npts = 20 times = tscale*np.linspace(1,npts,npts)/5.0 # use these params, concentrations and times to define the MM system MM_system = MM.MM_System(Cs0, times, true_params, transform_id) # # visualize concentration profiles # conc_profiles = MM_system.gen_profile(Cs0, times, true_params) # fig = plt.figure() # ax = fig.add_subplot(111) # ax.plot(times, conc_profiles[:,0], label='S') # ax.plot(times, conc_profiles[:,1], label='C') # ax.plot(times, conc_profiles[:,2], label='P') # ax.set_xlabel('times') # ax.set_ylabel('concentration (potentially dimensionless)') # ax.legend(loc=2) # plt.show(fig) # always gen new data, can run dmaps far faster with c++ # sample params noisily in 5d space, 10 points per axis for a total of 10e5 points (too many?) # center each param at K = 2.0; V = 1.0; St = 2.0; epsilon = 1e-3; kappa = 10.0 npts_per_axis = 8 # # use these ranges as a guide for sampling (with true vals of K = 2.0; V = 1.0; St = 2.0; epsilon = 1e-3; kappa = 10.0): # # epsilons = np.linspace(-4, -1, 5) # little effect # # kappas = np.linspace(-2, 2, 5) # little effect # # Ks = np.linspace(-1, 3, 5) # very significant effect # # Vs = np.linspace(-1, 3, 5) # very significant effect Ks = np.power(10, 2*np.random.uniform(-3, 3, npts_per_axis)) Vs = np.power(10, np.random.uniform(-3, 3, npts_per_axis)) Sts = np.power(10, np.random.uniform(0, 1, npts_per_axis)) test_params = OrderedDict((('K',Ks), ('V',Vs), ('St',Sts))) # parameters being varied param_sets = test_params.values() ntest_params = len(param_sets) const_params = {'eps':epsilon, 'kappa':kappa} # parameters that will be held constant throughout npts = np.power(npts_per_axis, ntest_params) index = np.empty(ntest_params) # used in future calculation to get index of desired parameter combination powers = np.array([np.power(npts_per_axis, i) for i in range(ntest_params)]) # powers of ntest_params, e.g. 1, 5, 25, ... also used in index calc npts_per_proc = npts/nprocs # number of points that will be sent to each process tol = 1.0 # ob. fn. tolerance, i.e. any points for which the ob. fn. exceeds this value will be discarded kept_params = np.empty((npts_per_proc, ntest_params+1)) # storage for all possible params and their respective ob. fn. evaluations kept_npts = 0 # number of parameter sets that fall within tolerated ob. fn. range # unset, ordered param dict params = OrderedDict((('K',False), ('V',False), ('St',False), ('eps',False), ('kappa',False))) for i in range(rank*npts_per_proc, (rank+1)*npts_per_proc): # probably a more efficient method of calculating the current index instead of performing 'ntest_params' calculations every time index = i/powers%npts_per_axis new_params = np.array([param_sets[j][index[j]] for j in range(ntest_params)]) for j, key in enumerate(test_params.keys()): params[key] = new_params[j] for key, val in const_params.items(): params[key] = val # record param set and ob. fn. value if below tolerance ob_fn_eval = MM_system.of(params.values()) if ob_fn_eval < tol and ob_fn_eval is not False: kept_params[kept_npts,:-1] = np.log10(new_params) kept_params[kept_npts,-1] = ob_fn_eval kept_npts += 1 kept_params = kept_params[:kept_npts] # possible to use Gather kept_params = comm.gather(kept_params, root=0) if rank is 0: kept_params = np.concatenate(kept_params) kept_npts = kept_params.shape[0] # create fileheader specifying which params were investigated, e.g. K=True,V=False,St=True,eps=True,kappa=False file_header = ''.join([test_param_key + '=True,' for test_param_key in test_params.keys()]) file_header = file_header + ''.join([const_param_key + '=False,' for const_param_key in const_params.keys()]) # remove trailing comma file_header = file_header[:-1] np.savetxt('./data/input/sloppy_params' + str(kept_npts) + '.csv', kept_params, delimiter=',', header=file_header, comments='') print '************************************************************' print 'generated', kept_npts, 'new points with min obj. fn. value of', np.min(kept_params[:,-1]) print 'saved in ./data/input/sloppy_params' + str(kept_npts) + '.csv' print '************************************************************'
def mm_contour_grid(): nks = 1000 nvs = 1000 Ks = 2*np.logspace(-1, 3, nks) Vs = np.logspace(-1, 3, nvs) if os.path.isfile('./of_evals.csv'): kept_pts = np.genfromtxt('./of_evals.csv', delimiter=',') count = kept_pts.shape[0] else: # set up base system params = OrderedDict((('K',2.0), ('V',1.0), ('St',2.0), ('epsilon',1e-3), ('kappa',10.0))) # from Antonios' writeup true_params = np.array(params.values()) nparams = true_params.shape[0] transform_id = 't2' state_params = ['K'] continuation_param = 'V' # set init concentrations S0 = params['St']; C0 = 0.0; P0 = 0.0 # init concentrations Cs0 = np.array((S0, C0, P0)) # set times at which to collect data tscale = (params['St'] + params['K'])/params['V'] # timescale of slow evolution npts = 20 times = tscale*np.linspace(1,npts,npts)/5.0 # use these params, concentrations and times to define the MM system MM_system = MM.MM_System(Cs0, times, true_params, transform_id) print 'ofeval', MM_system.of(params.values()) of_evals = np.empty((nks, nvs)) test_params = true_params ndiscarded = 0 kept_pts = np.empty((nks*nvs,3)) tol = 0.1 count = 0 for i, K in enumerate(Ks): uf.progress_bar(i+1, nks) for j, V in enumerate(Vs): test_params[0] = K test_params[1] = V try: # of_evals[i,j] = MM_system.of(test_params) of_eval = MM_system.of(test_params) if of_eval < tol: kept_pts[count,0] = K kept_pts[count,1] = V kept_pts[count,2] = of_eval count = count + 1 except CustomErrors.EvalError: ndiscarded = ndiscarded + 1 continue np.savetxt('./of_evals.csv', kept_pts, delimiter=',') print 'threw away', ndiscarded, 'pts' vgrid, kgrid = np.meshgrid(Vs, Ks) solarize('light') # plt.imshow(of_evals) # plt.show() fig = plt.figure() ax = fig.add_subplot(111) ax.set_xscale('log') ax.set_yscale('log') plot = ax.scatter(kept_pts[:count,0], kept_pts[:count,1], c=kept_pts[:count,2], s=5, lw=0) ax.set_xlabel('K') ax.set_ylabel('V') plt.colorbar(plot) plt.show(fig)