-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFSPSolver.h
117 lines (86 loc) · 3.11 KB
/
FSPSolver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//
// Created by Huy Vo on 8/10/18.
//
#ifndef MCMC_FTT_CME_FSPSOLVER_H
#define MCMC_FTT_CME_FSPSOLVER_H
#include <armadillo>
#include "cme_util.h"
#include "FSPMat.h"
#include "KryExpvFSP.h"
namespace cme{
using namespace arma;
class FSPSolver{
const struct Model& model;
enum MatType {ELL, COO, CSR};
FSPMat A;
Col<double>& P;
Row<double> times;
size_t current_time_index {0};
double fsp_tol;
KryExpvFSP expv;
std::function<Col<double> (Col<double>&)> matvec;
public:
FSPSolver(Col<double>& _p, const struct Model& _model, Row<double>& _times, double _fsp_tol,
double _mg_tol = 1.0e-8, double _kry_tol = 1.0e-8):
model(_model),
times(_times),
fsp_tol(_fsp_tol),
A(_model),
expv(_p, _times(0), 30, _kry_tol, true),
P(_p)
{
const Row<size_t>& FSPSize = model.FSPSize;
const Mat<int>& states_init = model.states_init;
const Col<double>& prob_init = model.probs_init;
// Set up the initial vector
if (P.n_elem < arma::prod(FSPSize+1))
{
P.resize(arma::prod(FSPSize+1));
arma::Row<int> init_indices = sub2ind_fsp(FSPSize, states_init);
for (size_t i{0}; i < init_indices.n_elem; ++i)
{
P((uword) init_indices(i)) = prob_init(i);
}
}
// Update the Magnus object with the initial vector information
matvec = [this] (Col<double>& x){return A(0)*x;};
expv.update_vectors(P, matvec);
}
FSPSolver(Col<double>& _p, const struct Model& _model, double _t_final, double _fsp_tol,
double _mg_tol = 1.0e-8, double _kry_tol = 1.0e-8):
model(_model),
times({_t_final}),
fsp_tol(_fsp_tol),
A(_model),
expv(_p, _t_final, 30, _kry_tol, true),
P(_p)
{
const Row<size_t>& FSPSize = model.FSPSize;
const Mat<int>& states_init = model.states_init;
const Col<double>& prob_init = model.probs_init;
// Set up the initial vector
if (P.n_elem < arma::prod(FSPSize+1))
{
P.resize(arma::prod(FSPSize+1));
arma::Row<int> init_indices = sub2ind_fsp(FSPSize, states_init);
for (size_t i{0}; i < init_indices.n_elem; ++i)
{
P((uword) init_indices(i)) = prob_init(i);
}
}
// Update the Magnus object with the initial vector information
matvec = [this] (Col<double>& x){return A(0)*x;};
expv.update_vectors(P, matvec);
}
void next_time();
void solve();
void reset_time()
{
current_time_index = 0;
A(0.0);
expv.reset_time();
expv.update_final_time(times(0));
}
};
};
#endif //MCMC_FTT_CME_FSPSOLVER_H