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

Revision 766, 8.6 kB (checked in by mido, 14 years ago)

abstract methods restored wherever they are meaningful
macros NOT_IMPLEMENTED and NOT_IMPLEMENTED_VOID defined to make sources shorter
emix::set_parameters and mmix::set_parameters removed, corresponding acces methods created and the corresponding validate methods improved appropriately
some compilator warnings were avoided
and also a few other things cleaned up

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