numerics 0.1.0
Loading...
Searching...
No Matches
solve.hpp
Go to the documentation of this file.
1/// @file solve/solve.hpp
2/// @brief Unified solve() dispatcher -- the single entry point for all solvers.
3#pragma once
4
5#include "ode/implicit.hpp"
6#include "ode/ode.hpp"
8#include "solve/problems.hpp"
9#include "stochastic/mcmc.hpp"
10#include <concepts>
11#include <random>
12
13namespace num {
14
15template<typename P>
16concept IsODEProblem = requires(const P& p, double t, const Vector& y, Vector& dy) {
17 p.f(t, y, dy);
18 { p.u0 } -> std::convertible_to<const Vector&>;
19 { p.t0 } -> std::convertible_to<double>;
20 { p.tf } -> std::convertible_to<double>;
21};
22
23template<typename A>
24concept IsExplicitODEAlg = std::same_as<std::remove_cvref_t<A>, Euler>
25 || std::same_as<std::remove_cvref_t<A>, RK4>
26 || std::same_as<std::remove_cvref_t<A>, RK45>;
27
28template<typename A>
29concept IsImplicitODEAlg = requires(const A& a) {
30 { a.solver } -> std::convertible_to<LinearSolver>;
31 { a.dt } -> std::convertible_to<double>;
32 { a.nstep } -> std::convertible_to<int>;
33};
34
35template<typename A>
36concept IsMCMCAlg = std::same_as<std::remove_cvref_t<A>, Metropolis>;
37
38template<IsODEProblem P>
39ODEResult solve(const P& prob, const RK45& alg, ObserverFn obs = nullptr) {
40 ODEParams p{.t0 = prob.t0,
41 .tf = prob.tf,
42 .h = alg.h,
43 .rtol = alg.rtol,
44 .atol = alg.atol,
45 .max_steps = alg.max_steps};
46 return ode_rk45(prob.f, prob.u0, p, obs);
47}
48
49template<IsODEProblem P>
50ODEResult solve(const P& prob, const RK4& alg, ObserverFn obs = nullptr) {
51 return ode_rk4(prob.f, prob.u0, {.t0 = prob.t0, .tf = prob.tf, .h = alg.h}, obs);
52}
53
54template<IsODEProblem P>
55ODEResult solve(const P& prob, const Euler& alg, ObserverFn obs = nullptr) {
56 return ode_euler(prob.f, prob.u0, {.t0 = prob.t0, .tf = prob.tf, .h = alg.h}, obs);
57}
58
59template<VecField F>
60void solve(F& u, const BackwardEuler& alg) {
61 ode::advance(u, alg.solver, {alg.nstep, alg.dt});
62}
63
64template<VecField F, typename Observer>
65void solve(F& u, const BackwardEuler& alg, Observer&& obs) {
66 ode::advance(u, alg.solver, {alg.nstep, alg.dt}, std::forward<Observer>(obs));
67}
68
69/// @brief Run equilibration and measurement sweeps, then return the mean.
70template<IsMCMCAlg A, typename MeasureFn, typename RNG>
71double solve(const MCMCProblem& prob, const A& alg, MeasureFn&& measure, RNG& rng) {
72 for (int s = 0; s < alg.equilibration; ++s)
74 double acc = 0.0;
75 for (int s = 0; s < alg.measurements; ++s) {
77 acc += measure();
78 }
79 return acc / alg.measurements;
80}
81
82} // namespace num
Algorithm tags: carry the numerics, not the mathematics.
Implicit time integration via a user-supplied LinearSolver.
Metropolis-Hastings sweep API.
MetropolisStats metropolis_sweep_prob(idx n_sites, ProbFn acceptance_prob, Apply apply_flip, RNG &rng)
Metropolis sweep with caller-supplied acceptance probabilities.
Definition mcmc_impl.hpp:54
void advance(Field &u, const LinearSolver &solver, ImplicitParams p, Observer &&obs)
Definition implicit.hpp:35
ODEResult ode_rk4(ODERhsFn f, Vector y0, ODEParams p={}, ObserverFn obs=nullptr)
Classic 4th-order Runge-Kutta, fixed step.
Definition ode.cpp:399
std::function< void(real t, const Vector &y)> ObserverFn
Definition ode.hpp:14
ODEResult solve(const P &prob, const RK45 &alg, ObserverFn obs=nullptr)
Definition solve.hpp:39
BasicVector< real > Vector
Real-valued dense vector with full backend dispatch (CPU + GPU)
Definition vector.hpp:129
ODEResult ode_euler(ODERhsFn f, Vector y0, ODEParams p={}, ObserverFn obs=nullptr)
Forward Euler, 1st-order, fixed step.
Definition ode.cpp:392
ODEResult ode_rk45(ODERhsFn f, Vector y0, ODEParams p={}, ObserverFn obs=nullptr)
Adaptive Dormand-Prince RK45 with FSAL and PI step-size control.
Definition ode.cpp:406
ODE and symplectic integrators.
Problem types: carry the mathematics, not the numerics.
LinearSolver solver
std::function< double(int)> accept_prob
Definition problems.hpp:20
std::function< void(int)> propose
Definition problems.hpp:21
double atol
double rtol