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

Last change on this file since 1121 was 1121, checked in by Peter, 14 years ago

fixes #308

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