13
13
#define EIGEN_MALLOC_NOT_ALLOWED
14
14
#endif
15
15
16
+ #include " unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h"
17
+ #include " utils/stop-watch.h"
16
18
#include < Eigen/Core>
17
19
#include < Eigen/LU>
18
20
#include < iostream>
19
21
#include < stdio.h>
20
- #include " unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h"
21
- #include " utils/stop-watch.h"
22
22
23
23
#ifdef __cplusplus
24
24
extern " C" {
@@ -35,7 +35,6 @@ template <typename T, int N>
35
35
class MatrixExponential {
36
36
37
37
private:
38
-
39
38
int size;
40
39
41
40
// Typedefs to make code more readable
@@ -55,7 +54,7 @@ class MatrixExponential {
55
54
int squarings;
56
55
57
56
MatrixType prevEA, prevA, deltaA; // Used in delta update
58
- bool delta;
57
+ bool delta, deltaUsed ;
59
58
60
59
public:
61
60
MatrixExponential ();
@@ -66,9 +65,11 @@ class MatrixExponential {
66
65
67
66
int get_squarings () const { return squarings; }
68
67
69
- void setDelta (bool delta) { this ->delta = delta; }
68
+ void useDelta (bool delta) { this ->delta = delta; }
70
69
bool getDelta () { return delta; }
71
70
71
+ bool wasDeltaUsed () { return deltaUsed; }
72
+
72
73
/* * Compute the exponential of the given matrix arg and writes it in result.
73
74
*/
74
75
void compute (RefMatrix A, RefOutMatrix out);
@@ -132,13 +133,11 @@ class MatrixExponential {
132
133
template <typename T, int N>
133
134
MatrixExponential<T, N>::MatrixExponential()
134
135
{
135
- START_PROFILER (" MatrixExponential::constructor" );
136
136
if (N == Dynamic) {
137
137
init (2 ); // Init to dym 2 for no particular reason
138
138
} else {
139
139
init (N);
140
140
}
141
- STOP_PROFILER (" MatrixExponential::constructor" );
142
141
}
143
142
144
143
template <typename T, int N>
@@ -178,27 +177,28 @@ void MatrixExponential<T, N>::resize(int n)
178
177
}
179
178
180
179
template <typename T, int N>
181
- void MatrixExponential<T, N>::resetDelta() {
180
+ void MatrixExponential<T, N>::resetDelta()
181
+ {
182
182
// Necessary to trigger full computation at the first call
183
- prevA = MatrixType::Zero (size, size);
183
+ prevA = MatrixType::Zero (size, size);
184
184
prevEA = MatrixType::Identity (size, size);
185
185
}
186
186
187
187
template <typename T, int N>
188
188
void MatrixExponential<T, N>::compute(RefMatrix A, RefOutMatrix out)
189
189
{
190
- bool deltaUsed = false ;
190
+ deltaUsed = false ;
191
191
if (delta) {
192
- deltaA = A - prevEA ;
192
+ deltaA = A - prevA ;
193
193
const double l1normA = A.cwiseAbs ().colwise ().sum ().maxCoeff ();
194
194
const double l1normDeltaA = deltaA.cwiseAbs ().colwise ().sum ().maxCoeff ();
195
195
// Speedup only if the difference in number of squaring is greater than 2
196
196
deltaUsed = determineSquarings (l1normA) - determineSquarings (l1normDeltaA) > 1 ;
197
- }
198
-
199
- if (deltaUsed)
200
- computeUV (deltaA);
201
- else
197
+ }
198
+
199
+ if (deltaUsed)
200
+ computeUV (deltaA);
201
+ else
202
202
computeUV (A); // Pade approximant is (U+V) / (-U+V)
203
203
numer = U + V;
204
204
denom = -U + V;
@@ -213,31 +213,24 @@ void MatrixExponential<T, N>::compute(RefMatrix A, RefOutMatrix out)
213
213
214
214
if (deltaUsed) { // Saving result for next delta computation
215
215
out = prevEA * tmp;
216
- prevA = A;
217
- prevEA = tmp;
218
216
} else {
219
217
out = tmp;
220
218
}
219
+
220
+ prevA = A;
221
+ prevEA = out;
221
222
}
222
223
223
224
template <typename T, int N>
224
225
void MatrixExponential<T, N>::computeExpTimesVector(RefMatrix A, RefVector v, RefOutVector out, int vec_squarings)
225
226
{
226
- START_PROFILER (" MatrixExponential::computeExpTimesVector" );
227
- START_PROFILER (" MatrixExponential:computeExpTimesVector:computeUV" );
228
227
computeUV (A); // Pade approximant is (U+V) / (-U+V)
229
- STOP_PROFILER (" MatrixExponential:computeExpTimesVector:computeUV" );
230
228
numer = U + V;
231
229
denom = -U + V;
232
- START_PROFILER (" MatrixExponential:computeExpTimesVector:computeLUdecomposition" );
233
230
ppLU.compute (denom);
234
- STOP_PROFILER (" MatrixExponential:computeExpTimesVector:computeLUdecomposition" );
235
- START_PROFILER (" MatrixExponential:computeExpTimesVector:LUsolve" );
236
231
tmp = ppLU.solve (numer);
237
- STOP_PROFILER (" MatrixExponential:computeExpTimesVector:LUsolve" );
238
232
239
233
// undo scaling by repeated squaring
240
- START_PROFILER (" MatrixExponential:computeExpTimesVector:squaringVector" );
241
234
/*
242
235
* If the matrix size is n and the number of squaring is s, applying
243
236
* matrix-vector multiplications is only convenient if
@@ -273,8 +266,6 @@ void MatrixExponential<T, N>::computeExpTimesVector(RefMatrix A, RefVector v, Re
273
266
out.noalias () = tmp * v_tmp;
274
267
v_tmp = out;
275
268
}
276
- STOP_PROFILER (" MatrixExponential:computeExpTimesVector:squaringVector" );
277
- STOP_PROFILER (" MatrixExponential::computeExpTimesVector" );
278
269
}
279
270
280
271
template <typename T, int N>
@@ -296,9 +287,7 @@ void MatrixExponential<T, N>::computeUV(const RefMatrix& A)
296
287
if (l1norm > 2.097847961257068e+000 ) {
297
288
squarings = determineSquarings (l1norm);
298
289
A_scaled = A.unaryExpr (Eigen::internal::MatrixExponentialScalingOp<double >(squarings));
299
- START_PROFILER (" MatrixExponential::matrix_exp_pade13" );
300
290
matrix_exp_pade13 (A_scaled);
301
- STOP_PROFILER (" MatrixExponential::matrix_exp_pade13" );
302
291
} else if (l1norm < 1.495585217958292e-002 ) {
303
292
matrix_exp_pade3 (A);
304
293
} else if (l1norm < 2.539398330063230e-001 ) {
0 commit comments