libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNMultivariateRandomTools.cpp
Go to the documentation of this file.
1 /* Copyright 2008-2016 INSA-Lyon, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: MultivariateRandomTools.cpp
19  * \author Jean DUONG, Yann LEYDIER
20  */
21 
23 #include <CRNMath/CRNMatrixInt.h>
29 
30 using namespace crn;
31 
32 /*****************************************************************************/
45 MatrixDouble MultivariateRandomTools::NewGaussianSample(const MatrixDouble& Mu, const SquareMatrixDouble& Sigma, size_t n, size_t m, bool reseed)
46 {
47  size_t dimension = Mu.GetRows();
48  MatrixDouble M(n, dimension, 0.0);
49  SquareMatrixDouble L = Sigma.MakeCholesky();
50 
51  for (size_t v = 0; v < n; v++)
52  {
53  MatrixDouble X = UnivariateRandomTools::NewGaussianSample(0.0, 1.0, dimension, m, reseed);
54  MatrixDouble Y = makeMLTransform(Mu, L, X);
55 
56  for (size_t c = 0; c < dimension; c++)
57  {
58  M.At(v, c) = Y.At(c, 0);
59  }
60  }
61  return M;
62 }
63 
64 /*****************************************************************************/
65 
78 {
79  size_t dimension = P.GetDimension();
80 
81  MatrixDouble Mu = P.GetMean();
82  SquareMatrixDouble Sigma = P.GetVariance();
83 
84  MatrixDouble Patterns(n, dimension, 0.0);
85  SquareMatrixDouble L = Sigma.MakeCholesky();
86 
87  for (size_t r = 0; r < n; r++)
88  {
89  MatrixDouble X = UnivariateRandomTools::NewGaussianSample(0.0, 1.0, dimension, m, reseed);
90  MatrixDouble Y = makeMLTransform(Mu, L, X);
91 
92  for (size_t c = 0; c < dimension; c++)
93  Patterns.At(r, c) = Y.At(c, 0);
94  }
95  return Patterns;
96 }
97 
101 MatrixDouble MultivariateRandomTools::makeMLTransform(const MatrixDouble& M, const SquareMatrixDouble& L, const MatrixDouble& X)
102 {
103  size_t n = X.GetRows();
104 
105  MatrixDouble Y(n, 1, 0.0);
106 
107  for (size_t r = 0; r < n; r++)
108  {
109  double Yr = M.At(r, 0);
110 
111  for (size_t c = 0; c <= r; c++)
112  Yr += L.At(r, c) * X.At(c, 0);
113 
114  Y.At(r, 0) = Yr;
115  }
116 
117  return Y;
118 }
119 
120 /*****************************************************************************/
121 
135 {
136  size_t dim = Mx.GetDimension();
137  size_t nbPDF = Mx.GetNbMembers();
138 
139  MatrixDouble Patterns(n, dim, 0.0);
140 
141  MatrixDouble CumulWeights(nbPDF, 1, 0.0);
142  MatrixDouble IndexeSample = UnivariateRandomTools::NewUniformSample(n, reseed);
143  MatrixInt Pop(nbPDF, 1, 0);
144 
145  // Cumulative weights from the mixture
146 
147  double Mass = 0.0;
148 
149  for (size_t k = 0; k < nbPDF; k++)
150  {
151  Mass += Mx.GetWeight(k);
152 
153  CumulWeights.At(k, 0) = Mass;
154  }
155 
156  CumulWeights *= 1.0 / Mass;
157 
158  // Build indexes to indicate which PDF of the mixture is used to generate each pattern
159 
160  for (size_t k = 0; k < n; k++)
161  {
162  double d = IndexeSample.At(k, 0);
163  bool Continue = true;
164  size_t Id = 0;
165 
166  while (Continue)
167  {
168  if ((CumulWeights.At(Id, 0) >= d) || (Id == nbPDF - 1))
169  {
170  Continue = false;
171  }
172  else
173  {
174  Id++;
175  }
176  }
177 
178  Pop.IncreaseElement(Id, 0, 1);
179  }
180 
181  // Create patterns
182 
183  size_t PatternIndex = 0;
184 
185  for (size_t p = 0; p < nbPDF; p++)
186  {
187  size_t SubSamplePop = Pop.At(p, 0);
188 
189  MatrixDouble SubSample = NewGaussianSample(Mx.GetMember(p), SubSamplePop, m, reseed);
190 
191  for (size_t r = 0; r < SubSamplePop; r++)
192  {
193  for (size_t c = 0; c < dim; c++)
194  Patterns.At(PatternIndex, c) = SubSample.At(r, c);
195 
196  PatternIndex++;
197  }
198  }
199  return Patterns;
200 }
201 
size_t GetRows() const noexcept
Returns the number of rows.
Definition: CRNMatrix.h:157
const SquareMatrixDouble & GetVariance() const
Returns the variance of a given density function.
crn::StringUTF8 Id
Definition: CRNAltoUtils.h:31
size_t GetNbMembers() const noexcept
Returns the number of density functions.
static MatrixDouble NewGaussianSample(const MatrixDouble &Mu, const SquareMatrixDouble &Sigma, size_t n=1, size_t m=100, bool reseed=true)
Creates a data sample following a Gaussian probability law.
Integer matrix class.
Definition: CRNMatrixInt.h:40
double GetWeight(size_t k) const
Returns the weight of a given density function.
static MatrixDouble NewGaussianMixtureSample(const MultivariateGaussianMixture &Mx, size_t n=1, size_t m=100, bool reseed=true)
Creates a data sample following a Gaussian probability law.
std::vector< double > NewGaussianSample(double mu=0.0, double sigma=1.0, size_t n=1, size_t m=100, bool reseed=true)
Creates a data sample following a Gaussian probability law.
size_t GetDimension() const noexcept
Returns the number of features.
double matrix class
size_t GetDimension() const noexcept
Returns the number of features.
MultivariateGaussianPDF GetMember(size_t k) const
Returns a given density function.
std::vector< double > NewUniformSample(size_t n=1, bool reseed=true)
Creates a data sample following an uniform probability law.
const T & At(size_t pos) const noexcept
Definition: CRNMatrix.h:165
Square double matrix class.
Multivariate Gaussian distribution.
SquareMatrixDouble MakeCholesky() const
Get the lower triangular factor in Cholesky decomposition.
void IncreaseElement(size_t r, size_t c, const T &delta)
Increases the value of an element.
Definition: CRNMatrix.h:230
const MatrixDouble & GetMean() const
Returns the mean of a given density function.