Пример #1
0
inline
Row<eT>::Row()
  : Mat<eT>(arma_vec_indicator(), 2)
  {
  arma_extra_debug_sigprint();
  }
Пример #2
0
inline
GlueCube<T1,T2,glue_type>::~GlueCube()
  {
  arma_extra_debug_sigprint();
  }
Пример #3
0
inline
bool
eig_gen
  (
        Col< std::complex<eT> >& eigval, 
        Mat< std::complex<eT> >& eigvec,
  const Base<eT, T1>&            X, 
  const char                     side = 'r',
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  //std::cout << "real" << std::endl;
  
  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" );
  
  Mat<eT> dummy_eigvec;
  Mat<eT> tmp_eigvec;
  
  bool status;
  
  switch(side)
    {
    case 'r':
      status = auxlib::eig_gen(eigval, dummy_eigvec, tmp_eigvec, X, side);
      break;
    
    case 'l':
      status = auxlib::eig_gen(eigval, tmp_eigvec, dummy_eigvec, X, side);
      break;
      
    default:
      arma_stop("eig_gen(): parameter 'side' is invalid");
      status = false;
    }
  
  if(status == false)
    {
    eigval.reset();
    eigvec.reset();
    arma_bad("eig_gen(): failed to converge", false);
    }
  else
    {
    const uword n = eigval.n_elem;
    
    if(n > 0)
      {
      eigvec.set_size(n,n);
      
      for(uword j=0; j<n; ++j)
        {
        if( (j < n-1) && (eigval[j] == std::conj(eigval[j+1])) )
          {
          // eigvec.col(j)   = Mat< std::complex<eT> >( tmp_eigvec.col(j),  tmp_eigvec.col(j+1) );
          // eigvec.col(j+1) = Mat< std::complex<eT> >( tmp_eigvec.col(j), -tmp_eigvec.col(j+1) );
          
          for(uword i=0; i<n; ++i)
            {
            eigvec.at(i,j)   = std::complex<eT>( tmp_eigvec.at(i,j),  tmp_eigvec.at(i,j+1) );
            eigvec.at(i,j+1) = std::complex<eT>( tmp_eigvec.at(i,j), -tmp_eigvec.at(i,j+1) );
            }
          
          ++j;
          }
        else
          {
          // eigvec.col(i) = tmp_eigvec.col(i);
          
          for(uword i=0; i<n; ++i)
            {
            eigvec.at(i,j) = std::complex<eT>(tmp_eigvec.at(i,j), eT(0));
            }
          
          }
        }
      }
    }
  
  return status;
  }
inline
subview_cube_each1<eT>::~subview_cube_each1()
  {
  arma_extra_debug_sigprint();
  }
inline
void
running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample)
  {
  arma_extra_debug_sigprint();
  
  typedef typename std::complex<T> eT;
  
  const T N = x.counter.value();
  
  if(N > T(0))
    {
    arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
    
    const u32 n_elem           = sample.n_elem;
    const eT* sample_mem       = sample.memptr();
          eT* r_mean_mem       = x.r_mean.memptr();
           T* r_var_mem        = x.r_var.memptr();
          eT* min_val_mem      = x.min_val.memptr();
          eT* max_val_mem      = x.max_val.memptr();
           T* min_val_norm_mem = x.min_val_norm.memptr();
           T* max_val_norm_mem = x.max_val_norm.memptr();
    
    const T  N_plus_1   = x.counter.value_plus_1();
    const T  N_minus_1  = x.counter.value_minus_1();
    
    if(x.calc_cov == true)
      {
      Mat<eT>& tmp1 = x.tmp1;
      Mat<eT>& tmp2 = x.tmp2;
      
      tmp1 = sample - x.r_mean;
      
      if(sample.n_cols == 1)
        {
        tmp2 = conj(tmp1)*trans(tmp1);
        }
      else
        {
        tmp2 = trans(conj(tmp1))*tmp1;
        }
      
      x.r_cov *= (N_minus_1/N);
      x.r_cov += tmp2 / N_plus_1;
      }
    
    
    for(u32 i=0; i<n_elem; ++i)
      {
      const eT& val      = sample_mem[i];
      const  T  val_norm = std::norm(val);
      
      if(val_norm < min_val_norm_mem[i])
        {
        min_val_norm_mem[i] = val_norm;
        min_val_mem[i]      = val;
        }
      
      if(val_norm > max_val_norm_mem[i])
        {
        max_val_norm_mem[i] = val_norm;
        max_val_mem[i]      = val;
        }
      
      const eT& r_mean_val = r_mean_mem[i];
      
      r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1;
      
      r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
      }
    
    }
  else
    {
    arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
    
    x.r_mean.set_size(sample.n_rows, sample.n_cols);
    
    x.r_var.zeros(sample.n_rows, sample.n_cols);
    
    if(x.calc_cov == true)
      {
      x.r_cov.zeros(sample.n_elem, sample.n_elem);
      }
    
    x.min_val.set_size(sample.n_rows, sample.n_cols);
    x.max_val.set_size(sample.n_rows, sample.n_cols);
    
    x.min_val_norm.set_size(sample.n_rows, sample.n_cols);
    x.max_val_norm.set_size(sample.n_rows, sample.n_cols);
    
    
    const u32 n_elem           = sample.n_elem;
    const eT* sample_mem       = sample.memptr();
          eT* r_mean_mem       = x.r_mean.memptr();
          eT* min_val_mem      = x.min_val.memptr();
          eT* max_val_mem      = x.max_val.memptr();
           T* min_val_norm_mem = x.min_val_norm.memptr();
           T* max_val_norm_mem = x.max_val_norm.memptr();
    
    for(u32 i=0; i<n_elem; ++i)
      {
      const eT& val      = sample_mem[i];
      const  T  val_norm = std::norm(val);
      
      r_mean_mem[i]  = val;
      min_val_mem[i] = val;
      max_val_mem[i] = val;
      
      min_val_norm_mem[i] = val_norm;
      max_val_norm_mem[i] = val_norm;
      }
    }
  
  x.counter++;
  }
