@@ -443,7 +443,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
443443 " // Step-size bounds of a refined run, none unless the caller set them." ,
444444 " cppde::step_limit_scope _cppde_sl_scope(args.limits);" ,
445445 " " ,
446- " StepChecker checker(args.maxprogress , args.maxsteps);" ,
446+ " StepChecker checker(args.maxattempts , args.maxsteps);" ,
447447 " " ,
448448 sprintf(" cppde::vector_t<%s> x(%d);" , numType , n_variables ),
449449 sprintf(" cppde::vector_t<%s> full_params(%d);" , numType , n_variables + n_params ),
@@ -455,20 +455,20 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
455455 externC <- c(
456456 externC ,
457457 " // Custom sensitivity initial values (length validated after n_sens is computed)" ,
458- " bool has_sens1ini = (args.sens1ini != nullptr);" ,
459- " const double* sens1ini = has_sens1ini ? args.sens1ini : nullptr;"
458+ " bool has_sens1ini = (args.tangent != nullptr);" ,
459+ " const double* sens1ini = has_sens1ini ? args.tangent : nullptr;"
460460 )
461461
462462 if (deriv2 ) {
463463 externC <- c(
464464 externC ,
465- " bool has_sens2ini = (args.sens2ini != nullptr);" ,
466- " const double* sens2ini = has_sens2ini ? args.sens2ini : nullptr;"
465+ " bool has_sens2ini = (args.hessian != nullptr);" ,
466+ " const double* sens2ini = has_sens2ini ? args.hessian : nullptr;"
467467 )
468468 } else {
469469 externC <- c(
470470 externC ,
471- " if (args.sens2ini != nullptr)" ,
471+ " if (args.hessian != nullptr)" ,
472472 " return res.fail(cppde::RC_ILL_INPUT, \" hessian supplied but deriv2 = FALSE\" );"
473473 )
474474 }
@@ -917,6 +917,8 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
917917 if (useNDF ) " true" else " false" ),
918918 sprintf(" controlledStepper.stepper().set_sens_err_con(%s);" ,
919919 sens_err_con_arg ),
920+ " controlledStepper.stepper().set_max_order(args.max_order);" ,
921+ " controlledStepper.stepper().set_stald(args.stald);" ,
920922 # Slab priming for any AD path (heap dual<T,0> or static-N dual<T,N>),
921923 # a no-op for non-AD and nested-AD types. Emitted before the
922924 # std::move into denseStepper.
@@ -1005,15 +1007,15 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
10051007 if (use_sparse ) " sparse" else " dense" ),
10061008 " double abstol = args.abstol;" ,
10071009 " double reltol = args.reltol;" ,
1008- " double root_tol = args.root_tol ;" ,
1010+ " double root_tol = args.roottol ;" ,
10091011 " double hini = args.hini;" ,
10101012 " int maxroot = args.maxroot;" ,
10111013 " ode_system sys(full_params, F);" ,
10121014 " jacobian jac(full_params, F);" ,
10131015 if (is_reverse ) c(
10141016 " // Checkpoint store for the reverse pass: reused from the caller, or" ,
10151017 " // made here and freed on return unless the caller keeps it." ,
1016- " rev_state* _rev_st = static_cast<rev_state*>(args.store_in );" ,
1018+ " rev_state* _rev_st = static_cast<rev_state*>(args.store );" ,
10171019 " bool _rev_reuse = (_rev_st != nullptr);" ,
10181020 " std::unique_ptr<rev_state> _rev_owned;" ,
10191021 " if (!_rev_reuse) { _rev_owned.reset(new rev_state()); _rev_st = _rev_owned.get(); }" ,
@@ -1261,15 +1263,15 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
12611263 " _rev_st->out_t.assign(result_times.begin(), result_times.end());" ,
12621264 " _rev_st->out_y.assign(y.begin(), y.end());" ,
12631265 " }" ,
1264- " if (args.want_store ) {" ,
1266+ " if (args.keep_store ) {" ,
12651267 " res.store_out = _rev_owned.release();" ,
12661268 " res.wrap_store = &rev_state_wrap;" ,
12671269 " }" ,
12681270 " " ,
12691271 " // --- The backward sweep ---" ,
12701272 " // No seed with a store to keep: return the checkpoints without a sweep." ,
1271- " if (args.seed == nullptr) {" ,
1272- " if (args.want_store ) return res.return_code;" ,
1273+ " if (args.cotangent == nullptr) {" ,
1274+ " if (args.keep_store ) return res.return_code;" ,
12731275 " return res.fail(cppde::RC_ILL_INPUT," ,
12741276 " \" a model compiled with derivMode = reverse needs a cotangent\" );" ,
12751277 " }" ,
@@ -1295,7 +1297,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
12951297 " res.adjoint2.assign((size_t)n_phi_rows * n_sens * n_seed, 0.0);" )
12961298 else character (0 ),
12971299 solver_decl ,
1298- " if (args.adj_trace ) {" ,
1300+ " if (args.adjoint_grid ) {" ,
12991301 " const int _ns = (int)_rev_store.n_steps();" ,
13001302 sprintf(" res.n_adj_steps = _ns; res.n_adj_states = %d;" , n_variables ),
13011303 " res.step_t.assign((size_t)_ns, 0.0);" ,
@@ -1326,7 +1328,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
13261328 if (! second_reverse )
13271329 sprintf(" cppde::adjoint::extrapolated_flow<%s::lu_type> _flow;" , rb4_double )
13281330 else character (0 )),
1329- " _cl.trace_lambda(args.adj_trace );" ,
1331+ " _cl.trace_lambda(args.adjoint_grid );" ,
13301332 if (second_reverse ) character (0 )
13311333 else if (written_onestep ) " if (args.refine > 0) _cl.set_refine(args.refine * args.reltol, args.abstol, args.gradtol);"
13321334 else " if (args.refine > 0) _flow.set_refine(args.refine * args.reltol, args.abstol, args.gradtol);" ,
@@ -1340,16 +1342,16 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
13401342 " for (int o = 0; o < n_out; ++o)" ,
13411343 sprintf(" for (int i = 0; i < %d; ++i)" , n_variables ),
13421344 sprintf(" _seed_col[(size_t)o * %d + i] =" , n_variables ),
1343- sprintf(" args.seed [o + (size_t)n_out * (i + (size_t)%d * c)];" , n_variables ),
1345+ sprintf(" args.cotangent [o + (size_t)n_out * (i + (size_t)%d * c)];" , n_variables ),
13441346 if (second_reverse ) c(
1345- " if (args.seed_tan != nullptr && args.n_seed_tan > 0) {" ,
1347+ " if (args.curvature != nullptr && args.n_seed_tan > 0) {" ,
13461348 " const int _ntg = args.n_seed_tan < n_sens ? args.n_seed_tan : n_sens;" ,
13471349 " for (int o = 0; o < n_out; ++o)" ,
13481350 sprintf(" for (int i = 0; i < %d; ++i) {" , n_variables ),
13491351 sprintf(" auto& _sc = _seed_col[(size_t)o * %d + i];" , n_variables ),
13501352 " _sc.diff(0, n_sens);" ,
13511353 " for (int v = 0; v < _ntg; ++v)" ,
1352- " _sc.d(v) = args.seed_tan [o + (size_t)n_out *" ,
1354+ " _sc.d(v) = args.curvature [o + (size_t)n_out *" ,
13531355 sprintf(" (i + (size_t)%d * ((size_t)c + (size_t)n_seed * v))];" , n_variables ),
13541356 " }" ,
13551357 " }" )
@@ -1380,7 +1382,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
13801382 " res.adjoint[i + (size_t)n_phi_rows * c] = _cl.wx0()[i] + _cl.wp()[i];" ,
13811383 sprintf(" for (int j = %d; j < n_phi_rows; ++j)" , n_variables ),
13821384 " res.adjoint[j + (size_t)n_phi_rows * c] = _cl.wp()[j];" ),
1383- " if (args.adj_trace ) {" ,
1385+ " if (args.adjoint_grid ) {" ,
13841386 " const int _ns = res.n_adj_steps;" ,
13851387 if (written_onestep || ! second_reverse ) c(
13861388 " if (c == 0) {" ,
@@ -1455,30 +1457,21 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
14551457 }
14561458 externC <- c(
14571459 externC ,
1458- sprintf(paste0(' extern "C" SEXP solve_%s(SEXP timesSEXP, SEXP paramsSEXP, ' ,
1459- ' SEXP sens1iniSEXP, SEXP sens2iniSEXP, SEXP fixedSEXP, SEXP abstolSEXP, ' ,
1460- ' SEXP reltolSEXP, SEXP maxprogressSEXP, SEXP maxstepsSEXP, SEXP hiniSEXP, ' ,
1461- ' SEXP root_tolSEXP, SEXP maxrootSEXP, SEXP forcingTimesSEXP, ' ,
1462- ' SEXP forcingValuesSEXP, SEXP seedSEXP, SEXP dimnamesSEXP) {' ),
1463- modelname ),
1464- " cppde::rbatch::solve_args a = cppde::rbatch::read_solve_args(" ,
1465- " timesSEXP, paramsSEXP, sens1iniSEXP, sens2iniSEXP, fixedSEXP," ,
1466- " abstolSEXP, reltolSEXP, maxprogressSEXP, maxstepsSEXP, hiniSEXP," ,
1467- " root_tolSEXP, maxrootSEXP, forcingTimesSEXP, forcingValuesSEXP, seedSEXP);" ,
1468- sprintf(" return cppde::rbatch::solve_one(a, %d, %s, %s, &solve_impl, dimnamesSEXP);" ,
1460+ sprintf(' extern "C" SEXP solve_%s(SEXP argsSEXP) {' , modelname ),
1461+ " cppde::rbatch::solve_args a = cppde::rbatch::read_solve_args(argsSEXP);" ,
1462+ sprintf(" return cppde::rbatch::solve_one(a, %d, %s, %s, &solve_impl);" ,
14691463 n_variables , dflag , d2flag ),
14701464 " }" ,
14711465 " " ,
1472- sprintf(' extern "C" SEXP solve_%s_batch(SEXP condsSEXP, SEXP nthreadsSEXP, SEXP dimnamesSEXP ) {' , modelname ),
1466+ sprintf(' extern "C" SEXP solve_%s_batch(SEXP condsSEXP, SEXP nthreadsSEXP) {' , modelname ),
14731467 " const int K = Rf_length(condsSEXP);" ,
14741468 " const int nt = Rf_isNull(nthreadsSEXP) ? 0 : INTEGER(nthreadsSEXP)[0];" ,
1475- if (fixed_grid ) " " else " (void)dimnamesSEXP;" ,
14761469 " " ,
14771470 " // Phase A: every R read and every R allocation, serially." ,
14781471 " std::vector<cppde::rbatch::solve_args> A;" ,
14791472 " A.reserve(K);" ,
14801473 " for (int k = 0; k < K; ++k)" ,
1481- " A.push_back(cppde::rbatch::read_cond_args (VECTOR_ELT(condsSEXP, k)));" ,
1474+ " A.push_back(cppde::rbatch::read_solve_args (VECTOR_ELT(condsSEXP, k)));" ,
14821475 " std::vector<cppde::rbatch::solve_result> R_(K);" ,
14831476 " SEXP out = PROTECT(Rf_allocVector(VECSXP, K));" ,
14841477 if (fixed_grid ) paste0(
@@ -1488,7 +1481,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
14881481 paste0(" std::vector<std::vector<double> > EV(K, std::vector<double>(%d));\n " ,
14891482 " for (int k = 0; k < K; ++k) %s_fixed_event_times(A[k].params, EV[k].data());\n " ),
14901483 n_ev_times , modelname ) else " " ,
1491- sprintf(" std::vector<cppde::rbatch::pre_ctx> P = cppde::rbatch::prealloc_batch(\n out, A, %d, %d, %s, %s, %s, dimnamesSEXP %s);\n " ,
1484+ sprintf(" std::vector<cppde::rbatch::pre_ctx> P = cppde::rbatch::prealloc_batch(\n out, A, %d, %d, %s, %s, %s%s);\n " ,
14921485 n_variables , n_total_sens , dflag , d2flag ,
14931486 if (includeTimeZero ) " true" else " false" ,
14941487 if (n_ev_times > 0L ) " , &EV" else " " ),
@@ -1629,6 +1622,7 @@ cppODE <- function(rhs, events = NULL, rootfunc = NULL, fixed = NULL, forcings =
16291622 attr(modelname , " sparse" ) <- use_sparse
16301623 attr(modelname , " method" ) <- method
16311624 attr(modelname , " useNDF" ) <- useNDF
1625+ attr(modelname , " solveAbi" ) <- .solveAbi
16321626 # Dimension names: under reparametrization the sens columns are theta slots.
16331627 # The sens dim defaults to model-parameter names; solveODE() overrides it per
16341628 # call when the tangent has a full Phi' shape.
0 commit comments