tomoto 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/ext/tomoto/ct.cpp +8 -4
  4. data/ext/tomoto/dmr.cpp +10 -4
  5. data/ext/tomoto/dt.cpp +13 -4
  6. data/ext/tomoto/extconf.rb +1 -1
  7. data/ext/tomoto/gdmr.cpp +14 -6
  8. data/ext/tomoto/hdp.cpp +9 -4
  9. data/ext/tomoto/hlda.cpp +9 -4
  10. data/ext/tomoto/hpa.cpp +9 -4
  11. data/ext/tomoto/lda.cpp +8 -4
  12. data/ext/tomoto/llda.cpp +8 -4
  13. data/ext/tomoto/mglda.cpp +11 -1
  14. data/ext/tomoto/pa.cpp +9 -4
  15. data/ext/tomoto/plda.cpp +8 -4
  16. data/ext/tomoto/slda.cpp +13 -5
  17. data/lib/tomoto/gdmr.rb +2 -2
  18. data/lib/tomoto/version.rb +1 -1
  19. data/vendor/EigenRand/EigenRand/Core.h +6 -1107
  20. data/vendor/EigenRand/EigenRand/Dists/Basic.h +490 -43
  21. data/vendor/EigenRand/EigenRand/Dists/Discrete.h +916 -285
  22. data/vendor/EigenRand/EigenRand/Dists/GammaPoisson.h +85 -36
  23. data/vendor/EigenRand/EigenRand/Dists/NormalExp.h +1038 -290
  24. data/vendor/EigenRand/EigenRand/EigenRand +2 -2
  25. data/vendor/EigenRand/EigenRand/Macro.h +4 -4
  26. data/vendor/EigenRand/EigenRand/MorePacketMath.h +54 -22
  27. data/vendor/EigenRand/EigenRand/MvDists/Multinomial.h +222 -0
  28. data/vendor/EigenRand/EigenRand/MvDists/MvNormal.h +492 -0
  29. data/vendor/EigenRand/EigenRand/PacketFilter.h +2 -2
  30. data/vendor/EigenRand/EigenRand/PacketRandomEngine.h +2 -2
  31. data/vendor/EigenRand/EigenRand/RandUtils.h +65 -11
  32. data/vendor/EigenRand/EigenRand/doc.h +142 -25
  33. data/vendor/EigenRand/LICENSE +1 -1
  34. data/vendor/EigenRand/README.md +109 -24
  35. data/vendor/tomotopy/README.kr.rst +27 -6
  36. data/vendor/tomotopy/README.rst +29 -8
  37. data/vendor/tomotopy/src/Labeling/FoRelevance.cpp +60 -12
  38. data/vendor/tomotopy/src/Labeling/FoRelevance.h +2 -2
  39. data/vendor/tomotopy/src/Labeling/Phraser.hpp +33 -21
  40. data/vendor/tomotopy/src/TopicModel/CT.h +8 -5
  41. data/vendor/tomotopy/src/TopicModel/CTModel.cpp +2 -6
  42. data/vendor/tomotopy/src/TopicModel/CTModel.hpp +29 -23
  43. data/vendor/tomotopy/src/TopicModel/DMR.h +33 -4
  44. data/vendor/tomotopy/src/TopicModel/DMRModel.cpp +2 -6
  45. data/vendor/tomotopy/src/TopicModel/DMRModel.hpp +231 -57
  46. data/vendor/tomotopy/src/TopicModel/DT.h +24 -5
  47. data/vendor/tomotopy/src/TopicModel/DTModel.cpp +2 -8
  48. data/vendor/tomotopy/src/TopicModel/DTModel.hpp +41 -28
  49. data/vendor/tomotopy/src/TopicModel/GDMR.h +31 -5
  50. data/vendor/tomotopy/src/TopicModel/GDMRModel.cpp +2 -7
  51. data/vendor/tomotopy/src/TopicModel/GDMRModel.hpp +211 -104
  52. data/vendor/tomotopy/src/TopicModel/HDP.h +11 -2
  53. data/vendor/tomotopy/src/TopicModel/HDPModel.cpp +2 -6
  54. data/vendor/tomotopy/src/TopicModel/HDPModel.hpp +52 -45
  55. data/vendor/tomotopy/src/TopicModel/HLDA.h +11 -2
  56. data/vendor/tomotopy/src/TopicModel/HLDAModel.cpp +2 -6
  57. data/vendor/tomotopy/src/TopicModel/HLDAModel.hpp +13 -16
  58. data/vendor/tomotopy/src/TopicModel/HPA.h +5 -2
  59. data/vendor/tomotopy/src/TopicModel/HPAModel.cpp +2 -6
  60. data/vendor/tomotopy/src/TopicModel/HPAModel.hpp +51 -21
  61. data/vendor/tomotopy/src/TopicModel/LDA.h +9 -2
  62. data/vendor/tomotopy/src/TopicModel/LDACVB0Model.hpp +8 -8
  63. data/vendor/tomotopy/src/TopicModel/LDAModel.cpp +2 -6
  64. data/vendor/tomotopy/src/TopicModel/LDAModel.hpp +70 -28
  65. data/vendor/tomotopy/src/TopicModel/LLDA.h +1 -2
  66. data/vendor/tomotopy/src/TopicModel/LLDAModel.cpp +2 -6
  67. data/vendor/tomotopy/src/TopicModel/LLDAModel.hpp +22 -12
  68. data/vendor/tomotopy/src/TopicModel/MGLDA.h +12 -3
  69. data/vendor/tomotopy/src/TopicModel/MGLDAModel.cpp +2 -10
  70. data/vendor/tomotopy/src/TopicModel/MGLDAModel.hpp +42 -19
  71. data/vendor/tomotopy/src/TopicModel/PA.h +9 -4
  72. data/vendor/tomotopy/src/TopicModel/PAModel.cpp +2 -6
  73. data/vendor/tomotopy/src/TopicModel/PAModel.hpp +48 -25
  74. data/vendor/tomotopy/src/TopicModel/PLDA.h +13 -2
  75. data/vendor/tomotopy/src/TopicModel/PLDAModel.cpp +2 -6
  76. data/vendor/tomotopy/src/TopicModel/PLDAModel.hpp +27 -19
  77. data/vendor/tomotopy/src/TopicModel/PT.h +12 -5
  78. data/vendor/tomotopy/src/TopicModel/PTModel.cpp +2 -3
  79. data/vendor/tomotopy/src/TopicModel/PTModel.hpp +29 -14
  80. data/vendor/tomotopy/src/TopicModel/SLDA.h +18 -6
  81. data/vendor/tomotopy/src/TopicModel/SLDAModel.cpp +2 -10
  82. data/vendor/tomotopy/src/TopicModel/SLDAModel.hpp +93 -43
  83. data/vendor/tomotopy/src/TopicModel/TopicModel.hpp +58 -23
  84. data/vendor/tomotopy/src/Utils/AliasMethod.hpp +6 -6
  85. data/vendor/tomotopy/src/Utils/Dictionary.h +11 -0
  86. data/vendor/tomotopy/src/Utils/SharedString.hpp +26 -1
  87. data/vendor/tomotopy/src/Utils/Trie.hpp +46 -21
  88. data/vendor/tomotopy/src/Utils/Utils.hpp +99 -14
  89. data/vendor/tomotopy/src/Utils/exception.h +1 -1
  90. data/vendor/tomotopy/src/Utils/math.h +5 -7
  91. data/vendor/tomotopy/src/Utils/serializer.hpp +329 -201
  92. data/vendor/tomotopy/src/Utils/text.hpp +8 -0
  93. data/vendor/tomotopy/src/Utils/tvector.hpp +49 -7
  94. metadata +9 -7