inline
std::streamsize
arma_ostream::modify_stream(std::ostream& o, typename SpMat<eT>::const_iterator begin, const uword n_elem, const typename arma_not_cx<eT>::result* junk)
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);

  o.unsetf(ios::showbase);
  o.unsetf(ios::uppercase);
  o.unsetf(ios::showpos);

  o.fill(' ');

  std::streamsize cell_width;

  bool use_layout_B  = false;
  bool use_layout_C  = false;

  for(typename SpMat<eT>::const_iterator it = begin; it.pos() < n_elem; ++it)
    {
    const eT val = *it;

    if(
      val >= eT(+100) ||
      ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
      ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
      ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) )
      )
      {
      use_layout_C = true;
      break;
      }

    if(
      (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
      )
      {
      use_layout_B = true;
      }
    }

  if(use_layout_C == true)
    {
    o.setf(ios::scientific);
    o.setf(ios::right);
    o.unsetf(ios::fixed);
    o.precision(4);
    cell_width = 13;
    }
  else
  if(use_layout_B == true)
    {
    o.unsetf(ios::scientific);
    o.setf(ios::right);
    o.setf(ios::fixed);
    o.precision(4);
    cell_width = 10;
    }
  else
    {
    o.unsetf(ios::scientific);
    o.setf(ios::right);
    o.setf(ios::fixed);
    o.precision(4);
    cell_width = 9;
    }
  
  return cell_width;
  }
inline
void
arma_ostream::print(std::ostream& o, const SpMat<eT>& m, const bool modify)
  {
  arma_extra_debug_sigprint();
  
  const arma_ostream_state stream_state(o);
  
  o.unsetf(ios::showbase);
  o.unsetf(ios::uppercase);
  o.unsetf(ios::showpos);
  o.unsetf(ios::scientific);
  o.setf(ios::right);
  o.setf(ios::fixed);
  o.precision(2);
  
  const uword m_n_nonzero = m.n_nonzero;
  
  o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero
    << "; density: " << ((m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0))
    << "%]\n\n";
  
  if(modify == false) { stream_state.restore(o); }
  
  if(m_n_nonzero > 0)
    {
    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m_n_nonzero) : o.width();
    
    typename SpMat<eT>::const_iterator begin = m.begin();
    
    while(begin != m.end())
      {
      const uword row = begin.row();
      
      // TODO: change the maximum number of spaces before and after each location to be dependent on n_rows and n_cols
      
           if(row < 10)      { o << "     "; }
      else if(row < 100)     { o << "    ";  }
      else if(row < 1000)    { o << "   ";   }
      else if(row < 10000)   { o << "  ";    }
      else if(row < 100000)  { o << ' ';     }
      
      const uword col = begin.col();
      
      o << '(' << row << ", " << col << ") ";
      
           if(col < 10)      { o << "     "; }
      else if(col < 100)     { o << "    ";  }
      else if(col < 1000)    { o << "   ";   }
      else if(col < 10000)   { o << "  ";    }
      else if(col < 100000)  { o << ' ';     }
      
      if(cell_width > 0) { o.width(cell_width); }
        
      arma_ostream::print_elem(o, eT(*begin), modify);
      o << '\n';
      
      ++begin;
      }
    
    o << '\n';
    }
  
  o.flush();
  stream_state.restore(o);
  }
