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

Revision 737, 8.9 kB (checked in by mido, 15 years ago)

ASTYLER RUN OVER THE WHOLE LIBRARY, JUPEE

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