handle all conditions in one function
This commit is contained in:
@@ -129,6 +129,17 @@ class spop_htrans;
|
||||
class spop_vectorise_row;
|
||||
class spop_vectorise_col;
|
||||
|
||||
class spop_rel_lt_pre;
|
||||
class spop_rel_lt_post;
|
||||
class spop_rel_gt_pre;
|
||||
class spop_rel_gt_post;
|
||||
class spop_rel_lteq_pre;
|
||||
class spop_rel_lteq_post;
|
||||
class spop_rel_gteq_pre;
|
||||
class spop_rel_gteq_post;
|
||||
class spop_rel_eq;
|
||||
class spop_rel_noteq;
|
||||
|
||||
class spglue_plus;
|
||||
class spglue_minus;
|
||||
class spglue_schur;
|
||||
|
||||
@@ -1111,18 +1111,15 @@ accu(const SpOp<T1, spop_type>& expr)
|
||||
|
||||
|
||||
|
||||
// optimisations for sparse relational operations
|
||||
|
||||
|
||||
template<typename T1>
|
||||
template<typename T1, typename spop_type>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_lt_pre>& X)
|
||||
accu(const mtSpOp<uword,T1,spop_type>& X, const typename arma_spop_rel_only<spop_type>::result* junk1 = nullptr, const typename arma_not_cx<typename T1::elem_type>::result* junk2 = nullptr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(scalar < spmat)
|
||||
arma_ignore(junk1);
|
||||
arma_ignore(junk2);
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
@@ -1132,29 +1129,70 @@ accu(const mtSpOp<uword,T1,spop_rel_lt_pre>& X)
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
const eT zero = eT(0);
|
||||
|
||||
// shortcuts
|
||||
|
||||
if( (is_same_type<spop_type, spop_rel_eq >::yes) && (k == zero) ) { return n_zeros; }
|
||||
if( (is_same_type<spop_type, spop_rel_noteq>::yes) && (k == zero) ) { return P.get_n_nonzero(); }
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (k < eT(0)) ? n_zeros : 0;
|
||||
|
||||
bool use_n_zeros;
|
||||
|
||||
if(is_same_type<spop_type, spop_rel_eq >::yes) { use_n_zeros = (zero == k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_noteq >::yes) { use_n_zeros = (zero != k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_lt_pre >::yes) { use_n_zeros = (k < zero); }
|
||||
else if(is_same_type<spop_type, spop_rel_lt_post >::yes) { use_n_zeros = (zero < k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_gt_pre >::yes) { use_n_zeros = (k > zero); }
|
||||
else if(is_same_type<spop_type, spop_rel_gt_post >::yes) { use_n_zeros = (zero > k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_lteq_pre >::yes) { use_n_zeros = (k <= zero); }
|
||||
else if(is_same_type<spop_type, spop_rel_lteq_post>::yes) { use_n_zeros = (zero <= k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_gteq_pre >::yes) { use_n_zeros = (k >= zero); }
|
||||
else if(is_same_type<spop_type, spop_rel_gteq_post>::yes) { use_n_zeros = (zero >= k ); }
|
||||
else { use_n_zeros = false; }
|
||||
|
||||
uword count = (use_n_zeros) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += (k < (*it)) ? uword(1) : uword(0); }
|
||||
for(; it != it_end; ++it)
|
||||
{
|
||||
const eT val = (*it);
|
||||
|
||||
bool condition;
|
||||
|
||||
if(is_same_type<spop_type, spop_rel_eq >::yes) { condition = (val == k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_noteq >::yes) { condition = (val != k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_lt_pre >::yes) { condition = (k < val); }
|
||||
else if(is_same_type<spop_type, spop_rel_lt_post >::yes) { condition = (val < k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_gt_pre >::yes) { condition = (k > val); }
|
||||
else if(is_same_type<spop_type, spop_rel_gt_post >::yes) { condition = (val > k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_lteq_pre >::yes) { condition = (k <= val); }
|
||||
else if(is_same_type<spop_type, spop_rel_lteq_post>::yes) { condition = (val <= k ); }
|
||||
else if(is_same_type<spop_type, spop_rel_gteq_pre >::yes) { condition = (k >= val); }
|
||||
else if(is_same_type<spop_type, spop_rel_gteq_post>::yes) { condition = (val >= k ); }
|
||||
else { condition = false; }
|
||||
|
||||
count += (condition) ? uword(1) : uword(0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
template<typename T1, typename spop_type>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_gt_pre>& X)
|
||||
accu(const mtSpOp<uword,T1,spop_type>& X, const typename arma_spop_rel_only<spop_type>::result* junk1 = nullptr, const typename arma_cx_only<typename T1::elem_type>::result* junk2 = nullptr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(scalar > spmat)
|
||||
arma_ignore(junk1);
|
||||
arma_ignore(junk2);
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
@@ -1164,270 +1202,39 @@ accu(const mtSpOp<uword,T1,spop_rel_gt_pre>& X)
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
const eT zero = eT(0);
|
||||
|
||||
// shortcuts
|
||||
|
||||
if( (is_same_type<spop_type, spop_rel_eq >::yes) && (k == zero) ) { return n_zeros; }
|
||||
if( (is_same_type<spop_type, spop_rel_noteq>::yes) && (k == zero) ) { return P.get_n_nonzero(); }
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (k > eT(0)) ? n_zeros : 0;
|
||||
|
||||
bool use_n_zeros;
|
||||
|
||||
if(is_same_type<spop_type, spop_rel_eq >::yes) { use_n_zeros = (zero == k); }
|
||||
else if(is_same_type<spop_type, spop_rel_noteq>::yes) { use_n_zeros = (zero != k); }
|
||||
else { use_n_zeros = false; }
|
||||
|
||||
uword count = (use_n_zeros) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += (k > (*it)) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_lteq_pre>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(scalar <= spmat)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (k <= eT(0)) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += (k <= (*it)) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_gteq_pre>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(scalar >= spmat)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (k >= eT(0)) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += (k >= (*it)) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_lt_post>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat < scalar)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (eT(0) < k) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += ((*it) < k) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_gt_post>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat > scalar)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (eT(0) > k) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += ((*it) > k) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_lteq_post>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat <= scalar)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (eT(0) <= k) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += ((*it) <= k) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_gteq_post>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat >= scalar) ##
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
const uword n_zeros = P.get_n_elem() - P.get_n_nonzero();
|
||||
|
||||
// take into account all implicit zeros
|
||||
uword count = (eT(0) >= k) ? n_zeros : 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// take into account all non-zero elements
|
||||
for(; it != it_end; ++it) { count += ((*it) >= k) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_eq>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat == scalar)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
// accu(spmat == 0) -> number of zeros
|
||||
if(k == eT(0)) { return P.get_n_elem() - P.get_n_nonzero(); }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
for(; it != it_end; ++it) { count += ((*it) == k) ? uword(1) : uword(0); }
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
arma_warn_unused
|
||||
inline
|
||||
uword
|
||||
accu(const mtSpOp<uword,T1,spop_rel_noteq>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// operation: accu(spmat != scalar)
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
const eT k = X.aux;
|
||||
|
||||
const SpProxy<T1> P(X.m);
|
||||
|
||||
// accu(spmat != 0) -> number of non-zeros
|
||||
if(k == eT(0)) { return P.get_n_nonzero(); }
|
||||
|
||||
// start with worst-case scenario: all elements are not equal to k
|
||||
uword count = P.get_n_elem();
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type it = P.begin();
|
||||
typename SpProxy<T1>::const_iterator_type it_end = P.end();
|
||||
|
||||
// decrease the count by the number of elements that are equal to k
|
||||
for(; it != it_end; ++it) { count -= ((*it) == k) ? uword(1) : uword(0); }
|
||||
for(; it != it_end; ++it)
|
||||
{
|
||||
const eT val = (*it);
|
||||
|
||||
bool condition;
|
||||
|
||||
if(is_same_type<spop_type, spop_rel_eq >::yes) { condition = (val == k); }
|
||||
else if(is_same_type<spop_type, spop_rel_noteq>::yes) { condition = (val != k); }
|
||||
else { condition = false; }
|
||||
|
||||
count += (condition) ? uword(1) : uword(0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,21 @@ template<> struct arma_glue_rel_only< glue_rel_or > { typedef int result; };
|
||||
|
||||
|
||||
|
||||
template<typename T> struct arma_spop_rel_only { };
|
||||
|
||||
template<> struct arma_op_rel_only< spop_rel_lt_pre > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_lt_post > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_gt_pre > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_gt_post > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_lteq_pre > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_lteq_post > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_gteq_pre > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_gteq_post > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_eq > { typedef int result; };
|
||||
template<> struct arma_op_rel_only< spop_rel_noteq > { typedef int result; };
|
||||
|
||||
|
||||
|
||||
template<typename T> struct arma_Mat_Col_Row_only { };
|
||||
|
||||
template<typename eT> struct arma_Mat_Col_Row_only< Mat<eT> > { typedef Mat<eT> result; };
|
||||
|
||||
Reference in New Issue
Block a user