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

Revision 477, 8.3 kB (checked in by mido, 15 years ago)

panove, vite, jak jsem peclivej na upravu kodu.. snad se vam bude libit:) konfigurace je v souboru /system/astylerc

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