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 = functions.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.erf(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.derf(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
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 a_double_property_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- a3 = cppad_py.a_double(3.0) # ok = ok and a3 == 3.0 ok = ok and a3.parameter() ok = ok and not a3.variable() # # near_equal r3 = a3.sqrt() ok = ok and a3.near_equal(r3 * r3) # 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_params() : # ----------------------------------------------------------------------- # Test parameters num_param = 3 num_group = 2 # ----------------------------------------------------------------------- # call effects2params num_fe = num_param num_x = (num_group + 1) * num_fe x = numpy.array( range(num_x), dtype = float ) / num_x ax = a_functions.array2a_double(x) group_sizes = numpy.arange(num_group) * 2 + 1 num_obs = sum( group_sizes ) covs = list() for k in range(num_param) : covs.append( numpy.ones( (num_obs, 1), dtype = float ) ) a_exp = a_functions.a_exp a_link_fun = [ a_exp, identity_fun, a_exp ] a_var_link_fun = num_param * [ identity_fun ] expand = False aparam = a_effects2params( ax, group_sizes, covs, a_link_fun, a_var_link_fun, expand ) # ---------------------------------------------------------------------- # check result eps99 = 99.0 * numpy.finfo(float).eps afe = ax[0 : num_fe] are = ax[num_fe :].reshape( (num_group, num_fe), order='C') asum = afe + are avar = numpy.empty( (num_group, num_fe), dtype=a_double) for j in range(num_fe) : avar[:,j] = a_var_link_fun[j]( asum[:,j] ) acheck = numpy.empty( (num_param, num_group), dtype=a_double ) for k in range(num_param) : acheck[k,:] = a_link_fun[k]( avar[:,k] * covs[k][0] ) # rel_error = aparam / acheck - a_double(1.0) for k in range(num_param) : for i in range(num_group) : assert rel_error[k,i].value() < eps99
def vector_set_get_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- n = 4 bv = cppad_py.vec_bool(n) iv = cppad_py.vec_int(n) dv = numpy.empty(n, dtype=float) av = numpy.empty(n, dtype=cppad_py.a_double) # # setting elements for i in range(n): bv[i] = i > n / 2 iv[i] = 2 * i dv[i] = 3.0 * i av[i] = cppad_py.a_double(4.0 * i) # # for i in range(n): be = bv[i] ok = ok and be == (i > n / 2) # ie = iv[i] ok = ok and ie == 2 * i # de = dv[i] ok = ok and de == 3.0 * i # ae = av[i] ok = ok and ae == 4.0 * i # # return (ok)
def test_dgaussian_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_pdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_gaussian_pdf(at, aparam) f = cppad_py.d_fun(at, ay) # # g(t) = dgaussian_pdf(t, param) at = cppad_py.independent(t) ay = a_functions.a_dgaussian_pdf(at, aparam) g = cppad_py.d_fun(at, ay) # # check a_dgaussian_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
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)
def sparse_hes_xam(): # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables n = 3 # # 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) # # ay[i] = j * ax[j] * ax[i] # 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) ax_j = ax[j] ax_i = ax[i] ay[i] = aj * ax_j * ax_i # # # define af corresponding to f(x) f = cppad_py.d_fun(ax, ay) # # Set select_d (domain) to all true, # initial select_r (range) to all false # initialize r to all zeros select_d = numpy.empty(n, dtype=bool) select_r = numpy.empty(n, dtype=bool) r = numpy.empty(n, dtype=float) for i in range(n): select_d[i] = True select_r[i] = False r[i] = 0.0 # # # only select component n-1 of the range function # f_0 (x) = (n-1) * x_{n-1} * x_0 select_r[0] = True r[0] = 1.0 # # sparisty pattern for Hessian pattern = cppad_py.sparse_rc() f.for_hes_sparsity(select_d, select_r, pattern) # # compute all possibly non-zero entries in Hessian # (should only compute lower triangle becuase matrix is symmetric) subset = cppad_py.sparse_rcv(pattern) # # work space used to save time for multiple calls work = cppad_py.sparse_hes_work() # f.sparse_hes(subset, x, r, pattern, work) # # check that result is sparsity pattern for Hessian of f_0 (x) ok = ok and subset.nnz() == 2 row = subset.row() col = subset.col() val = subset.val() for k in range(2): i = row[k] j = col[k] v = val[k] if i <= j: ok = ok and i == 0 ok = ok and j == n - 1 # if i >= j: ok = ok and i == n - 1 ok = ok and j == 0 # ok = ok and v == n - 1 # # return (ok)
def fun_forward_xam() : # import numpy import cppad_py # # initialize return variable ok = True # --------------------------------------------------------------------- # number of dependent and independent variables n_dep = 1 n_ind = 2 # # create the independent variables ax xp = numpy.empty(n_ind, dtype=float) for i in range( n_ind ) : xp[i] = i + 1.0 # ax = cppad_py.independent(xp) # # create dependent varialbes ay with ay0 = ax0 * ax1 ax0 = ax[0] ax1 = ax[1] ay = numpy.empty(n_dep, dtype=cppad_py.a_double) ay[0] = ax0 * ax1 # # define af corresponding to f(x) = x0 * x1 f = cppad_py.d_fun(ax, ay) # # define X(t) = (3 + t, 2 + t) # it follows that Y(t) = f(X(t)) = (3 + t) * (2 + t) # # Y(0) = 6 and p ! = 1 p = 0 xp[0] = 3.0 xp[1] = 2.0 yp = f.forward(p, xp) ok = ok and yp[0] == 6.0 # # first order Taylor coefficients for X(t) p = 1 xp[0] = 1.0 xp[1] = 1.0 # # first order Taylor coefficient for Y(t) # Y'(0) = 3 + 2 = 5 and p ! = 1 yp = f.forward(p, xp) ok = ok and yp[0] == 5.0 # # second order Taylor coefficients for X(t) p = 2 xp[0] = 0.0 xp[1] = 0.0 # # second order Taylor coefficient for Y(t) # Y''(0) = 2.0 and p ! = 2 yp = f.forward(p, xp) ok = ok and yp[0] == 1.0 # --------------------------------------------------------------------- af = cppad_py.a_fun(f) ok = ok and af.size_order() == 0 # # zero order forward p = 0 axp = numpy.empty(n_ind, dtype=cppad_py.a_double) axp[0] = 3.0 axp[1] = 2.0 ayp = af.forward(p, axp) ok = ok and ayp[0] == cppad_py.a_double(6.0) ok = ok and af.size_order() == 1 # return( ok )
def fun_hessian_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) # # g(x) = w_0 * f_0 (x) = f(x) w = numpy.empty(n_dep, dtype=float) w[0] = 1.0 # # compute Hessian fpp = f.hessian(x, w) # # [ 0.0 , x_2 , x_1 ] # f''(x) = [ x_2 , 0.0 , x_0 ] # [ x_1 , x_0 , 0.0 ] ok = ok and fpp[0, 0] == 0.0 ok = ok and fpp[0, 1] == x[2] ok = ok and fpp[0, 2] == x[1] # ok = ok and fpp[1, 0] == x[2] ok = ok and fpp[1, 1] == 0.0 ok = ok and fpp[1, 2] == x[0] # ok = ok and fpp[2, 0] == x[1] ok = ok and fpp[2, 1] == x[0] ok = ok and fpp[2, 2] == 0.0 # --------------------------------------------------------------------- af = cppad_py.a_fun(f) # # compute and check Hessian aw = numpy.empty(n_dep, dtype=cppad_py.a_double) aw[0] = w[0] afpp = af.hessian(ax, aw) ok = ok and afpp.shape == fpp.shape (nr, nc) = fpp.shape for i in range(nr): for j in range(nc): ok = ok and afpp[i, j] == cppad_py.a_double(fpp[i, j]) # return (ok)
def a_st_loss(r, nu): return numpy.sum(numpy.log(a_double(1.0) + r * r / nu))
def a_expit(t, param): alpha, beta, p = unpack_param(t, param) z = alpha * (t - beta) return p / (a_double(1.0) + a_exp(-z))
def a_gaussian_cdf(t, param): alpha, beta, p = unpack_param(t, param) z = alpha * (t - beta) return p * (a_double(1.0) + a_erf(z)) / a_double(2.0)
def a_normal_loss(r): return a_double(0.5) * numpy.sum(r * r)
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 a_dgaussian_pdf(t, param): alpha, beta, p = unpack_param(t, param) z = alpha * (t - beta) two = a_double(2.0) return -two * z * alpha * a_gaussian_pdf(t, param)