source: trunk/c++_tools/utility/matrix.h @ 675

Last change on this file since 675 was 675, checked in by Jari Häkkinen, 17 years ago

References #83. Changing project name to yat. Compilation will fail in this revision.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1#ifndef _theplu_utility_matrix_
2#define _theplu_utility_matrix_
3
4// $Id: matrix.h 675 2006-10-10 12:08:45Z jari $
5
6/*
7  Copyright (C) 2003 Daniel Dalevi, Peter Johansson
8  Copyright (C) 2004 Jari Häkkinen, Peter Johansson
9  Copyright (C) 2005 Jari Häkkinen, Peter Johansson, Markus Ringnér
10  Copyright (C) 2006 Jari Häkkinen, Peter Johansson
11
12  This file is part of the yat library, http://lev.thep.lu.se/trac/yat
13
14  The yat library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU General Public License as
16  published by the Free Software Foundation; either version 2 of the
17  License, or (at your option) any later version.
18
19  The yat library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23
24  You should have received a copy of the GNU General Public License
25  along with this program; if not, write to the Free Software
26  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27  02111-1307, USA.
28*/
29
30#include "yat/utility/vector.h"
31#include "yat/utility/Exception.h"
32
33#include <gsl/gsl_matrix.h>
34#include <iostream>
35
36namespace theplu {
37namespace utility {
38
39  class vector;
40
41  ///
42  /// This is the yat interface to GSL matrix. 'double' is the
43  /// only type supported, maybe we should add a 'complex' type as
44  /// well in the future.
45  ///
46  /// \par[File streams] Reading and writing vectors to file streams
47  /// are of course supported. These are implemented without using GSL
48  /// functionality, and thus binary read and write to streams are not
49  /// supported.
50  ///
51  /// \par[Matrix views] GSL matrix views are supported and these are
52  /// disguised as ordinary utility::matrix'es. A support function is
53  /// added, utility::matrix::isview(), that can be used to check if a
54  /// matrix object is a view. Note that view matricess do not own the
55  /// undelying data, and a view is not valid if the matrix owning the
56  /// data is deallocated.
57  ///
58  /// @note All GSL matrix related functions are not implement but
59  /// most functionality defined for GSL matrices can be achieved with
60  /// this interface class. Most notable GSL functionality not
61  /// supported are no binary file support and views on arrays,
62  /// utility::vectors, gsl_vectors, diagonals, subdiagonals, and
63  /// superdiagonals. If there is an interest from the user community,
64  /// the omitted functionality could be included.
65  ///
66  /// @todo Maybe it would be smart to create temporary objects need
67  /// for BLAS in constructors. As it is now temporary objects are
68  /// called before BLAS functionality iss used, cf. const matrix&
69  /// matrix::operator*=(const matrix& other)
70  ///
71  class matrix
72  {
73  public:
74
75    /**
76       @brief The default constructor.
77   
78       This contructor does not initialize underlying (essential)
79       structures.
80    */
81    inline matrix(void) : m_(NULL), view_(NULL) {}
82
83    ///
84    /// Constructor. Allocates memory space for \a r times \a c
85    /// elements, and sets all elements to \a init_value.
86    ///
87    inline matrix(const size_t& r, const size_t& c, double init_value=0)
88      : view_(NULL) { m_ = gsl_matrix_alloc(r,c); set_all(init_value); }
89
90    ///
91    /// The copy constructor.
92    ///
93    /// @note If the object to be copied is a matrix view, the values
94    /// of the view will be copied, i.e. the view is not copied.
95    ///
96    inline matrix(const matrix& o) : view_(NULL) {m_=o.create_gsl_matrix_copy();}
97
98    ///
99    /// The matrix view constructor.
100    ///
101    /// Create a view of matrix \a m, with starting row \a offset_row,
102    /// starting column \a offset_column, row size \a n_row, and
103    /// column size \a n_column.
104    ///
105    /// A matrix view can be used as any matrix with the difference
106    /// that changes made to the view will also change the object that
107    /// is viewed. Also, using the copy constructor will create a new
108    /// matrix object that is a copy of whatever is viewed. If a copy
109    /// of the view is needed then you should use this constructor to
110    /// obtain a copy.
111    ///
112    /// @note If the object viewed by the view goes out of scope or is
113    /// deleted, the view becomes invalid and the result of further
114    /// use is undefined.
115    ///
116    matrix(matrix& m, size_t offset_row, size_t offset_column, size_t n_row,
117           size_t n_column);
118
119    ///
120    /// The istream constructor.
121    ///
122    /// Matrix rows are sepearated with the new line character, and
123    /// column elements in a row must be separated either with white space
124    /// characters except the new line (\\n) character (default), or
125    /// by the delimiter \a sep.
126    ///. Rows, and
127    /// columns, are read consecutively and only rectangular matrices
128    /// are supported. Empty lines are ignored. End of input is at end
129    /// of file marker.
130    ///
131    //    explicit matrix(std::istream &) throw (utility::IO_error,std::exception);
132    explicit matrix(std::istream &, char sep='\0') 
133      throw (utility::IO_error,std::exception);
134
135
136    ///
137    /// The destructor.
138    ///
139    ~matrix(void);
140
141    ///
142    /// Elementwise addition of the elements of matrix \a b to the
143    /// elements of the calling matrix ,\f$ a_{ij} = a_{ij} + b_{ij} \;
144    /// \forall i,j \f$. The result is stored into the calling matrix.
145    ///
146    /// @return Whatever GSL returns.
147    ///
148    inline int add(const matrix& b) { return gsl_matrix_add(m_,b.m_); }
149
150    ///
151    /// Add the scalar value \a d to the elements of the calling
152    /// matrix, \f$ a_{ij} = a_{ij} + d \; \forall i,j \f$. The result
153    /// is stored into the calling matrix.
154    ///
155    /// @return Whatever GSL returns.
156    ///
157    inline int
158    add_constant(const double d) { return gsl_matrix_add_constant(m_,d); }
159
160    ///
161    /// @return The number of columns in the matrix.
162    ///
163    inline size_t columns(void) const { return m_->size2; }
164
165    ///
166    /// Elementwise division of the elemnts of the calling matrix by
167    /// the elements of matrix \a b, \f$ a_{ij} = a_{ij} / b_{ij} \;
168    /// \forall i,j \f$. The result is stored into the calling matrix.
169    ///
170    /// @return Whatever GSL returns.
171    ///
172    inline int
173    div_elements(const matrix& b) { return gsl_matrix_div_elements(m_,b.m_); }
174
175    ///
176    /// Check whether matrices are equal within a user defined
177    /// precision, set by \a precision.
178    ///
179    /// @return True if each element deviates less or equal than \a
180    /// d. If any matrix contain a NaN, false is always returned.
181    ///
182    bool equal(const matrix&, const double precision=0) const;
183
184    ///
185    /// @return A const pointer to the internal GSL matrix.
186    ///
187    inline const gsl_matrix* gsl_matrix_p(void) const { return m_; }
188
189    ///
190    /// @return A pointer to the internal GSL matrix.
191    ///
192    // Jari, is this needed?
193    inline gsl_matrix* gsl_matrix_p(void) { return m_; };
194
195    ///
196    /// @return True if all elements in the matrix is zero, false
197    /// othwerwise;
198    ///
199    inline bool isnull(void) const { return gsl_matrix_isnull(m_); }
200
201    ///
202    /// Check if the matrix object is a view (sub-matrix) to another
203    /// matrix.
204    ///
205    /// @return True if the object is a view, false othwerwise.
206    ///
207    inline bool isview(void) const { return view_; }
208
209    ///
210    /// @return The maximum value of the matrix.
211    ///
212    inline double max(void) const { return gsl_matrix_max(m_); }
213
214    ///
215    /// @return The index to the element with the maximum value of the
216    /// matrix. The lowest index has precedence (searching in
217    /// row-major order).
218    ///
219    inline std::pair<size_t,size_t> max_index(void) const;
220
221    ///
222    /// @return The minimum value of the matrix.
223    ///
224    inline double min(void) const { return gsl_matrix_min(m_); }
225
226    ///
227    /// @return The index to the element with the minimum value of the
228    /// matrix. The lowest index has precedence (searching in
229    /// row-major order).
230    ///
231    inline std::pair<size_t,size_t> min_index(void) const;
232
233    ///
234    /// @return The indecies to the element with the minimum and
235    /// maximum values of the matrix, respectively. The lowest index
236    /// has precedence (searching in row-major order).
237    ///
238    inline void minmax_index(std::pair<size_t,size_t>& min,
239                             std::pair<size_t,size_t>& max) const
240      { gsl_matrix_minmax_index(m_,&min.first,&min.second,
241                                &max.first,&max.second); }
242
243    ///
244    /// @return The minimum and maximum values of the matrix, as the
245    /// \a first and \a second member of the returned \a pair,
246    /// respectively.
247    ///
248    std::pair<double,double> minmax(void) const;
249
250    ///
251    /// The argument is changed into a matrix containing 1's and 0's
252    /// only. 1 means element in matrix is valid and a zero means
253    /// element is a NaN.
254    ///
255    /// @return true if matrix contains at least one NaN.
256    ///
257    bool nan(matrix&) const;
258
259    ///
260    /// Multiply the elements of matrix \a b with the elements of the
261    /// calling matrix ,\f$ a_{ij} = a_{ij} * b_{ij} \; \forall
262    /// i,j \f$. The result is stored into the calling matrix.
263    ///
264    /// @return Whatever GSL returns.
265    ///
266    inline int
267    mul_elements(const matrix& b) { return gsl_matrix_mul_elements(m_,b.m_); }
268
269    ///
270    /// @return The number of rows in the matrix.
271    ///
272    inline size_t rows(void) const { return m_->size1; }
273
274    ///
275    /// Multiply the elements of the calling matrix with a scalar \a
276    /// d, \f$ a_{ij} = d * a_{ij} \; \forall i,j \f$. The result is
277    /// stored into the calling matrix.
278    ///
279    /// @return Whatever GSL returns.
280    ///
281    inline int scale(const double d) { return gsl_matrix_scale(m_,d); }
282
283    ///
284    /// Set element values to values in \a mat. This function is
285    /// needed for assignment of viewed elements.
286    ///
287    /// @return Whatever GSL returns.
288    ///
289    /// @note No check on size is done.
290    ///
291    /// @see const matrix& operator=(const matrix&)
292    ///
293    inline int set(const matrix& mat) { return gsl_matrix_memcpy(m_,mat.m_); }
294
295    ///
296    /// Set all elements to \a value.
297    ///
298    inline void set_all(const double value) { gsl_matrix_set_all(m_,value); }
299
300    ///
301    /// Set \a column values to values in \a vec.
302    ///
303    /// @return Whatever GSL returns.
304    ///
305    /// @note No check on size is done.
306    ///
307    inline int set_column(const size_t column, const vector& vec)
308      { return gsl_matrix_set_col(m_, column, vec.gsl_vector_p()); }
309
310    ///
311    /// Set \a row values to values in \a vec.
312    ///
313    /// @return Whatever GSL returns.
314    ///
315    /// @note No check on size is done.
316    ///
317    inline int set_row(const size_t row, const vector& vec)
318      { return gsl_matrix_set_row(m_, row, vec.gsl_vector_p()); }
319
320    ///
321    /// Subtract the elements of matrix \a b from the elements of the
322    /// calling matrix ,\f$ a_{ij} = a_{ij} - b_{ij} \; \forall
323    /// i,j \f$. The result is stored into the calling matrix.
324    ///
325    /// @return Whatever GSL returns.
326    ///
327    inline int sub(const matrix& b) { return gsl_matrix_sub(m_,b.m_); }
328
329    ///
330    /// Exchange the elements of the this and \a other by copying. The
331    /// two matrices must have the same size.
332    ///
333    /// @return Whatever GSL returns.
334    ///
335    inline int swap(matrix& other) { return gsl_matrix_swap(m_,other.m_); }
336
337    ///
338    /// Swap columns \a i and \a j.
339    ///
340    inline int swap_columns(const size_t i,const size_t j)
341      { return gsl_matrix_swap_columns(m_,i,j); }
342
343    ///
344    /// Swap row \a i and column \a j.
345    ///
346    inline int swap_rowcol(const size_t i,const size_t j)
347      { return gsl_matrix_swap_rowcol(m_,i,j); }
348
349    ///
350    /// Swap rows \a i and \a j.
351    ///
352    inline int swap_rows(const size_t i, const size_t j)
353      { return gsl_matrix_swap_rows(m_,i,j); }
354
355    ///
356    /// Transpose the matrix.
357    ///
358    void transpose(void);
359
360    ///
361    /// @return Reference to the element position (\a row, \a column).
362    ///
363    inline double& operator()(size_t row,size_t column)
364    { return (*gsl_matrix_ptr(m_,row,column)); }
365
366    ///
367    /// @return Const reference to the element position (\a row, \a
368    /// column).
369    ///
370    inline const double& operator()(size_t row,size_t column) const
371    { return (*gsl_matrix_const_ptr(m_,row,column)); }
372
373    ///
374    /// Matrix-vector multiplication.
375    ///
376    /// @return The resulting vector.
377    ///
378    // Jari, where should this go?
379    const vector operator*(const vector&) const;
380
381    ///
382    /// Comparison operator.
383    ///
384    /// @return True if all elements are equal otherwise False.
385    ///
386    /// @see equal
387    ///
388    inline bool operator==(const matrix& other) const { return equal(other); }
389
390    ///
391    /// Comparison operator.
392    ///
393    /// @return False if all elements are equal otherwise True.
394    ///
395    /// @see equal
396    ///
397    inline bool operator!=(const matrix& other) const { return !equal(other); }
398
399    ///
400    /// The assignment operator. There is no requirements on
401    /// dimensions, i.e. the matrix is remapped in memory if
402    /// necessary. This implies that in general views cannot be
403    /// assigned using this operator. Views will be mutated into
404    /// normal matrices. The only exception to this behaviour on views
405    /// is when self-assignemnt is done, since self-assignment is
406    /// ignored.
407    ///
408    /// @return A const reference to the resulting matrix.
409    ///
410    /// @see int set(const matrix&)
411    ///
412    const matrix& operator=(const matrix& other);
413
414    ///
415    /// Add and assign operator.
416    ///
417    inline const matrix& operator+=(const matrix& m) { add(m); return *this; }
418
419    ///
420    /// Add and assign operator.
421    ///
422    inline const matrix&
423    operator+=(const double d) { add_constant(d); return *this; }
424
425    ///
426    /// Subtract and assign operator.
427    ///
428    inline const matrix& operator-=(const matrix& m) { sub(m); return *this; }
429
430    ///
431    /// Multiply and assigment operator.
432    ///
433    /// @return Const reference to the resulting matrix.
434    ///
435    const matrix& operator*=(const matrix&);
436
437    ///
438    /// Multiply and assign operator.
439    ///
440    inline const matrix& operator*=(const double d) { scale(d); return *this; }
441
442
443  private:
444
445    ///
446    /// Create a new copy of the internal GSL matrix.
447    ///
448    /// Necessary memory for the new GSL matrix is allocated and the
449    /// caller is responsible for freeing the allocated memory.
450    ///
451    /// @return A pointer to a copy of the internal GSL matrix.
452    ///
453    gsl_matrix* create_gsl_matrix_copy(void) const;
454
455    gsl_matrix* m_;
456    gsl_matrix_view* view_;
457  };
458
459  ///
460  /// The output operator for the matrix class.
461  ///
462  std::ostream& operator<< (std::ostream& s, const matrix&);
463
464
465}} // of namespace utility and namespace theplu
466
467#endif
Note: See TracBrowser for help on using the repository browser.