Пример #8
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_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.zeros(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
          {
          const eT val = (*x_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;
          }
        else
          {
          const eT val = (*y_it);
          
          if(val != eT(0))
            {
            access::rw(out.values[cur_val]) = val;
            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
typename arma_cx_only<typename T1::elem_type>::result
op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type            eT;
  typedef typename get_pod_type<eT>::result T;
  
  const uword n_elem = P.get_n_elem();
  
  if(n_elem == 0)
    {
    arma_debug_check(true, "max(): object has no elements");
    
    return Datum<eT>::nan;
    }
  
  T best_val = priv::most_neg<T>();
  
  if(Proxy<T1>::prefer_at_accessor == false)
    {
    typedef typename Proxy<T1>::ea_type ea_type;
    
    ea_type A = P.get_ea();
    
    uword best_index = 0;
    
    for(uword i=0; i<n_elem; ++i)
      {
      const T tmp = std::abs(A[i]);
      
      if(tmp > best_val)  { best_val = tmp;  best_index = i; }
      }
    
    index_of_max_val = best_index;
    
    return( A[best_index] );
    }
  else
    {
    const uword n_rows = P.get_n_rows();
    const uword n_cols = P.get_n_cols();
    
    uword best_row   = 0;
    uword best_col   = 0;
    uword best_index = 0;
    
    if(n_rows == 1)
      {
      for(uword col=0; col < n_cols; ++col)
        {
        const T tmp = std::abs(P.at(0,col));
        
        if(tmp > best_val)  { best_val = tmp;  best_col = col; }
        }
      
      best_index = best_col;
      }
    else
    if(n_cols == 1)
      {
      for(uword row=0; row < n_rows; ++row)
        {
        const T tmp = std::abs(P.at(row,0));
        
        if(tmp > best_val)  { best_val = tmp;  best_row = row; }
        }
      
      best_index = best_row;
      }
    else
      {
      uword count = 0;
      
      for(uword col=0; col < n_cols; ++col)
      for(uword row=0; row < n_rows; ++row)
        {
        const T tmp = std::abs(P.at(row,col));
        
        if(tmp > best_val)
          {
          best_val = tmp;
          
          best_row = row;
          best_col = col;
          
          best_index = count;
          }
        
        ++count;
        }
      }
    
    index_of_max_val = best_index;
    
    return P.at(best_row, best_col);
    }
  }
Пример #11
0
inline
eT
spop_var::direct_var
  (
  const eT* const X,
  const uword length,
  const uword N,
  const uword norm_type
  )
  {
  arma_extra_debug_sigprint();

  if(length >= 2 && N >= 2)
    {
    const eT acc1 = spop_mean::direct_mean(X, length, N);

    eT acc2 = eT(0);
    eT acc3 = eT(0);

    uword i, j;

    for(i = 0, j = 1; j < length; i += 2, j += 2)
      {
      const eT Xi = X[i];
      const eT Xj = X[j];

      const eT tmpi = acc1 - Xi;
      const eT tmpj = acc1 - Xj;

      acc2 += tmpi * tmpi + tmpj * tmpj;
      acc3 += tmpi + tmpj;
      }

    if(i < length)
      {
      const eT Xi = X[i];

      const eT tmpi = acc1 - Xi;

      acc2 += tmpi * tmpi;
      acc3 += tmpi;
      }

    // Now add in all zero elements.
    acc2 += (N - length) * (acc1 * acc1);
    acc3 += (N - length) * acc1;

    const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N);
    const eT var_val  = (acc2 - (acc3 * acc3) / eT(N)) / norm_val;

    return var_val;
    }
  else if(length == 1 && N > 1) // if N == 1, then variance is zero.
    {
    const eT mean = X[0] / eT(N);
    const eT val = mean - X[0];

    const eT acc2 = (val * val) + (N - length) * (mean * mean);
    const eT acc3 = val + (N - length) * mean;

    const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N);
    const eT var_val  = (acc2 - (acc3 * acc3) / eT(N)) / norm_val;

    return var_val;
    }
  else
    {
    return eT(0);
    }
  }
inline
std::complex<T>
op_max::max(const subview< std::complex<T> >& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename std::complex<T> eT;
  
  if(X.n_elem == 0)
    {
    arma_debug_check(true, "max(): object has no elements");
    
    return Datum<eT>::nan;
    }
  
  const Mat<eT>& A = X.m;
  
  const uword X_n_rows = X.n_rows;
  const uword X_n_cols = X.n_cols;
  
  const uword start_row = X.aux_row1;
  const uword start_col = X.aux_col1;
  
  const uword end_row_p1 = start_row + X_n_rows;
  const uword end_col_p1 = start_col + X_n_cols;
  
  T max_val = priv::most_neg<T>();
  
  uword best_row = 0;
  uword best_col = 0;
    
  if(X_n_rows == 1)
    {
    best_col = 0;
    
    for(uword col=start_col; col < end_col_p1; ++col)
      {
      const T tmp_val = std::abs( A.at(start_row, col) );
      
      if(tmp_val > max_val)
        {
        max_val  = tmp_val;
        best_col = col;
        }
      }
    
    best_row = start_row;
    }
  else
    {
    for(uword col=start_col; col < end_col_p1; ++col)
    for(uword row=start_row; row < end_row_p1; ++row)
      {
      const T tmp_val = std::abs( A.at(row, col) );
      
      if(tmp_val > max_val)
        {
        max_val  = tmp_val;
        best_row = row;
        best_col = col;
        }
      }
    }
  
  return A.at(best_row, best_col);
  }
Пример #13
0
inline
mtGlue<out_eT,T1,T2,glue_type>::~mtGlue()
{
    arma_extra_debug_sigprint();
}
Пример #14
0
inline
Row<eT>::Row(const uword in_n_elem)
  : Mat<eT>(arma_vec_indicator(), 1, in_n_elem, 2)
  {
  arma_extra_debug_sigprint();
  }
Пример #15
0
inline
void
glue_join::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword join_type)
  {
  arma_extra_debug_sigprint();
  
  const uword A_n_rows = A.n_rows;
  const uword A_n_cols = A.n_cols;
  
  const uword B_n_rows = B.n_rows;
  const uword B_n_cols = B.n_cols;
  
  if(join_type == 0)
    {
    arma_debug_check
      (
      ( (A_n_cols != B_n_cols) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
      "join_cols() / join_vert(): number of columns must be the same"
      );
    }
  else
    {
    arma_debug_check
      (
      ( (A_n_rows != B.n_rows) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
      "join_rows() / join_horiz(): number of rows must be the same"
      );
    }
  
  
  if(join_type == 0)   // join columns (i.e. result matrix has more rows)
    {
    out.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) );
    
    if( out.n_elem > 0 )
      {
      if(A.is_empty() == false)
        { 
        out.submat(0,        0,   A_n_rows-1, out.n_cols-1) = A;
        }
      
      if(B.is_empty() == false)
        {
        out.submat(A_n_rows, 0, out.n_rows-1, out.n_cols-1) = B;
        }
      }
    }
  else   // join rows  (i.e. result matrix has more columns)
    {
    out.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols );
    
    if( out.n_elem > 0 )
      {
      if(A.is_empty() == false)
        {
        out.submat(0, 0,        out.n_rows-1,   A.n_cols-1) = A;
        }
      
      if(B.is_empty() == false)
        {
        out.submat(0, A_n_cols, out.n_rows-1, out.n_cols-1) = B;
        }
      }
    }
  }
