CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_FOR_JAC_SWEEP_INCLUDED 00003 # define CPPAD_FOR_JAC_SWEEP_INCLUDED 00004 /* -------------------------------------------------------------------------- 00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell 00006 00007 CppAD is distributed under multiple licenses. This distribution is under 00008 the terms of the 00009 Eclipse Public License Version 1.0. 00010 00011 A copy of this license is included in the COPYING file of this distribution. 00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00013 -------------------------------------------------------------------------- */ 00014 00015 # include <set> 00016 # include <cppad/local/pod_vector.hpp> 00017 00018 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00019 /*! 00020 \file for_jac_sweep.hpp 00021 Compute Forward mode Jacobian sparsity patterns. 00022 */ 00023 00024 /*! 00025 \def CPPAD_FOR_JAC_SWEEP_TRACE 00026 This value is either zero or one. 00027 Zero is the normal operational value. 00028 If it is one, a trace of every for_jac_sweep computation is printed. 00029 */ 00030 # define CPPAD_FOR_JAC_SWEEP_TRACE 0 00031 00032 /* 00033 \def CPPAD_ATOMIC_CALL 00034 This avoids warnings when NDEBUG is defined and user_ok is not used. 00035 If \c NDEBUG is defined, this resolves to 00036 \code 00037 user_atom->for_sparse_jac 00038 \endcode 00039 otherwise, it respolves to 00040 \code 00041 user_ok = user_atom->for_sparse_jac 00042 \endcode 00043 This maco is undefined at the end of this file to facillitate is 00044 use with a different definition in other files. 00045 */ 00046 # ifdef NDEBUG 00047 # define CPPAD_ATOMIC_CALL user_atom->for_sparse_jac 00048 # else 00049 # define CPPAD_ATOMIC_CALL user_ok = user_atom->for_sparse_jac 00050 # endif 00051 00052 /*! 00053 Given the sparsity pattern for the independent variables, 00054 ForJacSweep computes the sparsity pattern for all the other variables. 00055 00056 \tparam Base 00057 base type for the operator; i.e., this operation sequence was recorded 00058 using AD< \a Base > and computations by this routine are done using type 00059 \a Base. 00060 00061 \tparam Vector_set 00062 is the type used for vectors of sets. It can be either 00063 \c sparse_pack, \c sparse_set, or \c sparse_list. 00064 00065 \param n 00066 is the number of independent variables on the tape. 00067 00068 \param numvar 00069 is the total number of variables on the tape; i.e., 00070 \a play->num_var_rec(). 00071 00072 \param play 00073 The information stored in \a play 00074 is a recording of the operations corresponding to a function 00075 \f[ 00076 F : {\bf R}^n \rightarrow {\bf R}^m 00077 \f] 00078 where \f$ n \f$ is the number of independent variables 00079 and \f$ m \f$ is the number of dependent variables. 00080 The object \a play is effectly constant. 00081 It is not declared const because while playing back the tape 00082 the object \a play holds information about the currentl location 00083 with in the tape and this changes during playback. 00084 00085 \param var_sparsity 00086 \b Input: For j = 1 , ... , \a n, 00087 the sparsity pattern for the independent variable with index (j-1) 00088 corresponds to the set with index j in \a var_sparsity. 00089 \n 00090 \n 00091 \b Output: For i = \a n + 1 , ... , \a numvar - 1, 00092 the sparsity pattern for the variable with index i on the tape 00093 corresponds to the set with index i in \a var_sparsity. 00094 00095 \par Checked Assertions: 00096 \li numvar == var_sparsity.n_set() 00097 \li numvar == play->num_var_rec() 00098 */ 00099 00100 template <class Base, class Vector_set> 00101 void ForJacSweep( 00102 size_t n , 00103 size_t numvar , 00104 player<Base>* play , 00105 Vector_set& var_sparsity ) 00106 { 00107 OpCode op; 00108 size_t i_op; 00109 size_t i_var; 00110 00111 const addr_t* arg = CPPAD_NULL; 00112 00113 size_t i, j, k; 00114 00115 // check numvar argument 00116 CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); 00117 CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == numvar ); 00118 00119 // length of the parameter vector (used by CppAD assert macros) 00120 const size_t num_par = play->num_par_rec(); 00121 00122 // cum_sparsity accumulates sparsity pattern a cummulative sum 00123 size_t limit = var_sparsity.end(); 00124 00125 // vecad_sparsity contains a sparsity pattern from each VecAD object 00126 // to all the other variables. 00127 // vecad_ind maps a VecAD index (the beginning of the 00128 // VecAD object) to its from index in vecad_sparsity 00129 size_t num_vecad_ind = play->num_vec_ind_rec(); 00130 size_t num_vecad_vec = play->num_vecad_vec_rec(); 00131 Vector_set vecad_sparsity; 00132 vecad_sparsity.resize(num_vecad_vec, limit); 00133 pod_vector<size_t> vecad_ind; 00134 if( num_vecad_vec > 0 ) 00135 { size_t length; 00136 vecad_ind.extend(num_vecad_ind); 00137 j = 0; 00138 for(i = 0; i < num_vecad_vec; i++) 00139 { // length of this VecAD 00140 length = play->GetVecInd(j); 00141 // set to proper index for this VecAD 00142 vecad_ind[j] = i; 00143 for(k = 1; k <= length; k++) 00144 vecad_ind[j+k] = num_vecad_vec; // invalid index 00145 // start of next VecAD 00146 j += length + 1; 00147 } 00148 CPPAD_ASSERT_UNKNOWN( j == play->num_vec_ind_rec() ); 00149 } 00150 00151 // -------------------------------------------------------------- 00152 // work space used by UserOp. 00153 // 00154 typedef std::set<size_t> size_set; 00155 size_set::iterator set_itr; // iterator for a standard set 00156 size_set::iterator set_end; // end of iterator sequence 00157 vector< size_set > set_r; // set sparsity pattern for the argument x 00158 vector< size_set > set_s; // set sparisty pattern for the result y 00159 // 00160 vector<bool> bool_r; // bool sparsity pattern for the argument x 00161 vector<bool> bool_s; // bool sparisty pattern for the result y 00162 // 00163 const size_t user_q = limit; // maximum element plus one 00164 size_t user_index = 0; // indentifier for this atomic operation 00165 size_t user_id = 0; // user identifier for this call to operator 00166 size_t user_i = 0; // index in result vector 00167 size_t user_j = 0; // index in argument vector 00168 size_t user_m = 0; // size of result vector 00169 size_t user_n = 0; // size of arugment vector 00170 // 00171 atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator 00172 bool user_bool = false; // use bool or set sparsity ? 00173 # ifndef NDEBUG 00174 bool user_ok = false; // atomic op return value 00175 # endif 00176 // 00177 // next expected operator in a UserOp sequence 00178 enum { user_start, user_arg, user_ret, user_end } user_state = user_start; 00179 // -------------------------------------------------------------- 00180 00181 # if CPPAD_FOR_JAC_SWEEP_TRACE 00182 std::cout << std::endl; 00183 CppAD::vector<bool> z_value(limit); 00184 # endif 00185 00186 // skip the BeginOp at the beginning of the recording 00187 play->forward_start(op, arg, i_op, i_var); 00188 CPPAD_ASSERT_UNKNOWN( op == BeginOp ); 00189 bool more_operators = true; 00190 while(more_operators) 00191 { 00192 // this op 00193 play->forward_next(op, arg, i_op, i_var); 00194 CPPAD_ASSERT_UNKNOWN( (i_op > n) | (op == InvOp) ); 00195 CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); 00196 00197 // rest of information depends on the case 00198 switch( op ) 00199 { 00200 case AbsOp: 00201 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00202 forward_sparse_jacobian_unary_op( 00203 i_var, arg[0], var_sparsity 00204 ); 00205 break; 00206 // ------------------------------------------------- 00207 00208 case AddvvOp: 00209 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00210 forward_sparse_jacobian_binary_op( 00211 i_var, arg, var_sparsity 00212 ); 00213 break; 00214 // ------------------------------------------------- 00215 00216 case AddpvOp: 00217 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00218 forward_sparse_jacobian_unary_op( 00219 i_var, arg[1], var_sparsity 00220 ); 00221 break; 00222 // ------------------------------------------------- 00223 00224 case AcosOp: 00225 // sqrt(1 - x * x), acos(x) 00226 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00227 forward_sparse_jacobian_unary_op( 00228 i_var, arg[0], var_sparsity 00229 ); 00230 break; 00231 // ------------------------------------------------- 00232 00233 case AsinOp: 00234 // sqrt(1 - x * x), asin(x) 00235 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00236 forward_sparse_jacobian_unary_op( 00237 i_var, arg[0], var_sparsity 00238 ); 00239 break; 00240 // ------------------------------------------------- 00241 00242 case AtanOp: 00243 // 1 + x * x, atan(x) 00244 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00245 forward_sparse_jacobian_unary_op( 00246 i_var, arg[0], var_sparsity 00247 ); 00248 break; 00249 // ------------------------------------------------- 00250 00251 case CSkipOp: 00252 // CSipOp has a variable number of arguments and 00253 // forward_next thinks it has no arguments. 00254 // we must inform forward_next of this special case. 00255 play->forward_cskip(op, arg, i_op, i_var); 00256 break; 00257 // ------------------------------------------------- 00258 00259 case CSumOp: 00260 // CSumOp has a variable number of arguments and 00261 // forward_next thinks it has no arguments. 00262 // we must inform forward_next of this special case. 00263 forward_sparse_jacobian_csum_op( 00264 i_var, arg, var_sparsity 00265 ); 00266 play->forward_csum(op, arg, i_op, i_var); 00267 break; 00268 // ------------------------------------------------- 00269 00270 case CExpOp: 00271 forward_sparse_jacobian_cond_op( 00272 i_var, arg, num_par, var_sparsity 00273 ); 00274 break; 00275 // --------------------------------------------------- 00276 00277 case ComOp: 00278 CPPAD_ASSERT_NARG_NRES(op, 4, 0); 00279 CPPAD_ASSERT_UNKNOWN( arg[1] > 1 ); 00280 break; 00281 // -------------------------------------------------- 00282 00283 case CosOp: 00284 // sin(x), cos(x) 00285 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00286 forward_sparse_jacobian_unary_op( 00287 i_var, arg[0], var_sparsity 00288 ); 00289 break; 00290 // --------------------------------------------------- 00291 00292 case CoshOp: 00293 // sinh(x), cosh(x) 00294 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00295 forward_sparse_jacobian_unary_op( 00296 i_var, arg[0], var_sparsity 00297 ); 00298 break; 00299 // ------------------------------------------------- 00300 00301 case DisOp: 00302 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00303 var_sparsity.clear(i_var); 00304 break; 00305 // ------------------------------------------------- 00306 00307 case DivvvOp: 00308 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00309 forward_sparse_jacobian_binary_op( 00310 i_var, arg, var_sparsity 00311 ); 00312 break; 00313 // ------------------------------------------------- 00314 00315 case DivpvOp: 00316 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00317 forward_sparse_jacobian_unary_op( 00318 i_var, arg[1], var_sparsity 00319 ); 00320 break; 00321 // ------------------------------------------------- 00322 00323 case DivvpOp: 00324 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00325 forward_sparse_jacobian_unary_op( 00326 i_var, arg[0], var_sparsity 00327 ); 00328 break; 00329 // ------------------------------------------------- 00330 00331 case EndOp: 00332 CPPAD_ASSERT_NARG_NRES(op, 0, 0); 00333 more_operators = false; 00334 break; 00335 // ------------------------------------------------- 00336 00337 case ExpOp: 00338 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00339 forward_sparse_jacobian_unary_op( 00340 i_var, arg[0], var_sparsity 00341 ); 00342 break; 00343 // ------------------------------------------------- 00344 00345 case InvOp: 00346 CPPAD_ASSERT_NARG_NRES(op, 0, 1); 00347 // sparsity pattern is already defined 00348 break; 00349 // ------------------------------------------------- 00350 00351 case LdpOp: 00352 forward_sparse_load_op( 00353 op, 00354 i_var, 00355 arg, 00356 num_vecad_ind, 00357 vecad_ind.data(), 00358 var_sparsity, 00359 vecad_sparsity 00360 ); 00361 break; 00362 // ------------------------------------------------- 00363 00364 case LdvOp: 00365 forward_sparse_load_op( 00366 op, 00367 i_var, 00368 arg, 00369 num_vecad_ind, 00370 vecad_ind.data(), 00371 var_sparsity, 00372 vecad_sparsity 00373 ); 00374 break; 00375 // ------------------------------------------------- 00376 00377 case LogOp: 00378 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00379 forward_sparse_jacobian_unary_op( 00380 i_var, arg[0], var_sparsity 00381 ); 00382 break; 00383 // ------------------------------------------------- 00384 00385 case MulvvOp: 00386 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00387 forward_sparse_jacobian_binary_op( 00388 i_var, arg, var_sparsity 00389 ); 00390 break; 00391 // ------------------------------------------------- 00392 00393 case MulpvOp: 00394 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00395 forward_sparse_jacobian_unary_op( 00396 i_var, arg[1], var_sparsity 00397 ); 00398 break; 00399 // ------------------------------------------------- 00400 00401 case ParOp: 00402 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00403 var_sparsity.clear(i_var); 00404 break; 00405 // ------------------------------------------------- 00406 00407 case PowvpOp: 00408 CPPAD_ASSERT_NARG_NRES(op, 2, 3); 00409 forward_sparse_jacobian_unary_op( 00410 i_var, arg[0], var_sparsity 00411 ); 00412 break; 00413 // ------------------------------------------------- 00414 00415 case PowpvOp: 00416 CPPAD_ASSERT_NARG_NRES(op, 2, 3); 00417 forward_sparse_jacobian_unary_op( 00418 i_var, arg[1], var_sparsity 00419 ); 00420 break; 00421 // ------------------------------------------------- 00422 00423 case PowvvOp: 00424 CPPAD_ASSERT_NARG_NRES(op, 2, 3); 00425 forward_sparse_jacobian_binary_op( 00426 i_var, arg, var_sparsity 00427 ); 00428 break; 00429 // ------------------------------------------------- 00430 00431 case PriOp: 00432 CPPAD_ASSERT_NARG_NRES(op, 5, 0); 00433 break; 00434 // ------------------------------------------------- 00435 00436 case SignOp: 00437 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00438 forward_sparse_jacobian_unary_op( 00439 i_var, arg[0], var_sparsity 00440 ); 00441 break; 00442 // ------------------------------------------------- 00443 00444 case SinOp: 00445 // cos(x), sin(x) 00446 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00447 forward_sparse_jacobian_unary_op( 00448 i_var, arg[0], var_sparsity 00449 ); 00450 break; 00451 // ------------------------------------------------- 00452 00453 case SinhOp: 00454 // cosh(x), sinh(x) 00455 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00456 forward_sparse_jacobian_unary_op( 00457 i_var, arg[0], var_sparsity 00458 ); 00459 break; 00460 // ------------------------------------------------- 00461 00462 case SqrtOp: 00463 CPPAD_ASSERT_NARG_NRES(op, 1, 1); 00464 forward_sparse_jacobian_unary_op( 00465 i_var, arg[0], var_sparsity 00466 ); 00467 break; 00468 // ------------------------------------------------- 00469 00470 case StppOp: 00471 CPPAD_ASSERT_NARG_NRES(op, 3, 0); 00472 // storing a parameter does not affect vector sparsity 00473 break; 00474 // ------------------------------------------------- 00475 00476 case StpvOp: 00477 forward_sparse_store_op( 00478 op, 00479 arg, 00480 num_vecad_ind, 00481 vecad_ind.data(), 00482 var_sparsity, 00483 vecad_sparsity 00484 ); 00485 break; 00486 // ------------------------------------------------- 00487 00488 case StvpOp: 00489 CPPAD_ASSERT_NARG_NRES(op, 3, 0); 00490 // storing a parameter does not affect vector sparsity 00491 break; 00492 // ------------------------------------------------- 00493 00494 case StvvOp: 00495 forward_sparse_store_op( 00496 op, 00497 arg, 00498 num_vecad_ind, 00499 vecad_ind.data(), 00500 var_sparsity, 00501 vecad_sparsity 00502 ); 00503 break; 00504 // ------------------------------------------------- 00505 00506 case SubvvOp: 00507 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00508 forward_sparse_jacobian_binary_op( 00509 i_var, arg, var_sparsity 00510 ); 00511 break; 00512 // ------------------------------------------------- 00513 00514 case SubpvOp: 00515 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00516 forward_sparse_jacobian_unary_op( 00517 i_var, arg[1], var_sparsity 00518 ); 00519 break; 00520 // ------------------------------------------------- 00521 00522 case SubvpOp: 00523 CPPAD_ASSERT_NARG_NRES(op, 2, 1); 00524 forward_sparse_jacobian_unary_op( 00525 i_var, arg[0], var_sparsity 00526 ); 00527 break; 00528 // ------------------------------------------------- 00529 00530 case TanOp: 00531 // tan(x)^2, tan(x) 00532 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00533 forward_sparse_jacobian_unary_op( 00534 i_var, arg[0], var_sparsity 00535 ); 00536 break; 00537 // ------------------------------------------------- 00538 00539 case TanhOp: 00540 // tanh(x)^2, tanh(x) 00541 CPPAD_ASSERT_NARG_NRES(op, 1, 2); 00542 forward_sparse_jacobian_unary_op( 00543 i_var, arg[0], var_sparsity 00544 ); 00545 break; 00546 // ------------------------------------------------- 00547 00548 case UserOp: 00549 // start or end an atomic operation sequence 00550 CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 ); 00551 CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 ); 00552 if( user_state == user_start ) 00553 { user_index = arg[0]; 00554 user_id = arg[1]; 00555 user_n = arg[2]; 00556 user_m = arg[3]; 00557 user_atom = atomic_base<Base>::class_object(user_index); 00558 # ifndef NDEBUG 00559 if( user_atom == CPPAD_NULL ) 00560 { std::string msg = 00561 atomic_base<Base>::class_name(user_index) 00562 + ": atomic_base function has been deleted"; 00563 CPPAD_ASSERT_KNOWN(false, msg.c_str() ); 00564 } 00565 # endif 00566 user_bool = user_atom->sparsity() == 00567 atomic_base<Base>::bool_sparsity_enum; 00568 if( user_bool ) 00569 { if( bool_r.size() != user_n * user_q ) 00570 bool_r.resize( user_n * user_q ); 00571 if( bool_s.size() != user_m * user_q ) 00572 bool_s.resize( user_m * user_q ); 00573 for(i = 0; i < user_n; i++) 00574 for(j = 0; j < user_q; j++) 00575 bool_r[ i * user_q + j] = false; 00576 } 00577 else 00578 { if(set_r.size() != user_n ) 00579 set_r.resize(user_n); 00580 if(set_s.size() != user_m ) 00581 set_s.resize(user_m); 00582 for(i = 0; i < user_n; i++) 00583 set_r[i].clear(); 00584 } 00585 user_j = 0; 00586 user_i = 0; 00587 user_state = user_arg; 00588 } 00589 else 00590 { CPPAD_ASSERT_UNKNOWN( user_state == user_end ); 00591 CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) ); 00592 CPPAD_ASSERT_UNKNOWN( user_id == size_t(arg[1]) ); 00593 CPPAD_ASSERT_UNKNOWN( user_n == size_t(arg[2]) ); 00594 CPPAD_ASSERT_UNKNOWN( user_m == size_t(arg[3]) ); 00595 # ifndef NDEBUG 00596 if( ! user_ok ) 00597 { std::string msg = 00598 atomic_base<Base>::class_name(user_index) 00599 + ": atomic_base.for_sparse_jac: returned false"; 00600 CPPAD_ASSERT_KNOWN(false, msg.c_str() ); 00601 } 00602 # endif 00603 user_state = user_start; 00604 } 00605 break; 00606 00607 case UsrapOp: 00608 // parameter argument in an atomic operation sequence 00609 CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); 00610 CPPAD_ASSERT_UNKNOWN( user_j < user_n ); 00611 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); 00612 // set row user_j to empty sparsity pattern 00613 ++user_j; 00614 if( user_j == user_n ) 00615 { // call users function for this operation 00616 user_atom->set_id(user_id); 00617 if( user_bool ) 00618 CPPAD_ATOMIC_CALL( 00619 user_q, bool_r, bool_s 00620 ); 00621 else 00622 CPPAD_ATOMIC_CALL( 00623 user_q, set_r, set_s 00624 ); 00625 user_state = user_ret; 00626 } 00627 break; 00628 00629 case UsravOp: 00630 // variable argument in an atomic operation sequence 00631 CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); 00632 CPPAD_ASSERT_UNKNOWN( user_j < user_n ); 00633 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var ); 00634 // set row user_j to sparsity pattern for variable arg[0] 00635 var_sparsity.begin(arg[0]); 00636 i = var_sparsity.next_element(); 00637 while( i < user_q ) 00638 { if( user_bool ) 00639 bool_r[user_j * user_q + i] = true; 00640 else 00641 set_r[user_j].insert(i); 00642 i = var_sparsity.next_element(); 00643 } 00644 ++user_j; 00645 if( user_j == user_n ) 00646 { // call users function for this operation 00647 user_atom->set_id(user_id); 00648 if( user_bool ) 00649 CPPAD_ATOMIC_CALL( 00650 user_q, bool_r, bool_s 00651 ); 00652 else 00653 CPPAD_ATOMIC_CALL( 00654 user_q, set_r, set_s 00655 ); 00656 user_state = user_ret; 00657 } 00658 break; 00659 00660 case UsrrpOp: 00661 // parameter result in an atomic operation sequence 00662 CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); 00663 CPPAD_ASSERT_UNKNOWN( user_i < user_m ); 00664 user_i++; 00665 if( user_i == user_m ) 00666 user_state = user_end; 00667 break; 00668 00669 case UsrrvOp: 00670 // variable result in an atomic operation sequence 00671 CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); 00672 CPPAD_ASSERT_UNKNOWN( user_i < user_m ); 00673 // It might be faster if we add set union to var_sparsity 00674 // where one of the sets is not in var_sparsity 00675 if( user_bool ) 00676 { for(j = 0; j < user_q; j++) 00677 if( bool_s[ user_i * user_q + j ] ) 00678 var_sparsity.add_element(i_var, j); 00679 } 00680 else 00681 { set_itr = set_s[user_i].begin(); 00682 set_end = set_s[user_i].end(); 00683 while( set_itr != set_end ) 00684 var_sparsity.add_element(i_var, *set_itr++); 00685 } 00686 user_i++; 00687 if( user_i == user_m ) 00688 user_state = user_end; 00689 break; 00690 // ------------------------------------------------- 00691 00692 default: 00693 CPPAD_ASSERT_UNKNOWN(0); 00694 } 00695 # if CPPAD_FOR_JAC_SWEEP_TRACE 00696 // value for this variable 00697 for(j = 0; j < limit; j++) 00698 z_value[j] = false; 00699 var_sparsity.begin(i_var); 00700 j = var_sparsity.next_element(); 00701 while( j < limit ) 00702 { z_value[j] = true; 00703 j = var_sparsity.next_element(); 00704 } 00705 printOp( 00706 std::cout, 00707 play, 00708 i_op, 00709 i_var, 00710 op, 00711 arg, 00712 1, 00713 &z_value, 00714 0, 00715 (CppAD::vector<bool> *) CPPAD_NULL 00716 ); 00717 } 00718 std::cout << std::endl; 00719 # else 00720 } 00721 # endif 00722 CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() ); 00723 00724 return; 00725 } 00726 00727 } // END_CPPAD_NAMESPACE 00728 00729 // preprocessor symbols that are local to this file 00730 # undef CPPAD_FOR_JAC_SWEEP_TRACE 00731 # undef CPPAD_ATOMIC_CALL 00732 00733 # endif