root/bdm/math/libDC.h @ 262

Revision 262, 8.4 kB (checked in by smidl, 15 years ago)

cleanup of include files

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