Пример #16
0
 inline
 static
 void
 apply_blas_type( Mat<eT>& C, const TA& A, const TB& B, const eT alpha = eT(1), const eT beta = eT(0) )
   {
   arma_extra_debug_sigprint();
   
   if( (A.n_rows <= 4) && (A.n_rows == A.n_cols) && (A.n_rows == B.n_rows) && (B.n_rows == B.n_cols) && (is_cx<eT>::no) ) 
     {
     if(do_trans_B == false)
       {
       gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, B, alpha, beta);
       }
     else
       {
       Mat<eT> BB(B.n_rows, B.n_rows);
       
       op_strans::apply_mat_noalias_tinysq(BB, B);
       
       gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
       }
     }
   else
     {
     #if defined(ARMA_USE_ATLAS)
       {
       arma_extra_debug_print("atlas::cblas_gemm()");
       
       atlas::cblas_gemm<eT>
         (
         atlas::CblasColMajor,
         (do_trans_A) ? ( is_cx<eT>::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
         (do_trans_B) ? ( is_cx<eT>::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
         C.n_rows,
         C.n_cols,
         (do_trans_A) ? A.n_rows : A.n_cols,
         (use_alpha) ? alpha : eT(1),
         A.mem,
         (do_trans_A) ? A.n_rows : C.n_rows,
         B.mem,
         (do_trans_B) ? C.n_cols : ( (do_trans_A) ? A.n_rows : A.n_cols ),
         (use_beta) ? beta : eT(0),
         C.memptr(),
         C.n_rows
         );
       }
     #elif defined(ARMA_USE_BLAS)
       {
       arma_extra_debug_print("blas::gemm()");
       
       const char trans_A = (do_trans_A) ? ( is_cx<eT>::yes ? 'C' : 'T' ) : 'N';
       const char trans_B = (do_trans_B) ? ( is_cx<eT>::yes ? 'C' : 'T' ) : 'N';
       
       const blas_int m   = C.n_rows;
       const blas_int n   = C.n_cols;
       const blas_int k   = (do_trans_A) ? A.n_rows : A.n_cols;
       
       const eT local_alpha = (use_alpha) ? alpha : eT(1);
       
       const blas_int lda = (do_trans_A) ? k : m;
       const blas_int ldb = (do_trans_B) ? n : k;
       
       const eT local_beta  = (use_beta) ? beta : eT(0);
       
       arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_A = %c") % trans_A );
       arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_B = %c") % trans_B );
       
       blas::gemm<eT>
         (
         &trans_A,
         &trans_B,
         &m,
         &n,
         &k,
         &local_alpha,
         A.mem,
         &lda,
         B.mem,
         &ldb,
         &local_beta,
         C.memptr(),
         &m
         );
       }
     #else
       {
       gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
       }
     #endif
     }
   }
Пример #17
0
inline
void
op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(X.m);
  const Mat<eT>& A = tmp.M;
  
  if(A.is_vec() == true)
    {
    // generate a diagonal matrix out of a vector
    
    const u32 N     = A.n_elem;
    const eT* A_mem = A.memptr();
    
    if(&out != &A)
      {
      // no aliasing
      out.zeros(N,N);
      
      for(u32 i=0; i<N; ++i)
        {
        out.at(i,i) = A_mem[i];
        }
      }
    else
      {
      // aliasing
      
      const podarray<eT> tmp(A_mem, N);
      
      const eT* tmp_mem = tmp.memptr();
      
      out.zeros(N,N);
      
      for(u32 i=0; i<N; ++i)
        {
        out.at(i,i) = tmp_mem[i];
        }
      }
    }
  else
    {
    // generate a diagonal matrix out of a matrix
    
    arma_debug_check( (A.is_square() == false), "diagmat(): given matrix is not square" );
    
    const u32 N = A.n_rows;
    
    out.set_size(N,N);
    
    for(u32 col=0; col<N; ++col)
      {
      for(u32 row=0;     row<col; ++row) { out.at(row,col) = eT(0); }
      
      out.at(col,col) = A.at(col,col);
      
      for(u32 row=col+1; row<N;   ++row) { out.at(row,col) = eT(0); }
      }
    }
  }
