CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_FORWARD1SWEEP_INCLUDED 00003 # define CPPAD_FORWARD1SWEEP_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Eclipse Public License Version 1.0. 00011 00012 A copy of this license is included in the COPYING file of this distribution. 00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00014 -------------------------------------------------------------------------- */ 00015 00016 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00017 /*! 00018 \file forward1sweep.hpp 00019 Compute one Taylor coefficient for each order requested. 00020 */ 00021 00022 /* 00023 \def CPPAD_ATOMIC_CALL 00024 This avoids warnings when NDEBUG is defined and user_ok is not used. 00025 If NDEBUG is defined, this resolves to 00026 \code 00027 user_atom->forward 00028 \endcode 00029 otherwise, it respolves to 00030 \code 00031 user_ok = user_atom->forward 00032 \endcode 00033 This macro is undefined at the end of this file to facillitate its 00034 use with a different definition in other files. 00035 */ 00036 # ifdef NDEBUG 00037 # define CPPAD_ATOMIC_CALL user_atom->forward 00038 # else 00039 # define CPPAD_ATOMIC_CALL user_ok = user_atom->forward 00040 # endif 00041 00042 /*! 00043 \def CPPAD_FORWARD1SWEEP_TRACE 00044 This value is either zero or one. 00045 Zero is the normal operational value. 00046 If it is one, a trace of every forward1sweep computation is printed. 00047 */ 00048 # define CPPAD_FORWARD1SWEEP_TRACE 0 00049 00050 /*! 00051 Compute arbitrary order forward mode Taylor coefficients. 00052 00053 <!-- replace forward0sweep_doc_define --> 00054 \tparam Base 00055 The type used during the forward mode computations; i.e., the corresponding 00056 recording of operations used the type AD<Base>. 00057 00058 \param s_out 00059 Is the stream where output corresponding to PriOp operations will 00060 be written. 00061 00062 \param print 00063 If print is false, 00064 suppress the output that is otherwise generated by the c PriOp instructions. 00065 00066 \param n 00067 is the number of independent variables on the tape. 00068 00069 \param numvar 00070 is the total number of variables on the tape. 00071 This is also equal to the number of rows in the matrix taylor; i.e., 00072 play->num_var_rec(). 00073 00074 \param play 00075 The information stored in play 00076 is a recording of the operations corresponding to the function 00077 \f[ 00078 F : {\bf R}^n \rightarrow {\bf R}^m 00079 \f] 00080 where \f$ n \f$ is the number of independent variables and 00081 \f$ m \f$ is the number of dependent variables. 00082 \n 00083 \n 00084 The object play is effectly constant. 00085 The exception to this is that while palying back the tape 00086 the object play holds information about the current location 00087 with in the tape and this changes during palyback. 00088 00089 \param J 00090 Is the number of columns in the coefficient matrix taylor. 00091 This must be greater than or equal one. 00092 00093 <!-- end forward0sweep_doc_define --> 00094 00095 \param cskip_op 00096 Is a vector with size play->num_op_rec(). 00097 \n 00098 \n 00099 <tt>p = 0</tt> 00100 \n 00101 In this case, 00102 the input value of the elements does not matter. 00103 Upon return, if cskip_op[i] is true, the operator with index i 00104 does not affect any of the dependent variable 00105 (given the value of the independent variables). 00106 \n 00107 \n 00108 <tt>p > 0</tt> 00109 \n 00110 In this case cskip_op is not modified and has the same meaning 00111 as its return value above. 00112 00113 \param var_by_load_op 00114 is a vector with size play->num_load_op_rec(). 00115 \n 00116 \n 00117 <tt>p == 0</tt> 00118 \n 00119 In this case, 00120 The input value of the elements does not matter. 00121 Upon return, 00122 it is the variable index corresponding the result for each load operator. 00123 In the case where the index is zero, 00124 the load operator results in a parameter (not a variable). 00125 Note that the is no variable with index zero on the tape. 00126 \n 00127 \n 00128 <tt>p > 0</tt> 00129 \n 00130 In this case var_by_load_op is not modified and has the meaning 00131 as its return value above. 00132 00133 \param p 00134 is the lowest order of the Taylor coefficients 00135 that are computed during this call. 00136 00137 \param q 00138 is the highest order of the Taylor coefficients 00139 that are computed during this call. 00140 00141 \param taylor 00142 \n 00143 \b Input: 00144 For <code>i = 1 , ... , numvar-1</code>, 00145 <code>k = 0 , ... , p-1</code>, 00146 <code>taylor[ J*i + k]</code> 00147 is the k-th order Taylor coefficient corresponding to 00148 the i-th variable. 00149 \n 00150 \n 00151 \b Input: 00152 For <code>i = 1 , ... , n</code>, 00153 <code>k = p , ... , q</code>, 00154 <code>taylor[ J*j + k]</code> 00155 is the k-th order Taylor coefficient corresponding to 00156 the i-th variable 00157 (these are the independent varaibles). 00158 \n 00159 \n 00160 \b Output: 00161 For <code>i = n+1 , ... , numvar-1</code>, and 00162 <code>k = 0 , ... , p-1</code>, 00163 <code>taylor[ J*i + k]</code> 00164 is the k-th order Taylor coefficient corresponding to 00165 the i-th variable. 00166 00167 \return 00168 If p is not zero, the return value is zero. 00169 If p is zero, 00170 the return value is equal to the number of ComOp operations 00171 that have a different result from when the information in 00172 a play was recorded. 00173 (Note that if NDEBUG is true, there are no ComOp operations 00174 in play and hence this return value is always zero.) 00175 */ 00176 00177 template <class Base> 00178 size_t forward1sweep( 00179 std::ostream& s_out, 00180 const bool print, 00181 const size_t p, 00182 const size_t q, 00183 const size_t n, 00184 const size_t numvar, 00185 player<Base>* play, 00186 const size_t J, 00187 Base* taylor, 00188 bool* cskip_op, 00189 pod_vector<addr_t>& var_by_load_op 00190 ) 00191 { 00192 CPPAD_ASSERT_UNKNOWN( p <= q ); 00193 CPPAD_ASSERT_UNKNOWN( J >= q + 1 ); 00194 CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); 00195 00196 /* 00197 <!-- replace forward0sweep_code_define --> 00198 */ 00199 // op code for current instruction 00200 OpCode op; 00201 00202 // index for current instruction 00203 size_t i_op; 00204 00205 // next variables 00206 size_t i_var; 00207 00208 // operation argument indices 00209 const addr_t* arg = CPPAD_NULL; 00210 00211 // initialize the comparision operator (ComOp) counter 00212 size_t compareCount = 0; 00213 00214 // If this includes a zero calculation, initialize this information 00215 pod_vector<bool> isvar_by_ind; 00216 pod_vector<size_t> index_by_ind; 00217 if( p == 0 ) 00218 { size_t i; 00219 00220 // this includes order zero calculation, initialize vector indices 00221 size_t num = play->num_vec_ind_rec(); 00222 if( num > 0 ) 00223 { isvar_by_ind.extend(num); 00224 index_by_ind.extend(num); 00225 for(i = 0; i < num; i++) 00226 { index_by_ind[i] = play->GetVecInd(i); 00227 isvar_by_ind[i] = false; 00228 } 00229 } 00230 // includes zero order, so initialize conditional skip flags 00231 num = play->num_op_rec(); 00232 for(i = 0; i < num; i++) 00233 cskip_op[i] = false; 00234 } 00235 00236 // work space used by UserOp. 00237 vector<bool> user_vx; // empty vecotor 00238 vector<bool> user_vy; // empty vecotor 00239 vector<Base> user_tx; // argument vector Taylor coefficients 00240 vector<Base> user_ty; // result vector Taylor coefficients 00241 size_t user_index = 0; // indentifier for this atomic operation 00242 size_t user_id = 0; // user identifier for this call to operator 00243 size_t user_i = 0; // index in result vector 00244 size_t user_j = 0; // index in argument vector 00245 size_t user_m = 0; // size of result vector 00246 size_t user_n = 0; // size of arugment vector 00247 // 00248 atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator 00249 # ifndef NDEBUG 00250 bool user_ok = false; // atomic op return value 00251 # endif 00252 // 00253 // next expected operator in a UserOp sequence 00254 enum { user_start, user_arg, user_ret, user_end } user_state = user_start; 00255 00256 // length of the parameter vector (used by CppAD assert macros) 00257 const size_t num_par = play->num_par_rec(); 00258 00259 // pointer to the beginning of the parameter vector 00260 const Base* parameter = CPPAD_NULL; 00261 if( num_par > 0 ) 00262 parameter = play->GetPar(); 00263 00264 // length of the text vector (used by CppAD assert macros) 00265 const size_t num_text = play->num_text_rec(); 00266 00267 // pointer to the beginning of the text vector 00268 const char* text = CPPAD_NULL; 00269 if( num_text > 0 ) 00270 text = play->GetTxt(0); 00271 /* 00272 <!-- end forward0sweep_code_define --> 00273 */ 00274 // temporary indices 00275 size_t i, k; 00276 00277 // number of orders for this user calculation 00278 // (not needed for order zero) 00279 const size_t user_q1 = q+1; 00280 00281 // variable indices for results vector 00282 // (done differently for order zero). 00283 vector<size_t> user_iy; 00284 00285 // skip the BeginOp at the beginning of the recording 00286 play->forward_start(op, arg, i_op, i_var); 00287 CPPAD_ASSERT_UNKNOWN( op == BeginOp ); 00288 # if CPPAD_FORWARD1SWEEP_TRACE 00289 std::cout << std::endl; 00290 # endif 00291 bool more_operators = true; 00292 while(more_operators) 00293 { 00294 // this op 00295 play->forward_next(op, arg, i_op, i_var); 00296 CPPAD_ASSERT_UNKNOWN( (i_op > n) | (op == InvOp) ); 00297 CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); 00298 CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() ); 00299 00300 // check if we are skipping this operation 00301 while( cskip_op[i_op] ) 00302 { if( op == CSumOp ) 00303 { // CSumOp has a variable number of arguments 00304 play->forward_csum(op, arg, i_op, i_var); 00305 } 00306 play->forward_next(op, arg, i_op, i_var); 00307 CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() ); 00308 } 00309 00310 // action depends on the operator 00311 switch( op ) 00312 { 00313 case AbsOp: 00314 forward_abs_op(p, q, i_var, arg[0], J, taylor); 00315 break; 00316 // ------------------------------------------------- 00317 00318 case AddvvOp: 00319 forward_addvv_op(p, q, i_var, arg, parameter, J, taylor); 00320 break; 00321 // ------------------------------------------------- 00322 00323 case AddpvOp: 00324 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00325 forward_addpv_op(p, q, i_var, arg, parameter, J, taylor); 00326 break; 00327 // ------------------------------------------------- 00328 00329 case AcosOp: 00330 // sqrt(1 - x * x), acos(x) 00331 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00332 forward_acos_op(p, q, i_var, arg[0], J, taylor); 00333 break; 00334 // ------------------------------------------------- 00335 00336 case AsinOp: 00337 // sqrt(1 - x * x), asin(x) 00338 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00339 forward_asin_op(p, q, i_var, arg[0], J, taylor); 00340 break; 00341 // ------------------------------------------------- 00342 00343 case AtanOp: 00344 // 1 + x * x, atan(x) 00345 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00346 forward_atan_op(p, q, i_var, arg[0], J, taylor); 00347 break; 00348 // ------------------------------------------------- 00349 00350 case CExpOp: 00351 forward_cond_op( 00352 p, q, i_var, arg, num_par, parameter, J, taylor 00353 ); 00354 break; 00355 // --------------------------------------------------- 00356 00357 case ComOp: 00358 if( p == 0 ) forward_comp_op_0( 00359 compareCount, arg, num_par, parameter, J, taylor 00360 ); 00361 break; 00362 // --------------------------------------------------- 00363 00364 case CosOp: 00365 // sin(x), cos(x) 00366 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00367 forward_cos_op(p, q, i_var, arg[0], J, taylor); 00368 break; 00369 // --------------------------------------------------- 00370 00371 case CoshOp: 00372 // sinh(x), cosh(x) 00373 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00374 forward_cosh_op(p, q, i_var, arg[0], J, taylor); 00375 break; 00376 // ------------------------------------------------- 00377 00378 case CSkipOp: 00379 // CSkipOp has a variable number of arguments and 00380 // forward_next thinks it has no arguments. 00381 // we must inform forward_next of this special case. 00382 if( p == 0 ) 00383 { forward_cskip_op_0( 00384 i_var, arg, num_par, parameter, J, taylor, cskip_op 00385 ); 00386 } 00387 play->forward_cskip(op, arg, i_op, i_var); 00388 break; 00389 // ------------------------------------------------- 00390 00391 case CSumOp: 00392 // CSumOp has a variable number of arguments and 00393 // forward_next thinks it has no arguments. 00394 // we must inform forward_next of this special case. 00395 forward_csum_op( 00396 p, q, i_var, arg, num_par, parameter, J, taylor 00397 ); 00398 play->forward_csum(op, arg, i_op, i_var); 00399 break; 00400 // ------------------------------------------------- 00401 00402 case DisOp: 00403 i = p; 00404 if( i == 0 ) 00405 { forward_dis_op_0(i_var, arg, J, taylor); 00406 i++; 00407 } 00408 while(i <= q) 00409 { taylor[ i_var * J + i] = Base(0); 00410 i++; 00411 } 00412 break; 00413 // ------------------------------------------------- 00414 00415 case DivvvOp: 00416 forward_divvv_op(p, q, i_var, arg, parameter, J, taylor); 00417 break; 00418 // ------------------------------------------------- 00419 00420 case DivpvOp: 00421 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00422 forward_divpv_op(p, q, i_var, arg, parameter, J, taylor); 00423 break; 00424 // ------------------------------------------------- 00425 00426 case DivvpOp: 00427 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); 00428 forward_divvp_op(p, q, i_var, arg, parameter, J, taylor); 00429 break; 00430 // ------------------------------------------------- 00431 00432 case EndOp: 00433 CPPAD_ASSERT_NARG_NRES(op, 0, 0); 00434 more_operators = false; 00435 break; 00436 // ------------------------------------------------- 00437 00438 case ExpOp: 00439 forward_exp_op(p, q, i_var, arg[0], J, taylor); 00440 break; 00441 // ------------------------------------------------- 00442 00443 case InvOp: 00444 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 ); 00445 break; 00446 // ------------------------------------------------- 00447 00448 case LdpOp: 00449 if( p == 0 ) 00450 { forward_load_p_op_0( 00451 play, 00452 i_var, 00453 arg, 00454 parameter, 00455 J, 00456 taylor, 00457 isvar_by_ind.data(), 00458 index_by_ind.data(), 00459 var_by_load_op.data() 00460 ); 00461 if( p < q ) forward_load_op( 00462 op, p+1, q, i_var, arg, J, taylor, var_by_load_op.data() 00463 ); 00464 } 00465 else forward_load_op( 00466 op, p, q, i_var, arg, J, taylor, var_by_load_op.data() 00467 ); 00468 break; 00469 // ------------------------------------------------- 00470 00471 case LdvOp: 00472 if( p == 0 ) 00473 { forward_load_v_op_0( 00474 play, 00475 i_var, 00476 arg, 00477 parameter, 00478 J, 00479 taylor, 00480 isvar_by_ind.data(), 00481 index_by_ind.data(), 00482 var_by_load_op.data() 00483 ); 00484 if( p < q ) forward_load_op( 00485 op, p+1, q, i_var, arg, J, taylor, var_by_load_op.data() 00486 ); 00487 } 00488 else forward_load_op( 00489 op, p, q, i_var, arg, J, taylor, var_by_load_op.data() 00490 ); 00491 break; 00492 // ------------------------------------------------- 00493 00494 case LogOp: 00495 forward_log_op(p, q, i_var, arg[0], J, taylor); 00496 break; 00497 // ------------------------------------------------- 00498 00499 case MulvvOp: 00500 forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor); 00501 break; 00502 // ------------------------------------------------- 00503 00504 case MulpvOp: 00505 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00506 forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor); 00507 break; 00508 // ------------------------------------------------- 00509 00510 case ParOp: 00511 i = p; 00512 if( i == 0 ) 00513 { forward_par_op_0( 00514 i_var, arg, num_par, parameter, J, taylor 00515 ); 00516 i++; 00517 } 00518 while(i <= q) 00519 { taylor[ i_var * J + i] = Base(0); 00520 i++; 00521 } 00522 break; 00523 // ------------------------------------------------- 00524 00525 case PowvpOp: 00526 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); 00527 forward_powvp_op(p, q, i_var, arg, parameter, J, taylor); 00528 break; 00529 // ------------------------------------------------- 00530 00531 case PowpvOp: 00532 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00533 forward_powpv_op(p, q, i_var, arg, parameter, J, taylor); 00534 break; 00535 // ------------------------------------------------- 00536 00537 case PowvvOp: 00538 forward_powvv_op(p, q, i_var, arg, parameter, J, taylor); 00539 break; 00540 // ------------------------------------------------- 00541 00542 case PriOp: 00543 if( (p == 0) & print ) forward_pri_0(s_out, 00544 i_var, arg, num_text, text, num_par, parameter, J, taylor 00545 ); 00546 break; 00547 // ------------------------------------------------- 00548 00549 case SignOp: 00550 // sign(x) 00551 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00552 forward_sign_op(p, q, i_var, arg[0], J, taylor); 00553 break; 00554 // ------------------------------------------------- 00555 00556 case SinOp: 00557 // cos(x), sin(x) 00558 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00559 forward_sin_op(p, q, i_var, arg[0], J, taylor); 00560 break; 00561 // ------------------------------------------------- 00562 00563 case SinhOp: 00564 // cosh(x), sinh(x) 00565 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00566 forward_sinh_op(p, q, i_var, arg[0], J, taylor); 00567 break; 00568 // ------------------------------------------------- 00569 00570 case SqrtOp: 00571 forward_sqrt_op(p, q, i_var, arg[0], J, taylor); 00572 break; 00573 // ------------------------------------------------- 00574 00575 case StppOp: 00576 if( p == 0 ) 00577 { forward_store_pp_op_0( 00578 i_var, 00579 arg, 00580 num_par, 00581 J, 00582 taylor, 00583 isvar_by_ind.data(), 00584 index_by_ind.data() 00585 ); 00586 } 00587 break; 00588 // ------------------------------------------------- 00589 00590 case StpvOp: 00591 if( p == 0 ) 00592 { forward_store_pv_op_0( 00593 i_var, 00594 arg, 00595 num_par, 00596 J, 00597 taylor, 00598 isvar_by_ind.data(), 00599 index_by_ind.data() 00600 ); 00601 } 00602 break; 00603 // ------------------------------------------------- 00604 00605 case StvpOp: 00606 if( p == 0 ) 00607 { forward_store_vp_op_0( 00608 i_var, 00609 arg, 00610 num_par, 00611 J, 00612 taylor, 00613 isvar_by_ind.data(), 00614 index_by_ind.data() 00615 ); 00616 } 00617 break; 00618 // ------------------------------------------------- 00619 00620 case StvvOp: 00621 if( p == 0 ) 00622 { forward_store_vv_op_0( 00623 i_var, 00624 arg, 00625 num_par, 00626 J, 00627 taylor, 00628 isvar_by_ind.data(), 00629 index_by_ind.data() 00630 ); 00631 } 00632 break; 00633 // ------------------------------------------------- 00634 00635 case SubvvOp: 00636 forward_subvv_op(p, q, i_var, arg, parameter, J, taylor); 00637 break; 00638 // ------------------------------------------------- 00639 00640 case SubpvOp: 00641 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00642 forward_subpv_op(p, q, i_var, arg, parameter, J, taylor); 00643 break; 00644 // ------------------------------------------------- 00645 00646 case SubvpOp: 00647 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); 00648 forward_subvp_op(p, q, i_var, arg, parameter, J, taylor); 00649 break; 00650 // ------------------------------------------------- 00651 00652 case TanOp: 00653 // tan(x)^2, tan(x) 00654 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00655 forward_tan_op(p, q, i_var, arg[0], J, taylor); 00656 break; 00657 // ------------------------------------------------- 00658 00659 case TanhOp: 00660 // tanh(x)^2, tanh(x) 00661 CPPAD_ASSERT_UNKNOWN( i_var < numvar ); 00662 forward_tanh_op(p, q, i_var, arg[0], J, taylor); 00663 break; 00664 // ------------------------------------------------- 00665 00666 case UserOp: 00667 // start or end an atomic operation sequence 00668 CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 ); 00669 CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 ); 00670 if( user_state == user_start ) 00671 { user_index = arg[0]; 00672 user_id = arg[1]; 00673 user_n = arg[2]; 00674 user_m = arg[3]; 00675 user_atom = atomic_base<Base>::class_object(user_index); 00676 # ifndef NDEBUG 00677 if( user_atom == CPPAD_NULL ) 00678 { std::string msg = 00679 atomic_base<Base>::class_name(user_index) 00680 + ": atomic_base function has been deleted"; 00681 CPPAD_ASSERT_KNOWN(false, msg.c_str() ); 00682 } 00683 # endif 00684 if(user_tx.size() != user_n * user_q1) 00685 user_tx.resize(user_n * user_q1); 00686 if(user_ty.size() != user_m * user_q1) 00687 user_ty.resize(user_m * user_q1); 00688 if(user_iy.size() != user_m) 00689 user_iy.resize(user_m); 00690 user_j = 0; 00691 user_i = 0; 00692 user_state = user_arg; 00693 } 00694 else 00695 { CPPAD_ASSERT_UNKNOWN( user_state == user_end ); 00696 CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) ); 00697 CPPAD_ASSERT_UNKNOWN( user_id == size_t(arg[1]) ); 00698 CPPAD_ASSERT_UNKNOWN( user_n == size_t(arg[2]) ); 00699 CPPAD_ASSERT_UNKNOWN( user_m == size_t(arg[3]) ); 00700 00701 // call users function for this operation 00702 user_atom->set_id(user_id); 00703 CPPAD_ATOMIC_CALL( 00704 p, q, user_vx, user_vy, user_tx, user_ty 00705 ); 00706 # ifndef NDEBUG 00707 if( ! user_ok ) 00708 { std::string msg = 00709 atomic_base<Base>::class_name(user_index) 00710 + ": atomic_base.forward: returned false"; 00711 CPPAD_ASSERT_KNOWN(false, msg.c_str() ); 00712 } 00713 # endif 00714 for(i = 0; i < user_m; i++) 00715 if( user_iy[i] > 0 ) 00716 for(k = p; k <= q; k++) 00717 taylor[ user_iy[i] * J + k ] = 00718 user_ty[ i * user_q1 + k ]; 00719 00720 user_state = user_start; 00721 } 00722 break; 00723 00724 case UsrapOp: 00725 // parameter argument in an atomic operation sequence 00726 CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); 00727 CPPAD_ASSERT_UNKNOWN( user_j < user_n ); 00728 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00729 user_tx[user_j * user_q1 + 0] = parameter[ arg[0]]; 00730 for(k = 1; k < user_q1; k++) 00731 user_tx[user_j * user_q1 + k] = Base(0); 00732 ++user_j; 00733 if( user_j == user_n ) 00734 user_state = user_ret; 00735 break; 00736 00737 case UsravOp: 00738 // variable argument in an atomic operation sequence 00739 CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); 00740 CPPAD_ASSERT_UNKNOWN( user_j < user_n ); 00741 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var ); 00742 for(k = 0; k < user_q1; k++) 00743 user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k]; 00744 ++user_j; 00745 if( user_j == user_n ) 00746 user_state = user_ret; 00747 break; 00748 00749 case UsrrpOp: 00750 // parameter result in an atomic operation sequence 00751 CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); 00752 CPPAD_ASSERT_UNKNOWN( user_i < user_m ); 00753 user_iy[user_i] = 0; 00754 user_ty[user_i * user_q1 + 0] = parameter[ arg[0]]; 00755 for(k = 1; k < p; k++) 00756 user_ty[user_i * user_q1 + k] = Base(0); 00757 user_i++; 00758 if( user_i == user_m ) 00759 user_state = user_end; 00760 break; 00761 00762 case UsrrvOp: 00763 // variable result in an atomic operation sequence 00764 CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); 00765 CPPAD_ASSERT_UNKNOWN( user_i < user_m ); 00766 user_iy[user_i] = i_var; 00767 for(k = 0; k < p; k++) 00768 user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k]; 00769 user_i++; 00770 if( user_i == user_m ) 00771 user_state = user_end; 00772 break; 00773 // ------------------------------------------------- 00774 00775 default: 00776 CPPAD_ASSERT_UNKNOWN(0); 00777 } 00778 # if CPPAD_FORWARD1SWEEP_TRACE 00779 size_t i_tmp = i_var; 00780 Base* Z_tmp = taylor + J * i_var; 00781 printOp( 00782 std::cout, 00783 play, 00784 i_op, 00785 i_tmp, 00786 op, 00787 arg, 00788 q + 1, 00789 Z_tmp, 00790 0, 00791 (Base *) CPPAD_NULL 00792 ); 00793 } 00794 std::cout << std::endl; 00795 # else 00796 } 00797 # endif 00798 CPPAD_ASSERT_UNKNOWN( user_state == user_start ); 00799 CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() ); 00800 00801 return compareCount; 00802 } 00803 00804 // preprocessor symbols that are local to this file 00805 # undef CPPAD_FORWARD1SWEEP_TRACE 00806 # undef CPPAD_ATOMIC_CALL 00807 00808 } // END_CPPAD_NAMESPACE 00809 # endif