Esempio n. 1
0
inline
void
op_sp_plus::apply(SpMat<typename T1::elem_type>& out, const SpToDOp<T1,op_sp_plus>& in)
  {
  arma_extra_debug_sigprint();

  typedef typename T1::elem_type eT;

  // Note that T1 will be a sparse type, so we use SpProxy.
  const SpProxy<T1> proxy(in.m);
  
  const uword n_rows = proxy.get_n_rows();
  const uword n_cols = proxy.get_n_cols();
  
  out.set_size(n_rows, n_cols);
  
  const eT k = in.aux;
  
  // We have to loop over all the elements.
  for(uword c = 0; c < n_cols; ++c)
  for(uword r = 0; r < n_rows; ++r)
    {
    out.at(r, c) = proxy.at(r, c) + k;
    }
  }
Esempio n. 2
0
inline
void
spop_repmat::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_repmat>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap_spmat<T1> U(in.m);
  const SpMat<eT>& X =   U.M;
  
  const uword X_n_rows = X.n_rows;
  const uword X_n_cols = X.n_cols;
  
  const uword copies_per_row = in.aux_uword_a;
  const uword copies_per_col = in.aux_uword_b;
  
  // out.set_size(X_n_rows * copies_per_row, X_n_cols * copies_per_col);
  // 
  // const uword out_n_rows = out.n_rows;
  // const uword out_n_cols = out.n_cols;
  // 
  // if( (out_n_rows > 0) && (out_n_cols > 0) )
  //   {
  //   for(uword col = 0; col < out_n_cols; col += X_n_cols)
  //   for(uword row = 0; row < out_n_rows; row += X_n_rows)
  //     {
  //     out.submat(row, col, row+X_n_rows-1, col+X_n_cols-1) = X;
  //     }
  //   }
  
  SpMat<eT> tmp(X_n_rows * copies_per_row, X_n_cols);
  
  if(tmp.n_elem > 0)
    {
    for(uword row = 0; row < tmp.n_rows; row += X_n_rows)
      {
      tmp.submat(row, 0, row+X_n_rows-1, X_n_cols-1) = X;
      }
    }
  
  // tmp contains copies of the input matrix, so no need to check for aliasing
  
  out.set_size(X_n_rows * copies_per_row, X_n_cols * copies_per_col);
  
  const uword out_n_rows = out.n_rows;
  const uword out_n_cols = out.n_cols;
  
  if( (out_n_rows > 0) && (out_n_cols > 0) )
    {
    for(uword col = 0; col < out_n_cols; col += X_n_cols)
      {
      out.submat(0, col, out_n_rows-1, col+X_n_cols-1) = tmp;
      }
    }
  }
Esempio n. 3
0
arma_hot
inline
void
spop_htrans::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_htrans>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk)
{
    arma_extra_debug_sigprint();
    arma_ignore(junk);

    typedef typename   T1::elem_type  eT;
    typedef typename umat::elem_type ueT;

    const SpProxy<T1> p(in.m);

    const uword N = p.get_n_nonzero();

    if(N == uword(0))
    {
        out.set_size(p.get_n_cols(), p.get_n_rows());
        return;
    }

    umat locs(2, N);

    Col<eT> vals(N);

    eT* vals_ptr = vals.memptr();

    typename SpProxy<T1>::const_iterator_type it = p.begin();

    for(uword count = 0; count < N; ++count)
    {
        ueT* locs_ptr = locs.colptr(count);

        locs_ptr[0] = it.col();
        locs_ptr[1] = it.row();

        vals_ptr[count] = std::conj(*it);

        ++it;
    }

    SpMat<eT> tmp(locs, vals, p.get_n_cols(), p.get_n_rows());

    out.steal_mem(tmp);
}
arma_hot
inline
void
spglue_plus::apply_noalias(SpMat<eT>& out, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
  {
  arma_extra_debug_sigprint();
  
  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "addition");

  if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) )
    {
    out.set_size(pa.get_n_rows(), pa.get_n_cols());
    
    // Resize memory to correct size.
    out.mem_resize(n_unique(pa, pb, op_n_unique_add()));
    
    // Now iterate across both matrices.
    typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
    typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
    
    typename SpProxy<T1>::const_iterator_type x_end = pa.end();
    typename SpProxy<T2>::const_iterator_type y_end = pb.end();
    
    uword cur_val = 0;
    while( (x_it != x_end) || (y_it != y_end) )
      {
      if(x_it == y_it)
        {
        const eT val = (*x_it) + (*y_it);
        
        if (val != eT(0))
          {
          access::rw(out.values[cur_val]) = val;
          access::rw(out.row_indices[cur_val]) = x_it.row();
          ++access::rw(out.col_ptrs[x_it.col() + 1]);
          ++cur_val;
          }

        ++x_it;
        ++y_it;
        }
      else
        {
        const uword x_it_row = x_it.row();
        const uword x_it_col = x_it.col();
        
        const uword y_it_row = y_it.row();
        const uword y_it_col = y_it.col();
        
        if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
          {
          access::rw(out.values[cur_val]) = (*x_it);
          access::rw(out.row_indices[cur_val]) = x_it_row;
          ++access::rw(out.col_ptrs[x_it_col + 1]);
          ++cur_val;
          ++x_it;
          }
        else
          {
          access::rw(out.values[cur_val]) = (*y_it);
          access::rw(out.row_indices[cur_val]) = y_it_row;
          ++access::rw(out.col_ptrs[y_it_col + 1]);
          ++cur_val;
          ++y_it;
          }
        }
      }
    
    const uword out_n_cols = out.n_cols;
    
    uword* col_ptrs = access::rwp(out.col_ptrs);
    
    // Fix column pointers to be cumulative.
    for(uword c = 1; c <= out_n_cols; ++c)
      {
      col_ptrs[c] += col_ptrs[c - 1];
      }
    }
  else
    {
    if(pa.get_n_nonzero() == 0)
      {
      out = pb.Q;
      return;
      }
    
    if(pb.get_n_nonzero() == 0)
      {
      out = pa.Q;
      return;
      }
    }
  }