Пример #18
0
  arma_hot
  inline
  static
  void
  apply
    (
          Mat<eT>& C,
    const TA&      A,
    const TB&      B,
    const eT       alpha = eT(1),
    const eT       beta  = eT(0)
    )
    {
    arma_extra_debug_sigprint();

    const uword A_n_rows = A.n_rows;
    const uword A_n_cols = A.n_cols;
    
    const uword B_n_rows = B.n_rows;
    const uword B_n_cols = B.n_cols;
    
    if( (do_trans_A == false) && (do_trans_B == false) )
      {
      arma_aligned podarray<eT> tmp(A_n_cols);
      
      eT* A_rowdata = tmp.memptr();
      
      for(uword row_A=0; row_A < A_n_rows; ++row_A)
        {
        tmp.copy_row(A, row_A);
        
        for(uword col_B=0; col_B < B_n_cols; ++col_B)
          {
          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_rowdata, B.colptr(col_B));
          
               if( (use_alpha == false) && (use_beta == false) )  { C.at(row_A,col_B) =       acc;                          }
          else if( (use_alpha == true ) && (use_beta == false) )  { C.at(row_A,col_B) = alpha*acc;                          }
          else if( (use_alpha == false) && (use_beta == true ) )  { C.at(row_A,col_B) =       acc + beta*C.at(row_A,col_B); }
          else if( (use_alpha == true ) && (use_beta == true ) )  { C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B); }
          }
        }
      }
    else
    if( (do_trans_A == true) && (do_trans_B == false) )
      {
      for(uword col_A=0; col_A < A_n_cols; ++col_A)
        {
        // col_A is interpreted as row_A when storing the results in matrix C
        
        const eT* A_coldata = A.colptr(col_A);
        
        for(uword col_B=0; col_B < B_n_cols; ++col_B)
          {
          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_coldata, B.colptr(col_B));
          
               if( (use_alpha == false) && (use_beta == false) )  { C.at(col_A,col_B) =       acc;                          }
          else if( (use_alpha == true ) && (use_beta == false) )  { C.at(col_A,col_B) = alpha*acc;                          }
          else if( (use_alpha == false) && (use_beta == true ) )  { C.at(col_A,col_B) =       acc + beta*C.at(col_A,col_B); }
          else if( (use_alpha == true ) && (use_beta == true ) )  { C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B); }
          }
        }
      }
    else
    if( (do_trans_A == false) && (do_trans_B == true) )
      {
      Mat<eT> BB;
      op_strans::apply_mat_noalias(BB, B);
      
      gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
      }
    else
    if( (do_trans_A == true) && (do_trans_B == true) )
      {
      // mat B_tmp = trans(B);
      // dgemm_arma<true, false,  use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
      
      
      // By using the trans(A)*trans(B) = trans(B*A) equivalency,
      // transpose operations are not needed
      
      arma_aligned podarray<eT> tmp(B.n_cols);
      eT* B_rowdata = tmp.memptr();
      
      for(uword row_B=0; row_B < B_n_rows; ++row_B)
        {
        tmp.copy_row(B, row_B);
        
        for(uword col_A=0; col_A < A_n_cols; ++col_A)
          {
          const eT acc = op_dot::direct_dot_arma(A_n_rows, B_rowdata, A.colptr(col_A));
          
               if( (use_alpha == false) && (use_beta == false) )  { C.at(col_A,row_B) =       acc;                          }
          else if( (use_alpha == true ) && (use_beta == false) )  { C.at(col_A,row_B) = alpha*acc;                          }
          else if( (use_alpha == false) && (use_beta == true ) )  { C.at(col_A,row_B) =       acc + beta*C.at(col_A,row_B); }
          else if( (use_alpha == true ) && (use_beta == true ) )  { C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B); }
          }
        }
      }
    }
