#ifndef _theplu_yat_classifier_matrix_lookup_weighted_
#define _theplu_yat_classifier_matrix_lookup_weighted_
// $Id$
/*
Copyright (C) 2006 Jari Häkkinen, Peter Johansson, Markus Ringnér
Copyright (C) 2007 Jari Häkkinen, Peter Johansson
Copyright (C) 2008 Peter Johansson
This file is part of the yat library, http://dev.thep.lu.se/yat
The yat library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The yat library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include "yat/utility/Container2DIterator.h"
#include "yat/utility/Index.h"
#include "yat/utility/IteratorPolicy.h"
#include "yat/utility/SmartPtr.h"
#include "yat/utility/StrideIterator.h"
#include
#include
#include
namespace theplu {
namespace yat {
namespace utility {
class Matrix;
}
namespace classifier {
class MatrixLookup;
///
/// @brief Class viewing into data and weight matrix.
///
/// A MatrixLookupWeighted is very similar to a MatrixLookup, but
/// contains a pointer to a weight matrix as well meaning each data
/// element is associated to a weight.
///
/// A MatrixLookupWeighted can be created directly from a utility::Matrix or
/// from another MatrixLookupWeighted. In the latter case, the
/// resulting MatrixLookupWeighted is looking directly into the
/// underlying matrix to avoid multiple lookups.
///
/// There is a possibility to set the MatrixLookupWeighted as owner
/// of the underlying matrices (data and weight).
/// This implies that underlying data is deleted
/// in destructor of MatrixLookupWeighted, but only if there is no other
/// owner of the underlying data. A reference counter is used to
/// keep track of number of owners. Ownership is copied in copy
/// constructors and assignments.
///
class MatrixLookupWeighted
{
public:
/// 'Read Only' iterator
typedef utility::StrideIterator<
utility::Container2DIterator, void,
const std::pair,
utility::IteratorPolicyWeighted > >
const_iterator;
/**
'Read only' iterator used to iterate over a column
*/
typedef const_iterator const_column_iterator;
/**
'Read only' iterator used to iterate over a row
*/
typedef const_iterator const_row_iterator;
///
/// Constructor creating a lookup into the entire \a matrix and \a
/// weights.
///
/// @note If @a matrix or @a weights goes out of scope or is
/// deleted, the MatrixLookupWeighted becomes invalid and the
/// result of further use is undefined.
///
MatrixLookupWeighted(const utility::Matrix& matrix,
const utility::Matrix& weights,
const bool owner=false);
///
/// Constructor creating a lookup into the entire @a matrix. A
/// weight matrix is constructed with weights 1 for values and 0
/// for nan's in @a matrix.
///
/// \see bool utility::nan(const Matrix&, Matrix&);
///
/// @note If @a matrix goes out of scope or
/// is deleted, the MatrixLookupWeighted becomes invalid and the
/// result of further use is undefined.
///
MatrixLookupWeighted(const utility::Matrix& matrix);
/**
Constructor creating a MatrixLookupWeighted from a MatrixLookup. A
weight matrix with unitary weights are created internally.
\note no check for nan is performed.
@note If underlying utility::Matrix goes out of scope or
is deleted, the MatrixLookupWeighted becomes invalid and the
result of further use is undefined.
*/
MatrixLookupWeighted(const MatrixLookup& matrix);
///
/// Constructor creating a lookup into a sub-matrix of @a matrix.
/// The @a row and @a column define what sub-matrix to look into,
/// in other words, the created MatrixLookupWeighted will fullfill
/// the following:
/// MatrixLookupWeighted(i,j)=matrix(row[i],column[j])
/// weights(row[i],column[j]). This also means that number of
/// rows in created MatrixLookupWeighted is equal to size of
/// @a row, and number of columns is equal to size of @a column.
///
/// @note If @a matrix or @a weights goes out of scope or is deleted, the
/// MatrixLookupWeighted becomes invalid and the result of further use is
/// undefined.
///
MatrixLookupWeighted(const utility::Matrix& matrix,
const utility::Matrix& weights,
const utility::Index& row,
const utility::Index& column);
///
/// Constructor creating a lookup into a sub-matrix of @a matrix.
///
/// If @a row_vectors is true the new MatrixLookupWeighted will be
/// consist of the row vectors defined by @a index. This means
/// that the created MatrixLookupWeighted will fullfill:
/// MatrixLookupWeighted(i,j)=matrix(i,index[j])*weights(i,index[j])
///
///
/// If @a row_vectors is false the new MatrixLookupWeighted will be consist
/// of the rolumn vectors defined by @a index. This means that the
/// created MatrixLookupWeighted will fullfill:
///
///
/// @note If @a matrix or @a weights goes out of scope or is
/// deleted, the MatrixLookupWeighted becomes invalid and the
/// result of further use is undefined.
///
MatrixLookupWeighted(const utility::Matrix& matrix,
const utility::Matrix& weights,
const utility::Index& index,
const bool row_vectors);
///
/// @brief Copy constructor.
///
/// If \a other is owner of underlying data, constructed
/// MatrixLookup will also be set as owner of underlying data.
///
/// @note If underlying matrix goes out of scope or is deleted, the
/// MatrixLookupWeighted becomes invalid and the result of further use is
/// undefined.
///
MatrixLookupWeighted(const MatrixLookupWeighted& other);
///
/// Creates a sub-MatrixLookupWeighted. The Lookup is independent of
/// MatrixLookupWeighted @a ml. The MatrixLookupWeighted is created to look
/// directly into the underlying matrix to avoid multiple lookups.
///
/// The @a row and @a column define what sub-matrix to look into,
/// in other words, the created MatrixLookupWeighted will fullfill the
/// following: \f$ MatrixLookupWeighted(i,j)=ml(row[i],column[j]) \f$. This
/// also means that number of rows in created MatrixLookupWeighted is
/// equal to size of vector @a row, and number of columns is equal
/// to size of vector @a column.
///
/// If \a ml is owner of underlying data, constructed
/// MatrixLookup will also be set as owner of underlying data.
///
/// @note If underlying matrix goes out of scope or is deleted, the
/// MatrixLookupWeighted becomes invalid and the result of further use is
/// undefined.
///
MatrixLookupWeighted(const MatrixLookupWeighted& ml,
const utility::Index& row,
const utility::Index& column);
///
/// Constructor creating a lookup into a sub-matrix of
/// @a ml. The MatrixLookupWeighted is created to look directly into the
/// underlying matrix to avoid multiple lookups.
///
/// If @a row_vectors is true the new MatrixLookupWeighted will consist
/// of the row vectors defined by @a index. This means that the
/// created MatrixLookupWeighted will fullfill:
/// \f$ MatrixLookupWeighted(i,j)=ml(i,index[j])\f$
///
/// If @a row_vectors is false the new MatrixLookupWeighted will consist
/// of the rolumn vectors defined by @a index. This means that the
/// created MatrixLookupWeighted will fullfill:
/// \f$ MatrixLookupWeighted(i,j) = ml(index[i],j) \f$
///
/// If \a ml is owner of underlying data, constructed
/// MatrixLookup will also be set as owner of underlying data.
///
/// @note If underlying matrix goes out of scope or is deleted, the
/// MatrixLookupWeighted becomes invalid and the result of further use is
/// undefined.
///
MatrixLookupWeighted(const MatrixLookupWeighted& ml,
const utility::Index&,
const bool row_vectors);
///
/// Constructor creating a MatrixLookupWeighted with @a rows rows, @a
/// columns columns, and all values are set to @a value. Created
/// MatrixLookupWeighted owns its underlying matrix.
///
MatrixLookupWeighted(const size_t rows, const size_t columns,
const double value=0, const double weight=1);
///
/// @brief The istream constructor.
///
/// In construction the underlying matrix is created from
/// stream. The MatrixLookupWeighted will be owner of the underlying
/// matrix.
///
/// @see matrix(istream&) for details.
///
MatrixLookupWeighted(std::istream&, char sep='\0');
///
/// Destructor. If MatrixLookup is owner (and the only owner) of
/// underlying matrix, the matrices are destroyed.
///
virtual ~MatrixLookupWeighted();
/**
Iterator iterates along a row. When end of row is reached it
jumps to beginning of next row.
\return const_iterator pointing to upper-left element.
*/
const_iterator begin(void) const;
/**
Iterator iterates along a column.
\return iterator pointing to first element of column \a i.
*/
const_column_iterator begin_column(size_t) const;
/**
Iterator iterates along a column.
\return const_iterator pointing to first element of column \a i.
*/
const_row_iterator begin_row(size_t) const;
/**
\return number of columns
*/
size_t columns(void) const;
///
/// @return data value of element (@a row, @a column)
///
double data(size_t row, size_t column) const;
/**
\return const_iterator pointing to end of matrix
*/
const_iterator end(void) const;
/**
\return const_iterator pointing to end of column \a i
*/
const_column_iterator end_column(size_t) const;
/**
\return const_iterator pointing to end of row \a i
*/
const_row_iterator end_row(size_t) const;
/**
\return number of rows
*/
size_t rows(void) const;
///
/// @return weight value of element (@a row, @a column)
///
double weight(size_t row, size_t column) const;
///
/// @return true
///
bool weighted(void) const;
///
/// Access operator
///
/// @return data-weight pair (@a row, @a column)
///
std::pair
operator()(const size_t row, const size_t column) const;
///
/// @brief assigment operator
///
/// Does only change MatrixLookupWeighted not the underlying
/// matrix object. However if the MatrixLookupWeighted is owner
/// (and the only owner) of its underlying data, those data will
/// be deleted here.
///
const MatrixLookupWeighted& operator=(const MatrixLookupWeighted&);
private:
typedef utility::SmartPtr MatrixP;
utility::Index column_index_;
MatrixP data_;
utility::Index row_index_;
MatrixP weights_;
// for assertions
bool validate(void) const;
};
///
/// The output operator MatrixLookupWeighted
///
/// For eacd data element data(i,j) is printed except those being
/// associated with a zero weight for which nothing is printed.
///
std::ostream& operator<< (std::ostream& s, const MatrixLookupWeighted&);
}}} // of namespace classifier, yat, and theplu
#endif