inline
void
spop_mean::apply_noalias_slow
  (
        SpMat<typename T1::elem_type>& out,
  const SpProxy<T1>&                   p,
  const uword                          dim
  )
  {
  arma_extra_debug_sigprint();

  typedef typename T1::elem_type eT;
  
  const uword p_n_rows = p.get_n_rows();
  const uword p_n_cols = p.get_n_cols();

  if(dim == 0)  // find the mean in each column
    {
    arma_extra_debug_print("spop_mean::apply_noalias(): dim = 0");
    
    out.set_size((p_n_rows > 0) ? 1 : 0, p_n_cols);
    
    if( (p_n_rows == 0) || (p.get_n_nonzero() == 0) )  { return; }
    
    for(uword col = 0; col < p_n_cols; ++col)
      {
      // Do we have to use an iterator or can we use memory directly?
      if(SpProxy<T1>::must_use_iterator)
        {
        typename SpProxy<T1>::const_iterator_type it  = p.begin_col(col);
        typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1);
        
        const uword n_zero = p_n_rows - (end.pos() - it.pos());
        
        out.at(0,col) = spop_mean::iterator_mean(it, end, n_zero, eT(0));
        }
      else
        {
        out.at(0,col) = spop_mean::direct_mean
          (
          &p.get_values()[p.get_col_ptrs()[col]],
          p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col],
          p_n_rows
          );
        }
      }
    }
  else
  if(dim == 1)  // find the mean in each row
    {
    arma_extra_debug_print("spop_mean::apply_noalias(): dim = 1");
    
    out.set_size(p_n_rows, (p_n_cols > 0) ? 1 : 0);
    
    if( (p_n_cols == 0) || (p.get_n_nonzero() == 0) )  { return; }
    
    for(uword row = 0; row < p_n_rows; ++row)
      {
      // We must use an iterator regardless of how it is stored.
      typename SpProxy<T1>::const_row_iterator_type it  = p.begin_row(row);
      typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row);
      
      const uword n_zero = p_n_cols - (end.pos() - it.pos());
      
      out.at(row,0) = spop_mean::iterator_mean(it, end, n_zero, eT(0));
      }
    }
  }
Esempio n. 6
0
inline
void
spop_var::apply_noalias
  (
        SpMat<typename T1::pod_type>& out_ref,
  const SpProxy<T1>&                  p,
  const uword                         norm_type,
  const uword                         dim
  )
  {
  arma_extra_debug_sigprint();

  typedef typename T1::elem_type  in_eT;
  //typedef typename T1::pod_type  out_eT;

  const uword p_n_rows = p.get_n_rows();
  const uword p_n_cols = p.get_n_cols();

  if(dim == 0)
    {
    arma_extra_debug_print("spop_var::apply(), dim = 0");

    arma_debug_check((p_n_rows == 0), "var(): given object has zero rows");

    out_ref.set_size(1, p_n_cols);

    for(uword col = 0; col < p_n_cols; ++col)
      {
      if(SpProxy<T1>::must_use_iterator == true)
        {
        // We must use an iterator; we can't access memory directly.
        typename SpProxy<T1>::const_iterator_type it  = p.begin_col(col);
        typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1);
        
        const uword n_zero = p.get_n_rows() - (end.pos() - it.pos());
        
        // in_eT is used just to get the specialization right (complex / noncomplex)
        out_ref.at(col) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
        }
      else
        {
        // We can use direct memory access to calculate the variance.
        out_ref.at(col) = spop_var::direct_var
          (
          &p.get_values()[p.get_col_ptrs()[col]],
          p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col],
          p.get_n_rows(),
          norm_type
          );
        }
      }
    }
  else if(dim == 1)
    {
    arma_extra_debug_print("spop_var::apply_noalias(), dim = 1");
    
    arma_debug_check((p_n_cols == 0), "var(): given object has zero columns");
    
    out_ref.set_size(p_n_rows, 1);
    
    for(uword row = 0; row < p_n_rows; ++row)
      {
      // We have to use an iterator here regardless of whether or not we can
      // directly access memory.
      typename SpProxy<T1>::const_row_iterator_type it  = p.begin_row(row);
      typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row);
      
      const uword n_zero = p.get_n_cols() - (end.pos() - it.pos());
      
      out_ref.at(row) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
      }
    }
  }
