rework sum(sp_mat) to produce dense vectors by default

This commit is contained in:
conrad
2024-04-09 13:37:13 +10:00
parent ba443e4bdc
commit 87c2b2d870
8 changed files with 39 additions and 52 deletions
+2 -2
View File
@@ -316,6 +316,7 @@ namespace arma
#include "armadillo_bits/op_rcond_bones.hpp"
#include "armadillo_bits/op_sp_plus_bones.hpp"
#include "armadillo_bits/op_sp_minus_bones.hpp"
#include "armadillo_bits/op_sp_sum_bones.hpp"
#include "armadillo_bits/op_powmat_bones.hpp"
#include "armadillo_bits/op_rank_bones.hpp"
#include "armadillo_bits/op_row_as_mat_bones.hpp"
@@ -354,7 +355,6 @@ namespace arma
#include "armadillo_bits/spop_max_bones.hpp"
#include "armadillo_bits/spop_min_bones.hpp"
#include "armadillo_bits/spop_sum_bones.hpp"
#include "armadillo_bits/spop_strans_bones.hpp"
#include "armadillo_bits/spop_htrans_bones.hpp"
#include "armadillo_bits/spop_misc_bones.hpp"
@@ -764,6 +764,7 @@ namespace arma
#include "armadillo_bits/op_rcond_meat.hpp"
#include "armadillo_bits/op_sp_plus_meat.hpp"
#include "armadillo_bits/op_sp_minus_meat.hpp"
#include "armadillo_bits/op_sp_sum_meat.hpp"
#include "armadillo_bits/op_powmat_meat.hpp"
#include "armadillo_bits/op_rank_meat.hpp"
#include "armadillo_bits/op_row_as_mat_meat.hpp"
@@ -802,7 +803,6 @@ namespace arma
#include "armadillo_bits/spop_max_meat.hpp"
#include "armadillo_bits/spop_min_meat.hpp"
#include "armadillo_bits/spop_sum_meat.hpp"
#include "armadillo_bits/spop_strans_meat.hpp"
#include "armadillo_bits/spop_htrans_meat.hpp"
#include "armadillo_bits/spop_misc_meat.hpp"
+1 -2
View File
@@ -140,8 +140,7 @@ class SpMat : public SpBase< eT, SpMat<eT> >
template<typename T1> inline SpMat& operator/=(const Op<T1, op_diagmat>& expr);
template<typename T1> inline SpMat& operator%=(const Op<T1, op_diagmat>& expr);
//! explicit specification of sparse +/- scalar
template<typename T1, typename op_type> inline explicit SpMat(const SpToDOp<T1, op_type>& expr);
template<typename T1, typename op_type> inline SpMat(const SpToDOp<T1, op_type>& expr);
//! construction of complex matrix out of two non-complex matrices
template<typename T1, typename T2>
+3 -3
View File
@@ -802,12 +802,12 @@ SpMat<eT>::SpMat(const SpToDOp<T1, op_type>& expr)
{
arma_extra_debug_sigprint_this(this);
typedef typename T1::elem_type T;
typedef typename T1::elem_type T1_eT;
// Make sure the type is compatible.
arma_type_check(( is_same_type< eT, T >::no ));
arma_type_check(( is_same_type< eT, T1_eT >::no ));
op_type::apply(*this, expr);
(*this) = Mat<eT>(expr);
}
+3
View File
@@ -42,10 +42,13 @@ class SpToDOp : public Base< typename T1::elem_type, SpToDOp<T1, op_type> >
inline explicit SpToDOp(const T1& in_m);
inline SpToDOp(const T1& in_m, const elem_type in_aux);
inline SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
inline ~SpToDOp();
arma_aligned const T1& m; //!< the operand; must be derived from SpBase
arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1
arma_aligned uword aux_uword_a; //!< auxiliary data, uword format
arma_aligned uword aux_uword_b; //!< auxiliary data, uword format
static constexpr bool is_row = op_type::template traits<T1>::is_row;
static constexpr bool is_col = op_type::template traits<T1>::is_col;
+12
View File
@@ -42,6 +42,18 @@ SpToDOp<T1, op_type>::SpToDOp(const T1& in_m, const typename T1::elem_type in_au
template<typename T1, typename op_type>
inline
SpToDOp<T1, op_type>::SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
: m(in_m)
, aux_uword_a(in_aux_uword_a)
, aux_uword_b(in_aux_uword_b)
{
arma_extra_debug_sigprint();
}
template<typename T1, typename op_type>
inline
SpToDOp<T1, op_type>::~SpToDOp()
+4 -4
View File
@@ -115,13 +115,13 @@ typename
enable_if2
<
is_arma_sparse_type<T1>::value && resolves_to_sparse_vector<T1>::no,
const SpOp<T1,spop_sum>
const SpToDOp<T1,op_sp_sum>
>::result
sum(const T1& x)
{
arma_extra_debug_sigprint();
return SpOp<T1,spop_sum>(x, 0, 0);
return SpToDOp<T1,op_sp_sum>(x, 0, 0);
}
@@ -133,13 +133,13 @@ typename
enable_if2
<
is_arma_sparse_type<T1>::value,
const SpOp<T1,spop_sum>
const SpToDOp<T1,op_sp_sum>
>::result
sum(const T1& x, const uword dim)
{
arma_extra_debug_sigprint();
return SpOp<T1,spop_sum>(x, dim, 0);
return SpToDOp<T1,op_sp_sum>(x, dim, 0);
}
@@ -16,18 +16,11 @@
// ------------------------------------------------------------------------
//! \addtogroup spop_sum
//! @{
class spop_sum
class op_sp_sum
: public traits_op_xvec
{
public:
template<typename T1>
inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_sum>& in);
inline static void apply(Mat<typename T1::elem_type>& out, const SpToDOp<T1, op_sp_sum>& in);
};
//! @}
@@ -16,21 +16,18 @@
// ------------------------------------------------------------------------
//! \addtogroup spop_sum
//! @{
template<typename T1>
inline
void
spop_sum::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_sum>& in)
op_sp_sum::apply(Mat<typename T1::elem_type>& out, const SpToDOp<T1,op_sp_sum>& in)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const uword dim = in.aux_uword_a;
arma_debug_check( (dim > 1), "sum(): parameter 'dim' must be 0 or 1" );
const SpProxy<T1> p(in.m);
@@ -38,29 +35,24 @@ spop_sum::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_sum>& in)
const uword p_n_rows = p.get_n_rows();
const uword p_n_cols = p.get_n_cols();
if(p.get_n_nonzero() == 0)
{
if(dim == 0) { out.zeros(1,p_n_cols); }
if(dim == 1) { out.zeros(p_n_rows,1); }
return;
}
if(dim == 0) { out.zeros(1, p_n_cols); }
if(dim == 1) { out.zeros(p_n_rows, 1); }
if(p.get_n_nonzero() == 0) { return; }
eT* out_mem = out.memptr();
if(dim == 0) // find the sum in each column
{
Row<eT> acc(p_n_cols, arma_zeros_indicator());
eT* acc_mem = acc.memptr();
if(SpProxy<T1>::use_iterator)
{
typename SpProxy<T1>::const_iterator_type it = p.begin();
const uword N = p.get_n_nonzero();
for(uword i=0; i < N; ++i)
{
acc_mem[it.col()] += (*it);
out_mem[it.col()] += (*it);
++it;
}
}
@@ -68,37 +60,25 @@ spop_sum::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_sum>& in)
{
for(uword col = 0; col < p_n_cols; ++col)
{
acc_mem[col] = arrayops::accumulate
out_mem[col] = arrayops::accumulate
(
&p.get_values()[p.get_col_ptrs()[col]],
p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col]
);
}
}
out = acc;
}
else
if(dim == 1) // find the sum in each row
{
Col<eT> acc(p_n_rows, arma_zeros_indicator());
eT* acc_mem = acc.memptr();
typename SpProxy<T1>::const_iterator_type it = p.begin();
const uword N = p.get_n_nonzero();
for(uword i=0; i < N; ++i)
{
acc_mem[it.row()] += (*it);
out_mem[it.row()] += (*it);
++it;
}
out = acc;
}
}
//! @}