def test_loss() : eps99 = 99.0 * numpy.finfo(float).eps # # test values for t, param r = numpy.array( [ 1, 2, 3], dtype=float ) nu = numpy.array( [ 3, 2, 1], dtype=float ) # ----------------------------------------------------------------------- # f(t) = st_loss ar = cppad_py.independent(r) anu = a_functions.array2a_double(nu) aloss = a_functions.a_st_loss(ar, anu) ay = numpy.array( [ aloss ] ) f = cppad_py.d_fun(ar, ay) # y = f.forward(0, r) check = curvefit.core.functions.st_loss(r, nu) rel_error = y[0] / check - 1.0 # ----------------------------------------------------------------------- # f(t) = normal_loss ar = cppad_py.independent(r) aloss = a_functions.a_normal_loss(ar) ay = numpy.array( [ aloss ] ) f = cppad_py.d_fun(ar, ay) # y = f.forward(0, r) check = curvefit.core.functions.normal_loss(r) rel_error = y[0] / check - 1.0
def test_gaussian_cdf() : eps99 = 99.0 * numpy.finfo(float).eps # # test values for t, param t = numpy.array( [ 5.0 , 10.0 ] ) beta = numpy.array( [ 30.0 , 20.0 ] ) alpha = 2.0 / beta p = numpy.array( [ 0.1, 0.2 ] ) param = numpy.vstack( (alpha, beta, p) ) # # aparam aparam = numpy.empty( param.shape , dtype = cppad_py.a_double ) for i in range( param.shape[0] ) : for j in range( param.shape[1] ) : aparam[i][j] = cppad_py.a_double( param[i][j] ) # ----------------------------------------------------------------------- # f(t) = gaussian_cdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_gaussian_cdf(at, aparam) f = cppad_py.d_fun(at, ay) # # zero order foward mode using same values as during recording y = f.forward(0, t) # # check using curvefit values for same function check = curvefit.core.functions.gaussian_cdf(t, param) rel_error = y / check - 1.0 assert all( abs( rel_error ) < eps99 ) # # compute entire Jacobian of f # (could instead calculate a sparse Jacobian here). J = f.jacobian(t) assert J.shape[0] == t.size assert J.shape[1] == t.size # # check using curvefitl values for derivative function check = curvefit.core.functions.gaussian_pdf(t, param) for i in range( t.size ) : for i in range( t.size ) : if i == j : rel_error = J[i,j] / check[i] - 1.0 assert abs( rel_error ) < eps99 else : assert J[i,j] == 0.0 # ----------------------------------------------------------------------- # g(t) = ln_gaussian_cdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_ln_gaussian_cdf(at, aparam) g = cppad_py.d_fun(at, ay) # # zero order foward mode using same values as during recording y = g.forward(0, t) # # check using curvefit values for same function check = curvefit.core.functions.ln_gaussian_cdf(t, param) rel_error = y / check - 1.0 assert all( abs( rel_error ) < eps99 )
def a_fun_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables m = 1 n = 3 # # Record the function # f(x) = 0.5 * ( x[0]^2 + ... + x[n-1]^2 ) x = numpy.empty(n, dtype=float) for i in range(n): x[i] = i ax = cppad_py.independent(x) ay = numpy.empty(m, dtype=cppad_py.a_double) asum = cppad_py.a_double(0.0) for i in range(n): asum = asum + ax[i] * ax[i] ay[0] = cppad_py.a_double(0.5) * asum f = cppad_py.d_fun(ax, ay) af = cppad_py.a_fun(f) # # Record the function # g(x) = f'(x) * v au = numpy.empty(m, dtype=cppad_py.a_double) av = numpy.empty(n, dtype=cppad_py.a_double) for i in range(n): av[i] = cppad_py.a_double(i) ax = cppad_py.independent(x) af.forward(0, ax) au = af.forward(1, av) g = cppad_py.d_fun(ax, au) # # compute g(x) u = g.forward(0, x) # # compute g'(x) uq = numpy.empty((m, 1), dtype=float) uq[0, 0] = 1.0 xq = g.reverse(1, uq) # # g'(x) = f''(x) * v = v for i in range(n): ok = ok and cppad_py.a_double(xq[i, 0]) == av[i] return ok
def optimize_fixed_1() : import cppad_py import numpy ok = True # theta_true = 2.0 # theta = numpy.array([ 1 ], dtype=float ) atheta = cppad_py.independent(theta) av_0 = (atheta[0] - theta_true) * (atheta[0] - theta_true) / 2.0 av = numpy.array( [ av_0 ] ) f = cppad_py.d_fun(atheta, av) # mixed_obj = cppad_py.mixed( fixed_init = theta , fix_likelihood = f, ) # options = 'String sb yes\n' # suppress optimizer banner options += 'Integer print_level 0\n' # suppress optimizer trace solution = mixed_obj.optimize_fixed( fixed_ipopt_options = options ) theta_opt = solution.fixed_opt[0] ok = ok and abs( theta_true - theta_opt ) < 1e-10 return ok
def to_json_xam(): # import numpy import cppad_py import re # # initialize return variable ok = True # --------------------------------------------------------------------- n = 1 # number of independent variables m = 2 # number of dependent variables # # independent variables x = numpy.array([1.0]) ax = cppad_py.independent(x) # # f(x) = [ x0 + x0, sin(x0) ] ay = numpy.empty(m, dtype=cppad_py.a_double) ay[0] = ax[0] + ax[0] ay[1] = ax[0].sin() f = cppad_py.d_fun(ax, ay) # # check f.to_json json = f.to_json() pattern = r'"op_code" *: *([^,]*),' match = re.search(pattern, json) op_code = int(match.group(1)) ok &= op_code == 1 pattern = r'"name" *: *"([^"]*)" *,' match = re.search(pattern, json) name = match.group(1) ok &= name == 'add' or name == 'sub' # return ok
def fun_property_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n_ind = 1 # number of independent variables n_dep = 2 # number of dependent variables n_var = 1 # phantom variable at address 0 n_op = 1 # special operator at beginning # # dimension some vectors # x = numpy.empty(n_ind, dtype=float) x = numpy.empty(n_ind, dtype=float) ay = numpy.empty(n_dep, dtype=cppad_py.a_double) # # independent variables x[0] = 1.0 ax = cppad_py.independent(x) n_var = n_var + n_ind # one for each indpendent n_op = n_op + n_ind # # first dependent variable ay[0] = ax[0] + ax[0] n_var = n_var + 1 # one variable and operator n_op = n_op + 1 # # second dependent variable ax0 = ax[0] ay[1] = ax0.sin() n_var = n_var + 2 # two varialbes, one operator n_op = n_op + 1 # # define f(x) = y f = cppad_py.d_fun(ax, ay) n_op = n_op + 1 # speical operator at end # # check af properties ok = ok and f.size_domain() == n_ind ok = ok and f.size_range() == n_dep ok = ok and f.size_var() == n_var ok = ok and f.size_op() == n_op ok = ok and f.size_order() == 0 # # compute zero order Taylor coefficients y = f.forward(0, x) ok = ok and f.size_order() == 1 # --------------------------------------------------------------------- af = cppad_py.a_fun(f) # # check af properties ok = ok and af.size_domain() == n_ind ok = ok and af.size_range() == n_dep ok = ok and af.size_var() == n_var ok = ok and af.size_op() == n_op ok = ok and af.size_order() == 0 # return (ok)
def simple_inv_xam(): ok = True x = numpy.array([1.0, 2.0, 3.0, 4.0]) ax = cppad_py.independent(x) # # create the matrix [ [x_0, x_1], [x_2, x_3] ] aA = numpy.reshape(ax, (2, 2), order='C') # # compute inverse of A aAinv = simple_inv(aA) # # create f(x) ay = numpy.reshape(aAinv, 4, order='C') ay = (ax[3] * ax[0] - ax[1] * ax[2]) * ay f = cppad_py.d_fun(ax, ay) # # evaluate the derivative f'(x) J = f.jacobian(x) # # Check the derivative check = numpy.zeros((4, 4)) check[0, 3] = 1.0 check[1, 1] = -1.0 check[2, 2] = -1.0 check[3, 0] = 1.0 # eps99 = 99.0 * numpy.finfo(float).eps ok &= numpy.all(numpy.fabs(J - check) < eps99) return ok
def objective_d_fun(t_all, I_data): # # 8 variables, 4 in ode_p, 4 in y_init x = numpy.ones(8) ax = cppad_py.independent(x) # # x = concatenate( ode_p , y_init ) aode_p = ax[0:4] ay_init = ax[4:8] # # set up seirs model seirs = seirs_class() seirs.set_t_all(t_all) seirs.set_ode_p(aode_p) seirs.set_initial(ay_init) # # compute model for data ay_model = seirs.model() # # Only have I(t) data. aI_model = ay_model[:, 2] # S=0, E=1, I=2, R=3 # # compute Gaussian loss function aresidual = I_data - aI_model aloss = numpy.sum(aresidual * aresidual) aloss = numpy.array([aloss]) # objective_ad = cppad_py.d_fun(ax, aloss) return objective_ad
def optimize_fixed_2() : import cppad_py import numpy ok = True inf = numpy.inf # # define f(x) = x_0 x_3 ( x_0 + x_1 + x_2) + x_2 x_start = numpy.array([ 1, 5, 5, 1 ], dtype=float ) ax = cppad_py.independent(x_start) av_0 = ax[0] * ax[3] * ( ax[0] + ax[1] + ax[2] ) + ax[2] av = numpy.array( [ av_0 ] ) f = cppad_py.d_fun(ax, av) # # define g_0 (x) = x_0 * x_1 * x_2 * x_3 # g_1 (x) = x_0^2 + x_1^2 + x_2^2 + x_3^2 ax = cppad_py.independent(x_start) av_0 = ax[0] * ax[1] * ax[2] * ax[3] av_1 = ax[0]*ax[0] + ax[1]*ax[1] + ax[2]*ax[2] + ax[3]*ax[3] av = numpy.array( [av_0, av_1] ) g = cppad_py.d_fun(ax, av) # x_lower = numpy.array( [1, 1, 1, 1], dtype=float ) x_upper = numpy.array( [5, 5, 5, 5], dtype=float ) g_lower = numpy.array( [ 25, 40], dtype=float ) g_upper = numpy.array( [ inf, 40], dtype=float ) # mixed_obj = cppad_py.mixed( fixed_init = x_start, fix_likelihood = f, fix_constraint = g, ) # options = 'String sb yes\n' # suppress optimizer banner options += 'Integer print_level 0\n' # suppress optimizer trace solution = mixed_obj.optimize_fixed( fixed_ipopt_options = options, fixed_lower = x_lower, fixed_upper = x_upper, fixed_in = x_start, fix_constraint_lower = g_lower, fix_constraint_upper = g_upper, ) x_opt = solution.fixed_opt x_check = numpy.array( [1.00000000, 4.74299963, 3.82114998, 1.37940829] ) ok = ok and numpy.all( numpy.abs( x_opt - x_check ) < 1e-7 ) return ok
def fix_constraint_xam() : import cppad_py import numpy ok = True # g_L = 10.0 theta_hat = numpy.sqrt(g_L) - 2 # # value of theta at which we will record fix_likelihood( theta ) theta = numpy.array([ 0 ], dtype=float ) # # fix_likelihood atheta = cppad_py.independent(theta) av_0 = ( atheta[0] - 1.0 ) * ( atheta[0] - 1.0 ) av = numpy.array( [ av_0 ] ) f = cppad_py.d_fun(atheta, av) # # fix_constraint atheta = cppad_py.independent(theta) av_0 = ( atheta[0] + 2.0 ) * ( atheta[0] + 2.0 ) av = numpy.array( [ av_0] ) g = cppad_py.d_fun(atheta, av) # # # mixed_obj mixed_obj = cppad_py.mixed( fixed_init = theta , fix_likelihood = f, fix_constraint = g, ) # # optimize_fixed options = 'String sb yes\n' # suppress optimizer banner options += 'Integer print_level 0\n' # suppress optimizer trace solution = mixed_obj.optimize_fixed( fixed_ipopt_options = options, fix_constraint_lower = numpy.array( [g_L], dtype=float) ) # # optimal value for theta theta_opt = solution.fixed_opt[0] # # check solution ok = ok and abs(theta_opt / theta_hat - 1.0 ) < 1e-9 return ok
def ran_likelihood_xam(): import cppad_py import numpy ok = True # y_bar = 1.0 # mean of the data y y = 2.0 # data that depends on random effects sigma = 0.5 # standard deviation for the random effects # # value of theta and u at which we will record ran_likelihood( theta , u) theta_u = numpy.array([sigma * sigma, 0.0], dtype=float) # # independent variables during the recording atheta_u = cppad_py.independent(theta_u) # # split out theta and u atheta = atheta_u[0] au = atheta_u[1] # # - log[ p(y|theta,u) ] (dropping terms that are constant w.r.t. theta,u) atmp = (y - y_bar - au) ap_y_theta_u = 0.5 * atmp * atmp / atheta ap_y_theta_u += 0.5 * numpy.log(atheta) # # - log[ p(u|theta) ] (dropping terms that are constant w.r.t. theta,u) atmp = au / sigma ap_u_theta = 0.5 * atmp * atmp # # - log[ p(y|theta, u) p(u|theta) ] av_0 = ap_y_theta_u + ap_u_theta # # function mapping (theta,u) -> v av = numpy.array([av_0]) r = cppad_py.d_fun(atheta_u, av) # # mixed_obj mixed_obj = cppad_py.mixed( fixed_init=theta_u[0:1], random_init=theta_u[1:2], ran_likelihood=r, ) # # optimize_fixed options = 'String sb yes\n' # suppress optimizer banner options += 'Integer print_level 0\n' # suppress optimizer trace solution = mixed_obj.optimize_fixed( fixed_ipopt_options=options, random_ipopt_options=options, ) # # optimal value for theta theta_opt = solution.fixed_opt[0] theta_hat = (y - y_bar) * (y - y_bar) - sigma * sigma # # check solution ok = ok and abs(theta_opt / theta_hat - 1.0) < 1e-8 return ok
def test_gaussian_pdf(): eps99 = 99.0 * numpy.finfo(float).eps # # test values for t, param t = numpy.array([5.0, 10.0]) beta = numpy.array([30.0, 20.0]) alpha = 2.0 / beta p = numpy.array([0.1, 0.2]) param = numpy.vstack((alpha, beta, p)) # # aparam aparam = numpy.empty(param.shape, dtype=cppad_py.a_double) for i in range(param.shape[0]): for j in range(param.shape[1]): aparam[i][j] = cppad_py.a_double(param[i][j]) # ----------------------------------------------------------------------- # f(t) = gaussian_cdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_gaussian_cdf(at, aparam) f = cppad_py.d_fun(at, ay) # # g(t) = d/dt gaussian_cdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_gaussian_pdf(at, aparam) g = cppad_py.d_fun(at, ay) # # check a_gaussian_pdf f.forward(0, t) g0 = g.forward(0, t) dt = a_functions.constant_array((t.size, ), 0.0) for i in range(len(t)): dt[i] = 1.0 df = f.forward(1, dt) rel_error = g0[i] / df[i] - 1.0 dt[i] = 0.0 assert abs(rel_error) < eps99 # ----------------------------------------------------------------------- # check a_ln_dgaussain_cdf at = cppad_py.independent(t) ay = a_functions.a_ln_gaussian_pdf(at, aparam) f = cppad_py.d_fun(at, ay) f0 = f.forward(0, t) rel_error = f0 / numpy.log(g0) - 1 assert all(abs(rel_error) < eps99)
def runge4_multi_step_xam(): ok = True nx = 4 eps99 = 99.0 * numpy.finfo(float).eps # # independent variables for this g(x) = y(1, x) x = numpy.array(nx * [1.0]) ax = cppad_py.independent(x) # # function to pass to runge4.multi_step def fun(t, ay): return f(t, ay, ax) # # initiali value for the ODE n_step = 10 ay_init = numpy.array(nx * [cppad_py.a_double(0.0)]) t_final = 0.75 t_all = [t_final * i / (n_step - 1) for i in range(n_step)] t_all = numpy.array(t_all) # # take multiple steps ay = runge4.multi_step(fun, t_all, ay_init) ay_final = ay[n_step - 1, :] # # g(x) = y(t_final, x) g = cppad_py.d_fun(ax, ay_final) # # Check g_i (x) = prod_{j=0}^i x[j] t^(i+1) / (i+1) ! # 4th order method should be very accutate for functions # or order 4 or less in t. x = numpy.arange(0, nx) + 1.0 gx = g.forward(0, x) prod = 1.0 for i in range(nx): prod = prod * x[i] power = numpy.power(t_final, i + 1) factorial = scipy.misc.factorial(i + 1) check = prod * power / factorial rel_error = gx[i] / check - 1.0 ok &= abs(rel_error) < eps99 # # Check derivative of g_i (x) w.r.t x_j # is zero for i < j and g_i(x) / x_j otherwise J = g.jacobian(x) for j in range(nx): for i in range(nx): if i < j: ok &= J[i, j] == 0.0 else: check = gx[i] / x[j] rel_error = J[i, j] / check - 1.0 ok &= abs(rel_error) < eps99 return ok
def objective_d_fun(t_all, D_data): # n_x = len(x_name) x = 0.1 * numpy.ones(n_x) ax = cppad_py.independent(x) aloss = objective(t_all, D_data, ax) aloss = numpy.array([aloss]) # objective_ad = cppad_py.d_fun(ax, aloss) return objective_ad
def fun_jacobian_xam() : # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables n_dep = 1 n_ind = 3 # # create the independent variables ax x = numpy.empty(n_ind, dtype=float) for i in range( n_ind ) : x[i] = i + 2.0 # ax = cppad_py.independent(x) # # create dependent variables ay with ay0 = ax_0 * ax_1 * ax_2 ax_0 = ax[0] ax_1 = ax[1] ax_2 = ax[2] ay = numpy.empty(n_dep, dtype=cppad_py.a_double) ay[0] = ax_0 * ax_1 * ax_2 # # define af corresponding to f(x) = x_0 * x_1 * x_2 f = cppad_py.d_fun(ax, ay) # # compute the Jacobian f'(x) = ( x_1*x_2, x_0*x_2, x_0*x_1 ) fp = f.jacobian(x) # # check Jacobian x_0 = x[0] x_1 = x[1] x_2 = x[2] ok = ok and fp[0, 0] == x_1 * x_2 ok = ok and fp[0, 1] == x_0 * x_2 ok = ok and fp[0, 2] == x_0 * x_1 # --------------------------------------------------------------------- af = cppad_py.a_fun(f) # ax = numpy.empty(n_ind, dtype=cppad_py.a_double) for i in range( n_ind ) : ax[i] = x[i] # # compute the Jacobian f'(x) = ( x_1*x_2, x_0*x_2, x_0*x_1 ) afp = af.jacobian(ax) # # check Jacobian ok = ok and afp[0, 0] == cppad_py.a_double(x_1 * x_2) ok = ok and afp[0, 1] == cppad_py.a_double(x_0 * x_2) ok = ok and afp[0, 2] == cppad_py.a_double(x_0 * x_1) # return( ok )
def test_expit() : eps99 = 99.0 * numpy.finfo(float).eps # # test values for t, param t = numpy.array( [ 5.0 , 10.0 ] ) beta = numpy.array( [ 30.0 , 20.0 ] ) alpha = 2.0 / beta p = numpy.array( [ 0.1, 0.2 ] ) param = numpy.vstack( (alpha, beta, p) ) # # aparam aparam = numpy.empty( param.shape , dtype = cppad_py.a_double ) for i in range( param.shape[0] ) : for j in range( param.shape[1] ) : aparam[i][j] = cppad_py.a_double( param[i][j] ) # ----------------------------------------------------------------------- # f(t) = expit(t, param) at = cppad_py.independent(t) ay = a_functions.a_expit(at, aparam) f = cppad_py.d_fun(at, ay) # # zero order foward mode using same values as during recording y = f.forward(0, t) # # check using curvefit values for same function check = curvefit.core.functions.expit(t, param) rel_error = y / check - 1.0 assert all( abs( rel_error ) < eps99 ) # ----------------------------------------------------------------------- # g(t) = ln_gaussian_cdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_ln_expit(at, aparam) g = cppad_py.d_fun(at, ay) # # zero order foward mode using same values as during recording y = g.forward(0, t) # # check using curvefit values for same function check = curvefit.core.functions.ln_expit(t, param) rel_error = y / check - 1.0 assert all( abs( rel_error ) < eps99 )
def test_case(case): ok = True nx = 3 eps99 = 99.0 * numpy.finfo(float).eps # # independent variables for this g(x) = y(1, x) x = numpy.array(nx * [1.0]) ax = cppad_py.independent(x) # if case == 1: fun = first_fun_class(ax) elif case == 2: fun = second_fun_class(ax) else: assert (False) # # initiali value for the ODE ay_start = numpy.array(nx * [cppad_py.a_double(0.0)]) t_start = 0.0 t_step = 0.75 # # take one step ay = rosen3_step(fun, t_start, ay_start, t_step) # # g(x) = y(t_step, x) g = cppad_py.d_fun(ax, ay) # # Check g_i (x) = prod_{j=0}^i x[j] t^(i+1) / (i+1) ! # 3th order method should be very accutate for functions # or order 3 or less in t. x = numpy.arange(0, nx) + 1.0 gx = g.forward(0, x) prod = 1.0 for i in range(nx): prod = prod * x[i] check = prod * numpy.power(t_step, i + 1) / factorial(i + 1) rel_error = gx[i] / check - 1.0 ok &= abs(rel_error) < eps99 # # Check derivative of g_i (x) w.r.t x_j # is zero for i < j and g_i(x) / x_j otherwise J = g.jacobian(x) for j in range(nx): for i in range(nx): if i < j: ok &= J[i, j] == 0.0 else: check = gx[i] / x[j] rel_error = J[i, j] / check - 1.0 ok &= abs(rel_error) < eps99 return ok
def hes_fixed_obj(): import cppad_py import numpy ok = True # n_fixed = 5 n_random = 0 # # value of theta and we will record fix_likelihood( theta ) theta = numpy.ones(n_fixed, dtype=float) # # independent variables during the recording atheta = cppad_py.independent(theta) # a_sum = 0.0 for i in range(n_fixed): j = (i + 1) % n_fixed a_sum += (i + j) * atheta[i] * atheta[j] # av = numpy.array([a_sum], dtype=cppad_py.a_double) f = cppad_py.d_fun(atheta, av) # # mixed_obj empty = numpy.array([], dtype=float) mixed_obj = cppad_py.mixed( fixed_init=theta, random_init=empty, fix_likelihood=f, ) # # hes_fixed_obj_rcv hes_fixed_obj_rcv = cppad_py.sparse_rcv() mixed_obj.hes_fixed_obj( hes_fixed_obj_rcv, fixed_vec=theta, random_opt=empty, ) # check lower triangle of the Hessian ok = ok and hes_fixed_obj_rcv.nr() == n_fixed ok = ok and hes_fixed_obj_rcv.nc() == n_fixed ok = ok and hes_fixed_obj_rcv.nnz() == n_fixed row = hes_fixed_obj_rcv.row() col = hes_fixed_obj_rcv.col() val = hes_fixed_obj_rcv.val() for k in range(hes_fixed_obj_rcv.nnz()): i = row[k] j = col[k] ok = ok and j < i ok = ok and ((j + 1 == i) or (j == 0 and i == n_fixed - 1)) ok = ok and val[k] == (i + j) return ok
def from_json_xam(): # import numpy import cppad_py import math # # initialize return variable ok = True # --------------------------------------------------------------------- # AD graph repersentation of f(x) = sin(x) / cos(x) # # node_1 : x[0] # node_2 : sin( x[0] ) # node_3 : cos( x[0] ) # node_4 : sin( x[0] ) / cos( x[0] ) # y[0] = sin( x[0] ) / cos( x[0] ) json = ''' { "function_name" : "tangent function", "op_define_vec" : [ 3, [ { "op_code":1, "name":"sin", "n_arg":1 } , { "op_code":2, "name":"cos", "n_arg":1 } , { "op_code":3, "name":"div", "n_arg":2 } ] ], "n_dynamic_ind" : 0, "n_variable_ind" : 1, "constant_vec" : [ 0, [ ] ], "op_usage_vec" : [ 3, [ [ 1, 1 ] , [ 2, 1 ] , [ 3, 2, 3] ] ], "dependent_vec" : [ 1, [4] ] }; ''' # convert json to a fucntion object f = cppad_py.d_fun() f.from_json(json) # # compute y = f(x) x = numpy.array([1.0]) y = f.forward(0, x) # # check the function value eps99 = 99.0 * numpy.finfo(float).eps check = math.tan(x[0]) rel_error = y[0] / check - 1.0 ok &= abs(rel_error) < eps99 # return ok
def fix_likelihood_xam() : import cppad_py import numpy ok = True # theta_bar = 1.5 # mean of prior for theta z = 2.0 # data that does not depend on random effects sigma = 0.5 # standard deviation of both data and prior # # value of theta at which we will record fix_likelihood( theta ) theta = numpy.array([ theta_bar ], dtype=float ) # # independent variables during the recording atheta = cppad_py.independent(theta) # # - log[ p(theta) ] (dropping terms that are constant w.r.t theta) atmp = ( atheta[0] - theta_bar ) / sigma ap_theta = 0.5 * atmp * atmp # # - log[ p(z|theta) ] (dropping terms that are constant w.r.t. theta) atmp = ( z - atheta[0] ) / sigma ap_z_theta = 0.5 * atmp * atmp # # - log[ p(z|theta) p(theta) ] av_0 = ap_z_theta + ap_theta # # function mapping theta -> v av = numpy.array( [ av_0 ] ) f = cppad_py.d_fun(atheta, av) # # mixed_obj mixed_obj = cppad_py.mixed( fixed_init = theta , fix_likelihood = f, ) # # optimize_fixed options = 'String sb yes\n' # suppress optimizer banner options += 'Integer print_level 0\n' # suppress optimizer trace solution = mixed_obj.optimize_fixed( fixed_ipopt_options = options ) # # optimal value for theta theta_opt = solution.fixed_opt[0] theta_hat = (theta_bar + z) / 2.0 # # check solution ok = ok and abs( theta_opt - theta_hat ) < 1e-10 return ok
def fun_check_for_nan_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n_ind = 2 # number of independent variables n_dep = 2 # number of dependent variables # # dimension some vectors x = numpy.empty(n_ind, dtype=float) ay = numpy.empty(n_dep, dtype=cppad_py.a_double) # # independent variables x[0] = -1.0 x[1] = 2.0 ax = cppad_py.independent(x) # # dependent variables ay[0] = ax[0]**ax[1] ay[1] = ax[0]**2.0 # # define f(x) = y f = cppad_py.d_fun(ax, ay) # # turn off checking for nan f.check_for_nan(False) # # funtion values are not nan y = f.forward(0, x) ok = ok and y[0] == 1.0 # y[0] = f(x) ok = ok and y[1] == 1.0 # y[1] = f(x) # # Derivative of pow is nan. This would case an assert # if build_type were debug and check_for_nan were true. dx = numpy.ones(n_ind, dtype=float) dy = f.forward(1, dx) ok = ok and numpy.isnan(dy[0]) ok = ok and dy[1] == -2.0 # dy[1] = f'(x) # # Second derivative of pow in also nan ddx = numpy.zeros(n_ind, dtype=float) ddy = f.forward(2, ddx) ok = ok and numpy.isnan(ddy[0]) ok = ok and ddy[1] == 1.0 # ddy[1] = 1/2 * f''(x) # return ok
def fun_optimize_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n_ind = 1 # number of independent variables n_dep = 1 # number of dependent variables n_var = 1 # phantom variable at address 0 n_op = 1 # special operator at beginning # # dimension some vectors x = numpy.empty(n_ind, dtype=float) ay = numpy.empty(n_dep, dtype=cppad_py.a_double) # # independent variables x[0] = 1.0 ax = cppad_py.independent(x) n_var = n_var + n_ind # one for each indpendent n_op = n_op + n_ind # # accumulate summation ax0 = ax[0] csum = cppad_py.a_double(0.0) csum = ax0 + ax0 + ax0 + ax0 n_var = n_var + 3 # one per + operator n_op = n_op + 3 # # define f(x) = y_0 = csum ay[0] = csum f = cppad_py.d_fun(ax, ay) n_op = n_op + 1 # speical operator at end # # check number of variables and operators ok = ok and f.size_var() == n_var ok = ok and f.size_op() == n_op # # optimize f.optimize() # # number of variables and operators has decreased by two ok = ok and f.size_var() == n_var - 2 ok = ok and f.size_op() == n_op - 2 # return (ok)
def check_rosen3_step(fun, ti, yi, h) : ok = True eps99 = 99.0 * numpy.finfo(float).eps # ny = yi.size both = numpy.concatenate( (yi, [ti]) ) aboth = cppad_py.independent(both) az = fun.f(aboth[ny], aboth[0:ny] ) fun_d = cppad_py.d_fun(aboth, az) # J = fun_d.jacobian(both) # # check fun.f_t(t, y) fun_t = fun.f_t(ti, yi) printed = False for i in range(ny) : if J[i, ny] == 0.0 : ok = ok and fun_t[i] == 0.0 else : rel_error = fun_t[i] / J[i,ny] - 1.0 if abs(rel_error) > eps99 : ok = False if not printed : print('check_rosen3_step: fun.f_t check failed') printed = True print('fun_t[', i, '] = ', fun_t[i], ', check = ', J[i,ny]) # # check fun.f_y(t, y) fun_y = fun.f_y(ti, yi) printed = False for i in range(ny) : for j in range(ny) : if J[i, j] == 0.0 : ok_ij =fun_y[i, j] == 0.0 else : rel_error = fun_y[i, j] / J[i, j] - 1.0 ok_ij = abs( rel_error ) < eps99 if (not ok_ij) and (not printed) : print('check_rosen3_step: fun.f_y check failed') printed = True if not ok_ij : msg = 'fun_y[' + str(i) + ',' + str(j) + '] =' msg += str( fun_y[i, j] ) msg += ', check = ' + str( J[i, j] ) print(msg) # return ok
def fun_dynamic_xam(): ok = True nx = 2 nd = 2 # # value of independent variables during recording x = numpy.empty(nx, dtype=float) x[0] = 1.0 x[1] = 2.0 # # value of independent dynamic parameters during recording dynamic = numpy.empty(nd, dtype=float) dynamic[0] = 3.0 dynamic[1] = 4.0 # # start recording (ax, adynamic) = cppad_py.independent(x, dynamic) # # create another dynamic paramerer adyn = adynamic[0] + adynamic[1] # # create another variable avar = ax[0] + ax[1] + adyn # # create f(x) = x[0] + x[1] + dynamic[0] + dynamic[1] ay = numpy.empty(1, dtype=cppad_py.a_double) ay[0] = avar f = cppad_py.d_fun(ax, ay) # # check some properties of f ok = ok and f.size_domain() == nx ok = ok and f.size_order() == 0 # # zero order forward mode using same values as during the recording y = cppad_py.vec_double(1) y = f.forward(0, x) ok = ok and y[0] == (x[0] + x[1] + dynamic[0] + dynamic[1]) # # zero order forward mode using different value for dynamic parameters dynamic[0] = dynamic[0] + 1.0 dynamic[1] = dynamic[1] + 1.0 f.new_dynamic(dynamic) y = f.forward(0, x) ok = ok and y[0] == (x[0] + x[1] + dynamic[0] + dynamic[1]) # return ok
def a_double_cond_assign_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n_ind = 4 n_dep = 1 # # create ax (value of independent variables does not matter) x = numpy.empty(n_ind, dtype=float) x[0] = 0.0 x[1] = 1.0 x[2] = 2.0 x[3] = 3.0 ax = cppad_py.independent(x) # # arguments to conditional assignment left = ax[0] right = ax[1] if_true = ax[2] if_false = ax[3] # # assignment target = cppad_py.a_double() target.cond_assign("<", left, right, if_true, if_false) # # f(x) = taget ay = numpy.empty(n_dep, dtype=cppad_py.a_double) ay[0] = target f = cppad_py.d_fun(ax, ay) # # assignment with different independent variable values x[0] = 9.0 # left x[1] = 8.0 # right x[2] = 7.0 # if_true x[3] = 6.0 # if_false p = 0 y = f.forward(p, x) ok = ok and y[0] == 6.0 # return (ok)
def cppad_error_xam() : # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n_ind = 1 # number of independent variables n_dep = 2 # number of dependent variables # # dimension some vectors x = numpy.empty(n_ind, dtype=float) ay = numpy.empty(n_dep, dtype=cppad_py.a_double) # # independent variables x[0] = 0.0 ax = cppad_py.independent(x) # # dependent variables ay[0] = ax[0] ** 2.0 ay[1] = cppad_py.pow_int(ax[0], 2) # # define f(x) = y f = cppad_py.d_fun(ax, ay) # # Attempt to use first order before zero order try : y = f.forward(1, x) except RuntimeError as error : message = str(error) index = 0 index = message.find('file =', index) ok = ok and 0 < index index = message.find('line =', index) ok = ok and 0 < index index = message.find('exp =', index) ok = ok and 0 < index index = message.find('msg =', index) ok = ok and 0 < index # return ok
def fun_reverse_xam() : # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables n_dep = 1 n_ind = 3 # # create the independent variables ax xp = numpy.empty(n_ind, dtype=float) for i in range( n_ind ) : xp[i] = i # ax = cppad_py.independent(xp) # # create dependent variables ay with ay0 = ax_0 * ax_1 * ax_2 ax_0 = ax[0] ax_1 = ax[1] ax_2 = ax[2] ay = numpy.empty(n_dep, dtype=cppad_py.a_double) ay[0] = ax_0 * ax_1 * ax_2 # # define af corresponding to f(x) = x_0 * x_1 * x_2 f = cppad_py.d_fun(ax, ay) # ----------------------------------------------------------------------- # define X(t) = (x_0 + t, x_1 + t, x_2 + t) # it follows that Y(t) = f(X(t)) = (x_0 + t) * (x_1 + t) * (x_2 + t) # and that Y'(0) = x_1 * x_2 + x_0 * x_2 + x_0 * x_1 # ----------------------------------------------------------------------- # zero order forward mode p = 0 xp[0] = 2.0 xp[1] = 3.0 xp[2] = 4.0 yp = f.forward(p, xp) ok = ok and yp[0] == 24.0 # ----------------------------------------------------------------------- # first order reverse (derivative of zero order forward) # define G( Y ) = y_0 = x_0 * x_1 * x_2 m = f.size_range() q = 1 yq1 = numpy.empty( (m, q), dtype=float) yq1[0, 0] = 1.0 xq1 = f.reverse(q, yq1) # partial G w.r.t x_0 ok = ok and xq1[0,0] == 3.0 * 4.0 # partial G w.r.t x_1 ok = ok and xq1[1,0] == 2.0 * 4.0 # partial G w.r.t x_2 ok = ok and xq1[2,0] == 2.0 * 3.0 # ----------------------------------------------------------------------- # first order forward mode p = 1 xp[0] = 1.0 xp[1] = 1.0 xp[2] = 1.0 yp = f.forward(p, xp) ok = ok and yp[0] == 3.0*4.0 + 2.0*4.0 + 2.0*3.0 # ----------------------------------------------------------------------- # second order reverse (derivative of first order forward) # define G( y_0^0 , y_0^1 ) = y_0^1 # = x_1^0 * x_2^0 + x_0^0 * x_2^0 + x_0^0 * x_1^0 q = 2 yq2 = numpy.empty( (m, q), dtype=float) yq2[0, 0] = 0.0 # partial of G w.r.t y_0^0 yq2[0, 1] = 1.0 # partial of G w.r.t y_0^1 xq2 = f.reverse(q, yq2) # partial G w.r.t x_0^0 ok = ok and xq2[0, 0] == 3.0 + 4.0 # partial G w.r.t x_1^0 ok = ok and xq2[1, 0] == 2.0 + 4.0 # partial G w.r.t x_2^0 ok = ok and xq2[2, 0] == 2.0 + 3.0 # ----------------------------------------------------------------------- af = cppad_py.a_fun(f) # # zero order forward axp = numpy.empty(n_ind, dtype=cppad_py.a_double) p = 0 axp[0] = 2.0 axp[1] = 3.0 axp[2] = 4.0 ayp = af.forward(p, axp) ok = ok and ayp[0] == cppad_py.a_double(24.0) # # first order reverse q = 1 ayq1 = numpy.empty( (m, q), dtype=cppad_py.a_double) ayq1[0, 0] = 1.0 axq1 = af.reverse(q, ayq1) # partial G w.r.t x_0 ok = ok and axq1[0,0] == cppad_py.a_double(3.0 * 4.0) # partial G w.r.t x_1 ok = ok and axq1[1,0] == cppad_py.a_double(2.0 * 4.0) # partial G w.r.t x_2 ok = ok and axq1[2,0] == cppad_py.a_double(2.0 * 3.0) # return( ok )
def optimize_fun_xam(): # import numpy import cppad_py import scipy.optimize from optimize_fun_class import optimize_fun_class # ok = True # def a_objective(ax): return ax[0] * ax[3] * (ax[0] + ax[1] + ax[2]) + ax[2] def a_constraint(ax): return [numpy.prod(ax), numpy.sum(ax * ax)] # # objective_ad x = numpy.array([1.0, 2.0, 3.0, 4.0]) ax = cppad_py.independent(x) ay = numpy.array([a_objective(ax)]) objective_ad = cppad_py.d_fun(ax, ay) # # constraint_ad ax = cppad_py.independent(x) ay = numpy.array(a_constraint(ax)) constraint_ad = cppad_py.d_fun(ax, ay) # # optimize_fun optimize_fun = optimize_fun_class(objective_ad, constraint_ad) # # constraints lower_bound = [25.0, 40.0] upper_bound = [numpy.inf, 40.0] nonlinear_constraint = scipy.optimize.NonlinearConstraint( optimize_fun.constraint_fun, lower_bound, upper_bound, jac=optimize_fun.constraint_jac, hess=optimize_fun.constraint_hess, keep_feasible=False) constraints = [nonlinear_constraint] # # bounds lower_bound = 4 * [1.0] upper_bound = 4 * [5.0] bounds = scipy.optimize.Bounds(lower_bound, upper_bound, keep_feasible=False) # # start_point start_point = [1.0, 5.0, 5.0, 1.0] # options = { 'gtol': 1e-8, 'xtol': 1e-8, 'barrier_tol': 1e-8, 'initial_tr_radius': 1.0, 'initial_constr_penalty': 1.0, 'initial_barrier_tolerance': 0.1, 'initial_barrier_parameter': 0.1, 'factorization_method': None, 'finite_diff_rel_step': None, 'maxiter': 50, 'verbose': 0, } # result = scipy.optimize.minimize( optimize_fun.objective_fun, start_point, method='trust-constr', jac=optimize_fun.objective_grad, hess=optimize_fun.objective_hess, constraints=constraints, options=options, bounds=bounds, ) ok = ok and result.success # optimal_point = result.x check = [1.00000000, 4.74299963, 3.82114998, 1.37940829] rel_error = optimal_point / check - 1.0 ok = ok and numpy.all(abs(rel_error) < 1e-5) return ok
sandbox.path() import curvefit # ---------------------------------------------------------------------------- # Loss Functions # ---------------------------------------------------------------------------- eps99 = 99.0 * numpy.finfo(float).eps # # test values for t, param r = numpy.array([1, 2, 3], dtype=float) nu = numpy.array([3, 2, 1], dtype=float) # ----------------------------------------------------------------------- # f(t) = st_loss ar = cppad_py.independent(r) aloss = curvefit.core.functions.st_loss(ar, nu) ay = numpy.array([aloss]) f = cppad_py.d_fun(ar, ay) # y = f.forward(0, r) check = curvefit.core.functions.st_loss(r, nu) rel_error = y[0] / check - 1.0 assert abs(rel_error) < eps99 # ----------------------------------------------------------------------- # f(t) = normal_loss ar = cppad_py.independent(r) aloss = curvefit.core.functions.normal_loss(ar) ay = numpy.array([aloss]) f = cppad_py.d_fun(ar, ay) # y = f.forward(0, r) check = curvefit.core.functions.normal_loss(r) rel_error = y[0] / check - 1.0
def sparse_jac_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables n = 3 # one aone = cppad_py.a_double(1.0) # # create the independent variables ax x = numpy.empty(n, dtype=float) for i in range(n): x[i] = i + 2.0 # ax = cppad_py.independent(x) # # create dependent variables ay with ay[i] = (j+1) * ax[j] # where i = mod(j + 1, n) ay = numpy.empty(n, dtype=cppad_py.a_double) for j in range(n): i = j + 1 if i >= n: i = i - n # aj = cppad_py.a_double(j) ay_i = (aj + aone) * ax[j] ay[i] = ay_i # # # define af corresponding to f(x) f = cppad_py.d_fun(ax, ay) # # sparsity pattern for identity matrix pat_eye = cppad_py.sparse_rc() pat_eye.resize(n, n, n) for k in range(n): pat_eye.put(k, k, k) # # # sparsity pattern for the Jacobian pat_jac = cppad_py.sparse_rc() f.for_jac_sparsity(pat_eye, pat_jac) # # loop over forward and reverse mode for mode in range(2): # compute all possibly non-zero entries in Jacobian subset = cppad_py.sparse_rcv(pat_jac) # work space used to save time for multiple calls work = cppad_py.sparse_jac_work() if mode == 0: f.sparse_jac_for(subset, x, pat_jac, work) # if mode == 1: f.sparse_jac_rev(subset, x, pat_jac, work) # # # check result ok = ok and n == subset.nnz() col_major = subset.col_major() row = subset.row() col = subset.col() val = subset.val() for k in range(n): ell = col_major[k] r = row[ell] c = col[ell] v = val[ell] i = c + 1 if i >= n: i = i - n # ok = ok and c == k ok = ok and r == i ok = ok and v == c + 1.0 # # # return (ok)