inline
arma_warn_unused
typename
enable_if2
  <(is_arma_sparse_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
   typename T1::elem_type
  >::result
dot
  (
  const SpBase<typename T1::elem_type, T1>& x,
  const SpBase<typename T2::elem_type, T2>& y
  )
  {
  arma_extra_debug_sigprint();

  const SpProxy<T1> pa(x.get_ref());
  const SpProxy<T2> pb(y.get_ref());

  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()");

  typedef typename T1::elem_type eT;

  if((&(x.get_ref()) == &(y.get_ref())) && (SpProxy<T1>::must_use_iterator == false))
    {
    // We can do it directly!
    return op_dot::direct_dot_arma(pa.get_n_nonzero(), pa.get_values(), pa.get_values());
    }
  else
    {
    // Iterate over both objects and see when they are the same
    eT result = eT(0);

    typename SpProxy<T1>::const_iterator_type a_it = pa.begin();
    typename SpProxy<T2>::const_iterator_type b_it = pb.begin();

    while((a_it.pos() < pa.get_n_nonzero()) && (b_it.pos() < pb.get_n_nonzero()))
      {
      if(a_it == b_it)
        {
        result += (*a_it) * (*b_it);

        ++a_it;
        ++b_it;
        }
      else if((a_it.col() < b_it.col()) || ((a_it.col() == b_it.col()) && (a_it.row() < b_it.row())))
        {
        // a_it is "behind"
        ++a_it;
        }
      else
        {
        // b_it is "behind"
        ++b_it;
        }
      }

    return result;
    }
  }
예제 #2
0
inline
const SpGlue<T1, T2, spglue_join_rows>
join_horiz(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B)
  {
  arma_extra_debug_sigprint();
  
  return SpGlue<T1, T2, spglue_join_rows>(A.get_ref(), B.get_ref());
  }
inline
const SpSubview<eT>&
SpSubview<eT>::operator/=(const SpBase<eT, T1>& x)
  {
  arma_extra_debug_sigprint();
  
  SpProxy<T1> p(x.get_ref());
  
  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
  
  if(p.is_alias(m) == false)
    {
    for(uword lcol = 0; lcol < n_cols; ++lcol)
    for(uword lrow = 0; lrow < n_rows; ++lrow)
      {
      at(lrow,lcol) /= p.at(lrow,lcol);
      }
    }
  else
    {
    const SpMat<eT> tmp(p.Q);
    
    (*this).operator/=(tmp);
    }
  
  return *this;
  }
inline
arma_warn_unused
typename
enable_if2
  <(is_arma_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
   typename T1::elem_type
  >::result
dot
  (
  const Base<typename T1::elem_type, T1>& x,
  const SpBase<typename T2::elem_type, T2>& y
  )
  {
  arma_extra_debug_sigprint();

  const Proxy<T1> pa(x.get_ref());
  const SpProxy<T2> pb(y.get_ref());

  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()");

  typedef typename T1::elem_type eT;

  eT result = eT(0);

  typename SpProxy<T2>::const_iterator_type it = pb.begin();

  // prefer_at_accessor won't save us operations
  while(it.pos() < pb.get_n_nonzero())
    {
    result += (*it) * pa.at(it.row(), it.col());
    ++it;
    }

  return result;
  }
예제 #5
0
arma_warn_unused
inline
Col<uword>
find(const SpBase<typename T1::elem_type,T1>& X, const uword k = 0)
  {
  arma_extra_debug_sigprint();
  
  const SpProxy<T1> P(X.get_ref());
  
  const uword n_rows = P.get_n_rows();
  const uword n_nz   = P.get_n_nonzero();
  
  Mat<uword> tmp(n_nz,1);
  
  uword* tmp_mem = tmp.memptr();
  
  typename SpProxy<T1>::const_iterator_type it = P.begin();
  
  for(uword i=0; i<n_nz; ++i)
    {
    const uword index = it.row() + it.col()*n_rows;
    
    tmp_mem[i] = index;
    
    ++it;
    }
  
  Col<uword> out;
  
  const uword count = (k == 0) ? uword(n_nz) : uword( (std::min)(n_nz, k) );
  
  out.steal_mem_col(tmp, count);
  
  return out;
  }
예제 #6
0
inline
void
op_nonzeros::apply_noalias(Mat<typename T1::elem_type>& out, const SpBase<typename T1::elem_type,T1>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const SpProxy<T1> P(X.get_ref());
  
  const uword N = P.get_n_nonzero();
  
  out.set_size(N,1);
  
  if(N > 0)
    {
    if(is_SpMat<typename SpProxy<T1>::stored_type>::value)
      {
      const unwrap_spmat<typename SpProxy<T1>::stored_type> U(P.Q);
      
      arrayops::copy(out.memptr(), U.M.values, N);
      }
    else
      {
      eT* out_mem = out.memptr();
      
      typename SpProxy<T1>::const_iterator_type it = P.begin();
      
      for(uword i=0; i<N; ++i)  { out_mem[i] = (*it); ++it; }
      }
    }
  }
예제 #7
0
inline
uword
n_unique
  (
  const SpBase<typename T1::elem_type, T1>& x,
  const SpBase<typename T2::elem_type, T2>& y,
  const op_n_unique_type junk
  )
  {
  arma_extra_debug_sigprint();
  
  const SpProxy<T1> pa(x.get_ref());
  const SpProxy<T2> pb(y.get_ref());
  
  return n_unique(pa,pb,junk);
  }
예제 #8
0
inline
arma_warn_unused
bool
is_finite(const SpBase<typename T1::elem_type,T1>& X)
  {
  arma_extra_debug_sigprint();
  
  const SpProxy<T1> P(X.get_ref());
  
  if(is_SpMat<typename SpProxy<T1>::stored_type>::value)
    {
    const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
    
    return tmp.M.is_finite();
    }
  else
    {
    typename SpProxy<T1>::const_iterator_type it     = P.begin();
    typename SpProxy<T1>::const_iterator_type it_end = P.end();
    
    while(it != it_end)
      {
      if(arma_isfinite(*it) == false)  { return false; }
      ++it;
      }
    }
  
  return true;
  }
예제 #9
0
inline
Mat<typename T1::elem_type>
spsolve
  (
  const SpBase<typename T1::elem_type, T1>& A,
  const   Base<typename T1::elem_type, T2>& B,
  const char*                          solver   = "superlu",
  const spsolve_opts_base&             settings = spsolve_opts_none(),
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::elem_type eT;
  
  Mat<eT> out;
  
  const bool status = spsolve_helper(out, A.get_ref(), B.get_ref(), solver, settings);
  
  if(status == false)
    {
    arma_bad("spsolve(): solution not found");
    }
  
  return out;
  }
inline
const SpSubview<eT>&
SpSubview<eT>::operator*=(const SpBase<eT, T1>& x)
  {
  arma_extra_debug_sigprint();

  return (*this).operator=( (*this) * x.get_ref() );
  }
arma_inline
const SpOp<T1, spop_repmat>
repmat(const SpBase<typename T1::elem_type,T1>& A, const uword r, const uword c)
  {
  arma_extra_debug_sigprint();

  return SpOp<T1, spop_repmat>(A.get_ref(), r, c);
  }
inline
const SpOp<T1, spop_reshape>
reshape(const SpBase<typename T1::elem_type, T1>& X, const SizeMat& s)
  {
  arma_extra_debug_sigprint();
  
  return SpOp<T1, spop_reshape>(X.get_ref(), s.n_rows, s.n_cols);
  }
예제 #13
0
arma_inline
const SpOp<T1, spop_sqrt>
sqrt(const SpBase<typename T1::elem_type,T1>& A)
  {
  arma_extra_debug_sigprint();
  
  return SpOp<T1, spop_sqrt>(A.get_ref());
  }
inline
const SpSubview<eT>&
SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
  {
  arma_extra_debug_sigprint();
  
  // TODO: implement dedicated machinery
  return (*this).operator=( (*this) % x.get_ref() );
  }
예제 #15
0
arma_inline
const SpOp<T1, spop_abs>
abs(const SpBase<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  return SpOp<T1, spop_abs>(X.get_ref());
  }
예제 #16
0
arma_inline
const mtSpOp<typename T1::pod_type, T1, spop_cx_abs>
abs(const SpBase< std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  return mtSpOp<typename T1::pod_type, T1, spop_cx_abs>(X.get_ref());
  }
예제 #17
0
arma_warn_unused
arma_inline
typename enable_if2< is_cx<typename T1::elem_type>::yes, const SpOp<T1, spop_symmat_cx> >::result
symmatl(const SpBase<typename T1::elem_type,T1>& X, const bool do_conj = true)
  {
  arma_extra_debug_sigprint();
  
  return SpOp<T1, spop_symmat_cx>(X.get_ref(), 1, (do_conj ? 1 : 0));
  }
예제 #18
0
inline
SpRow<eT>::SpRow(const SpBase<eT,T1>& X)
  {
  arma_extra_debug_sigprint();

  access::rw(SpMat<eT>::vec_state) = 2;
  
  SpMat<eT>::operator=(X.get_ref());
  }
예제 #19
0
arma_warn_unused
arma_inline
typename enable_if2< is_cx<typename T1::elem_type>::no, const SpOp<T1, spop_symmat> >::result
symmatl(const SpBase<typename T1::elem_type,T1>& X, const bool do_conj = false)
  {
  arma_extra_debug_sigprint();
  arma_ignore(do_conj);
  
  return SpOp<T1, spop_symmat>(X.get_ref(), 1, 0);
  }
예제 #20
0
inline
const SpRow<eT>&
SpRow<eT>::operator=(const SpBase<eT,T1>& X)
  {
  arma_extra_debug_sigprint();
  
  SpMat<eT>::operator=(X.get_ref());
  
  return *this;
  }
예제 #21
0
arma_warn_unused
inline
uword
size(const SpBase<typename T1::elem_type,T1>& X, const uword dim)
  {
  arma_extra_debug_sigprint();
  
  const SpProxy<T1> P(X.get_ref());
  
  return SizeMat( P.get_n_rows(), P.get_n_cols() )( dim );
  }
예제 #22
0
inline
const SpCol<eT>&
SpCol<eT>::operator=(const SpBase<eT,T1>& X)
  {
  arma_extra_debug_sigprint();

  access::rw(SpMat<eT>::vec_state) = 1;

  SpMat<eT>::operator=(X.get_ref());

  return *this;
  }
inline
const SpOp<T1,spop_htrans>
htrans
  (
  const SpBase<typename T1::elem_type, T1>& x,
  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  return SpOp<T1,spop_htrans>( x.get_ref() );
  }
예제 #24
0
arma_warn_unused
inline
const SpOp<T1, spop_reverse>
reverse
  (
  const SpBase<typename T1::elem_type,T1>& X,
  const uword dim = 0
  )
  {
  arma_extra_debug_sigprint();
  
  return SpOp<T1, spop_reverse>(X.get_ref(), dim, 0);
  }
예제 #25
0
arma_warn_unused
inline
Col<typename T1::elem_type>
nonzeros(const SpBase<typename T1::elem_type,T1>& X)
  {
  arma_extra_debug_sigprint();
  
  Col<typename T1::elem_type> out;
  
  op_nonzeros::apply_noalias(out, X.get_ref());
  
  return out;
  }
예제 #26
0
inline
SpMat<typename T1::elem_type>
sprandn(const SpBase<typename T1::elem_type, T1>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  SpMat<eT> out( X.get_ref() );
  
  arma_rng::randn<eT>::fill( access::rwp(out.values), out.n_nonzero );
  
  return out;
  }
예제 #27
0
inline
void
spdiagview<eT>::operator/=(const SpBase<eT,T1>& o)
  {
  arma_extra_debug_sigprint();
  
  spdiagview<eT>& d = *this;
  
  SpMat<eT>& d_m = const_cast< SpMat<eT>& >(d.m);
  
  const uword d_n_elem     = d.n_elem;
  const uword d_row_offset = d.row_offset;
  const uword d_col_offset = d.col_offset;
  
  const SpProxy<T1> P( o.get_ref() );
  
  arma_debug_check
    (
    ( (d_n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
    "spdiagview: given object has incompatible size"
    );
  
  if( SpProxy<T1>::must_use_iterator || P.is_alias(d_m) )
    {
    const SpMat<eT> tmp(P.Q);
    
    if(tmp.n_cols == 1)
      {
      for(uword i=0; i < d_n_elem; ++i)  { d_m.at(i + d_row_offset, i + d_col_offset) /= tmp.at(i,0); }
      }
    else
    if(tmp.n_rows == 1)
      {
      for(uword i=0; i < d_n_elem; ++i)  { d_m.at(i + d_row_offset, i + d_col_offset) /= tmp.at(0,i); }
      }
    }
  else
    {
    if(P.get_n_cols() == 1)
      {
      for(uword i=0; i < d_n_elem; ++i)  { d_m.at(i + d_row_offset, i + d_col_offset) /= P.at(i,0); }
      }
    else
    if(P.get_n_rows() == 1)
      {
      for(uword i=0; i < d_n_elem; ++i)  { d_m.at(i + d_row_offset, i + d_col_offset) /= P.at(0,i); }
      }
    }
  }
inline
typename
enable_if2
  <
  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
  Mat<typename T1::elem_type>
  >::result
operator/
  (
  const   Base<typename T1::elem_type, T1>& x,
  const SpBase<typename T2::elem_type, T2>& y
  )
  {
  arma_extra_debug_sigprint();

  const   Proxy<T1> pa(x.get_ref());
  const SpProxy<T2> pb(y.get_ref());

  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise division");

  Mat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols());

  result.fill(Datum<typename T1::elem_type>::inf);

  // Now divide each element
  typename SpProxy<T2>::const_iterator_type it = pb.begin();

  while(it.pos() < pb.get_n_nonzero())
    {
    if(Proxy<T1>::prefer_at_accessor == false)
      {
      const uword index = (it.col() * result.n_rows) + it.row();
      result[index] = pa[index] / (*it);
      }
    else
      {
      result.at(it.row(), it.col()) = pa.at(it.row(), it.col()) / (*it);
      }

    ++it;
    }

  return result;
  }
예제 #29
0
inline
bool
spsolve
  (
           Mat<typename T1::elem_type>&     out,
  const SpBase<typename T1::elem_type, T1>& A,
  const   Base<typename T1::elem_type, T2>& B,
  const char*                          solver   = "superlu",
  const spsolve_opts_base&             settings = spsolve_opts_none(),
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  const bool status = spsolve_helper(out, A.get_ref(), B.get_ref(), solver, settings);
  
  return status;
  }
예제 #30
0
inline
typename T1::elem_type
spop_mean::mean_all(const SpBase<typename T1::elem_type, T1>& X)
  {
  arma_extra_debug_sigprint();
  
  SpProxy<T1> p(X.get_ref());
  
  if(SpProxy<T1>::must_use_iterator)
    {
    typename SpProxy<T1>::const_iterator_type it  = p.begin();
    typename SpProxy<T1>::const_iterator_type end = p.end();

    return spop_mean::iterator_mean(it, end, p.get_n_elem() - p.get_n_nonzero(), typename T1::elem_type(0));
    }
  else // must_use_iterator == false; that is, we can directly access the values array
    {
    return spop_mean::direct_mean(p.get_values(), p.get_n_nonzero(), p.get_n_elem());
    }
  }