inline
void
spop_var::apply_noalias
  (
        SpMat<typename T1::pod_type>& out,
  const SpProxy<T1>&                  p,
  const uword                         norm_type,
  const uword                         dim
  )
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type  in_eT;
  //typedef typename T1::pod_type  out_eT;
  
  const uword p_n_rows = p.get_n_rows();
  const uword p_n_cols = p.get_n_cols();
  
  // TODO: this is slow; rewrite based on the approach used by sparse mean()
  
  if(dim == 0)  // find variance in each column
    {
    arma_extra_debug_print("spop_var::apply_noalias(): dim = 0");
    
    out.set_size((p_n_rows > 0) ? 1 : 0, p_n_cols);
    
    if( (p_n_rows == 0) || (p.get_n_nonzero() == 0) )  { return; }
    
    for(uword col = 0; col < p_n_cols; ++col)
      {
      if(SpProxy<T1>::must_use_iterator)
        {
        // We must use an iterator; we can't access memory directly.
        typename SpProxy<T1>::const_iterator_type it  = p.begin_col(col);
        typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1);
        
        const uword n_zero = p_n_rows - (end.pos() - it.pos());
        
        // in_eT is used just to get the specialization right (complex / noncomplex)
        out.at(0, col) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
        }
      else
        {
        // We can use direct memory access to calculate the variance.
        out.at(0, col) = spop_var::direct_var
          (
          &p.get_values()[p.get_col_ptrs()[col]],
          p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col],
          p_n_rows,
          norm_type
          );
        }
      }
    }
  else
  if(dim == 1)  // find variance in each row
    {
    arma_extra_debug_print("spop_var::apply_noalias(): dim = 1");
    
    out.set_size(p_n_rows, (p_n_cols > 0) ? 1 : 0);
    
    if( (p_n_cols == 0) || (p.get_n_nonzero() == 0) )  { return; }
    
    for(uword row = 0; row < p_n_rows; ++row)
      {
      // We have to use an iterator here regardless of whether or not we can
      // directly access memory.
      typename SpProxy<T1>::const_row_iterator_type it  = p.begin_row(row);
      typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row);
      
      const uword n_zero = p_n_cols - (end.pos() - it.pos());
      
      out.at(row, 0) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
      }
    }
  }
arma_hot
inline
void
spglue_minus::apply_noalias(SpMat<eT>& result, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
  {
  arma_extra_debug_sigprint();
  
  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "subtraction");

  result.set_size(pa.get_n_rows(), pa.get_n_cols());

  // Resize memory to correct size.
  result.mem_resize(n_unique(pa, pb, op_n_unique_sub()));

  // Now iterate across both matrices.
  typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
  typename SpProxy<T2>::const_iterator_type y_it = pb.begin();

  uword cur_val = 0;
  while((x_it.pos() < pa.get_n_nonzero()) || (y_it.pos() < pb.get_n_nonzero()))
    {
    if(x_it == y_it)
      {
      const typename T1::elem_type val = (*x_it) - (*y_it);
      if (val != 0)
        {
        access::rw(result.values[cur_val]) = val;
        access::rw(result.row_indices[cur_val]) = x_it.row();
        ++access::rw(result.col_ptrs[x_it.col() + 1]);
        ++cur_val;
        }

      ++x_it;
      ++y_it;
      }
    else
      {
      if((x_it.col() < y_it.col()) || ((x_it.col() == y_it.col()) && (x_it.row() < y_it.row()))) // if y is closer to the end
        {
        access::rw(result.values[cur_val]) = (*x_it);
        access::rw(result.row_indices[cur_val]) = x_it.row();
        ++access::rw(result.col_ptrs[x_it.col() + 1]);
        ++cur_val;
        ++x_it;
        }
      else
        {
        access::rw(result.values[cur_val]) = -(*y_it);
        access::rw(result.row_indices[cur_val]) = y_it.row();
        ++access::rw(result.col_ptrs[y_it.col() + 1]);
        ++cur_val;
        ++y_it;
        }
      }
    }

  // Fix column pointers to be cumulative.
  for(uword c = 1; c <= result.n_cols; ++c)
    {
    access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
    }
  }