Files
armadillo-code/include/armadillo_bits/spop_relational_meat.hpp
T
2024-06-24 23:10:25 +10:00

522 lines
11 KiB
C++

// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
// Copyright 2008-2016 National ICT Australia (NICTA)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
//! \addtogroup spop_relational
//! @{
// NOTE: in general, relational operations between sparse matrices and scalars
// NOTE: have the risk of producing sparse matrices with most elements as non-zeros.
// NOTE: these operations should only be used as an argument to the accu() function,
// NOTE: which aims to omit the generation of intermediate sparse matrices.
#undef operator_rel
#undef arma_applier_spmat_pre
#undef arma_applier_spmat_post
#define arma_applier_spmat_pre(operator_rel)\
{\
const uword zero_comp_val = (k operator_rel eT(0)) ? uword(1) : uword(0);\
\
const uword n_cols = A.n_cols;\
const uword n_rows = A.n_rows;\
const uword n_elem = A.n_elem;\
\
Mat<uword> tmp(n_rows, n_cols);\
\
typename SpMat<eT>::const_iterator it = A.begin();\
typename SpMat<eT>::const_iterator it_end = A.end();\
\
uword last_pos = 0;\
uword offset = 0;\
\
for(; it != it_end; ++it)\
{\
const uword cur_pos = it.row() + n_rows * it.col();\
\
if((cur_pos - last_pos) > offset)\
{\
arrayops::inplace_set( (tmp.memptr() + last_pos + offset), zero_comp_val, (cur_pos - last_pos - offset) );\
}\
\
tmp.at(cur_pos) = (k operator_rel (*it)) ? uword(1) : uword(0);\
\
last_pos = cur_pos;\
offset = 1;\
}\
\
if(last_pos < n_elem)\
{\
arrayops::inplace_set( (tmp.memptr() + last_pos + offset), zero_comp_val, (n_elem - last_pos - offset) );\
}\
\
out = tmp;\
}
#define arma_applier_spmat_post(operator_rel)\
{\
const uword zero_comp_val = (eT(0) operator_rel k) ? uword(1) : uword(0);\
\
const uword n_cols = A.n_cols;\
const uword n_rows = A.n_rows;\
const uword n_elem = A.n_elem;\
\
Mat<uword> tmp(n_rows, n_cols);\
\
typename SpMat<eT>::const_iterator it = A.begin();\
typename SpMat<eT>::const_iterator it_end = A.end();\
\
uword last_pos = 0;\
uword offset = 0;\
\
for(; it != it_end; ++it)\
{\
const uword cur_pos = it.row() + n_rows * it.col();\
\
if((cur_pos - last_pos) > offset)\
{\
arrayops::inplace_set( (tmp.memptr() + last_pos + offset), zero_comp_val, (cur_pos - last_pos - offset) );\
}\
\
tmp.at(cur_pos) = ((*it) operator_rel k) ? uword(1) : uword(0);\
\
last_pos = cur_pos;\
offset = 1;\
}\
\
if(last_pos < n_elem)\
{\
arrayops::inplace_set( (tmp.memptr() + last_pos + offset), zero_comp_val, (n_elem - last_pos - offset) );\
}\
\
out = tmp;\
}
template<typename T1>
inline
void
spop_rel_lt_pre::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_lt_pre>& X)
{
arma_debug_sigprint();
// operation: scalar < spmat
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k > eT(0))
{
arma_debug_print("optimisation: k > 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( k < (*it) ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_pre( < );
}
}
template<typename T1>
inline
void
spop_rel_gt_pre::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_gt_pre>& X)
{
arma_debug_sigprint();
// operation: scalar > spmat
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k < eT(0))
{
arma_debug_print("optimisation: k < 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( k > (*it) ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_pre( > );
}
}
template<typename T1>
inline
void
spop_rel_lteq_pre::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_lteq_pre>& X)
{
arma_debug_sigprint();
// operation: scalar <= spmat
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k > eT(0))
{
arma_debug_print("optimisation: k > 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( k <= (*it) ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_pre( <= );
}
}
template<typename T1>
inline
void
spop_rel_gteq_pre::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_gteq_pre>& X)
{
arma_debug_sigprint();
// operation: scalar >= spmat
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k < eT(0))
{
arma_debug_print("optimisation: k < 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( k >= (*it) ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_pre( >= );
}
}
template<typename T1>
inline
void
spop_rel_lt_post::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_lt_post>& X)
{
arma_debug_sigprint();
// operation: spmat < scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k < eT(0))
{
arma_debug_print("optimisation: k < 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( (*it) < k ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( < );
}
}
template<typename T1>
inline
void
spop_rel_gt_post::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_gt_post>& X)
{
arma_debug_sigprint();
// operation: spmat > scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k > eT(0))
{
arma_debug_print("optimisation: k > 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( (*it) > k ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( > );
}
}
template<typename T1>
inline
void
spop_rel_lteq_post::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_lteq_post>& X)
{
arma_debug_sigprint();
// operation: spmat <= scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k < eT(0))
{
arma_debug_print("optimisation: k < 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( (*it) <= k ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( <= );
}
}
template<typename T1>
inline
void
spop_rel_gteq_post::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_gteq_post>& X)
{
arma_debug_sigprint();
// operation: spmat >= scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k > eT(0))
{
arma_debug_print("optimisation: k > 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( (*it) >= k ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( >= );
}
}
template<typename T1>
inline
void
spop_rel_eq::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_eq>& X)
{
arma_debug_sigprint();
// operation: spmat == scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k != eT(0))
{
arma_debug_print("optimisation: k != 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
if( (*it) == k ) { tmp.at(it.row(), it.col()) = uword(1); }
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( == );
}
}
template<typename T1>
inline
void
spop_rel_noteq::apply(SpMat<uword>& out, const mtSpOp<uword, T1, spop_rel_noteq>& X)
{
arma_debug_sigprint();
// operation: spmat != scalar
typedef typename T1::elem_type eT;
const eT k = X.aux;
const unwrap_spmat<T1> U(X.m);
const SpMat<eT>& A = U.M;
if(k == eT(0))
{
arma_debug_print("optimisation: k = 0");
SpMat<uword> tmp(A.n_rows, A.n_cols);
typename SpMat<eT>::const_iterator it = A.begin();
typename SpMat<eT>::const_iterator it_end = A.end();
for(; it != it_end; ++it)
{
tmp.at(it.row(), it.col()) = uword(1);
}
out.steal_mem(tmp);
}
else
{
arma_applier_spmat_post( != );
}
}
#undef arma_applier_spmat_pre
#undef arma_applier_spmat_post
//! @}