inline
void
arma_ostream::print_dense(std::ostream& o, const SpMat<eT>& m, const bool modify)
  {
  arma_extra_debug_sigprint();
  
  const arma_ostream_state stream_state(o);
  
  const uword m_n_rows = m.n_rows;
  const uword m_n_cols = m.n_cols;
    
  if(m.n_nonzero > 0)
    {
    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m.n_nonzero) : o.width();
    
    typename SpMat<eT>::const_iterator begin = m.begin();
    
    if(m_n_cols > 0)
      {
      if(cell_width > 0)
        {
        // An efficient row_iterator would make this simpler and faster
        for(uword row=0; row < m_n_rows; ++row)
          {
          for(uword col=0; col < m_n_cols; ++col)
            {
            // the cell width appears to be reset after each element is printed,
            // hence we need to restore it
            o.width(cell_width);
            eT val = eT(0);
            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
              {
              if(it.row() == row && it.col() == col)
                {
                val = *it;
                break;
                }
              }
            arma_ostream::print_elem(o,eT(val), modify);
            }

          o << '\n';
          }
        }
      else
        {
        // An efficient row_iterator would make this simpler and faster
        for(uword row=0; row < m_n_rows; ++row)
          {
          for(uword col=0; col < m_n_cols; ++col)
            {
            eT val = eT(0);
            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
              {
              if(it.row() == row && it.col() == col)
                {
                val = *it;
                break;
                }
              }
            arma_ostream::print_elem(o,eT(val), modify);
            o << ' ';
            }

          o << '\n';
          }
        }
      }
    }
  else
    {
    if(m.n_elem == 0)
      {
      o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n";
      }
    else
      {
      eT tmp[1];
      tmp[0] = eT(0);
      
      const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, &tmp[0], 1) : o.width();
      
      for(uword row=0; row < m_n_rows; ++row)
        {
        for(uword col=0; col < m_n_cols; ++col)
          {
          o.width(cell_width);
          
          arma_ostream::print_elem_zero<eT>(o, modify);
          
          o << ' ';
          }
        
        o << '\n';
        }
      }
    }
  
  o.flush();
  stream_state.restore(o);
  }
Пример #20
0
 inline explicit Proxy(const eOp<T1, eop_type>& A)
   : Q(A)
   {
   arma_extra_debug_sigprint();
   }
inline
subview_cube_each2<eT,TB>::~subview_cube_each2()
  {
  arma_extra_debug_sigprint();
  }
Пример #22
0
 inline explicit Proxy(const eGlue<T1, T2, eglue_type>& A)
   : Q(A)
   {
   arma_extra_debug_sigprint();
   }
inline
subview_cube_each1<eT>::subview_cube_each1(const Cube<eT>& in_p)
  : subview_cube_each_common<eT>::subview_cube_each_common(in_p)
  {
  arma_extra_debug_sigprint();
  }
