47 using state_type =
typename base_type::state_type;
48 using time_type =
typename base_type::time_type;
49 using value_type =
typename base_type::value_type;
52 explicit SRAIntegrator(std::shared_ptr<typename base_type::sde_problem_type> problem,
53 std::shared_ptr<typename base_type::wiener_process_type> wiener =
nullptr,
54 tableau_type tableau = SRAIntegrator::create_sra1_tableau())
56 , tableau_(std::move(tableau)) {}
58 void step(state_type& state, time_type dt)
override {
59 const int stages = tableau_.stages;
62 std::vector<state_type> H0(stages);
63 for (
int i = 0; i < stages; ++i) {
76 this->wiener_->generate_increment(dW, dt);
77 this->wiener_->generate_increment(dZ, dt);
80 value_type sqrt3 = std::sqrt(
static_cast<value_type
>(3));
82 for (
size_t j = 0; j < chi2.size(); ++j) {
83 auto chi2_it = chi2.begin();
84 auto dW_it = dW.begin();
85 auto dZ_it = dZ.begin();
86 chi2_it[j] =
static_cast<value_type
>(0.5) * (dW_it[j] + dZ_it[j] / sqrt3);
90 for (
size_t j = 0; j < state.size(); ++j) {
91 auto state_it = state.begin();
92 auto H0_0_it = H0[0].begin();
93 H0_0_it[j] = state_it[j];
97 for (
int i = 1; i < stages; ++i) {
102 for (
int j = 0; j < i; ++j) {
103 this->problem_->drift(this->current_time_ + tableau_.c0[j] * dt, H0[j], ftmp);
104 this->problem_->diffusion(this->current_time_ + tableau_.c1[j] * dt, H0[j], gtmp);
106 for (
size_t k = 0; k < state.size(); ++k) {
107 auto A0temp_it = A0temp.begin();
108 auto B0temp_it = B0temp.begin();
109 auto ftmp_it = ftmp.begin();
110 auto gtmp_it = gtmp.begin();
111 auto chi2_it = chi2.begin();
113 A0temp_it[k] += tableau_.A0[j][i] * ftmp_it[k];
114 B0temp_it[k] += tableau_.B0[j][i] * gtmp_it[k] * chi2_it[k];
119 for (
size_t k = 0; k < state.size(); ++k) {
120 auto state_it = state.begin();
121 auto H0_i_it = H0[i].begin();
122 auto A0temp_it = A0temp.begin();
123 auto B0temp_it = B0temp.begin();
125 H0_i_it[k] = state_it[k] + dt * A0temp_it[k] + B0temp_it[k];
130 std::fill(atemp.begin(), atemp.end(), value_type(0));
131 std::fill(btemp.begin(), btemp.end(), value_type(0));
132 std::fill(E2.begin(), E2.end(), value_type(0));
134 for (
int i = 0; i < stages; ++i) {
135 this->problem_->drift(this->current_time_ + tableau_.c0[i] * dt, H0[i], ftmp);
136 this->problem_->diffusion(this->current_time_ + tableau_.c1[i] * dt, H0[i], gtmp);
138 for (
size_t k = 0; k < state.size(); ++k) {
139 auto atemp_it = atemp.begin();
140 auto btemp_it = btemp.begin();
141 auto E2_it = E2.begin();
142 auto ftmp_it = ftmp.begin();
143 auto gtmp_it = gtmp.begin();
144 auto dW_it = dW.begin();
145 auto chi2_it = chi2.begin();
147 atemp_it[k] += tableau_.alpha[i] * ftmp_it[k];
148 btemp_it[k] += tableau_.beta1[i] * gtmp_it[k] * dW_it[k];
149 E2_it[k] += tableau_.beta2[i] * gtmp_it[k] * chi2_it[k];
154 for (
size_t k = 0; k < state.size(); ++k) {
155 auto state_it = state.begin();
156 auto atemp_it = atemp.begin();
157 auto btemp_it = btemp.begin();
158 auto E2_it = E2.begin();
160 state_it[k] += dt * atemp_it[k] + btemp_it[k] + E2_it[k];
163 this->advance_time(dt);
166 std::string name()
const override {
167 return "SRA (Strong Order 1.5 for Additive Noise)";
181 tableau.order =
static_cast<value_type
>(1.5);
184 tableau.A0 = {{0, 0}, {1, 0}};
186 tableau.alpha = {
static_cast<value_type
>(0.5),
static_cast<value_type
>(0.5)};
189 tableau.B0 = {{0, 0}, {1, 0}};
191 tableau.beta1 = {
static_cast<value_type
>(0.5),
static_cast<value_type
>(0.5)};
192 tableau.beta2 = {0, 1};