source: trunk/yat/classifier/MatrixLookup.h @ 1788

Last change on this file since 1788 was 1788, checked in by Peter, 12 years ago

Changed MatrixLookup::operator() to return const double& rather than double. Fixes #488

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date ID
File size: 10.5 KB
Line 
1#ifndef _theplu_yat_classifier_matrix_lookup_
2#define _theplu_yat_classifier_matrix_lookup_
3
4// $Id$
5
6/*
7  Copyright (C) 2005 Peter Johansson, Markus Ringnér
8  Copyright (C) 2006 Jari Häkkinen, Peter Johansson, Markus Ringnér
9  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
10  Copyright (C) 2008, 2009 Peter Johansson
11
12  This file is part of the yat library, http://dev.thep.lu.se/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 3 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 yat. If not, see <http://www.gnu.org/licenses/>.
26*/
27
28#include "yat/utility/Container2DIterator.h"
29#include "yat/utility/Index.h"
30#include "yat/utility/iterator_traits.h"
31#include "yat/utility/Matrix.h"
32#include "yat/utility/SmartPtr.h"
33
34#include <boost/iterator/permutation_iterator.hpp>
35
36#include <iostream>
37#include <vector>
38
39namespace theplu {
40namespace yat {
41namespace classifier { 
42
43  ///
44  /// @brief General view into utility::Matrix
45  ///
46  /// MatrixLookups can be used to create lookups/views into matrices
47  /// in a more general way than the views supported in the matrix
48  /// class. The object does not contain any data, but only a pointer
49  /// to a utility::Matrix and row and columns incices defining which
50  /// sub-matrix to look into.  Each row and each column corresponds
51  /// to a row and a column in the utility::Matrix, respectively. This design
52  /// allow for fast creation of sub-matrices, which is a common
53  /// operation in most traning/validation procedures. The views are
54  /// const views in the sense that they cannot modify underlying
55  /// utility::Matrix.
56  ///
57  /// A MatrixLookup can be created directly from a utility::Matrix or from
58  /// another MatrixLookup. In the latter case, the resulting
59  /// MatrixLookup is looking directly into the underlying utility::Matrix to
60  /// avoid multiple lookups.
61  ///
62  /// There is a possibility to set the MatrixLookup as owner of the
63  /// underlying utility::Matrix. This implies that underlying data is deleted
64  /// in destructor of MatrixLookup, but only if there is no other
65  /// owner of the underlying data.
66  ///
67  /// \see MatrixLookupWeighted
68  ///
69  class MatrixLookup
70  {
71  public:
72    /**
73       value_type is double
74
75       \since New in yat 0.5
76     */
77    typedef utility::Matrix::value_type value_type;
78
79    /**
80       const_reference type is const double&
81
82       \since New in yat 0.5
83     */
84    typedef utility::Matrix::const_reference const_reference;
85
86    /// 'Read Only' iterator
87    typedef utility::Container2DIterator<const MatrixLookup, value_type, 
88                                         const_reference>
89    const_iterator;
90
91    /**
92       'Read only' iterator used to iterate over a column
93     */
94    typedef boost::permutation_iterator<utility::Matrix::const_column_iterator,
95                                        utility::Index::const_iterator> 
96    const_column_iterator;
97
98    /**
99       'Read only' iterator used to iterate over a row
100     */
101    typedef const_column_iterator const_row_iterator;
102
103    ///
104    /// Constructor creating a lookup into the entire @a matrix.
105    /// \param matrix underlying matrix
106    /// @param own if true MatrixLookup owns its underlying @a matrix
107    ///
108    /// @note If \a own is true and \a matrix is already owned by some
109    /// other object, this will lead to \a matrix having multiple
110    /// owners without the owners being aware of each
111    /// other. Consequently multiple deletion will occur.
112    ///
113    /// @note If @a matrix goes out of scope or is deleted, the
114    /// MatrixLookup becomes invalid and the result of further use is
115    /// undefined.
116    ///
117    MatrixLookup(const utility::Matrix& matrix, const bool own=false);
118
119    ///
120    /// Constructor creating a lookup into a sub-matrix of @a matrix.
121    /// The @a row and @a column define what sub-matrix to look into,
122    /// in other words, the created MatrixLookup will fullfill the
123    /// following: \f$ MatrixLookup(i,j)=matrix(row[i],column[j])
124    /// \f$. This also means that number of rows in created
125    /// MatrixLookup is equal to size of vector @a row, and number of
126    /// columns is equal to size of vector @a column.
127    ///
128    /// @note If @a matrix goes out of scope or is deleted, the
129    /// MatrixLookup becomes invalid and the result of further use is
130    /// undefined.
131    ///
132    MatrixLookup(const utility::Matrix& matrix, const utility::Index& row, 
133                 const utility::Index& column);
134
135    ///
136    /// Constructor creating a lookup into a sub-matrix of @a matrix.
137    ///
138    /// If @a row_vectors is true the new MatrixLookup will consist
139    /// of the row vectors defined by @a index. This means that the
140    /// created MatrixLookup will fullfill:
141    /// \f$ MatrixLookup(i,j)=matrix(i,index[j]) \f$
142    ///
143    /// If @a row_vectors is false the new MatrixLookup will be consist
144    /// of the rolumn vectors defined by @a index. This means that the
145    /// created MatrixLookup will fullfill:
146    /// \f$ MatrixLookup(i,j)=matrix(index[i],j) \f$
147    ///
148    /// @note If @a matrix goes out of scope or is deleted, the
149    /// MatrixLookup becomes invalid and the result of further use is
150    /// undefined.
151    ///
152    MatrixLookup(const utility::Matrix& matrix, 
153                 const utility::Index& index, 
154                 const bool row_vectors);
155
156    ///
157    /// @brief Copy constructor.
158    ///
159    /// If \a other is owner of underlying data, constructed
160    /// MatrixLookup will also be set as owner of underlying data.
161    ///
162    /// @note If underlying matrix goes out of scope or is deleted, the
163    /// MatrixLookup becomes invalid and the result of further use is
164    /// undefined.
165    ///
166    MatrixLookup(const MatrixLookup& other);
167
168    ///
169    /// @brief Create a sub-MatrixLookup.
170    ///
171    /// The Lookup is independent of
172    /// MatrixLookup @a ml. The MatrixLookup is created to look
173    /// directly into the underlying matrix to avoid multiple lookups.
174    ///
175    /// If \a ml is owner of underlying data, constructed
176    /// MatrixLookup will also be set as owner of underlying data.
177    ///
178    /// The @a row and @a column define what sub-matrix to look into,
179    /// in other words, the created MatrixLookup will fullfill the
180    /// following: MatrixLookup(i,j)=ml(row[i],column[j]). This
181    /// also means that number of rows in created MatrixLookup is
182    /// equal to size of vector @a row, and number of columns is equal
183    /// to size of vector @a column.
184    ///
185    /// If \a ml is owner of underlying data, constructed
186    /// MatrixLookup will also be set as owner of underlying data.
187    ///
188    /// @note If underlying matrix goes out of scope or is deleted, the
189    /// MatrixLookup becomes invalid and the result of further use is
190    /// undefined.
191    ///
192    MatrixLookup(const MatrixLookup& ml, const utility::Index& row, 
193                 const utility::Index& column);
194
195    ///
196    /// Constructor creating a lookup into a sub-matrix of
197    /// @a ml. The MatrixLookup is created to look directly into the
198    /// underlying matrix to avoid multiple lookups.
199    ///
200    /// If @a row_vectors is true the new MatrixLookup will consist
201    /// of the row vectors defined by @a index. This means that the
202    /// created MatrixLookup will fullfill:
203    /// MatrixLookup(i,j)=ml(i,index[j])
204    ///
205    /// If @a row_vectors is false the new MatrixLookup will consist
206    /// of the rolumn vectors defined by @a index. This means that the
207    /// created MatrixLookup will fullfill:
208    /// \f$ MatrixLookup(i,j) = ml(index[i],j) \f$
209    ///
210    /// If \a ml is owner of underlying data, constructed
211    /// MatrixLookup will also be set as owner of underlying data.
212    ///
213    /// @note If underlying matrix goes out of scope or is deleted, the
214    /// MatrixLookup becomes invalid and the result of further use is
215    /// undefined.
216    ///
217    MatrixLookup(const MatrixLookup& ml, const utility::Index&, 
218                 const bool row_vectors);
219
220    ///
221    /// Constructor creating a MatrixLookup with @a rows rows, @a
222    /// columns columns, and all values are set to @a value. Created
223    /// MatrixLookup owns its underlying matrix.
224    ///
225    MatrixLookup(const size_t rows, const size_t columns, const double value=0);
226
227    ///
228    /// @brief The istream constructor.
229    ///
230    /// In construction the underlying matrix is created from
231    /// stream. The MatrixLookup will be owner of the underlying
232    /// matrix.
233    ///
234    /// @see matrix(istream&) for details.
235    ///
236    MatrixLookup(std::istream&, char sep='\0');
237
238    ///
239    /// @brief Destructor.
240    ///
241    /// If ownership is set true and there is no other owner of
242    /// underlying data, underlying data is deleted.
243    ///
244    virtual ~MatrixLookup();
245
246    /**
247       Iterator iterates along a row. When end of row is reached it
248       jumps to beginning of next row.
249
250       \return const_iterator pointing to upper-left element.
251     */
252    const_iterator begin(void) const;
253
254    /**
255       Iterator iterates along a column.
256
257       \return iterator pointing to first element of column \a i.
258     */
259    const_column_iterator begin_column(size_t) const;
260
261    /**
262       Iterator iterates along a column.
263
264       \return const_iterator pointing to first element of column \a i.
265     */
266    const_row_iterator begin_row(size_t) const;
267
268    /**
269       \return number of columns
270    */
271    size_t columns(void) const;
272
273    /**
274       \return const_iterator pointing to end of matrix
275     */
276    const_iterator end(void) const;
277
278    /**
279       \return const_iterator pointing to end of column \a i
280     */
281    const_column_iterator end_column(size_t) const;
282
283    /**
284       \return const_iterator pointing to end of row \a i
285     */
286    const_row_iterator end_row(size_t) const;
287
288    /**
289       \return number of rows
290    */
291    size_t rows(void) const;
292
293    ///
294    /// @return false
295    ///
296    bool weighted(void) const;
297
298    ///
299    /// Access operator
300    ///
301    /// @return element
302    ///
303    const_reference operator()(size_t row, size_t column) const;
304
305    ///
306    /// @brief assigment operator
307    ///
308    /// Does only change MatrixLookup not the underlying matrix
309    /// object. However if the MatrixLookup is owner (and the only owner)
310    /// of its underlying
311    /// matrix, that matrix will be deleted here.
312    ///
313    const MatrixLookup& operator=(const MatrixLookup&);
314   
315  private:
316    friend class MatrixLookupWeighted;
317
318    utility::Index column_index_;
319    typedef utility::SmartPtr<const utility::Matrix> MatrixP;
320    MatrixP data_;
321    utility::Index row_index_;
322
323    // for assertions
324    bool validate(void) const;
325  }; 
326 
327  ///
328  /// The output operator MatrixLookup
329  ///
330  std::ostream& operator<< (std::ostream& s, const MatrixLookup&);
331
332}}} // of namespace classifier, yat, and theplu
333
334#endif
Note: See TracBrowser for help on using the repository browser.