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

Revision 1079, 9.5 kB (checked in by smidl, 14 years ago)

Changes in merger + change in loading ARX

  • 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//! Access functions
318    vec& __D() {
319        return D;
320    }
321//! Access functions
322    mat& __L() {
323        return L;
324    }
325    void validate() {
326                bdm_assert(L.rows()==D.length(),"Incompatible L and D in ldmat");
327        dim= L.rows();
328    }
329
330    //! add another ldmat matrix
331    ldmat& operator += ( const ldmat &ldA );
332    //! subtract another ldmat matrix
333    ldmat& operator -= ( const ldmat &ldA );
334    //! multiply by a scalar
335    ldmat& operator *= ( double x );
336
337    //! print both \c L and \c D
338    friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq );
339
340protected:
341    //! Positive vector \f$D\f$
342    vec D;
343    //! Lower-triangular matrix \f$L\f$
344    mat L;
345
346};
347
348//////// Operations:
349//!mapping of add operation to operators
350inline ldmat& ldmat::operator += ( const ldmat & ldA )  {
351    this->add ( ldA );
352    return *this;
353}
354//!mapping of negative add operation to operators
355inline ldmat& ldmat::operator -= ( const ldmat & ldA )  {
356    this->add ( ldA, -1.0 );
357    return *this;
358}
359
360}
361
362#endif // DC_H
Note: See TracBrowser for help on using the browser.