source: trunk/yat/utility/matrix.h @ 754

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

Addresses #2 and #65. Continued adding GSL_error exceptions, and added doxygen briefs.

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