@@ -0,0 +1,492 @@
1
+ /**
2
+ * @file MvNormal.h
3
+ * @author bab2min (bab2min@gmail.com)
4
+ * @brief
5
+ * @version 0.3.0
6
+ * @date 2020-10-07
7
+ *
8
+ * @copyright Copyright (c) 2020
9
+ *
10
+ */
11
+
12
+ #ifndef EIGENRAND_MVDISTS_MVNORMAL_H
13
+ #define EIGENRAND_MVDISTS_MVNORMAL_H
14
+
15
+ namespace Eigen
16
+ {
17
+ namespace Rand
18
+ {
19
+ namespace detail
20
+ {
21
+ template<typename _Scalar, Index Dim, typename _Mat>
22
+ Matrix<_Scalar, Dim, Dim> get_lt(const MatrixBase<_Mat>& mat)
23
+ {
24
+ LLT<Matrix<_Scalar, Dim, Dim>> llt(mat);
25
+ if (llt.info() == Eigen::Success)
26
+ {
27
+ return llt.matrixL();
28
+ }
29
+ else
30
+ {
31
+ SelfAdjointEigenSolver<Matrix<_Scalar, Dim, Dim>> solver(mat);
32
+ if (solver.info() != Eigen::Success)
33
+ {
34
+ throw std::runtime_error{ "The matrix cannot be solved!" };
35
+ }
36
+ return solver.eigenvectors() * solver.eigenvalues().cwiseMax(0).cwiseSqrt().asDiagonal();
37
+ }
38
+ }
39
+
40
+ class FullMatrix {};
41
+ class LowerTriangular {};
42
+ class InvLowerTriangular {};
43
+ }
44
+
45
+ constexpr detail::FullMatrix full_matrix;
46
+ constexpr detail::LowerTriangular lower_triangular;
47
+ constexpr detail::InvLowerTriangular inv_lower_triangular;
48
+
49
+
50
+ /**
51
+ * @brief Generator of real vectors on a multivariate normal distribution
52
+ *
53
+ * @tparam _Scalar Numeric type
54
+ * @tparam Dim number of dimensions, or `Eigen::Dynamic`
55
+ */
56
+ template<typename _Scalar, Index Dim = -1>
57
+ class MvNormalGen : public MvVecGenBase<MvNormalGen<_Scalar, Dim>, _Scalar, Dim>
58
+ {
59
+ Matrix<_Scalar, Dim, 1> mean;
60
+ Matrix<_Scalar, Dim, Dim> lt;
61
+ StdNormalGen<_Scalar> stdnorm;
62
+
63
+ public:
64
+ /**
65
+ * @brief Construct a new multivariate normal generator from lower triangular matrix of decomposed covariance
66
+ *
67
+ * @tparam MeanTy
68
+ * @tparam LTTy
69
+ * @param _mean mean vector of the distribution
70
+ * @param _lt lower triangular matrix of decomposed covariance
71
+ */
72
+ template<typename MeanTy, typename LTTy>
73
+ MvNormalGen(const MatrixBase<MeanTy>& _mean, const MatrixBase<LTTy>& _lt, detail::LowerTriangular)
74
+ : mean{ _mean }, lt{ _lt }
75
+ {
76
+ eigen_assert(_mean.cols() == 1 && _mean.rows() == _lt.rows() && _lt.rows() == _lt.cols());
77
+ }
78
+
79
+ /**
80
+ * @brief Construct a new multivariate normal generator from covariance matrix
81
+ *
82
+ * @tparam MeanTy
83
+ * @tparam CovTy
84
+ * @param _mean mean vector of the distribution
85
+ * @param _cov covariance matrix (should be positive semi-definite)
86
+ */
87
+ template<typename MeanTy, typename CovTy>
88
+ MvNormalGen(const MatrixBase<MeanTy>& _mean, const MatrixBase<CovTy>& _cov, detail::FullMatrix = {})
89
+ : MvNormalGen{ _mean, detail::template get_lt<_Scalar, Dim>(_cov), lower_triangular }
90
+ {
91
+ }
92
+
93
+ MvNormalGen(const MvNormalGen&) = default;
94
+ MvNormalGen(MvNormalGen&&) = default;
95
+
96
+ MvNormalGen& operator=(const MvNormalGen&) = default;
97
+ MvNormalGen& operator=(MvNormalGen&&) = default;
98
+
99
+ Index dims() const { return mean.rows(); }
100
+
101
+ template<typename Urng>
102
+ inline auto generate(Urng&& urng, Index samples)
103
+ -> decltype((lt * stdnorm.template generate<Matrix<_Scalar, Dim, -1>>(mean.rows(), samples, std::forward<Urng>(urng))).colwise() + mean)
104
+ {
105
+ return (lt * stdnorm.template generate<Matrix<_Scalar, Dim, -1>>(mean.rows(), samples, std::forward<Urng>(urng))).colwise() + mean;
106
+ }
107
+
108
+ template<typename Urng>
109
+ inline auto generate(Urng&& urng)
110
+ -> decltype((lt * stdnorm.template generate<Matrix<_Scalar, Dim, 1>>(mean.rows(), 1, std::forward<Urng>(urng))).colwise() + mean)
111
+ {
112
+ return (lt * stdnorm.template generate<Matrix<_Scalar, Dim, 1>>(mean.rows(), 1, std::forward<Urng>(urng))).colwise() + mean;
113
+ }
114
+ };
115
+
116
+ /**
117
+ * @brief helper function constructing Eigen::Rand::MvNormal
118
+ *
119
+ * @tparam MeanTy
120
+ * @tparam CovTy
121
+ * @param mean mean vector of the distribution
122
+ * @param cov covariance matrix (should be positive semi-definite)
123
+ */
124
+ template<typename MeanTy, typename CovTy>
125
+ inline auto makeMvNormalGen(const MatrixBase<MeanTy>& mean, const MatrixBase<CovTy>& cov)
126
+ -> MvNormalGen<typename MatrixBase<MeanTy>::Scalar, MatrixBase<MeanTy>::RowsAtCompileTime>
127
+ {
128
+ static_assert(
129
+ std::is_same<typename MatrixBase<MeanTy>::Scalar, typename MatrixBase<CovTy>::Scalar>::value,
130
+ "Derived::Scalar must be the same with `mean` and `cov`'s Scalar."
131
+ );
132
+ static_assert(
133
+ MatrixBase<MeanTy>::RowsAtCompileTime == MatrixBase<CovTy>::RowsAtCompileTime &&
134
+ MatrixBase<CovTy>::RowsAtCompileTime == MatrixBase<CovTy>::ColsAtCompileTime,
135
+ "assert: mean.RowsAtCompileTime == cov.RowsAtCompileTime && cov.RowsAtCompileTime == cov.ColsAtCompileTime"
136
+ );
137
+ return { mean, cov };
138
+ }
139
+
140
+ /**
141
+ * @brief helper function constructing Eigen::Rand::MvNormal
142
+ *
143
+ * @tparam MeanTy
144
+ * @tparam LTTy
145
+ * @param mean mean vector of the distribution
146
+ * @param lt lower triangular matrix of decomposed covariance
147
+ */
148
+ template<typename MeanTy, typename LTTy>
149
+ inline auto makeMvNormalGenFromLt(const MatrixBase<MeanTy>& mean, const MatrixBase<LTTy>& lt)
150
+ -> MvNormalGen<typename MatrixBase<MeanTy>::Scalar, MatrixBase<MeanTy>::RowsAtCompileTime>
151
+ {
152
+ static_assert(
153
+ std::is_same<typename MatrixBase<MeanTy>::Scalar, typename MatrixBase<LTTy>::Scalar>::value,
154
+ "Derived::Scalar must be the same with `mean` and `lt`'s Scalar."
155
+ );
156
+ static_assert(
157
+ MatrixBase<MeanTy>::RowsAtCompileTime == MatrixBase<LTTy>::RowsAtCompileTime &&
158
+ MatrixBase<LTTy>::RowsAtCompileTime == MatrixBase<LTTy>::ColsAtCompileTime,
159
+ "assert: mean.RowsAtCompileTime == lt.RowsAtCompileTime && lt.RowsAtCompileTime == lt.ColsAtCompileTime"
160
+ );
161
+ return { mean, lt, lower_triangular };
162
+ }
163
+
164
+ /**
165
+ * @brief Generator of real matrices on a Wishart distribution
166
+ *
167
+ * @tparam _Scalar
168
+ * @tparam Dim number of dimensions, or `Eigen::Dynamic`
169
+ */
170
+ template<typename _Scalar, Index Dim>
171
+ class WishartGen : public MvMatGenBase<WishartGen<_Scalar, Dim>, _Scalar, Dim>
172
+ {
173
+ Index df;
174
+ Matrix<_Scalar, Dim, Dim> chol;
175
+ StdNormalGen<_Scalar> stdnorm;
176
+ std::vector<ChiSquaredGen<_Scalar>> chisqs;
177
+ public:
178
+ /**
179
+ * @brief Construct a new Wishart generator from lower triangular matrix of decomposed scale
180
+ *
181
+ * @tparam ScaleTy
182
+ * @param _df degrees of freedom
183
+ * @param _lt lower triangular matrix of decomposed scale
184
+ */
185
+ template<typename ScaleTy>
186
+ WishartGen(Index _df, const MatrixBase<ScaleTy>& _lt, detail::LowerTriangular)
187
+ : df{ _df }, chol{ _lt }
188
+ {
189
+ eigen_assert(df > chol.rows() - 1);
190
+ eigen_assert(chol.rows() == chol.cols());
191
+
192
+ for (Index i = 0; i < chol.rows(); ++i)
193
+ {
194
+ chisqs.emplace_back(df - i);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @brief Construct a new Wishart generator from scale matrix
200
+ *
201
+ * @tparam ScaleTy
202
+ * @param _df degrees of freedom
203
+ * @param _lt scale matrix (should be positive definitive)
204
+ */
205
+ template<typename ScaleTy>
206
+ WishartGen(Index _df, const MatrixBase<ScaleTy>& _scale, detail::FullMatrix = {})
207
+ : WishartGen{ _df, detail::template get_lt<_Scalar, Dim>(_scale), lower_triangular }
208
+ {
209
+ eigen_assert(_scale.rows() == _scale.cols());
210
+ }
211
+
212
+ WishartGen(const WishartGen&) = default;
213
+ WishartGen(WishartGen&&) = default;
214
+
215
+ WishartGen& operator=(const WishartGen&) = default;
216
+ WishartGen& operator=(WishartGen&&) = default;
217
+
218
+ Index dims() const { return chol.rows(); }
219
+
220
+ template<typename Urng>
221
+ inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
222
+ {
223
+ const Index dim = chol.rows();
224
+ const Index normSamples = samples * dim * (dim - 1) / 2;
225
+ using ArrayXs = Array<_Scalar, -1, 1>;
226
+ Matrix<_Scalar, Dim, -1> rand_mat(dim, dim * samples), tmp(dim, dim * samples);
227
+
228
+ _Scalar* ptr = tmp.data();
229
+ Map<ArrayXs>{ ptr, normSamples } = stdnorm.template generate<ArrayXs>(normSamples, 1, urng);
230
+ for (Index j = 0; j < samples; ++j)
231
+ {
232
+ for (Index i = 0; i < dim - 1; ++i)
233
+ {
234
+ rand_mat.col(i + j * dim).tail(dim - 1 - i) = Map<ArrayXs>{ ptr, dim - 1 - i };
235
+ ptr += dim - 1 - i;
236
+ }
237
+ }
238
+
239
+ for (Index i = 0; i < dim; ++i)
240
+ {
241
+ _Scalar* ptr = tmp.data();
242
+ Map<ArrayXs>{ ptr, samples } = chisqs[i].template generate<ArrayXs>(samples, 1, urng).sqrt();
243
+ for (Index j = 0; j < samples; ++j)
244
+ {
245
+ rand_mat(i, i + j * dim) = *ptr++;
246
+ }
247
+ }
248
+
249
+ for (Index j = 0; j < samples; ++j)
250
+ {
251
+ rand_mat.middleCols(j * dim, dim).template triangularView<StrictlyUpper>().setZero();
252
+ }
253
+ tmp.noalias() = chol * rand_mat;
254
+
255
+ for (Index j = 0; j < samples; ++j)
256
+ {
257
+ auto t = tmp.middleCols(j * dim, dim);
258
+ rand_mat.middleCols(j * dim, dim).noalias() = t * t.transpose();
259
+ }
260
+ return rand_mat;
261
+ }
262
+
263
+ template<typename Urng>
264
+ inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng)
265
+ {
266
+ const Index dim = chol.rows();
267
+ const Index normSamples = dim * (dim - 1) / 2;
268
+ using ArrayXs = Array<_Scalar, -1, 1>;
269
+ Matrix<_Scalar, Dim, Dim> rand_mat(dim, dim);
270
+ Map<ArrayXs>{ rand_mat.data(), normSamples } = stdnorm.template generate<ArrayXs>(normSamples, 1, urng);
271
+
272
+ for (Index i = 0; i < dim / 2; ++i)
273
+ {
274
+ rand_mat.col(dim - 2 - i).tail(i + 1) = rand_mat.col(i).head(i + 1);
275
+ }
276
+
277
+ for (Index i = 0; i < dim; ++i)
278
+ {
279
+ rand_mat(i, i) = chisqs[i].template generate<Array<_Scalar, 1, 1>>(1, 1, urng).sqrt()(0);
280
+ }
281
+ rand_mat.template triangularView<StrictlyUpper>().setZero();
282
+
283
+ auto t = (chol * rand_mat).eval();
284
+ return (t * t.transpose()).eval();
285
+ }
286
+ };
287
+
288
+ /**
289
+ * @brief helper function constructing Eigen::Rand::WishartGen
290
+ *
291
+ * @tparam ScaleTy
292
+ * @param df degrees of freedom
293
+ * @param scale scale matrix (should be positive definitive)
294
+ */
295
+ template<typename ScaleTy>
296
+ inline auto makeWishartGen(Index df, const MatrixBase<ScaleTy>& scale)
297
+ -> WishartGen<typename MatrixBase<ScaleTy>::Scalar, MatrixBase<ScaleTy>::RowsAtCompileTime>
298
+ {
299
+ static_assert(
300
+ MatrixBase<ScaleTy>::RowsAtCompileTime == MatrixBase<ScaleTy>::ColsAtCompileTime,
301
+ "assert: scale.RowsAtCompileTime == scale.ColsAtCompileTime"
302
+ );
303
+ return { df, scale };
304
+ }
305
+
306
+ /**
307
+ * @brief helper function constructing Eigen::Rand::WishartGen
308
+ *
309
+ * @tparam LTTy
310
+ * @param df degrees of freedom
311
+ * @param lt lower triangular matrix of decomposed scale
312
+ */
313
+ template<typename LTTy>
314
+ inline auto makeWishartGenFromLt(Index df, const MatrixBase<LTTy>& lt)
315
+ -> WishartGen<typename MatrixBase<LTTy>::Scalar, MatrixBase<LTTy>::RowsAtCompileTime>
316
+ {
317
+ static_assert(
318
+ MatrixBase<LTTy>::RowsAtCompileTime == MatrixBase<LTTy>::ColsAtCompileTime,
319
+ "assert: lt.RowsAtCompileTime == lt.ColsAtCompileTime"
320
+ );
321
+ return { df, lt, lower_triangular };
322
+ }
323
+
324
+ /**
325
+ * @brief Generator of real matrices on a inverse Wishart distribution
326
+ *
327
+ * @tparam _Scalar
328
+ * @tparam Dim number of dimensions, or `Eigen::Dynamic`
329
+ */
330
+ template<typename _Scalar, Index Dim>
331
+ class InvWishartGen : public MvMatGenBase<InvWishartGen<_Scalar, Dim>, _Scalar, Dim>
332
+ {
333
+ Index df;
334
+ Matrix<_Scalar, Dim, Dim> chol;
335
+ StdNormalGen<_Scalar> stdnorm;
336
+ std::vector<ChiSquaredGen<_Scalar>> chisqs;
337
+ public:
338
+ /**
339
+ * @brief Construct a new inverse Wishart generator
340
+ *
341
+ * @tparam ScaleTy
342
+ * @param _df degrees of freedom
343
+ * @param _ilt lower triangular matrix of decomposed inverse scale
344
+ */
345
+ template<typename ScaleTy>
346
+ InvWishartGen(Index _df, const MatrixBase<ScaleTy>& _ilt, detail::InvLowerTriangular)
347
+ : df{ _df }, chol{ _ilt }
348
+ {
349
+ eigen_assert(df > chol.rows() - 1);
350
+ eigen_assert(chol.rows() == chol.cols());
351
+
352
+ for (Index i = 0; i < chol.rows(); ++i)
353
+ {
354
+ chisqs.emplace_back(df - i);
355
+ }
356
+ }
357
+
358
+ /**
359
+ * @brief Construct a new inverse Wishart generator
360
+ *
361
+ * @tparam ScaleTy
362
+ * @param _df degrees of freedom
363
+ * @param _scale scale matrix (should be positive definitive)
364
+ */
365
+ template<typename ScaleTy>
366
+ InvWishartGen(Index _df, const MatrixBase<ScaleTy>& _scale, detail::FullMatrix = {})
367
+ : InvWishartGen{ _df, detail::template get_lt<_Scalar, Dim>(_scale.inverse()), inv_lower_triangular }
368
+ {
369
+ eigen_assert(_scale.rows() == _scale.cols());
370
+ }
371
+
372
+ InvWishartGen(const InvWishartGen&) = default;
373
+ InvWishartGen(InvWishartGen&&) = default;
374
+
375
+ InvWishartGen& operator=(const InvWishartGen&) = default;
376
+ InvWishartGen& operator=(InvWishartGen&&) = default;
377
+
378
+ Index dims() const { return chol.rows(); }
379
+
380
+ template<typename Urng>
381
+ inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
382
+ {
383
+ const Index dim = chol.rows();
384
+ const Index normSamples = samples * dim * (dim - 1) / 2;
385
+ using ArrayXs = Array<_Scalar, -1, 1>;
386
+ Matrix<_Scalar, Dim, -1> rand_mat(dim, dim * samples), tmp(dim, dim * samples);
387
+
388
+ _Scalar* ptr = tmp.data();
389
+ Map<ArrayXs>{ ptr, normSamples } = stdnorm.template generate<ArrayXs>(normSamples, 1, urng);
390
+ for (Index j = 0; j < samples; ++j)
391
+ {
392
+ for (Index i = 0; i < dim - 1; ++i)
393
+ {
394
+ rand_mat.col(i + j * dim).tail(dim - 1 - i) = Map<ArrayXs>{ ptr, dim - 1 - i };
395
+ ptr += dim - 1 - i;
396
+ }
397
+ }
398
+
399
+ for (Index i = 0; i < dim; ++i)
400
+ {
401
+ _Scalar* ptr = tmp.data();
402
+ Map<ArrayXs>{ ptr, samples } = chisqs[i].template generate<ArrayXs>(samples, 1, urng).sqrt();
403
+ for (Index j = 0; j < samples; ++j)
404
+ {
405
+ rand_mat(i, i + j * dim) = *ptr++;
406
+ }
407
+ }
408
+
409
+ for (Index j = 0; j < samples; ++j)
410
+ {
411
+ rand_mat.middleCols(j * dim, dim).template triangularView<StrictlyUpper>().setZero();
412
+ }
413
+ tmp.noalias() = chol * rand_mat;
414
+
415
+ auto id = Eigen::Matrix<_Scalar, Dim, Dim>::Identity(dim, dim);
416
+ for (Index j = 0; j < samples; ++j)
417
+ {
418
+ auto t = tmp.middleCols(j * dim, dim);
419
+ auto u = rand_mat.middleCols(j * dim, dim);
420
+ u.noalias() = t.template triangularView<Lower>().solve(id);
421
+ t.noalias() = u.transpose() * u;
422
+ }
423
+ return tmp;
424
+ }
425
+
426
+ template<typename Urng>
427
+ inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng)
428
+ {
429
+ const Index dim = chol.rows();
430
+ const Index normSamples = dim * (dim - 1) / 2;
431
+ using ArrayXs = Array<_Scalar, -1, 1>;
432
+ Matrix<_Scalar, Dim, Dim> rand_mat(dim, dim);
433
+ Map<ArrayXs>{ rand_mat.data(), normSamples } = stdnorm.template generate<ArrayXs>(normSamples, 1, urng);
434
+
435
+ for (Index i = 0; i < dim / 2; ++i)
436
+ {
437
+ rand_mat.col(dim - 2 - i).tail(i + 1) = rand_mat.col(i).head(i + 1);
438
+ }
439
+
440
+ for (Index i = 0; i < dim; ++i)
441
+ {
442
+ rand_mat(i, i) = chisqs[i].template generate<Array<_Scalar, 1, 1>>(1, 1, urng).sqrt()(0);
443
+ }
444
+ rand_mat.template triangularView<StrictlyUpper>().setZero();
445
+
446
+ auto t = (chol * rand_mat).eval();
447
+ auto id = Eigen::Matrix<_Scalar, Dim, Dim>::Identity(dim, dim);
448
+ rand_mat.noalias() = t.template triangularView<Lower>().solve(id);
449
+
450
+ return (rand_mat.transpose() * rand_mat).eval();
451
+ }
452
+ };
453
+
454
+ /**
455
+ * @brief helper function constructing Eigen::Rand::InvWishartGen
456
+ *
457
+ * @tparam ScaleTy
458
+ * @param df degrees of freedom
459
+ * @param scale scale matrix
460
+ */
461
+ template<typename ScaleTy>
462
+ inline auto makeInvWishartGen(Index df, const MatrixBase<ScaleTy>& scale)
463
+ -> InvWishartGen<typename MatrixBase<ScaleTy>::Scalar, MatrixBase<ScaleTy>::RowsAtCompileTime>
464
+ {
465
+ static_assert(
466
+ MatrixBase<ScaleTy>::RowsAtCompileTime == MatrixBase<ScaleTy>::ColsAtCompileTime,
467
+ "assert: scale.RowsAtCompileTime == scale.ColsAtCompileTime"
468
+ );
469
+ return { df, scale };
470
+ }
471
+
472
+ /**
473
+ * @brief helper function constructing Eigen::Rand::InvWishartGen
474
+ *
475
+ * @tparam ILTTy
476
+ * @param df degrees of freedom
477
+ * @param ilt lower triangular matrix of decomposed inverse scale
478
+ */
479
+ template<typename ILTTy>
480
+ inline auto makeInvWishartGenFromIlt(Index df, const MatrixBase<ILTTy>& ilt)
481
+ -> InvWishartGen<typename MatrixBase<ILTTy>::Scalar, MatrixBase<ILTTy>::RowsAtCompileTime>
482
+ {
483
+ static_assert(
484
+ MatrixBase<ILTTy>::RowsAtCompileTime == MatrixBase<ILTTy>::ColsAtCompileTime,
485
+ "assert: ilt.RowsAtCompileTime == ilt.ColsAtCompileTime"
486
+ );
487
+ return { df, ilt, inv_lower_triangular };
488
+ }
489
+ }
490
+ }
491
+
492
+ #endif