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

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

Fixes #171 and addresses #2. A few more GSL_error exceptions. Removed Jari comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.0 KB
Line 
1#ifndef _theplu_yat_utility_matrix_
2#define _theplu_yat_utility_matrix_
3
4// $Id: matrix.h 759 2007-02-19 19:41:25Z 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, IO_error if
140       unexpected input is found in the input stream.
141    */
142    explicit matrix(std::istream &, char sep='\0') 
143      throw(utility::IO_error, std::exception);
144
145    /**
146       \brief The destructor.
147    */
148    ~matrix(void);
149
150    /**
151       Elementwise addition of the elements of matrix \a b to the
152       elements of the calling matrix ,\f$ a_{ij} = a_{ij} + b_{ij} \;
153       \forall i,j \f$. The result is stored into the calling matrix.
154
155       \throw GSL_error if dimensions mis-match.
156    */
157    void add(const matrix& b);
158
159    /**
160       Add the scalar value \a d to the elements of the calling
161       matrix, \f$ a_{ij} = a_{ij} + d \; \forall i,j \f$. The result
162       is stored into the calling matrix.
163    */
164    void add(double d);
165
166    ///
167    /// @return The number of columns in the matrix.
168    ///
169    size_t columns(void) const;
170
171    /**
172       Elementwise division of the elemnts of the calling matrix by
173       the elements of matrix \a b, \f$ a_{ij} = a_{ij} / b_{ij} \;
174       \forall i,j \f$. The result is stored into the calling matrix.
175
176       \throw GSL_error if dimensions mis-match.
177    */
178    void div_elements(const matrix& b);
179
180    ///
181    /// Check whether matrices are equal within a user defined
182    /// precision, set by \a precision.
183    ///
184    /// @return True if each element deviates less or equal than \a
185    /// d. If any matrix contain a NaN, false is always returned.
186    ///
187    bool equal(const matrix&, const double precision=0) const;
188
189    ///
190    /// @return A const pointer to the internal GSL matrix.
191    ///
192    const gsl_matrix* gsl_matrix_p(void) const;
193
194    ///
195    /// @return A pointer to the internal GSL matrix.
196    ///
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 i,j
243       \f$. The result is stored into the calling matrix.
244
245       \throw GSL_error if dimensions mis-match.
246    */
247    void mul_elements(const matrix& b);
248
249    ///
250    /// @return The number of rows in the matrix.
251    ///
252    size_t rows(void) const;
253
254    /**
255       Multiply the elements of the calling matrix with a scalar \a d,
256       \f$ a_{ij} = d * a_{ij} \; \forall i,j \f$. The result is
257       stored into the calling matrix.
258    */
259    void scale(const double d);
260
261    /**
262       \brief Set element values to values in \a mat.
263
264       This function is needed for assignment of viewed elements.
265
266       \see const matrix& operator=(const matrix&)
267
268       \throw GSL_error if dimensions mis-match.
269    */
270    void set(const matrix& mat);
271
272    ///
273    /// Set all elements to \a value.
274    ///
275    void set_all(const double value);
276
277    /**
278       \brief Set \a column values to values in \a vec.
279
280       \note No check on size is done.
281
282       \throw GSL_error if index is out of range or mis-match in
283       sizes.
284    */
285    void set_column(const size_t column, const vector& vec);
286
287    /**
288       \brief Set \a row values to values in \a vec.
289
290       \note No check on size is done.
291
292       \throw GSL_error if index is out of range or mis-match in
293       sizes.
294    */
295    void set_row(const size_t row, const vector& vec);
296
297    /**
298       Subtract the elements of matrix \a b from the elements of the
299       calling matrix ,\f$ a_{ij} = a_{ij} - b_{ij} \; \forall i,j
300       \f$. The result is stored into the calling matrix.
301
302       \throw GSL_error if dimensions mis-match.
303    */
304    void sub(const matrix& b);
305
306    /**
307       \brief Exchange the elements of the this and \a other by copying.
308
309       The two matrices must have the same size.
310
311       \throw GSL_error if either index is out of bounds.
312    */
313    void swap(matrix& other);
314
315    /**
316       \brief Swap columns \a i and \a j.
317
318       \throw GSL_error if either index is out of bounds.
319    */
320    void swap_columns(const size_t i,const size_t j);
321
322    /**
323       \brief Swap row \a i and column \a j.
324
325       \throw GSL_error if either index is out of bounds, or if matrix
326       is not square.
327    */
328    void swap_rowcol(const size_t i,const size_t j);
329
330    /**
331       \brief Swap rows \a i and \a j.
332
333       \throw GSL_error if either index is out of bounds.
334    */
335    void swap_rows(const size_t i, const size_t j);
336
337    /**
338       \brief Transpose the matrix.
339
340       \throw GSL_error if memory allocation fails for the new
341       transposed matrix.
342    */
343    void transpose(void);
344
345    /**
346       \brief Element access operator.
347
348       \return Reference to the element position (\a row, \a column).
349
350       \throw If GSL range checks are enabled in the underlying GSL
351       library a GSL_error exception is thrown if either index is out
352       of range.
353    */
354    double& operator()(size_t row,size_t column);
355
356    /**
357       \brief Element access operator.
358
359       \return Const reference to the element position (\a row, \a
360       column).
361
362       \throw If GSL range checks are enabled in the underlying GSL
363       library a GSL_error exception is thrown if either index is out
364       of range.
365    */
366    const double& operator()(size_t row,size_t column) const;
367
368    ///
369    /// @brief Comparison operator.
370    ///
371    /// @return True if all elements are equal otherwise False.
372    ///
373    /// @see equal
374    ///
375    bool operator==(const matrix& other) const;
376
377    ///
378    /// @brief Comparison operator.
379    ///
380    /// @return False if all elements are equal otherwise True.
381    ///
382    /// @see equal
383    ///
384    bool operator!=(const matrix& other) const;
385
386    /**
387       \brief The assignment operator.
388
389       There is no requirements on dimensions, i.e. the matrix is
390       remapped in memory if necessary. This implies that in general
391       views cannot be assigned using this operator. Views will be
392       mutated into normal matrices. The only exception to this
393       behaviour on views is when self-assignemnt is done, since
394       self-assignment is ignored.
395
396       \return A const reference to the resulting matrix.
397
398       \see void set(const matrix&).
399
400       \throw A GSL_error is indirectly thrown if memory allocation
401       fails, or if dimensions mis-match.
402    */
403    const matrix& operator=(const matrix& other);
404
405    /**
406       \brief Add and assign operator.
407
408       \return A const reference to the resulting matrix.
409
410       \throw GSL_error if dimensions mis-match.
411    */
412    const matrix& operator+=(const matrix&);
413
414    ///
415    /// @brief Add and assign operator.
416    ///
417    const matrix& operator+=(const double);
418
419    /**
420       \brief Subtract and assign operator.
421
422       \return A const reference to the resulting matrix.
423
424       \throw GSL_error if dimensions mis-match.
425    */
426    const matrix& operator-=(const matrix&);
427
428    /**
429       \brief Multiply and assigment operator.
430
431       \return Const reference to the resulting matrix.
432
433       \throw GSL_error if memory allocation fails.
434    */
435    const matrix& operator*=(const matrix&);
436
437    /**
438       \brief Multiply and assignment operator
439
440       \throw GSL_error if memory allocation fails.
441    */
442    const matrix& operator*=(const double);
443
444  private:
445
446    /**
447       \brief Create a new copy of the internal GSL matrix.
448
449       Necessary memory for the new GSL matrix is allocated and the
450       caller is responsible for freeing the allocated memory.
451
452       \return A pointer to a copy of the internal GSL matrix.
453
454       \throw GSL_error if memory cannot be allocated for the new
455       copy, or if dimensions mis-match.
456    */
457    gsl_matrix* create_gsl_matrix_copy(void) const;
458
459    gsl_matrix* m_;
460    gsl_matrix_view* view_;
461  };
462
463  ///
464  /// The output operator for the matrix class.
465  ///
466  std::ostream& operator<< (std::ostream& s, const matrix&);
467
468  /**
469     @brief vector matrix multiplication
470   */
471  vector operator*(const matrix&, const vector&);
472
473  /**
474     @brief matrix vector multiplication
475   */
476  vector operator*(const vector&, const matrix&);
477
478}}} // of namespace utility, yat, and theplu
479
480#endif
Note: See TracBrowser for help on using the repository browser.