root/bdm/math/libDC.h @ 85

Revision 85, 8.0 kB (checked in by smidl, 16 years ago)

compilation and documantation fixes

  • Property svn:eol-style set to native
Line 
1/*!
2 * \file
3 * \brief Matrices in decomposed forms (LDL', LU, UDU', etc).
4 * \author Vaclav Smidl.
5 *
6 * -----------------------------------
7 * BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8 *
9 * Using IT++ for numerical operations
10 * -----------------------------------
11 */
12
13#ifndef DC_H
14#define DC_H
15
16#include <itpp/itbase.h>
17
18using namespace itpp;
19
20//! Auxiliary function dydr; dyadic reduction
21void dydr( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx );
22
23//! Auxiliary function ltuinv; inversion of a triangular matrix;
24//TODO can be done via: dtrtri.f from lapack
25mat ltuinv( const mat &L );
26
27/*! \brief Virtual class for representation of double symmetric matrices in square-root form.
28
29All operations defined on this class should be optimized for the chosen decomposition.
30*/
31class sqmat
32{
33        public:
34                /*!
35                 * Perfroms a rank-1 update by outer product of vectors: \f$V = V + w v v'\f$.
36                 * @param  v Vector forming the outer product to be added
37                 * @param  w weight of updating; can be negative
38
39                 BLAS-2b operation.
40                 */
41                virtual void opupdt ( const vec &v, double w ) =0;
42
43                /*! \brief Conversion to full matrix.
44                */
45
46                virtual mat to_mat() =0;
47
48                /*! \brief Inplace symmetric multiplication by a SQUARE matrix \f$C\f$, i.e. \f$V = C*V*C'\f$
49                @param C multiplying matrix,
50                */
51                virtual void mult_sym ( const mat &C ) =0;
52               
53                /*! \brief Inplace symmetric multiplication by a SQUARE transpose of matrix \f$C\f$, i.e. \f$V = C'*V*C\f$
54                @param C multiplying matrix,
55                */
56                virtual void mult_sym_t ( const mat &C ) =0;
57
58
59                /*!
60                \brief Logarithm of a determinant.
61
62                */
63                virtual double logdet() const =0;
64
65                /*!
66                \brief Multiplies square root of \f$V\f$ by vector \f$x\f$.
67
68                Used e.g. in generating normal samples.
69                */
70                virtual vec sqrt_mult (const vec &v ) const =0;
71
72                /*!
73                \brief Evaluates quadratic form \f$x= v'*V*v\f$;
74
75                */
76                virtual double qform (const vec &v ) const =0;
77
78                /*!
79                \brief Evaluates quadratic form \f$x= v'*inv(V)*v\f$;
80
81                */
82                virtual double invqform (const vec &v ) const =0;
83
84//      //! easy version of the
85//      sqmat inv();
86
87                //! Clearing matrix so that it corresponds to zeros.
88                virtual void clear() =0;
89
90                //! Reimplementing common functions of mat: cols().
91                int cols() const {return dim;};
92
93                //! Reimplementing common functions of mat: cols().
94                int rows() const {return dim;};
95
96                //! Destructor for future use;
97                virtual ~sqmat(){};
98                //! Default constructor
99                sqmat(const int dim0): dim(dim0){};
100        protected:
101                //! dimension of the square matrix
102                int dim;
103};
104
105
106/*! \brief Fake sqmat. This class maps sqmat operations to operations on full matrix.
107
108This class can be used to compare performance of algorithms using decomposed matrices with perormance of the same algorithms using full matrices;
109*/
110class fsqmat: public sqmat
111{
112        protected:
113                //! Full matrix on which the operations are performed
114                mat M;
115        public:
116                void opupdt ( const vec &v, double w );
117                mat to_mat() ;
118                void mult_sym ( const mat &C);
119                void mult_sym_t ( const mat &C);
120                //! store result of \c mult_sym in external matrix \f$U\f$
121                void mult_sym ( const mat &C, fsqmat &U) const;
122                //! store result of \c mult_sym_t in external matrix \f$U\f$
123                void mult_sym_t ( const mat &C, fsqmat &U) const;
124                void clear();
125
126                //! Default initialization
127                fsqmat(); // mat will be initialized OK
128                //! Default initialization with proper size
129                fsqmat(const int dim0); // mat will be initialized OK
130                //! Constructor
131                fsqmat ( const mat &M );
132                //! Constructor
133                fsqmat ( const vec &d ):sqmat(d.length()){M=diag(d);};
134
135                //! Destructor for future use;
136                virtual ~fsqmat(){};
137
138
139                /*! \brief Matrix inversion preserving the chosen form.
140
141                @param Inv a space where the inverse is stored.
142
143                */
144                virtual void inv ( fsqmat &Inv );
145
146                double logdet() const {return log ( det ( M ) );};
147                double qform (const  vec &v ) const {return ( v* ( M*v ) );};
148                double invqform (const  vec &v ) const {return ( v* ( itpp::inv(M)*v ) );};
149                vec sqrt_mult (const vec &v ) const {mat Ch=chol(M); return Ch*v;};
150
151                //! Add another matrix in fsq form with weight w
152                void add ( const fsqmat &fsq2, double w=1.0 ){M+=fsq2.M;};
153
154                //! Access functions
155                void setD (const vec &nD){M=diag(nD);}
156                //! Access functions
157                vec getD (){return diag(M);}
158                //! Access functions
159                void setD (const vec &nD, int i){for(int j=i;j<nD.length();j++){M(j,j)=nD(j-i);}} //Fixme can be more general
160
161
162                //! add another fsqmat matrix
163                fsqmat& operator += ( const fsqmat &A ) {M+=A.M;return *this;};
164                //! subtrack another fsqmat matrix
165                fsqmat& operator -= ( const fsqmat &A ) {M-=A.M;return *this;};
166                //! multiply by a scalar
167                fsqmat& operator *= ( double x ) {M*=x;return *this;};
168//              fsqmat& operator = ( const fsqmat &A) {M=A.M; return *this;};
169                //! print full matrix
170                friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq );
171
172};
173
174/*! \brief Matrix stored in LD form, (typically known as UD)
175
176Matrix is decomposed as follows: \f[M = L'DL\f] where only \f$L\f$ and \f$D\f$ matrices are stored.
177All inplace operations modifies only these and the need to compose and decompose the matrix is avoided.
178*/
179class ldmat: sqmat
180{
181        public:
182
183                //! Construct by copy of L and D.
184                ldmat ( const mat &L, const vec &D );
185                //! Construct by decomposition of full matrix V.
186                ldmat (const mat &V );
187                //! Construct diagonal matrix with diagonal D0
188                ldmat ( vec D0 );
189                //!Default constructor
190                ldmat ();
191                //! Default initialization with proper size
192                ldmat(const int dim0);
193
194                //! Destructor for future use;
195                virtual ~ldmat(){};
196
197                // Reimplementation of compulsory operatios
198
199                void opupdt ( const vec &v, double w );
200                mat to_mat();
201                void mult_sym ( const mat &C);
202                void mult_sym_t ( const mat &C);
203                //! Add another matrix in LD form with weight w
204                void add ( const ldmat &ld2, double w=1.0 );
205                double logdet() const;
206                double qform (const vec &v ) const;
207                double invqform (const vec &v ) const;
208//      sqmat& operator -= ( const sqmat & ld2 );
209                void clear();
210                int cols() const;
211                int rows() const;
212                vec sqrt_mult ( const vec &v ) const;
213
214                /*! \brief Matrix inversion preserving the chosen form.
215                @param Inv a space where the inverse is stored.
216                */
217                virtual void inv ( ldmat &Inv ) const;
218
219                /*! \brief Symmetric multiplication of \f$U\f$ by a general matrix \f$C\f$, result of which is stored in the current class.
220                @param C matrix to multiply with
221                @param U a space where the inverse is stored.
222                */
223                void mult_sym ( const mat &C, ldmat &U) const;
224
225                /*! \brief Symmetric multiplication of \f$U\f$ by a transpose of a general matrix \f$C\f$, result of which is stored in the current class.
226                @param C matrix to multiply with
227                @param U a space where the inverse is stored.
228                */
229                void mult_sym_t ( const mat &C, ldmat &U) const;
230
231
232                /*! \brief Transforms general \f$A'D0 A\f$ into pure \f$L'DL\f$
233
234                The new decomposition fullfills: \f$A'*diag(D)*A = self.L'*diag(self.D)*self.L\f$
235                @param A general matrix
236                @param D0 general vector
237                */
238                void ldform (const mat &A,const vec &D0 );
239
240                //! Access functions
241                void setD (const vec &nD){D=nD;}
242                //! Access functions
243                void setD (const vec &nD, int i){D.replace_mid(i,nD);} //Fixme can be more general
244                //! Access functions
245                void setL (const vec &nL){L=nL;}
246
247                //! add another ldmat matrix
248                ldmat& operator += ( const ldmat &ldA );
249                //! subtract another ldmat matrix
250                ldmat& operator -= ( const ldmat &ldA );
251                //! multiply by a scalar
252                ldmat& operator *= ( double x );
253
254                //! print both \c L and \c D
255                friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq );
256
257
258        protected:
259                //! Positive vector \f$D\f$
260                vec D;
261                //! Lower-triangular matrix \f$L\f$
262                mat L;
263
264};
265
266
267//////// Operations:
268//!mapping of add operation to operators
269inline ldmat& ldmat::operator += ( const ldmat &ldA )  {this->add ( ldA );return *this;}
270//!mapping of negative add operation to operators
271inline ldmat& ldmat::operator -= ( const ldmat &ldA )  {this->add ( ldA,-1.0 );return *this;}
272//!access function
273inline int ldmat::cols() const {return dim;}
274//!access function
275inline int ldmat::rows() const {return dim;}
276
277#endif // DC_H
Note: See TracBrowser for help on using the browser.