-
Praetorius, Simon authoredPraetorius, Simon authored
implicit_dense.hpp 9.40 KiB
// Software License for MTL
//
// Copyright (c) 2007 The Trustees of Indiana University.
// 2008 Dresden University of Technology and the Trustees of Indiana University.
// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com.
// All rights reserved.
// Authors: Peter Gottschling and Andrew Lumsdaine
//
// This file is part of the Matrix Template Library
//
// See also license.mtl.txt in the distribution.
#ifndef MTL_MATRIX_IMPLICIT_DENSE_INCLUDE
#define MTL_MATRIX_IMPLICIT_DENSE_INCLUDE
#include <vector>
#include <boost/numeric/linear_algebra/inverse.hpp>
#include <boost/numeric/mtl/mtl_fwd.hpp>
#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp>
#include <boost/numeric/mtl/matrix/mat_expr.hpp>
#include <boost/numeric/mtl/concept/std_concept.hpp>
#include <boost/numeric/mtl/concept/collection.hpp>
#ifdef MTL_HAS_MPI
# include <boost/numeric/mtl/matrix/distributed.hpp>
# include <boost/numeric/mtl/matrix/inserter.hpp>
# include <boost/mpi/collectives.hpp>
#endif
namespace mtl { namespace matrix {
template <typename Functor>
class implicit_dense
: public const_crtp_base_matrix< implicit_dense<Functor>,
typename Functor::result_type, typename Functor::size_type >,
public mat_expr< implicit_dense<Functor> >
{
typedef implicit_dense self;
public:
typedef mtl::tag::row_major orientation; // for completeness
typedef typename Functor::result_type value_type;
typedef typename Functor::result_type const_reference;
typedef typename Functor::size_type size_type;
// Should not be needed, to be removed after transposed_view is cleaned up
typedef index::c_index index_type;
typedef mtl::traits::detail::matrix_element_key<self> key_type;
typedef mtl::non_fixed::dimensions dim_type;
explicit implicit_dense (const Functor& functor) : my_functor(functor) {}
value_type operator() (size_type r, size_type c) const { return my_functor(r, c); }
size_type nnz() const { return dim1() * dim2(); }
size_type dim1() const { return num_rows(my_functor); }
size_type dim2() const { return num_cols(my_functor); }
friend size_type inline num_rows(const self& A) { return num_rows(A.my_functor); }
friend size_type inline num_cols(const self& A) { return num_cols(A.my_functor); }
Functor& functor() { return my_functor; }
Functor const& functor() const { return my_functor; }
private:
Functor my_functor;
};
template <typename Functor>
typename Functor::size_type inline size(const implicit_dense<Functor>& A)
{
return num_rows(A) * num_cols(A);
}
// ==========
// Sub matrix
// ==========
// To do later
}} // namespace mtl::matrix
namespace mtl { namespace traits {
// ================
// Range generators
// For cursors
// ================
template <typename Functor>
struct range_generator<glas::tag::row, mtl::matrix::implicit_dense<Functor> >
: detail::all_rows_range_generator<mtl::matrix::implicit_dense<Functor>, complexity_classes::linear>
{};
template <typename Functor>
struct range_generator<glas::tag::major, mtl::matrix::implicit_dense<Functor> >
: range_generator<glas::tag::row, mtl::matrix::implicit_dense<Functor> >
{};
template <typename Functor>
struct range_generator<glas::tag::nz,
detail::sub_matrix_cursor<mtl::matrix::implicit_dense<Functor>, glas::tag::row, 2> >
: detail::all_cols_in_row_range_generator<detail::sub_matrix_cursor<mtl::matrix::implicit_dense<Functor>, glas::tag::row, 2> >
{};
template <typename Functor>
struct range_generator<glas::tag::col, mtl::matrix::implicit_dense<Functor> >
: detail::all_cols_range_generator<mtl::matrix::implicit_dense<Functor>, complexity_classes::linear>
{};
template <typename Functor>
struct range_generator<glas::tag::nz,
detail::sub_matrix_cursor<mtl::matrix::implicit_dense<Functor>, glas::tag::col, 2> >
: detail::all_rows_in_col_range_generator<detail::sub_matrix_cursor<mtl::matrix::implicit_dense<Functor>, glas::tag::col, 2> >
{};
template <typename Tag, typename Value>
struct range_generator<Tag, mtl::matrix::ones_matrix<Value> >
: public range_generator<Tag, mtl::matrix::implicit_dense<mtl::matrix::ones_functor<Value> > >
{};
template <typename Value>
struct range_generator<glas::tag::major, mtl::matrix::ones_matrix<Value> >
: public range_generator<glas::tag::major, mtl::matrix::implicit_dense<mtl::matrix::ones_functor<Value> > >
{};
template <typename Tag, typename Value>
struct range_generator<Tag, mtl::matrix::hilbert_matrix<Value> >
: public range_generator<Tag, mtl::matrix::implicit_dense<mtl::matrix::hilbert_functor<Value> > >
{};
template <typename Value>
struct range_generator<glas::tag::major, mtl::matrix::hilbert_matrix<Value> >
: public range_generator<glas::tag::major, mtl::matrix::implicit_dense<mtl::matrix::hilbert_functor<Value> > >
{};
template <typename Tag, typename Vector1, typename Vector2>
struct range_generator<Tag, mtl::matrix::outer_product_matrix<Vector1, Vector2> >
: public range_generator<Tag, mtl::matrix::implicit_dense<mtl::matrix::outer_product_functor<Vector1, Vector2> > >
{};
template <typename Vector1, typename Vector2>
struct range_generator<glas::tag::major, mtl::matrix::outer_product_matrix<Vector1, Vector2> >
: public range_generator<glas::tag::major, mtl::matrix::implicit_dense<mtl::matrix::outer_product_functor<Vector1, Vector2> > >
{};
}} // mtl::traits
// =============
// Some functors
// =============
namespace mtl { namespace matrix {
template <typename Value= int>
class ones_functor
{
typedef ones_functor self;
public:
typedef std::size_t size_type;
typedef Value result_type;
ones_functor(size_type nr, size_type nc) : nr(nr), nc(nc) {}
friend size_type inline num_rows(const self& A) { return A.nr; }
friend size_type inline num_cols(const self& A) { return A.nc; }
result_type operator()(size_type, size_type) const { return Value(1); }
private:
size_type nr, nc;
};
template <typename Value= double>
class hilbert_functor
{
typedef hilbert_functor self;
public:
typedef std::size_t size_type;
typedef Value result_type;
hilbert_functor(size_type nr, size_type nc) : nr(nr), nc(nc) {}
friend size_type inline num_rows(const self& A) { return A.nr; }
friend size_type inline num_cols(const self& A) { return A.nc; }
result_type operator()(size_type r, size_type c) const
{
using math::reciprocal;
return reciprocal(Value(r + c + 1));
}
private:
size_type nr, nc;
};
template <typename Vector1, typename Vector2>
class outer_product_functor
{
typedef outer_product_functor self;
public:
typedef std::size_t size_type;
typedef typename Multiplicable<typename Collection<Vector1>::value_type,
typename Collection<Vector2>::value_type>::result_type result_type;
outer_product_functor(const Vector1& v1, const Vector2& v2) : my_v1(v1), my_v2(v2) {}
outer_product_functor(size_type r, size_type c) : my_v1(r), my_v2(c) {}
friend size_type inline num_rows(const self& A) { return size(A.my_v1); }
friend size_type inline num_cols(const self& A) { return size(A.my_v2); }
result_type operator()(size_type r, size_type c) const { return my_v1[r] * my_v2[c]; }
Vector1& v1() { return my_v1; }
Vector1 const& v1() const { return my_v1; }
Vector2& v2() { return my_v2; }
Vector2 const& v2() const { return my_v2; }
private:
Vector1 my_v1; // keeps copy
Vector2 my_v2;
};
// ======================
// Some implicit matrices
// ======================
template <typename Value= int>
class ones_matrix
: public implicit_dense<ones_functor<Value> >
{
public:
typedef ones_functor<Value> functor_type;
typedef typename functor_type::size_type size_type;
typedef implicit_dense<functor_type> base;
ones_matrix(size_type r, size_type c) : base(functor_type(r, c)) {}
};
template <typename Value= double>
class hilbert_matrix
: public implicit_dense<hilbert_functor<Value> >
{
public:
typedef hilbert_functor<Value> functor_type;
typedef typename functor_type::size_type size_type;
typedef implicit_dense<functor_type> base;
hilbert_matrix(size_type r, size_type c) : base(functor_type(r, c)) {}
};
template <typename Vector1, typename Vector2>
class outer_product_matrix
: public implicit_dense<outer_product_functor<Vector1, Vector2> >
{
typedef outer_product_matrix self;
public:
typedef outer_product_functor<Vector1, Vector2> functor_type;
typedef typename functor_type::size_type size_type;
typedef implicit_dense<functor_type> base;
outer_product_matrix(const Vector1& v1, const Vector2& v2) : base(functor_type(v1, v2)) {}
outer_product_matrix(size_type r, size_type c) : base(functor_type(r, c)) {}
Vector1& v1() { return this->functor().v1(); }
Vector1 const& v1() const { return this->functor().v1(); }
Vector2& v2() { return this->functor().v2(); }
Vector2 const& v2() const { return this->functor().v2(); }
};
}} // namespace mtl::matrix
#endif // MTL_MATRIX_IMPLICIT_DENSE_INCLUDE