[shark] 59/79: rewrote const_closure_Type generation of proxies. This is now by default Proxy<M> -> Proxy<const_expression<M>::type >. The old behaviour was Proxy<M>->Proxy<M const> const which, for nested proxies does not enforce read-onlyness due to proxy semantics (which behave more like references or pointers)
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Nov 26 15:41:02 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch master
in repository shark.
commit 9b913786663e4b0859f57c338faf8e53dfd413ee
Author: Oswin <oswin.krause at di.ku.dk>
Date: Mon Oct 26 08:19:51 2015 +0100
rewrote const_closure_Type generation of proxies. This is now by default Proxy<M> -> Proxy<const_expression<M>::type >. The old behaviour was Proxy<M>->Proxy<M const> const which, for nested proxies does not enforce read-onlyness due to proxy semantics (which behave more like references or pointers)
---
include/shark/LinAlg/BLAS/matrix_proxy.hpp | 287 +++++++++++++++++++----------
1 file changed, 189 insertions(+), 98 deletions(-)
diff --git a/include/shark/LinAlg/BLAS/matrix_proxy.hpp b/include/shark/LinAlg/BLAS/matrix_proxy.hpp
index ad08b93..5e6395e 100644
--- a/include/shark/LinAlg/BLAS/matrix_proxy.hpp
+++ b/include/shark/LinAlg/BLAS/matrix_proxy.hpp
@@ -56,7 +56,7 @@ public:
typedef typename M::const_index_pointer const_index_pointer;
typedef typename index_pointer<M>::type index_pointer;
- typedef const self_type const_closure_type;
+ typedef matrix_reference<M const> const_closure_type;
typedef self_type closure_type;
typedef typename M::orientation orientation;
typedef typename M::storage_category storage_category;
@@ -64,10 +64,10 @@ public:
// Construction and destruction
- matrix_reference(M& m):
- m_expression(&m) {}
-
- matrix_reference(matrix_reference const& ref):m_expression(ref.m_expression) {}
+ matrix_reference(M& m):m_expression(&m) {}
+ template<class E>
+ matrix_reference(matrix_reference<E> const& other)
+ :m_expression(&other.expression()){}
// Accessors
@@ -272,18 +272,30 @@ public:
typedef typename index_pointer<M>::type index_pointer;
typedef typename closure<M>::type matrix_closure_type;
- typedef const matrix_transpose<M> const_closure_type;
+ typedef matrix_transpose<typename const_expression<M>::type> const_closure_type;
typedef matrix_transpose<M> closure_type;
typedef typename M::orientation::transposed_orientation orientation;
typedef typename M::storage_category storage_category;
typedef elementwise_tag evaluation_category;
// Construction and destruction
- explicit matrix_transpose(matrix_closure_type m):
+ explicit matrix_transpose(matrix_closure_type const& m):
m_expression(m) {}
+
+ //conversion closure->const_closure
+ template<class E>
+ matrix_transpose(
+ matrix_transpose<E> const& m,
+ typename boost::disable_if<
+ boost::mpl::or_<
+ boost::is_same<matrix_transpose<E>,matrix_transpose>,
+ boost::is_same<matrix_transpose<E>,matrix_closure_type>
+ >
+ >::type* dummy = 0
+ ):m_expression(m.expression()) {}
// Expression accessors
- matrix_closure_type expression() const{
+ matrix_closure_type const& expression() const{
return m_expression;
}
matrix_closure_type expression(){
@@ -456,8 +468,9 @@ private:
// (trans m) [i] [j] = m [j] [i]
template<class M>
-matrix_transpose<M const> trans(matrix_expression<M> const& m) {
- return matrix_transpose<M const>(m());
+matrix_transpose<typename const_expression<M>::type >
+trans(matrix_expression<M> const& m) {
+ return matrix_transpose<typename const_expression<M>::type>(m());
}
template<class M>
temporary_proxy< matrix_transpose<M> > trans(matrix_expression<M>& m) {
@@ -472,6 +485,7 @@ temporary_proxy< matrix_transpose<M> > trans(temporary_proxy<M> m) {
template<class M>
class matrix_row: public vector_expression<matrix_row<M> > {
typedef matrix_row<M> self_type;
+
public:
typedef M matrix_type;
typedef std::size_t size_type;
@@ -488,7 +502,7 @@ public:
typedef typename index_pointer<M>::type index_pointer;
typedef typename closure<M>::type matrix_closure_type;
- typedef const self_type const_closure_type;
+ typedef matrix_row<typename const_expression<M>::type> const_closure_type;
typedef self_type closure_type;
typedef typename M::storage_category storage_category;
typedef elementwise_tag evaluation_category;
@@ -498,6 +512,10 @@ public:
SIZE_CHECK (i < expression.size1());
}
+ template<class E>
+ matrix_row(matrix_row<E> const& other)
+ :m_expression(other.expression()),m_i(other.index()){}
+
matrix_closure_type const& expression() const {
return m_expression;
}
@@ -671,8 +689,9 @@ temporary_proxy< matrix_row<M> > row(matrix_expression<M>& expression, typename
return matrix_row<M> (expression(), i);
}
template<class M>
-const matrix_row<M const> row(matrix_expression<M> const& expression, typename M::index_type i) {
- return matrix_row<M const> (expression(), i);
+matrix_row<typename const_expression<M>::type>
+row(matrix_expression<M> const& expression, typename M::index_type i) {
+ return matrix_row<typename const_expression<M>::type> (expression(), i);
}
template<class M>
@@ -681,19 +700,9 @@ temporary_proxy<matrix_row<M> > row(temporary_proxy<M> expression, typename M::i
}
template<class M>
-class matrix_column:
- public vector_expression<matrix_column<M> >
-{
+class matrix_column: public vector_expression<matrix_column<M> > {
typedef matrix_column<M> self_type;
- typedef matrix_row<matrix_transpose<M> > wrapper_type;
- // if the argument in the ctor is not M but matrix_reference<M> we need to strip it
- M& strip_reference( M& m){
- return m;
- }
- M& strip_reference( matrix_reference<M> m){
- return m.expression();
- }
public:
typedef M matrix_type;
typedef std::size_t size_type;
@@ -710,39 +719,44 @@ public:
typedef typename index_pointer<M>::type index_pointer;
typedef typename closure<M>::type matrix_closure_type;
- typedef const self_type const_closure_type;
+ typedef matrix_column<typename const_expression<M>::type> const_closure_type;
typedef self_type closure_type;
typedef typename M::storage_category storage_category;
typedef elementwise_tag evaluation_category;
// Construction and destruction
- matrix_column(matrix_closure_type expression, index_type j)
- :m_wrapper(trans(strip_reference(expression)), j) {}
-
-
- // Storage accessors
- const matrix_closure_type& expression() const {
- return m_wrapper.expression().expression();
+ matrix_column(matrix_closure_type const& expression, index_type j)
+ :m_expression(expression), m_j(j) {
+ SIZE_CHECK (j < expression.size2());
+ }
+
+ template<class E>
+ matrix_column(matrix_column<E> const& other)
+ :m_expression(other.expression()),m_j(other.index()){}
+
+ matrix_closure_type const& expression() const {
+ return m_expression;
}
matrix_closure_type& expression() {
- return m_wrapper.expression().expression();
+ return m_expression;
}
+
index_type index() const {
- return m_wrapper.index();
+ return m_j;
}
- // ---------
- // Dense low level interface
- // ---------
-
///\brief Returns the size of the vector
size_type size() const {
- return m_wrapper.size();
+ return expression().size1();
}
+
+ // ---------
+ // Dense low level interface
+ // ---------
///\brief Returns the stride in memory between two elements
difference_type stride()const{
- return m_wrapper.stride();
+ return expression().stride1();
}
///\brief Returns the pointer to the beginning of the vector storage
@@ -750,93 +764,141 @@ public:
/// Grants low-level access to the vector internals.
/// to access element i use storage()[i*stride()].
pointer storage()const{
- return m_wrapper.storage();
+ return expression().storage()+index()*expression().stride2();
}
// ---------
// Sparse low level interface
// ---------
- /// \brief Number of nonzero elements of the vector.
- size_type nnz()const{
- return m_wrapper.nnz();
- }
- /// \brief Array of values of the nonzero elements.
- const_pointer values()const{
- return m_wrapper.values();
- }
+ //~ /// \brief Number of nonzero elements of the vector.
+ //~ size_type nnz()const{
+ //~ return expression().inner_nnz(m_i);
+ //~ }
+ //~ /// \brief Array of values of the nonzero elements.
+ //~ const_pointer values()const{
+ //~ return expression().values()+expression().outer_indices()[m_i];
+ //~ }
- /// \brief Array of indices of the nonzero elements.
- index_pointer indices()const{
- return m_wrapper.indices();
- }
+ //~ /// \brief Array of indices of the nonzero elements.
+ //~ index_pointer indices()const{
+ //~ return expression().inner_indices()+expression().outer_indices()[m_i];
+ //~ }
// ---------
// High level interface
// ---------
-
+
// Element access
reference operator()(index_type i) const {
- return m_wrapper(i);
+ return m_expression(i,m_j);
}
reference operator [](index_type i) const {
- return m_wrapper[i];
+ return (*this)(i);
}
void set_element(size_type i,value_type t){
- m_wrapper.set_element(i,t);
+ expression().set_element(i,m_j,t);
}
// Assignment
template<class E>
matrix_column& operator = (vector_expression<E> const& e) {
- m_wrapper = e();
- return *this;
+ return assign(*this, typename vector_temporary<M>::type(e));
}
matrix_column& operator = (matrix_column const& e) {
- m_wrapper = e;
- return *this;
+ return assign(*this, typename vector_temporary<M>::type(e));
}
-
+
// Iterator types
- typedef typename wrapper_type::const_iterator const_iterator;
- typedef typename wrapper_type::iterator iterator;
+ typedef typename M::const_column_iterator const_iterator;
+ typedef typename column_iterator<M>::type iterator;
iterator begin() {
- return m_wrapper.begin();
+ return expression().column_begin(m_j);
}
iterator end() {
- return m_wrapper.end();
+ return expression().column_end(m_j);
}
const_iterator begin()const{
- return m_wrapper.begin();
+ return expression().column_begin(m_j);
}
const_iterator end()const{
- return m_wrapper.end();
+ return expression().column_end(m_j);
}
iterator set_element(iterator pos, index_type index, value_type value) {
- return m_wrapper.set_element(pos,index,value);
+ return set_element(pos, index, value,
+ typename M::orientation(), typename iterator::iterator_category()
+ );
}
iterator clear_range(iterator start, iterator end) {
- return m_wrapper.clear_range(start,end);
+ return clear_range(start,end,
+ typename M::orientation(), typename iterator::iterator_category()
+ );
}
iterator clear_element(iterator pos) {
- return m_wrapper.clear_element(pos);
+ return clear_element(pos,
+ typename M::orientation(), typename iterator::iterator_category()
+ );
}
void clear(){
- return m_wrapper.clear();
+ clear_range(begin(),end());
}
- void reserve(size_type non_zeros) {
- m_wrapper.reserve(non_zeros);
- }
+ //~ void reserve(size_type non_zeros) {
+ //~ expression().reserve_row(m_i,non_zeros);
+ //~ }
+
private:
- wrapper_type m_wrapper;
+ //we need two implementations of the sparse-interface,
+ //depending on whether M is row or column major.
+
+ //column major case is trivial
+ template<class Tag>
+ iterator set_element(iterator pos, index_type index, value_type value, column_major, Tag) {
+ return expression().set_element(pos,index,value);
+ }
+ template<class Tag>
+ iterator clear_range(iterator start, iterator end, column_major, Tag) {
+ return expression().clear_range(start,end);
+ }
+ template<class Tag>
+ iterator clear_element(iterator pos, column_major, Tag) {
+ return expression().clear_element(pos);
+ }
+ //dense row major case
+ iterator set_element(iterator pos, index_type index, value_type value,
+ row_major,
+ dense_random_access_iterator_tag
+ ) {
+ RANGE_CHECK(pos.index() == index);
+ *pos = value;
+ return pos;
+ }
+
+ iterator clear_element(iterator pos,
+ row_major m,
+ dense_random_access_iterator_tag t
+ ) {
+ return set_element(pos,pos.index(),value_type(),m,t);
+ }
+ iterator clear_range(iterator start, iterator end,
+ row_major m,
+ dense_random_access_iterator_tag t
+ ) {
+ for(;start != end; ++start)
+ clear_element(start,m,t);
+ return end;
+ }
+ //todo: sparse column major case.
+
+ matrix_closure_type m_expression;
+ size_type m_j;
};
// Projections
@@ -845,8 +907,9 @@ temporary_proxy<matrix_column<M> > column(matrix_expression<M>& expression, type
return matrix_column<M> (expression(), j);
}
template<class M>
-matrix_column<M const> column(matrix_expression<M> const& expression, typename M::index_type j) {
- return matrix_column<M const> (expression(), j);
+matrix_column<typename const_expression<M>::type>
+column(matrix_expression<M> const& expression, typename M::index_type j) {
+ return matrix_column<typename const_expression<M>::type> (expression(), j);
}
template<class M>
@@ -876,7 +939,7 @@ public:
typedef typename index_pointer<M>::type index_pointer;
typedef typename closure<M>::type matrix_closure_type;
- typedef const self_type const_closure_type;
+ typedef matrix_vector_range<typename const_expression<M>::type> const_closure_type;
typedef self_type closure_type;
typedef typename M::storage_category storage_category;
typedef elementwise_tag evaluation_category;
@@ -890,6 +953,10 @@ public:
SIZE_CHECK (m_range2.start() + m_range2.size() <= expression.size2());
SIZE_CHECK (m_range1.size() == m_range2.size());
}
+
+ template<class E>
+ matrix_vector_range(matrix_vector_range<E> const& other)
+ :m_expression(other.expression()),m_range1(other.range1()),m_range2(other.range2()){}
// Accessors
size_type start1() const {
@@ -906,6 +973,13 @@ public:
return m_expression;
}
+ range const& range1() const{
+ return m_range1;
+ }
+ range const& range2() const{
+ return m_range2;
+ }
+
// ---------
// Dense low level interface
// ---------
@@ -989,10 +1063,10 @@ private:
///
/// the diag operation results in
/// diag(A) = (1,5,9)
-template<class Matrix>
-matrix_vector_range<Matrix const> diag(matrix_expression<Matrix> const& mat){
+template<class M>
+matrix_vector_range<typename const_expression<M>::type > diag(matrix_expression<M> const& mat){
SIZE_CHECK(mat().size1() == mat().size2());
- matrix_vector_range<Matrix const> diagonal(mat(),range(0,mat().size1()),range(0,mat().size1()));
+ matrix_vector_range<typename const_expression<M>::type > diagonal(mat(),range(0,mat().size1()),range(0,mat().size1()));
return diagonal;
}
@@ -1005,16 +1079,16 @@ matrix_vector_range<Matrix const> diag(matrix_expression<Matrix> const& mat){
///
/// the diag operation results in
/// diag(A) = (1,5,9)
-template<class Matrix>
-temporary_proxy< matrix_vector_range<Matrix> > diag(matrix_expression<Matrix>& mat){
+template<class M>
+temporary_proxy< matrix_vector_range<M> > diag(matrix_expression<M>& mat){
SIZE_CHECK(mat().size1() == mat().size2());
- matrix_vector_range<Matrix> diagonal(mat(),range(0,mat().size1()),range(0,mat().size1()));
+ matrix_vector_range<M> diagonal(mat(),range(0,mat().size1()),range(0,mat().size1()));
return diagonal;
}
-template<class Matrix>
-temporary_proxy< matrix_vector_range<Matrix> > diag(temporary_proxy<Matrix> mat){
- return diag(static_cast<Matrix&>(mat));
+template<class M>
+temporary_proxy< matrix_vector_range<M> > diag(temporary_proxy<M> mat){
+ return diag(static_cast<M&>(mat));
}
// Matrix based range class
@@ -1037,7 +1111,7 @@ public:
typedef typename index_pointer<M>::type index_pointer;
typedef typename closure<M>::type matrix_closure_type;
- typedef const self_type const_closure_type;
+ typedef matrix_range<typename const_expression<M>::type> const_closure_type;
typedef self_type closure_type;
typedef typename M::storage_category storage_category;
typedef elementwise_tag evaluation_category;
@@ -1052,7 +1126,18 @@ public:
SIZE_CHECK(r2.start() <= expression.size2());
SIZE_CHECK(r2.start() +r2.size() <= expression.size2());
}
-
+
+ //conversion closure->const_closure
+ template<class E>
+ matrix_range(
+ matrix_range<E> const& other,
+ typename boost::disable_if<
+ boost::is_same<E,matrix_range>
+ >::type* dummy = 0
+ ):m_expression(other.expression())
+ , m_range1(other.range1())
+ , m_range2(other.range2()){}
+
// Accessors
size_type start1() const {
return m_range1.start();
@@ -1068,6 +1153,13 @@ public:
return m_expression;
}
+ range const& range1() const{
+ return m_range1;
+ }
+ range const& range2() const{
+ return m_range2;
+ }
+
// ---------
// Dense Low level interface
// ---------
@@ -1215,7 +1307,7 @@ temporary_proxy< matrix_range<M> > subrange(
return matrix_range<M> (expression(), range(start1, stop1), range(start2, stop2));
}
template<class M>
-matrix_range<M const> subrange(
+matrix_range<typename const_expression<M>::type> subrange(
matrix_expression<M> const& expression,
std::size_t start1, std::size_t stop1,
std::size_t start2, std::size_t stop2
@@ -1224,7 +1316,7 @@ matrix_range<M const> subrange(
RANGE_CHECK(start2 <= stop2);
SIZE_CHECK(stop1 <= expression().size1());
SIZE_CHECK(stop2 <= expression().size2());
- return matrix_range<M const> (expression(), range(start1, stop1), range(start2, stop2));
+ return matrix_range<typename const_expression<M>::type> (expression(), range(start1, stop1), range(start2, stop2));
}
template<class M>
@@ -1247,7 +1339,7 @@ temporary_proxy<matrix_range<M> > rows(
}
template<class M>
-matrix_range<M const> rows(
+matrix_range<typename const_expression<M>::type> rows(
matrix_expression<M> const& expression,
std::size_t start, std::size_t stop
) {
@@ -1275,7 +1367,7 @@ temporary_proxy< matrix_range<M> > columns(
}
template<class M>
-matrix_range<M const> columns(
+matrix_range<typename const_expression<M>::type> columns(
matrix_expression<M> const& expression,
typename M::index_type start, typename M::index_type stop
) {
@@ -1313,7 +1405,7 @@ public:
typedef index_type* index_pointer;
//ublas types
- typedef matrix_reference<self_type const> const const_closure_type;
+ typedef matrix_reference<self_type const> const_closure_type;
typedef matrix_reference<self_type> closure_type;
typedef dense_tag storage_category;
typedef elementwise_tag evaluation_category;
@@ -1321,14 +1413,13 @@ public:
// Construction and destruction
- dense_matrix_adaptor(dense_matrix_adaptor const& expression)
+ dense_matrix_adaptor(dense_matrix_adaptor<value_type, Orientation> const& expression)
: m_values(expression.storage())
, m_size1(expression.size1())
, m_size2(expression.size2())
, m_stride1(expression.stride1())
, m_stride2(expression.stride2())
- {
- }
+ {}
/// \brief Constructor of a self_type proxy from a Dense MatrixExpression
///
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/shark.git
More information about the debian-science-commits
mailing list