Пример #24
0
 inline explicit Proxy(const mtOp<out_eT, T1, op_type>& A)
   : Q(A)
   {
   arma_extra_debug_sigprint();
   }
Пример #25
0
inline
void
op_pinv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type            eT;
  typedef typename get_pod_type<eT>::result  T;
  
  const bool use_divide_and_conquer = (in.aux_uword_a == 1);
  
  T tol = access::tmp_real(in.aux);
  
  arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0");
  
  const Proxy<T1> P(in.m);
  
  const uword n_rows = P.get_n_rows();
  const uword n_cols = P.get_n_cols();
  
  if( (n_rows*n_cols) == 0 )
    {
    out.set_size(n_cols,n_rows);
    return;
    }
  
  
  // economical SVD decomposition 
  Mat<eT> U;
  Col< T> s;
  Mat<eT> V;
  
  bool status = false;
  
  if(use_divide_and_conquer)
    {
    status = (n_cols > n_rows) ? auxlib::svd_dc_econ(U, s, V, trans(P.Q)) : auxlib::svd_dc_econ(U, s, V, P.Q);
    }
  else
    {
    status = (n_cols > n_rows) ? auxlib::svd_econ(U, s, V, trans(P.Q), 'b') : auxlib::svd_econ(U, s, V, P.Q, 'b');
    }
  
  if(status == false)
    {
    out.reset();
    arma_bad("pinv(): svd failed");
    return;
    }
  
  const uword s_n_elem = s.n_elem;
  const T*    s_mem    = s.memptr();
  
  // set tolerance to default if it hasn't been specified as an argument 
  if( (tol == T(0)) && (s_n_elem > 0) )
    {
    tol = (std::max)(n_rows, n_cols) * eop_aux::direct_eps( op_max::direct_max(s_mem, s_n_elem) );
    }
  
  
  // count non zero valued elements in s
  
  uword count = 0;
  
  for(uword i = 0; i < s_n_elem; ++i)
    {
    if(s_mem[i] > tol)  { ++count; }
    }
  
  
  if(count > 0)
    {
    Col<T> s2(count);
    
    T* s2_mem = s2.memptr();
    
    uword count2 = 0;
    
    for(uword i=0; i < s_n_elem; ++i)
      {
      const T val = s_mem[i];
      
      if(val > tol)  {  s2_mem[count2] = T(1) / val;  ++count2; }
      }
    
    
    if(n_rows >= n_cols)
      {
      out = ( (V.n_cols > count) ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( (U.n_cols > count) ? U.cols(0,count-1) : U );
      }
    else
      {
      out = ( (U.n_cols > count) ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( (V.n_cols > count) ? V.cols(0,count-1) : V );
      }
    }
  else
    {
    out.zeros(n_cols, n_rows);
    }
  }
Пример #26
0
 inline explicit Proxy(const mtGlue<out_eT, T1, T2, glue_type>& A)
   : Q(A)
   {
   arma_extra_debug_sigprint();
   }
Пример #27
0
inline
bool
op_logmat_cx::apply_common(Mat< std::complex<T> >& out, Mat< std::complex<T> >& S, const uword n_iters)
  {
  arma_extra_debug_sigprint();
  
  typedef typename std::complex<T> eT;
  
  Mat<eT> U;
  
  const bool schur_ok = auxlib::schur(U,S);
  
  if(schur_ok == false)  { arma_extra_debug_print("logmat(): schur decomposition failed"); return false; }
  
//double theta[] = { 1.10e-5, 1.82e-3, 1.62e-2,               5.39e-2,               1.14e-1,               1.87e-1,               2.64e-1              };
  double theta[] = { 0.0,     0.0,     1.6206284795015624e-2, 5.3873532631381171e-2, 1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 };
  // theta[0] and theta[1] not really used
  
  const uword N = S.n_rows;
  
  uword p = 0;
  uword m = 6;
  
  uword iter = 0;
  
  while(iter < n_iters)
    {
    const T tau = norm( (S - eye< Mat<eT> >(N,N)), 1 );
    
    if(tau <= theta[6])
      {
      p++;
      
      uword j1 = 0;
      uword j2 = 0;
      
      for(uword i=2; i<=6; ++i)  { if( tau      <= theta[i])  { j1 = i; break; } }
      for(uword i=2; i<=6; ++i)  { if((tau/2.0) <= theta[i])  { j2 = i; break; } }
      
      // sanity check, for development purposes only
      arma_debug_check( (j2 > j1), "internal error: op_logmat::apply_direct(): j2 > j1" );
      
      if( ((j1 - j2) <= 1) || (p == 2) )  { m = j1; break; }
      }
    
    const bool sqrtmat_ok = op_sqrtmat_cx::apply_direct(S,S);
    
    if(sqrtmat_ok == false)  { arma_extra_debug_print("logmat(): sqrtmat() failed"); return false; }
    
    iter++;
    }
  
  if(iter >= n_iters)  { arma_debug_warn("logmat(): reached max iterations without full convergence"); }
  
  S.diag() -= eT(1);
  
  if(m >= 1)
    {
    const bool helper_ok = op_logmat_cx::helper(S,m);
    
    if(helper_ok == false)  { return false; }
    }
  
  out = U * S * U.t();
  
  out *= eT(eop_aux::pow(double(2), double(iter)));
  
  return true;
  }
Пример #28
0
 inline explicit Proxy(const Col<eT>& A)
   : Q(A)
   {
   arma_extra_debug_sigprint();
   }
Пример #29
0
inline
typename arma_not_cx<typename T1::elem_type>::result
op_min::min(const Base<typename T1::elem_type,T1>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> P(X.get_ref());
  
  const uword n_elem = P.get_n_elem();
  
  arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
  
  eT min_val = priv::most_pos<eT>();
  
  if(Proxy<T1>::prefer_at_accessor == false)
    {
    typedef typename Proxy<T1>::ea_type ea_type;
    
    ea_type A = P.get_ea();
    
    uword i,j;
    
    for(i=0, j=1; j<n_elem; i+=2, j+=2)
      {
      const eT tmp_i = A[i];
      const eT tmp_j = A[j];
      
      if(tmp_i < min_val) { min_val = tmp_i; }
      if(tmp_j < min_val) { min_val = tmp_j; }
      }
    
    if(i < n_elem)
      {
      const eT tmp_i = A[i];
      
      if(tmp_i < min_val) { min_val = tmp_i; }
      }
    }
  else
    {
    const uword n_rows = P.get_n_rows();
    const uword n_cols = P.get_n_cols();
    
    if(n_rows == 1)
      {
      uword i,j;
      for(i=0, j=1; j < n_cols; i+=2, j+=2)
        {
        const eT tmp_i = P.at(0,i);
        const eT tmp_j = P.at(0,j);
        
        if(tmp_i < min_val) { min_val = tmp_i; }
        if(tmp_j < min_val) { min_val = tmp_j; }
        }
      
      if(i < n_cols)
        {
        const eT tmp_i = P.at(0,i);
        
        if(tmp_i < min_val) { min_val = tmp_i; }
        }
      }
    else
      {
      for(uword col=0; col < n_cols; ++col)
        {
        uword i,j;
        for(i=0, j=1; j < n_rows; i+=2, j+=2)
          {
          const eT tmp_i = P.at(i,col);
          const eT tmp_j = P.at(j,col);
          
          if(tmp_i < min_val) { min_val = tmp_i; }
          if(tmp_j < min_val) { min_val = tmp_j; }
          }
          
        if(i < n_rows)
          {
          const eT tmp_i = P.at(i,col);
          
          if(tmp_i < min_val) { min_val = tmp_i; }
          }
        }
      }
    }
  
  return min_val;
  }
Пример #30
0
inline
void
op_princomp::direct_princomp
  (
        Mat< std::complex<T> >& coeff_out,
        Mat< std::complex<T> >& score_out,
  const Mat< std::complex<T> >& in
  )
  {
  arma_extra_debug_sigprint();
  
  typedef std::complex<T> eT;
  
  const u32 n_rows = in.n_rows;
  const u32 n_cols = in.n_cols;
  
  if(n_rows > 1) // more than one sample
    {
    // subtract the mean - use score_out as temporary matrix
    score_out = in - repmat(mean(in), n_rows, 1);
 	  
    // singular value decomposition
    Mat<eT> U;
    Col< T> s;
    
    const bool svd_ok = svd(U,s,coeff_out,score_out);
    
    if(svd_ok == false)
      {
      arma_print("princomp(): singular value decomposition failed");
      
      coeff_out.reset();
      score_out.reset();
      
      return;
      }
    
    // U.reset();
    
    // normalize the eigenvalues
    s /= std::sqrt(n_rows - 1);

    // project the samples to the principals
    score_out *= coeff_out;

    if(n_rows <= n_cols) // number of samples is less than their dimensionality
      {
      score_out.cols(n_rows-1,n_cols-1).zeros();
      }

    }
  else // single sample - row
    {
    if(n_rows == 1)
      {
      coeff_out = eye< Mat<eT> >(n_cols, n_cols);
      
      score_out.copy_size(in);
      score_out.zeros();
      }
    else
      {
      coeff_out.reset();
      score_out.reset();
      }
    }
  }