root/library/bdm/math/square_mat.h @ 495

Revision 495, 8.4 kB (checked in by vbarta, 15 years ago)

moved square matrices to namespace bdm

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