#ifndef _theplu_yat_classifier_matrix_lookup_weighted_
#define _theplu_yat_classifier_matrix_lookup_weighted_
// $Id$
/*
Copyright (C) 2006 Jari Häkkinen, Markus Ringnér, Peter Johansson
Copyright (C) 2007 Jari Häkkinen, Peter Johansson
This file is part of the yat library, http://trac.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 "DataLookup2D.h"
#include "yat/utility/Iterator.h"
#include "yat/utility/IteratorPolicy.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 matrix or
/// from an other 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 DataLookup2D
{
public:
/// 'Read Only' iterator
typedef utility::StrideIterator<
utility::Iterator, void,
const std::pair,
utility::IteratorPolicyWeighted > >
const_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.
\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 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
/// vector @a row, and number of columns is equal to size of
/// vector @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 std::vector& row,
const std::vector& 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 std::vector& 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 std::vector& row,
const std::vector& 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 std::vector&,
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();
///
/// @return data value of element (@a row, @a column)
///
double data(size_t row, size_t column) const;
/**
the new MatrixLookup will consist of the rolumn vectors
defined by @a index. This means that the returned
MatrixLookupWeighted
will fullfill:
returned(i,j) = original(index[i],j)
@note If underlying matrix goes out of scope or is deleted, the
returned pointer becomes invalid and the result of further use is
undefined.
*/
const MatrixLookupWeighted* selected(const std::vector& i) const;
///
/// The created MatrixLookupWeighted corresponds to all rows and the
/// columns defined by @a index in the original MatrixLookupWeighted. The
/// created MatrixLookupWeighted will fullfill:
/// novel_ml(i,j)=original(i,index[j]).
///
/// @return pointer to sub-Lookup of the MatrixLookupWeighted
///
/// @note If underlying matrix goes out of scope or is deleted, the
/// returned pointer becomes invalid and the result of further use is
/// undefined.
///
const MatrixLookupWeighted*
training_data(const std::vector& index) const;
///
/// The created MatrixLookupWeighted corresponds to all rows and the
/// columns defined by @a index in the original MatrixLookupWeighted. The
/// created MatrixLookupWeighted will fullfill:
/// novel_ml(i,j)=original(i,index[j])
///
/// @return pointer to sub-Lookup of the MatrixLookupWeighted
///
/// @note If underlying matrix goes out of scope or is deleted, the
/// returned pointer becomes invalid and the result of further use is
/// undefined.
///
const MatrixLookupWeighted* validation_data(const std::vector&,
const std::vector&) 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 weight * data for element (@a row, @a column)
///
double 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:
const utility::matrix* data_;
const utility::matrix* weights_;
u_int* ref_count_weights_;
};
///
/// 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