📄 morton_dense.hpp
字号:
// Software License for MTL// // Copyright (c) 2007 The Trustees of Indiana University. 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_MORTON_DENSE_INCLUDE
#define MTL_MORTON_DENSE_INCLUDE
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/mtl/utility/common_include.hpp>
#include <boost/numeric/mtl/utility/tag.hpp>
#include <boost/numeric/mtl/utility/exception.hpp>
#include <boost/numeric/mtl/detail/base_sub_matrix.hpp>
#include <boost/numeric/mtl/detail/contiguous_memory_block.hpp>
#include <boost/numeric/mtl/detail/dilated_int.hpp>
#include <boost/numeric/mtl/utility/iterator_adaptor.hpp>
#include <boost/numeric/mtl/operation/set_to_zero.hpp>
#include <boost/numeric/mtl/matrix/mat_expr.hpp>
#include <boost/numeric/mtl/operation/print_matrix.hpp>
#include <boost/numeric/mtl/operation/compute_factors.hpp>
// #include <boost/numeric/mtl/ahnentafel_detail/index.hpp>
namespace mtl {
template <unsigned long BitMask>
struct morton_dense_key
{
typedef std::size_t size_type;
typedef dilated_int<std::size_t, BitMask, true> dilated_row_t;
typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t;
typedef morton_dense_key self;
morton_dense_key(size_type my_row, size_type my_col)
: my_row(my_row), my_col(my_col), dilated_row(my_row), dilated_col(my_col)
{}
bool operator== (self const& x) const
{
return my_row == x.my_row && my_col == x.my_col;
}
bool operator!= (self const& x)
{
return !(*this == x);
}
size_type row() const
{
return my_row;
}
size_type col() const
{
return my_col;
}
self& advance_row(int row_inc)
{
dilated_row.advance(row_inc);
// potential addition of signed and unsigned
my_row+= row_inc;
return *this;
}
self& advance_col(int col_inc)
{
dilated_col.advance(col_inc);
// potential addition of signed and unsigned
my_col+= col_inc;
return *this;
}
self& advance(int row_inc, int col_inc)
{
advance_row(row_inc);
advance_col(col_inc);
return *this;
}
public:
size_type my_row, my_col;
dilated_row_t dilated_row;
dilated_col_t dilated_col;
};
template <unsigned long BitMask>
struct morton_dense_el_cursor
: public morton_dense_key<BitMask>
{
typedef std::size_t size_type;
typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t;
typedef morton_dense_el_cursor self;
typedef morton_dense_key<BitMask> base;
typedef base key_type;
morton_dense_el_cursor(size_type my_row, size_type my_col, size_type num_cols)
: base(my_row, my_col), num_cols(num_cols)
{}
self& operator++ ()
{
++this->my_col; ++this->dilated_col;
if (this->my_col == num_cols) {
this->my_col= 0; this->dilated_col= dilated_col_t(0);
++this->my_row; ++this->dilated_row;
}
return *this;
}
base& operator* ()
{
return *this;
}
const base& operator* () const
{
return *this;
}
protected:
size_t num_cols;
};
template <unsigned long BitMask>
struct morton_dense_row_cursor
: public morton_dense_key<BitMask>
{
typedef std::size_t size_type;
typedef morton_dense_row_cursor self;
typedef morton_dense_key<BitMask> base;
typedef base key_type;
morton_dense_row_cursor(size_type my_row, size_type my_col)
: base(my_row, my_col)
{}
self& operator++ ()
{
++this->my_row; ++this->dilated_row;
return *this;
}
self& operator+=(int inc)
{
this->advance_row(inc);
return *this;
};
self operator+ (int inc) const
{
self tmp(*this);
tmp.advance_row(inc);
return tmp;
}
base& operator* ()
{
return *this;
}
const base& operator* () const
{
return *this;
}
};
template <unsigned long BitMask>
struct morton_dense_col_cursor
: public morton_dense_key<BitMask>
{
typedef std::size_t size_type;
typedef morton_dense_col_cursor self;
typedef morton_dense_key<BitMask> base;
typedef base key_type;
morton_dense_col_cursor(size_type my_row, size_type my_col)
: base(my_row, my_col)
{}
self& operator++ ()
{
++this->my_col; ++this->dilated_col;
return *this;
}
self& operator+=(int inc)
{
this->advance_col(inc);
return *this;
};
self operator+ (int inc) const
{
self tmp(*this);
tmp.advance_col(inc);
return tmp;
}
base& operator* ()
{
return *this;
}
const base& operator* () const
{
return *this;
}
};
template <typename Matrix>
struct morton_dense_row_const_iterator
: utilities::const_iterator_adaptor<typename traits::const_value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>,
typename Matrix::value_type>
{
static const unsigned long mask= Matrix::mask;
typedef morton_dense_row_cursor<mask> cursor_type;
typedef typename traits::const_value<Matrix>::type map_type;
typedef typename Matrix::value_type value_type;
typedef typename Matrix::size_type size_type;
typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> base;
morton_dense_row_const_iterator(const Matrix& matrix, size_type row, size_type col)
: base(map_type(matrix), cursor_type(row, col))
{}
};
template <typename Matrix>
struct morton_dense_row_iterator
: utilities::iterator_adaptor<typename traits::value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>,
typename Matrix::value_type>
{
static const unsigned long mask= Matrix::mask;
typedef morton_dense_row_cursor<mask> cursor_type;
typedef typename traits::value<Matrix>::type map_type;
typedef typename Matrix::value_type value_type;
typedef typename Matrix::size_type size_type;
typedef utilities::iterator_adaptor<map_type, cursor_type, value_type> base;
morton_dense_row_iterator(Matrix& matrix, size_type row, size_type col)
: base(map_type(matrix), cursor_type(row, col))
{}
};
template <typename Matrix>
struct morton_dense_col_const_iterator
: utilities::const_iterator_adaptor<typename traits::const_value<Matrix>::type, morton_dense_col_cursor<Matrix::mask>,
typename Matrix::value_type>
{
static const unsigned long mask= Matrix::mask;
typedef morton_dense_col_cursor<mask> cursor_type;
typedef typename traits::const_value<Matrix>::type map_type;
typedef typename Matrix::value_type value_type;
typedef typename Matrix::size_type size_type;
typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> base;
morton_dense_col_const_iterator(const Matrix& matrix, size_type row, size_type col)
: base(map_type(matrix), cursor_type(row, col))
{}
};
template <typename Matrix>
struct morton_dense_col_iterator
: utilities::iterator_adaptor<typename traits::value<Matrix>::type, morton_dense_col_cursor<Matrix::mask>,
typename Matrix::value_type>
{
static const unsigned long mask= Matrix::mask;
typedef morton_dense_col_cursor<mask> cursor_type;
typedef typename traits::value<Matrix>::type map_type;
typedef typename Matrix::value_type value_type;
typedef typename Matrix::size_type size_type;
typedef utilities::iterator_adaptor<map_type, cursor_type, value_type> base;
morton_dense_col_iterator(Matrix& matrix, size_type row, size_type col)
: base(map_type(matrix), cursor_type(row, col)) {}
};
// Morton Dense matrix type
template <typename Elt, unsigned long BitMask, typename Parameters = mtl::matrix::parameters<> >
class morton_dense : public detail::base_sub_matrix<Elt, Parameters>,
public detail::contiguous_memory_block<Elt, false>,
public detail::crtp_base_matrix< morton_dense<Elt, BitMask, Parameters>, Elt, std::size_t >,
public matrix::mat_expr< morton_dense<Elt, BitMask, Parameters> >
{
typedef detail::base_sub_matrix<Elt, Parameters> super;
typedef detail::contiguous_memory_block<Elt, false> super_memory;
typedef morton_dense self;
typedef matrix::mat_expr< morton_dense<Elt, BitMask, Parameters> > expr_base;
typedef detail::crtp_matrix_assign< self, Elt, std::size_t > assign_base;
public:
typedef Parameters parameters;
typedef typename Parameters::orientation orientation;
typedef typename Parameters::index index_type;
typedef typename Parameters::dimensions dim_type;
typedef Elt value_type;
// return type of operator() const
typedef const value_type& const_access_type;
typedef std::size_t size_type;
const static size_type mask= BitMask;
// typedef self sub_matrix_type;
// typedef morton_dense_el_cursor<Elt> el_cursor_type;
// typedef morton_dense_indexer indexer_type;
// implement cursor for morton matrix, somewhere
// also, morton indexer?
typedef morton_dense_key<BitMask> key_type;
typedef morton_dense_el_cursor<BitMask> el_cursor_type;
typedef dilated_int<std::size_t, BitMask, true> dilated_row_t;
typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t;
public:
#if 0
// All Ahnentafel stuff is commented out
// add morton functions here
// boundary checking of the Ahnentafel index
bool isRoot(const AhnenIndex& index) const;
bool isLeaf(const AhnenIndex& index) const;
bool isInBound(const AhnenIndex& index) const;
// matrix access functions
int getRows() const;
int getCols() const;
int getMaxLevel() const;
int getLevel(const AhnenIndex& index) const;
int getBlockOrder(const AhnenIndex& index) const;
int getBlockSize(const AhnenIndex& index) const;
// get the value of the matrix element corresponding
// to the Ahnentafel index
value_type getElement(const AhnenIndex& index) const;
int getRowMask() const;
int getColMask() const;
// debugging functions
void printVec() const;
void printMat() const;
#endif
protected:
// ranges of rows and columns
dilated_row_t my_begin_row, my_end_row;
dilated_col_t my_begin_col, my_end_col;
// Set ranges from begin_r to end_r and begin_c to end_c
void set_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
{
super::set_ranges(begin_r, end_r, begin_c, end_c);
my_begin_row= begin_r; my_end_row= end_r;
my_begin_col= begin_c; my_end_col= end_c;
set_nnz();
}
// Set ranges to a num_row x num_col matrix, keeps indexing
void set_ranges(size_type num_rows, size_type num_cols)
{
set_ranges(this->begin_row(), this->begin_row() + num_rows,
this->begin_col(), this->begin_col() + num_cols);
}
void init(size_type num_rows, size_type num_cols)
{
set_ranges(num_rows, num_cols);
// set_to_zero(*this);
}
public:
// if compile time matrix size allocate memory
morton_dense() : super_memory(memory_need(dim_type().num_rows(), dim_type().num_cols())), expr_base(*this)
{
init(dim_type().num_rows(), dim_type().num_cols());
}
// only sets dimensions, only for run-time dimensions
explicit morton_dense(mtl::non_fixed::dimensions d)
: super_memory(memory_need(d.num_rows(), d.num_cols())), expr_base(*this)
{
init(d.num_rows(), d.num_cols());
}
// Same with separated row and column number
morton_dense(size_type num_rows, size_type num_cols)
: super_memory(memory_need(num_rows, num_cols)), expr_base(*this)
{
init(num_rows, num_cols);
}
// sets dimensions and pointer to external data
explicit morton_dense(mtl::non_fixed::dimensions d, value_type* a)
: super_memory(a, memory_need(d.num_rows(), d.num_cols())), expr_base(*this)
{
set_ranges(d.num_rows(), d.num_cols());
}
// sets dimensions and pointer to external data
explicit morton_dense(size_type num_rows, size_type num_cols, value_type* a)
: super_memory(a, memory_need(num_rows, num_cols)), expr_base(*this)
{
set_ranges(num_rows, num_cols);
}
// same constructor for compile time matrix size
// sets dimensions and pointer to external data
explicit morton_dense(value_type* a)
: super_memory(a, memory_need(dim_type().num_rows(), dim_type().num_cols())), expr_base(*this)
{
BOOST_ASSERT((dim_type::is_static));
set_ranges(dim_type().num_rows(), dim_type().num_cols());
}
// Default copy constructor doesn't work because CRTP refers to copied matrix not to itself
morton_dense(const self& m)
: super_memory(&(const_cast<self&>(m)[0][0]), size(m)), expr_base(*this)
{
set_ranges(m.num_rows(), m.num_cols());
// std::cout << "In copy constructor:\n"; print_matrix(*this);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -