1 # ifndef CPPAD_UTILITY_RUNGE_45_HPP
2 # define CPPAD_UTILITY_RUNGE_45_HPP
269 template <
typename Scalar,
typename Vector,
typename Fun>
276 { Vector e( xi.size() );
277 return Runge45(F, M, ti, tf, xi, e);
280 template <
typename Scalar,
typename Vector,
typename Fun>
292 CheckNumericType<Scalar>();
295 CheckSimpleVector<Scalar, Vector>();
300 static Scalar a[6] = {
302 Scalar(1) / Scalar(5),
303 Scalar(3) / Scalar(10),
304 Scalar(3) / Scalar(5),
306 Scalar(7) / Scalar(8)
308 static Scalar b[5 * 5] = {
309 Scalar(1) / Scalar(5),
315 Scalar(3) / Scalar(40),
316 Scalar(9) / Scalar(40),
321 Scalar(3) / Scalar(10),
322 -Scalar(9) / Scalar(10),
323 Scalar(6) / Scalar(5),
327 -Scalar(11) / Scalar(54),
328 Scalar(5) / Scalar(2),
329 -Scalar(70) / Scalar(27),
330 Scalar(35) / Scalar(27),
333 Scalar(1631) / Scalar(55296),
334 Scalar(175) / Scalar(512),
335 Scalar(575) / Scalar(13824),
336 Scalar(44275) / Scalar(110592),
337 Scalar(253) / Scalar(4096)
339 static Scalar c4[6] = {
340 Scalar(2825) / Scalar(27648),
342 Scalar(18575) / Scalar(48384),
343 Scalar(13525) / Scalar(55296),
344 Scalar(277) / Scalar(14336),
345 Scalar(1) / Scalar(4),
347 static Scalar c5[6] = {
348 Scalar(37) / Scalar(378),
350 Scalar(250) / Scalar(621),
351 Scalar(125) / Scalar(594),
353 Scalar(512) / Scalar(1771)
358 "Error in Runge45: the number of steps is less than one"
361 e.size() == xi.size(),
362 "Error in Runge45: size of e not equal to size of xi"
366 size_t n = xi.size();
367 Scalar ns = Scalar(
int(M));
368 Scalar h = (tf - ti) / ns;
369 Scalar zero_or_nan = Scalar(0);
370 for(i = 0; i < n; i++)
374 Vector fh(6 * n), xtmp(n), ftmp(n), x4(n), x5(n), xf(n);
377 for(m = 0; m < M; m++)
380 Scalar t = ti * (Scalar(
int(M - m)) / ns)
381 + tf * (Scalar(
int(m)) / ns);
385 for(j = 0; j < 6; j++)
388 for(k = 0; k < j; k++)
390 Scalar bjk = b[ (j-1) * 5 + k ];
391 for(i = 0; i < n; i++)
393 xtmp[i] += bjk * fh[i * 6 + k];
397 F.Ode(t + a[j] * h, xtmp, ftmp);
400 for(i = 0; i < n; i++)
401 zero_or_nan *= ftmp[i];
403 for(i = 0; i < n; i++)
405 Scalar fhi = ftmp[i] * h;
407 x4[i] += c4[j] * fhi;
408 x5[i] += c5[j] * fhi;
409 x5[i] += zero_or_nan;
413 for(i = 0; i < n; i++)
415 Scalar diff = x5[i] - x4[i];
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
Vector Runge45(Fun &F, size_t M, const Scalar &ti, const Scalar &tf, const Vector &xi)
File used to define the CppAD multi-threading allocator class.
std::complex< double > fabs(const std::complex< double > &x)