1 # ifndef CPPAD_UTILITY_ROSEN_34_HPP
2 # define CPPAD_UTILITY_ROSEN_34_HPP
295 template <
typename Scalar,
typename Vector,
typename Fun>
302 { Vector e( xi.size() );
303 return Rosen34(F, M, ti, tf, xi, e);
306 template <
typename Scalar,
typename Vector,
typename Fun>
318 CheckNumericType<Scalar>();
321 CheckSimpleVector<Scalar, Vector>();
326 static Scalar a[3] = {
329 Scalar(3) / Scalar(5)
331 static Scalar b[2 * 2] = {
334 Scalar(24) / Scalar(25),
335 Scalar(3) / Scalar(25)
337 static Scalar ct[4] = {
338 Scalar(1) / Scalar(2),
339 - Scalar(3) / Scalar(2),
340 Scalar(121) / Scalar(50),
341 Scalar(29) / Scalar(250)
343 static Scalar cg[3 * 3] = {
347 Scalar(186) / Scalar(25),
348 Scalar(6) / Scalar(5),
350 - Scalar(56) / Scalar(125),
351 - Scalar(27) / Scalar(125),
352 - Scalar(1) / Scalar(5)
354 static Scalar d3[3] = {
355 Scalar(97) / Scalar(108),
356 Scalar(11) / Scalar(72),
357 Scalar(25) / Scalar(216)
359 static Scalar d4[4] = {
360 Scalar(19) / Scalar(18),
361 Scalar(1) / Scalar(4),
362 Scalar(25) / Scalar(216),
363 Scalar(125) / Scalar(216)
367 "Error in Rosen34: the number of steps is less than one"
370 e.size() == xi.size(),
371 "Error in Rosen34: size of e not equal to size of xi"
373 size_t i, j, k, l, m;
375 size_t n = xi.size();
376 Scalar ns = Scalar(
double(M));
377 Scalar h = (tf - ti) / ns;
378 Scalar zero = Scalar(0);
379 Scalar one = Scalar(1);
380 Scalar two = Scalar(2);
386 Vector E(n * n), Eg(n), f_t(n);
387 Vector g(n * 3), x3(n), x4(n), xf(n), ftmp(n), xtmp(n), nan_vec(n);
390 for(i = 0; i < n; i++)
392 nan_vec[i] =
nan(zero);
396 for(m = 0; m < M; m++)
398 Scalar t = ti * (Scalar(
int(M - m)) / ns)
399 + tf * (Scalar(
int(m)) / ns);
405 F.Ode_ind(t, xf, f_t);
413 for(i = 0; i < n; i++)
414 {
for(j = 0; j < n; j++)
415 E[i * n + j] = - E[i * n + j] * h / two;
427 "Error in Rosen34: I - f_x * h / 2 not invertible"
431 for(k = 0; k < 3; k++)
434 for(l = 0; l < k; l++)
436 Scalar bkl = b[(k-1)*2 + l];
437 for(i = 0; i < n; i++)
439 xtmp[i] += bkl * g[i*3 + l] * h;
443 F.Ode(t + a[k] * h, xtmp, ftmp);
450 for(i = 0; i < n; i++)
451 Eg[i] = ftmp[i] + ct[k] * f_t[i] * h;
452 for(l = 0; l < k; l++)
453 {
for(i = 0; i < n; i++)
454 Eg[i] += cg[(k-1)*3 + l] * g[i*3 + l];
461 for(i = 0; i < n; i++)
462 { g[i*3 + k] = Eg[i];
463 x3[i] += h * d3[k] * Eg[i];
464 x4[i] += h * d4[k] * Eg[i];
468 for(i = 0; i < n; i++)
469 Eg[i] = ftmp[i] + ct[3] * f_t[i] * h;
470 for(l = 0; l < 3; l++)
471 {
for(i = 0; i < n; i++)
472 Eg[i] += cg[2*3 + l] * g[i*3 + l];
479 for(i = 0; i < n; i++)
480 { x4[i] += h * d4[3] * Eg[i];
483 Scalar diff = x4[i] - x3[i];
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Scalar nan(const Scalar &zero)
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
void LuInvert(const SizeVector &ip, const SizeVector &jp, const FloatVector &LU, FloatVector &B)
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
int LuFactor(SizeVector &ip, SizeVector &jp, FloatVector &LU)
Vector Rosen34(Fun &F, size_t M, const Scalar &ti, const Scalar &tf, const Vector &xi)
bool hasnan(const Vector &v)
std::complex< double > sign(const std::complex< double > &x)
File used to define CppAD::vector and CppAD::vectorBool.
File used to define the CppAD multi-threading allocator class.