STK++ 0.9.13
STK_MultiLaw_Normal.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23 */
24
25/*
26 * Project: stkpp::STatistiK::MultiLaw
27 * created on: 29 juil. 2011
28 * Purpose: define the template MultiLaw::Normal law.
29 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
30 *
31 **/
32
37#ifndef STK_MULTILAW_NORMAL_H
38#define STK_MULTILAW_NORMAL_H
39
40
52
54
56#include "STK_Law_Normal.h"
57
59
60namespace STK
61{
62
63namespace MultiLaw
64{
65
99template <class RowVector>
100class Normal: public MultiLaw::IMultiLaw<RowVector>
101{
102 public:
108 Normal( RowVector const& mu, ArraySquareX const& sigma)
109 : Base(_T("MultiLaw::Normal"))
110 , mu_()
111 , sigma_()
112 , decomp_(sigma)
114
116 virtual ~Normal() {}
118 inline RowVector const& mu() const { return mu_;}
120 inline ArraySquareX const& sigma() const { return sigma_;}
122 inline ArraySquareX const& squareroot() const { return squareroot_;}
124 inline SymEigen<ArraySquareX> const& decomp() const { return decomp_;}
126 void setParameters( RowVector const& mu, ArraySquareX const& sigma)
127 {
128 // check dimensions
129 if (mu.range() != sigma.range())
131 mu_ = mu;
132 sigma_ = sigma;
133 // decomposition of the covariance matrix
135 if (!decomp_.run())
136 {
137
138 throw runtime_error(decomp_.error());
139 }
140 // compute the inverse of the eigenvalues of sigma_ and the squareroot_
141 // matrix needed by rand
142 invEigenvalues_.resize(mu_.range());
143 squareroot_.resize(mu_.range());
144 // get dimension
145 int rank = decomp_.rank(), end = mu_.begin() + rank;
146 for (int j=mu_.begin(); j< end; j++)
147 { invEigenvalues_[j] = 1./decomp_.eigenValues()[j];}
148 for (int j=end; j< mu_.end(); j++) { invEigenvalues_[j] = 0.;}
149
150 squareroot_ = decomp_.rotation() * decomp_.eigenValues().sqrt().diagonalize() * decomp_.rotation().transpose();
151 }
162 virtual Real pdf( RowVector const& x) const
163 {
164 // check determinant is not 0
165 if (decomp_.det() == 0.)
167 // check ranges
168 if (x.range() != mu_.range() )
169 { STKRUNTIME_ERROR_NO_ARG(MultiLaw::Normal::pdf(x),x.range() != mu_.range());}
170 // compute pdf in log-space
171 return std::exp((double)lpdf(x));
172 }
173
179 Real lpdf( RowVector const& x) const
180 {
181 // check ranges
182 if (x.range() != mu_.range() )
183 { STKRUNTIME_ERROR_NO_ARG(MultiLaw::Normal::lpdf(x),x.range() != mu_.range());}
184 // compute pdf using ||(x-mu)'P||_{D^{-1}}^2
185 Real res = 0.5 * ((x - mu_) * decomp_.rotation()).wnorm2(invEigenvalues_)
186 + invEigenvalues_.size() * Const::_LNSQRT2PI_
187 + 0.5 * log((double)decomp_.det());
188 return -res;
189 }
190
196 template < class Array>
197 Real lnLikelihood( Array const& data) const
198 {
199 // check ranges
200 if (data.cols() != mu_.range() )
201 { STKRUNTIME_ERROR_NO_ARG(MultiLaw::Normal::lnLikelihood(x),data.cols() != mu_.range());}
202 // get dimensions of the samples and sum over all ln-likelihood values
203 const int first = data.beginRows(), last = data.lastIdxRows();
204 Real sum = 0.0;
205 for (int i=first; i<= last; i++)
206 {
207 // compute lpdf using \sum_i ||(x_i-mu)'P||_{D^{-1}}^2
208 Real res = 0.5 * ((data.row(i) - mu_) * decomp_.rotation()).wnorm2(invEigenvalues_) ;
209 sum += res;
210 }
211 sum += data.sizeRows()*( invEigenvalues_.size() * Const::_LNSQRT2PI_
212 + 0.5 * log((double)decomp_.det())
213 );
214 return -sum;
215 }
216
221 virtual void rand( RowVector& x) const
222 {
223 // fill it with iid N(0,1) variates
224 x.randGauss();
225 // rotate with squareroot_ and translate with mu_
226 x = x * squareroot_ + mu_;
227 }
233 template < class Array>
234 void rand( ArrayBase<Array>& x) const
235 {
236 // fill it with iid N(0,1) variates
237 x.randGauss();
238 // rotate with squareroot_ and translate with mu_
239 x.asDerived() = x.asDerived() * squareroot_ + Const::Vector<Real>(x.rows()) * mu_;
240 }
241
242 protected:
244 RowVector mu_;
253};
254
255} // namespace MultiLaw
256
257} // namespace STK
258
259#endif /* STK_MULTILAW_NORMAL_H */
In this file, we define Array2DDiagonal class.
In this file we define the Array2DLowerTriangular class.
In this file, we define Array2DSquare class.
In this file we define the ArrayXXTriangular class.
In this file, we define the final class Array2D.
In this file we implement the functors for performing operations on Array2D arrays.
In this file we implement the final class CArrayPoint.
In this file we implement the final class CArraySquare.
In this file we implement the final class CArrayVector.
In this file we implement the final class CArray.
In this file we define the constant Arrays.
In this file we give the main mathematical constants.
In this file we define the Normal probability law class.
#define STKRUNTIME_ERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:138
In this file we define the Interface base classes IMultiLaw and JointProbability.
In this file we define the SymEigen class (for a symmetric matrix).
#define _T(x)
Let x unmodified.
Define the constant point.
Derived & resize(Range const &I, Range const &J)
resize the array.
virtual bool run()
run the computations.
String const & error() const
get the last error message.
Definition STK_IRunner.h:82
virtual void setData(YArray_ const &y, XArray_ const &x)
set the data set.
Interface base Class for the multivariate distributions.
Class for the multivariate Normal distribution.
MultiLaw::IMultiLaw< RowVector > Base
ArraySquareX const & sigma() const
@return the variance-covariance matrix
ArrayDiagonalX invEigenvalues_
inverse of the eigenvalues of sigma_
SymEigen< ArraySquareX > decomp_
the decomposition in eigenvalues of the covariance matrix
RowVector mu_
The position parameter.
virtual Real pdf(RowVector const &x) const
compute the probability distribution function (density) of the multivariate normal law
SymEigen< ArraySquareX > const & decomp() const
@return the eigenvalue decomposition
virtual ~Normal()
destructor.
void rand(ArrayBase< Array > &x) const
simulate a realization of the Multivariate Law and store the result in x (using a reference vector).
Normal(RowVector const &mu, ArraySquareX const &sigma)
Constructor.
Real lpdf(RowVector const &x) const
compute the log probability distribution function.
ArraySquareX sigma_
The covariance parameter.
Real lnLikelihood(Array const &data) const
compute the log likehood of a data set.
RowVector const & mu() const
@return the location parameter
virtual void rand(RowVector &x) const
simulate a realization of the Multivariate Law and store the result in x.
ArraySquareX const & squareroot() const
@return the square root of the variance-covariance matrix
ArraySquareX squareroot_
The square root of the matrix Sigma_.
void setParameters(RowVector const &mu, ArraySquareX const &sigma)
update the parameters specific to the law.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Runtime errors represent problems outside the scope of a program; they cannot be easily predicted and...
Arrays::SumOp< Lhs, Rhs >::result_type sum(Lhs const &lhs, Rhs const &rhs)
convenience function for summing two arrays
double Real
STK fundamental type of Real values.
The namespace STK is the main domain space of the Statistical ToolKit project.