void JacobianRev(ADFun<Base> &f, const Vector &x, Vector &jac) { size_t i; size_t j; size_t n = f.Domain(); size_t m = f.Range(); CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == f.Domain() ); CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() ); // argument and result for reverse mode calculations Vector u(n); Vector v(m); // initialize all the components for(i = 0; i < m; i++) v[i] = Base(0); // loop through the different coordinate directions for(i = 0; i < m; i++) { if( f.Parameter(i) ) { // return zero for this component of f for(j = 0; j < n; j++) jac[ i * n + j ] = Base(0); } else { // set v to the i-th coordinate direction v[i] = Base(1); // compute the derivative of this component of f u = f.Reverse(1, v); // reset v to vector of all zeros v[i] = Base(0); // return the result for(j = 0; j < n; j++) jac[ i * n + j ] = u[j]; } } }
virtual void SetUp() { // use a special object for source code generation typedef double Base; typedef CG<Base> CGD; typedef AD<CGD> ADCG; x[0] = 0.5; x[1] = 1.5; // independent variables std::vector<ADCG> u(n); for (size_t j = 0; j < n; j++) u[j] = x[j]; CppAD::Independent(u); // dependent variable vector std::vector<ADCG> Z(m); /** * create the CppAD tape as usual */ Z[0] = 1.5 * x[0] + 1; Z[1] = 1.0 * x[1] + 2; // create f: U -> Z and vectors used for derivative calculations _fun = new ADFun<CGD>(u, Z); /** * Create the dynamic library * (generate and compile source code) */ ModelCSourceGen<double> compHelp(*_fun, _modelName); compHelp.setCreateForwardZero(true); compHelp.setCreateForwardOne(true); compHelp.setCreateReverseOne(true); compHelp.setCreateReverseTwo(true); compHelp.setCreateSparseJacobian(true); compHelp.setCreateSparseHessian(true); GccCompiler<double> compiler; ModelLibraryCSourceGen<double> compDynHelp(compHelp); DynamicModelLibraryProcessor<double> p(compDynHelp); _dynamicLib = p.createDynamicLibrary(compiler); _model = _dynamicLib->model(_modelName); // dimensions ASSERT_EQ(_model->Domain(), _fun->Domain()); ASSERT_EQ(_model->Range(), _fun->Range()); }
void JacobianFor(ADFun<Base> &f, const Vector &x, Vector &jac) { size_t i; size_t j; size_t n = f.Domain(); size_t m = f.Range(); // check Vector is Simple Vector class with Base type elements CheckSimpleVector<Base, Vector>(); CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == f.Domain() ); CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() ); // argument and result for forward mode calculations Vector u(n); Vector v(m); // initialize all the components for(j = 0; j < n; j++) u[j] = Base(0); // loop through the different coordinate directions for(j = 0; j < n; j++) { // set u to the j-th coordinate direction u[j] = Base(1); // compute the partial of f w.r.t. this coordinate direction v = f.Forward(1, u); // reset u to vector of all zeros u[j] = Base(0); // return the result for(i = 0; i < m; i++) jac[ i * n + j ] = v[i]; } }
bool FunCheck( ADFun<Base> &f , Fun &g , const Vector &x , const Base &r , const Base &a ) { bool ok = true; size_t m = f.Range(); Vector yf = f.Forward(0, x); Vector yg = g(x); size_t i; for(i = 0; i < m; i++) ok &= NearEqual(yf[i], yg[i], r, a); return ok; }
void ADFun<Base>::operator=(const ADFun<Base>& f) { size_t m = f.Range(); size_t n = f.Domain(); size_t i; // go through member variables in ad_fun.hpp order // // size_t objects has_been_optimized_ = f.has_been_optimized_; check_for_nan_ = f.check_for_nan_; compare_change_count_ = f.compare_change_count_; compare_change_number_ = f.compare_change_number_; compare_change_op_index_ = f.compare_change_op_index_; num_order_taylor_ = f.num_order_taylor_; cap_order_taylor_ = f.cap_order_taylor_; num_direction_taylor_ = f.num_direction_taylor_; num_var_tape_ = f.num_var_tape_; // // CppAD::vector objects ind_taddr_.resize(n); ind_taddr_ = f.ind_taddr_; dep_taddr_.resize(m); dep_taddr_ = f.dep_taddr_; dep_parameter_.resize(m); dep_parameter_ = f.dep_parameter_; // // pod_vector objects taylor_ = f.taylor_; cskip_op_ = f.cskip_op_; load_op_ = f.load_op_; // // player play_ = f.play_; // // sparse_pack for_jac_sparse_pack_.resize(0, 0); size_t n_set = f.for_jac_sparse_pack_.n_set(); size_t end = f.for_jac_sparse_pack_.end(); if( n_set > 0 ) { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ ); CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_set_.n_set() == 0 ); for_jac_sparse_pack_.resize(n_set, end); for(i = 0; i < num_var_tape_ ; i++) { for_jac_sparse_pack_.assignment( i , i , f.for_jac_sparse_pack_ ); } } // // sparse_set for_jac_sparse_set_.resize(0, 0); n_set = f.for_jac_sparse_set_.n_set(); end = f.for_jac_sparse_set_.end(); if( n_set > 0 ) { CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ ); CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_pack_.n_set() == 0 ); for_jac_sparse_set_.resize(n_set, end); for(i = 0; i < num_var_tape_; i++) { for_jac_sparse_set_.assignment( i , i , f.for_jac_sparse_set_ ); } } }
void ADFun<Base>::operator=(const ADFun<Base>& f) { size_t m = f.Range(); size_t n = f.Domain(); // go through member variables in order // (see ad_fun.hpp for meaning of each variable) compare_change_ = 0; taylor_per_var_ = 0; taylor_col_dim_ = 0; total_num_var_ = f.total_num_var_; ind_taddr_.resize(n); ind_taddr_ = f.ind_taddr_; dep_taddr_.resize(m); dep_taddr_ = f.dep_taddr_; dep_parameter_.resize(m); dep_parameter_ = f.dep_parameter_; play_ = f.play_; if( taylor_ != CPPAD_NULL ) CPPAD_TRACK_DEL_VEC(taylor_); taylor_ = CPPAD_NULL; for_jac_sparse_pack_.resize(0, 0); for_jac_sparse_set_.resize(0, 0); // allocate and copy the Taylor coefficients taylor_per_var_ = f.taylor_per_var_; taylor_col_dim_ = f.taylor_col_dim_; size_t length = total_num_var_ * taylor_col_dim_; if( length > 0 ) taylor_ = CPPAD_TRACK_NEW_VEC(length, taylor_); size_t i, j; for(i = 0; i < total_num_var_; i++) { for(j = 0; j < taylor_per_var_; j++) { taylor_[ i * taylor_col_dim_ + j ] = f.taylor_[ i * taylor_col_dim_ + j ]; } } // allocate and copy the forward sparsity information size_t n_set = f.for_jac_sparse_pack_.n_set(); size_t end = f.for_jac_sparse_pack_.end(); if( n_set > 0 ) { CPPAD_ASSERT_UNKNOWN( n_set == total_num_var_ ); CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_set_.n_set() == 0 ); for_jac_sparse_pack_.resize(n_set, end); for(i = 0; i < total_num_var_ ; i++) { for_jac_sparse_pack_.assignment( i , i , f.for_jac_sparse_pack_ ); } } n_set = f.for_jac_sparse_set_.n_set(); end = f.for_jac_sparse_set_.end(); if( n_set > 0 ) { CPPAD_ASSERT_UNKNOWN( n_set == total_num_var_ ); CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_pack_.n_set() == 0 ); for_jac_sparse_set_.resize(n_set, end); for(i = 0; i < total_num_var_; i++) { for_jac_sparse_set_.assignment( i , i , f.for_jac_sparse_set_ ); } } }