Esempio n. 1
0
inline
void
op_cumsum_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_vec>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& X = tmp.M;
  
  const uword n_elem = X.n_elem;
  
  out.copy_size(X);
  
        eT* out_mem = out.memptr();
  const eT* X_mem   = X.memptr();
  
  eT acc = eT(0);
  
  for(uword i=0; i<n_elem; ++i)
    {
    acc += X_mem[i];
    
    out_mem[i] = acc;
    }
  }
inline
void
op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>  tmp(in.m);
  const Mat<eT> X = tmp.M;
  
  if(&out != &X)
    {
    out.copy_size(X);
    
    for(uword i=0; i<X.n_cols; ++i)
      {
      out.col(i) = X.col(X.n_cols-1 - i);
      }
    }
  else
    {
    const uword N = X.n_cols / 2;
    
    for(uword i=0; i<N; ++i)
      {
      out.swap_cols(i, X.n_cols-1 - i);
      }
    }
  }
Esempio n. 3
0
inline
void
op_sort::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword sort_type, const uword dim)
  {
  arma_extra_debug_sigprint();
  
  if( (X.n_rows * X.n_cols) <= 1 )
    {
    out = X;
    return;
    }
  
  
  if(dim == 0)  // sort the contents of each column
    {
    arma_extra_debug_print("op_sort::apply(), dim = 0");
    
    out = X;
    
    const uword n_rows = out.n_rows;
    const uword n_cols = out.n_cols;
      
    for(uword col=0; col < n_cols; ++col)
      {
      op_sort::direct_sort( out.colptr(col), n_rows, sort_type );
      }
    }
  else
  if(dim == 1)  // sort the contents of each row
    {
    if(X.n_rows == 1)  // a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
      
      out = X;
      op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
      }
    else  // not a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
      
      out.copy_size(X);
      
      const uword n_rows = out.n_rows;
      const uword n_cols = out.n_cols;
      
      podarray<eT> tmp_array(n_cols);
      
      for(uword row=0; row < n_rows; ++row)
        {
        op_sort::copy_row(tmp_array.memptr(), X, row);
        
        op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type );
        
        op_sort::copy_row(out, tmp_array.memptr(), row);
        }
      }
    }
  }
Esempio n. 4
0
inline
bool
op_princomp::direct_princomp
  (
         Mat<typename T1::elem_type>&     coeff_out,
         Mat<typename T1::elem_type>&     score_out,
  const Base<typename T1::elem_type, T1>& X,
  const typename arma_not_cx<typename T1::elem_type>::result* junk
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::elem_type eT;
  
  const unwrap_check<T1> Y( X.get_ref(), score_out );
  const Mat<eT>& in    = Y.M;
  
  const uword n_rows = in.n_rows;
  const uword 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;  score_out.each_row() -= mean(in);
    
    // singular value decomposition
    Mat<eT> U;
    Col<eT> s;
    
    const bool svd_ok = svd(U, s, coeff_out, score_out);
    
    if(svd_ok == false)  { return false; }
    
    // normalize the eigenvalues
    s /= std::sqrt( double(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();
      
      Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
      s = s_tmp;
      }
    }
  else // 0 or 1 samples
    {
    coeff_out.eye(n_cols, n_cols);
    score_out.copy_size(in);
    score_out.zeros();
    }
  
  return true;
  }
Esempio n. 5
0
inline
void
interp1_helper_nearest(const Mat<eT>& XG, const Mat<eT>& YG, const Mat<eT>& XI, Mat<eT>& YI, const eT extrap_val)
  {
  arma_extra_debug_sigprint();
  
  const eT XG_min = XG.min();
  const eT XG_max = XG.max();
  
  YI.copy_size(XI);
  
  const eT* XG_mem = XG.memptr();
  const eT* YG_mem = YG.memptr();
  const eT* XI_mem = XI.memptr();
        eT* YI_mem = YI.memptr();
  
  const uword NG = XG.n_elem;
  const uword NI = XI.n_elem;
  
  uword best_j = 0;
  
  for(uword i=0; i<NI; ++i)
    {
    eT best_err = Datum<eT>::inf;
    
    const eT XI_val = XI_mem[i];
    
    if((XI_val < XG_min) || (XI_val > XG_max))
      {
      YI_mem[i] = extrap_val;
      }
    else
      {
      // XG and XI are guaranteed to be sorted in ascending manner,
      // so start searching XG from last known optimum position 
      
      for(uword j=best_j; j<NG; ++j)
        {
        const eT tmp = XG_mem[j] - XI_val;
        const eT err = (tmp >= eT(0)) ? tmp : -tmp;
        
        if(err >= best_err)
          {
          // error is going up, so we have found the optimum position
          break;
          }
        else
          {
          best_err = err;
          best_j   = j;   // remember the optimum position
          }
        }
      
      YI_mem[i] = YG_mem[best_j];
      }
    }
  }
inline
bool
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)
      {
      return false;
      }
    
    // U.reset();
    
    // normalize the eigenvalues
    s /= std::sqrt( double(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 // 0 or 1 samples
    {
    coeff_out.eye(n_cols, n_cols);
    
    score_out.copy_size(in);
    score_out.zeros();
    }
  
  return true;
  }
Esempio n. 7
0
inline
void
op_cumsum_mat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& X = tmp.M;
  
  const uword dim = in.aux_uword_a;
  arma_debug_check( (dim > 1), "cumsum(): incorrect usage. dim must be 0 or 1");
  
  out.copy_size(X);
  
  const uword X_n_rows = X.n_rows;
  const uword X_n_cols = X.n_cols;
  
  if(dim == 0)
    {
    arma_extra_debug_print("op_cumsum::apply(), dim = 0");
    
    for(uword col=0; col<X_n_cols; ++col)
      {
            eT* out_colmem = out.colptr(col);
      const eT* X_colmem   = X.colptr(col);
      
      eT acc = eT(0);
      
      for(uword row=0; row<X_n_rows; ++row)
        {
        acc += X_colmem[row];
        
        out_colmem[row] = acc;
        }
      }
    }
  else
  if(dim == 1)
    {
    arma_extra_debug_print("op_cumsum::apply(), dim = 1");
    
    for(uword row=0; row<X_n_rows; ++row)
      {
      eT acc = eT(0);
      
      for(uword col=0; col<X_n_cols; ++col)
        {
        acc += X.at(row,col);
        
        out.at(row,col) = acc;
        }
      }
    }
  }
Esempio n. 8
0
inline
void
op_trimat::apply_htrans
  (
        Mat<eT>& out,
  const Mat<eT>& A,
  const bool     upper,
  const typename arma_cx_only<eT>::result* junk
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" );
  
  const uword N = A.n_rows;
  
  if(&out != &A)
    {
    out.copy_size(A);
    }
  
  if(upper)
    {
    // Upper triangular: but since we're transposing, we're taking the lower
    // triangular and putting it in the upper half.
    for(uword row = 0; row < N; ++row)
      {
      eT* out_colptr = out.colptr(row);
      
      for(uword col = 0; col <= row; ++col)
        {
        //out.at(col, row) = std::conj( A.at(row, col) );
        out_colptr[col] = std::conj( A.at(row, col) );
        }
      }
    }
  else
    {
    // Lower triangular: but since we're transposing, we're taking the upper
    // triangular and putting it in the lower half.
    for(uword row = 0; row < N; ++row)
      {
      for(uword col = row; col < N; ++col)
        {
        out.at(col, row) = std::conj( A.at(row, col) );
        }
      }
    }
  
  op_trimat::fill_zeros(out, upper);
  }
Esempio n. 9
0
inline
void
op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& A = tmp.M;
  
  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" );
  
  const uword N     = A.n_rows;
  const bool  upper = (in.aux_uword_a == 0);
  
  if(&out != &A)
    {
    out.copy_size(A);
    
    if(upper)
      {
      // upper triangular: copy the diagonal and the elements above the diagonal
      for(uword i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( out_data, A_data, i+1 );
        }
      }
    else
      {
      // lower triangular: copy the diagonal and the elements below the diagonal
      for(uword i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( &out_data[i], &A_data[i], N-i );
        }
      }
    }
  
  op_trimat::fill_zeros(out, upper);
  }
Esempio n. 10
0
inline
void
op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& X = tmp.M;
  
  const uword X_n_cols = X.n_cols;
  
  if(&out != &X)
    {
    out.copy_size(X);
    
    if(T1::is_row || X.is_rowvec())
      {
      for(uword i=0; i<X_n_cols; ++i)  { out[i] = X[X_n_cols-1 - i]; }
      }
    else
      {
      for(uword i=0; i<X_n_cols; ++i)  { out.col(i) = X.col(X_n_cols-1 - i); }
      }
    }
  else
    {
    const uword N = X_n_cols / 2;
    
    if(T1::is_row || X.is_rowvec())
      {
      for(uword i=0; i<N; ++i)  { std::swap(out[i], out[X_n_cols-1 - i]); }
      }
    else
      {
      for(uword i=0; i<N; ++i)  { out.swap_cols(i, X_n_cols-1 - i); }
      }
    }
  }
inline
void
op_normalise_mat::apply(Mat<eT>& out, const Mat<eT>& A, const uword p, const uword dim)
  {
  arma_extra_debug_sigprint();
  
  typedef typename get_pod_type<eT>::result T;
  
  out.copy_size(A);
  
  if(A.n_elem == 0)  { return; }
  
  if(dim == 0)
    {
    const uword n_cols = A.n_cols;
    
    for(uword i=0; i<n_cols; ++i)
      {
      const T norm_val_a = norm(A.col(i), p);
      const T norm_val_b = (norm_val_a != T(0)) ? norm_val_a : T(1);
      
      out.col(i) = A.col(i) / norm_val_b;
      }
    }
  else
    {
    // better-than-nothing implementation
    
    const uword n_rows = A.n_rows;
    
    for(uword i=0; i<n_rows; ++i)
      {
      const T norm_val_a = norm(A.row(i), p);
      const T norm_val_b = (norm_val_a != T(0)) ? norm_val_a : T(1);
      
      out.row(i) = A.row(i) / norm_val_b;
      }
    }
  }
inline
void
op_symmat_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmat_cx>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& A = tmp.M;
  
  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square sized" );
  
  const uword N  = A.n_rows;
  
  const bool upper   = (in.aux_uword_a == 0);
  const bool do_conj = (in.aux_uword_b == 1);
  
  if(&out != &A)
    {
    out.copy_size(A);
    
    if(upper)
      {
      // upper triangular: copy the diagonal and the elements above the diagonal
      
      for(uword i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( out_data, A_data, i+1 );
        }
      }
    else
      {
      // lower triangular: copy the diagonal and the elements below the diagonal
      
      for(uword i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( &out_data[i], &A_data[i], N-i );
        }
      }
    }
  
  
  if(do_conj)
    {
    if(upper)
      {
      // reflect elements across the diagonal from upper triangle to lower triangle
      
      for(uword col=1; col < N; ++col)
        {
        const eT* coldata = out.colptr(col);
        
        for(uword row=0; row < col; ++row)
          {
          out.at(col,row) = std::conj(coldata[row]);
          }
        }
      }
    else
      {
      // reflect elements across the diagonal from lower triangle to upper triangle
      
      for(uword col=0; col < N; ++col)
        {
        const eT* coldata = out.colptr(col);
        
        for(uword row=(col+1); row < N; ++row)
          {
          out.at(col,row) = std::conj(coldata[row]);
          }
        }
      }
    }
  else  // don't do complex conjugation
    {
    if(upper)
      {
      // reflect elements across the diagonal from upper triangle to lower triangle
      
      for(uword col=1; col < N; ++col)
        {
        const eT* coldata = out.colptr(col);
        
        for(uword row=0; row < col; ++row)
          {
          out.at(col,row) = coldata[row];
          }
        }
      }
    else
      {
      // reflect elements across the diagonal from lower triangle to upper triangle
      
      for(uword col=0; col < N; ++col)
        {
        const eT* coldata = out.colptr(col);
        
        for(uword row=(col+1); row < N; ++row)
          {
          out.at(col,row) = coldata[row];
          }
        }
      }
    }
  }
inline
void
op_symmat::apply
  (
        Mat<typename T1::elem_type>& out,
  const Op<T1,op_symmat>&            in,
  const typename arma_not_cx<typename T1::elem_type>::result* junk
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1> tmp(in.m);
  const Mat<eT>& A = tmp.M;
  
  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square" );
  
  const u32  N     = A.n_rows;
  const bool upper = (in.aux_u32_a == 0);
  
  if(&out != &A)
    {
    out.copy_size(A);
    
    if(upper)
      {
      // upper triangular: copy the diagonal and the elements above the diagonal
      
      for(u32 i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( out_data, A_data, i+1 );
        }
      }
    else
      {
      // lower triangular: copy the diagonal and the elements below the diagonal
      
      for(u32 i=0; i<N; ++i)
        {
        const eT* A_data   = A.colptr(i);
              eT* out_data = out.colptr(i);
        
        arrayops::copy( &out_data[i], &A_data[i], N-i );
        }
      }
    }
  
  
  if(upper)
    {
    // reflect elements across the diagonal from upper triangle to lower triangle
    
    for(u32 col=1; col < N; ++col)
      {
      const eT* coldata = out.colptr(col);
      
      for(u32 row=0; row < col; ++row)
        {
        out.at(col,row) = coldata[row];
        }
      }
    }
  else
    {
    // reflect elements across the diagonal from lower triangle to upper triangle
    
    for(u32 col=0; col < N; ++col)
      {
      const eT* coldata = out.colptr(col);
      
      for(u32 row=(col+1); row < N; ++row)
        {
        out.at(col,row) = coldata[row];
        }
      }
    }
  }
Esempio n. 14
0
inline
void
interp1_helper_linear(const Mat<eT>& XG, const Mat<eT>& YG, const Mat<eT>& XI, Mat<eT>& YI, const eT extrap_val)
  {
  arma_extra_debug_sigprint();
  
  const eT XG_min = XG.min();
  const eT XG_max = XG.max();
  
  YI.copy_size(XI);
  
  const eT* XG_mem = XG.memptr();
  const eT* YG_mem = YG.memptr();
  const eT* XI_mem = XI.memptr();
        eT* YI_mem = YI.memptr();
  
  const uword NG = XG.n_elem;
  const uword NI = XI.n_elem;
  
  uword a_best_j = 0;
  uword b_best_j = 0;
  
  for(uword i=0; i<NI; ++i)
    {
    const eT XI_val = XI_mem[i];
    
    if((XI_val < XG_min) || (XI_val > XG_max))
      {
      YI_mem[i] = extrap_val;
      }
    else
      {
      // XG and XI are guaranteed to be sorted in ascending manner,
      // so start searching XG from last known optimum position 
      
      eT a_best_err = Datum<eT>::inf;
      eT b_best_err = Datum<eT>::inf;
      
      for(uword j=a_best_j; j<NG; ++j)
        {
        const eT tmp = XG_mem[j] - XI_val;
        const eT err = (tmp >= eT(0)) ? tmp : -tmp;
        
        if(err >= a_best_err)
          {
          break;
          }
        else
          {
          a_best_err = err;
          a_best_j   = j;
          }
        }
      
      if( (XG_mem[a_best_j] - XI_val) <= eT(0) )
        {
        // a_best_j is to the left of the interpolated position
        
        b_best_j = ( (a_best_j+1) < NG) ? (a_best_j+1) : a_best_j; 
        }
      else
        {
        // a_best_j is to the right of the interpolated position
        
        b_best_j = (a_best_j >= 1) ? (a_best_j-1) : a_best_j; 
        }
      
      b_best_err = std::abs( XG_mem[b_best_j] - XI_val );
      
      if(a_best_j > b_best_j)
        {
        std::swap(a_best_j,   b_best_j  );
        std::swap(a_best_err, b_best_err);
        }
      
      const eT weight = (a_best_err > eT(0)) ? (a_best_err / (a_best_err + b_best_err)) : eT(0);
      
      YI_mem[i] = (eT(1) - weight)*YG_mem[a_best_j] + (weight)*YG_mem[b_best_j];
      }
    }
  }
inline
bool
op_princomp::direct_princomp
  (
        Mat< std::complex<T> >& coeff_out,
        Mat< std::complex<T> >& score_out,
        Col<T>&                 latent_out,
        Col< std::complex<T> >& tsquared_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)
      {
      return false;
      }
    
    
    //U.reset();
    
    // normalize the eigenvalues
    s /= std::sqrt( double(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();
      
      Col<T> s_tmp = zeros< Col<T> >(n_cols);
      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
      s = s_tmp;
          
      // compute the Hotelling's T-squared   
      s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
      const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));                     
      tsquared_out = sum(S%S,1); 
      }
    else
      {
      // compute the Hotelling's T-squared   
      const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));                     
      tsquared_out = sum(S%S,1);
      }
    
    // compute the eigenvalues of the principal vectors
    latent_out = s%s;
    
    }
  else // 0 or 1 samples
    {
    coeff_out.eye(n_cols, n_cols);
    
    score_out.copy_size(in);
    score_out.zeros();
      
    latent_out.set_size(n_cols);
    latent_out.zeros();
      
    tsquared_out.set_size(n_rows);
    tsquared_out.zeros();
    }
  
  return true;
  }
inline
void
op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& X = tmp.M;
  
  if(X.is_empty()) { out.copy_size(X); return; }
  
  const uword dim = in.aux_uword_a;
  const uword N   = (dim == 0) ? X.n_rows : X.n_cols;
  
  // see "fn_sort_index.hpp" for the definition of "arma_sort_index_packet"
  // and the associated comparison functor
  std::vector< arma_sort_index_packet<int,uword> > packet_vec(N);
  
  for(uword i=0; i<N; ++i)
    {
    packet_vec[i].val   = std::rand();
    packet_vec[i].index = i;
    }
  
  arma_sort_index_helper_ascend comparator;

  std::sort( packet_vec.begin(), packet_vec.end(), comparator );
  
  const bool is_alias = (&out == &X);
  
  if(X.is_vec() == false)
    {
    if(is_alias == false)
      {
      arma_extra_debug_print("op_shuffle::apply(): matrix");
      
      out.copy_size(X);
      
      if(dim == 0)
        {
        for(uword i=0; i<N; ++i) { out.row(i) = X.row(packet_vec[i].index); }
        }
      else
        {
        for(uword i=0; i<N; ++i) { out.col(i) = X.col(packet_vec[i].index); }
        }
      }
    else  // in-place shuffle
      {
      arma_extra_debug_print("op_shuffle::apply(): in-place matrix");
      
      // reuse the val member variable of packet_vec
      // to indicate whether a particular row or column
      // has already been shuffled
      
      for(uword i=0; i<N; ++i)
        {
        packet_vec[i].val = 0;
        }
        
      if(dim == 0)
        {
        for(uword i=0; i<N; ++i)
          {
          if(packet_vec[i].val == 0)
            {
            const uword j = packet_vec[i].index;
            
            out.swap_rows(i, j);
            
            packet_vec[j].val = 1;
            }
          }
        }
      else
        {
        for(uword i=0; i<N; ++i)
          {
          if(packet_vec[i].val == 0)
            {
            const uword j = packet_vec[i].index;
            
            out.swap_cols(i, j);
            
            packet_vec[j].val = 1;
            }
          }
        }
      }
    }
  else  // we're dealing with a vector
    {
    if(is_alias == false)
      {
      arma_extra_debug_print("op_shuffle::apply(): vector");
      
      out.copy_size(X);
      
      if(dim == 0)
        {
        if(X.n_rows > 1)  // i.e. column vector
          {
          for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; }
          }
        else
          {
          out = X;
          }
        }
      else
        {
        if(X.n_cols > 1)  // i.e. row vector
          {
          for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; }
          }
        else
          {
          out = X;
          }
        }
      }
    else  // in-place shuffle
      {
      arma_extra_debug_print("op_shuffle::apply(): in-place vector");
      
      // reuse the val member variable of packet_vec
      // to indicate whether a particular row or column
      // has already been shuffled
      
      for(uword i=0; i<N; ++i)
        {
        packet_vec[i].val = 0;
        }
        
      if(dim == 0)
        {
        if(X.n_rows > 1)  // i.e. column vector
          {
          for(uword i=0; i<N; ++i)
            {
            if(packet_vec[i].val == 0)
              {
              const uword j = packet_vec[i].index;
              
              std::swap(out[i], out[j]);
              
              packet_vec[j].val = 1;
              }
            }
          }
        }
      else
        {
        if(X.n_cols > 1)  // i.e. row vector
          {
          for(uword i=0; i<N; ++i)
            {
            if(packet_vec[i].val == 0)
              {
              const uword j = packet_vec[i].index;
              
              std::swap(out[i], out[j]);
              
              packet_vec[j].val = 1;
              }
            }
          }
        }
      }
    }
  
  }
Esempio n. 17
0
inline
void
op_circshift::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_circshift>& in)
{
    arma_extra_debug_sigprint();
    
    typedef typename T1::elem_type eT;
    
    const unwrap<T1>   tmp(in.m);
    const Mat<eT>& X = tmp.M;
    
    if(X.is_empty()) { out.copy_size(X); return; }
    
    const uword dim = in.aux_uword_a;
    
    arma_debug_check( (dim > 1), "circshift(): dim must be 0 or 1" );
    
    const uword shift = in.aux_uword_b;
    
    const bool is_alias = (&out == &X);
    
    uword xshift = 0;
    uword yshift = 0;
    uword xdim = X.n_cols;
    uword ydim = X.n_rows;

    if(is_alias == 0) {
        
        out.copy_size(X);

        if(dim == 0) {
            xshift = shift;
            for (uword i = 0; i < xdim; i++) {
                uword ii = positive_modulo(i + xshift, xdim);
                for (uword j = 0; j < ydim; j++) {
                    uword jj = positive_modulo(j + yshift, ydim);
                    out(jj,ii) = X(j,i);
                }
            }
        } else {
            yshift = shift;
            for (uword i = 0; i < xdim; i++) {
                uword ii = positive_modulo(i + xshift, xdim);
                for (uword j = 0; j < ydim; j++) {
                    uword jj = positive_modulo(j + yshift, ydim);
                    out(jj,ii) = X(j,i);
                }
            }
        }
    } else { //X is an alias of out (same memory address)
        Mat<eT> temp;
        temp.copy_size(X);
        temp = X;
        
        if(dim == 0) {
            xshift = shift;
            for (uword i = 0; i < xdim; i++) {
                uword ii = positive_modulo(i + xshift, xdim);
                for (uword j = 0; j < ydim; j++) {
                    uword jj = positive_modulo(j + yshift, ydim);
                    out(jj,ii) = temp(j,i);
                }
            }
        } else {
            yshift = shift;
            for (uword i = 0; i < xdim; i++) {
                uword ii = positive_modulo(i + xshift, xdim);
                for (uword j = 0; j < ydim; j++) {
                    uword jj = positive_modulo(j + yshift, ydim);
                    out(jj,ii) = temp(j,i);
                }
            }
        }
    }
    
}
Esempio n. 18
0
inline
void
op_princomp::direct_princomp
  (
        Mat<eT>& coeff_out,
        Mat<eT>& score_out,
        Col<eT>& latent_out, 
        Col<eT>& tsquared_out,
  const Mat<eT>& in
  )
  {
  arma_extra_debug_sigprint();

  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<eT> 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();
      latent_out.reset();
      tsquared_out.reset();
      
      return;
      }
    
    
    //U.reset();  // TODO: do we need this ?  U will get automatically deleted anyway
    
    // 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();
      
      //Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
      Col<eT> s_tmp(n_cols);
      s_tmp.zeros();
      
      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
      s = s_tmp;
          
      // compute the Hotelling's T-squared
      s_tmp.rows(0,n_rows-2) = eT(1) / s_tmp.rows(0,n_rows-2);
      
      const Mat<eT> S = score_out * diagmat(Col<eT>(s_tmp));   
      tsquared_out = sum(S%S,1); 
      }
    else
      {
      // compute the Hotelling's T-squared   
      const Mat<eT> S = score_out * diagmat(Col<eT>( eT(1) / s));
      tsquared_out = sum(S%S,1);
      }
            
    // compute the eigenvalues of the principal vectors
    latent_out = s%s;
    }
  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();
      
      latent_out.set_size(n_cols);
      latent_out.zeros();
      
      tsquared_out.set_size(1);
      tsquared_out.zeros();    
      }
    else
      {
      coeff_out.reset();
      score_out.reset();
      latent_out.reset();
      tsquared_out.reset();
      }
    }
  
  }
Esempio n. 19
0
inline
void
op_princomp::direct_princomp
  (
        Mat< std::complex<T> >& coeff_out,
        Mat< std::complex<T> >& score_out,
        Col<T>&                 latent_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();
      latent_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();
      
      Col<T> s_tmp = zeros< Col<T> >(n_cols);
      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
      s = s_tmp;
      }
      
    // compute the eigenvalues of the principal vectors
    latent_out = s%s;

    }
  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();
      latent_out.set_size(n_cols);
      latent_out.zeros();
      }
    else
      {
      coeff_out.reset();
      score_out.reset();
      latent_out.reset();
      }
    }
  }
Esempio n. 20
0
inline
bool
op_princomp::direct_princomp
  (
         Mat< std::complex<typename T1::pod_type> >&     coeff_out,
         Mat< std::complex<typename T1::pod_type> >&     score_out,
         Col<              typename T1::pod_type  >&     latent_out,
         Col< std::complex<typename T1::pod_type> >&     tsquared_out,
  const Base< std::complex<typename T1::pod_type>, T1 >& X,
  const typename arma_cx_only<typename T1::elem_type>::result* junk
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::pod_type     T;
  typedef          std::complex<T> eT;
  
  const unwrap_check<T1> Y( X.get_ref(), score_out );
  const Mat<eT>& in    = Y.M;
  
  const uword n_rows = in.n_rows;
  const uword 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;  score_out.each_row() -= mean(in);
 	  
    // singular value decomposition
    Mat<eT> U;
    Col< T> s;
    
    const bool svd_ok = svd(U, s, coeff_out, score_out); 
    
    if(svd_ok == false)  { return false; }
    
    // normalize the eigenvalues
    s /= std::sqrt( double(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();
      
      Col<T> s_tmp = zeros< Col<T> >(n_cols);
      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
      s = s_tmp;
          
      // compute the Hotelling's T-squared   
      s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
      const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));                     
      tsquared_out = sum(S%S,1); 
      }
    else
      {
      // compute the Hotelling's T-squared   
      const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));                     
      tsquared_out = sum(S%S,1);
      }
    
    // compute the eigenvalues of the principal vectors
    latent_out = s%s;
    
    }
  else // 0 or 1 samples
    {
    coeff_out.eye(n_cols, n_cols);
    
    score_out.copy_size(in);
    score_out.zeros();
      
    latent_out.set_size(n_cols);
    latent_out.zeros();
      
    tsquared_out.set_size(n_rows);
    tsquared_out.zeros();
    }
  
  return true;
  }
Esempio n. 21
0
inline
void
op_trimat::apply_htrans
  (
        Mat<eT>& out,
  const Mat<eT>& A,
  const bool     upper,
  const typename arma_not_cx<eT>::result* junk
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also
  // trimatu(trans(X)) = trans(trimatl(X)).  We want to avoid the creation of an
  // extra temporary.
  
  // It doesn't matter if the input and output matrices are the same; we will
  // pull data from the upper or lower triangular to the lower or upper
  // triangular (respectively) and then set the rest to 0, so overwriting issues
  // aren't present.
  
  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" );
  
  const uword N = A.n_rows;
  
  if(&out != &A)
    {
    out.copy_size(A);
    }
  
  // We can't really get away with any array copy operations here,
  // unfortunately...
  
  if(upper)
    {
    // Upper triangular: but since we're transposing, we're taking the lower
    // triangular and putting it in the upper half.
    for(uword row = 0; row < N; ++row)
      {
      eT* out_colptr = out.colptr(row);
      
      for(uword col = 0; col <= row; ++col)
        {
        //out.at(col, row) = A.at(row, col);
        out_colptr[col] = A.at(row, col);
        }
      }
    }
  else
    {
    // Lower triangular: but since we're transposing, we're taking the upper
    // triangular and putting it in the lower half.
    for(uword row = 0; row < N; ++row)
      {
      for(uword col = row; col < N; ++col)
        {
        out.at(col, row) = A.at(row, col);
        }
      }
    }
  
  op_trimat::fill_zeros(out, upper);
  }
inline
void
op_sort::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap_check<T1>   tmp(in.m, out);
  const Mat<eT>&       X = tmp.M;
  
  const uword sort_type = in.aux_uword_a;
  const uword dim       = in.aux_uword_b;
  
  arma_debug_check( (sort_type > 1),          "sort(): incorrect usage. sort_type must be 0 or 1");
  arma_debug_check( (dim > 1),                "sort(): incorrect usage. dim must be 0 or 1"      );
  arma_debug_check( (X.is_finite() == false), "sort(): given object has non-finite elements"     );
  
  if( (X.n_rows * X.n_cols) <= 1 )
    {
    out = X;
    return;
    }
  
  
  if(dim == 0)  // sort the contents of each column
    {
    arma_extra_debug_print("op_sort::apply(), dim = 0");
    
    out = X;
    
    const uword n_rows = out.n_rows;
    const uword n_cols = out.n_cols;
      
    for(uword col=0; col < n_cols; ++col)
      {
      op_sort::direct_sort( out.colptr(col), n_rows, sort_type );
      }
    }
  else
  if(dim == 1)  // sort the contents of each row
    {
    if(X.n_rows == 1)  // a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
      
      out = X;
      op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
      }
    else  // not a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
      
      out.copy_size(X);
      
      const uword n_rows = out.n_rows;
      const uword n_cols = out.n_cols;
      
      podarray<eT> tmp_array(n_cols);
      
      for(uword row=0; row < n_rows; ++row)
        {
        op_sort::copy_row(tmp_array.memptr(), X, row);
        
        op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type );
        
        op_sort::copy_row(out, tmp_array.memptr(), row);
        }
      }
    }
  
  }
Esempio n. 23
0
inline
void
op_sort::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const unwrap<T1>   tmp(in.m);
  const Mat<eT>& X = tmp.M;
  
  const u32 sort_type = in.aux_u32_a;
  const u32 dim       = in.aux_u32_b;
  
  arma_debug_check( (X.is_finite() == false), "sort(): given object has non-finite elements"     );
  arma_debug_check( (sort_type > 1),          "sort(): incorrect usage. sort_type must be 0 or 1");
  arma_debug_check( (dim > 1),                "sort(): incorrect usage. dim must be 0 or 1"      );
  
  
  if(dim == 0)  // column-wise
    {
    arma_extra_debug_print("op_sort::apply(), dim = 0");
    
    out = X;
    
    for(u32 col=0; col<out.n_cols; ++col)
      {
      op_sort::direct_sort( out.colptr(col), out.n_rows, sort_type );
      }
    }
  else
  if(dim == 1)  // row-wise
    {
    if(X.n_rows != 1)  // not a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
      
      //out.set_size(X.n_rows, X.n_cols);
      out.copy_size(X);
      
      podarray<eT> tmp_array(X.n_cols);
      
      for(u32 row=0; row<out.n_rows; ++row)
        {
        
        for(u32 col=0; col<out.n_cols; ++col)
          {
          tmp_array[col] = X.at(row,col);
          }
        
        op_sort::direct_sort( tmp_array.memptr(), out.n_cols, sort_type );
        
        for(u32 col=0; col<out.n_cols; ++col)
          {
          out.at(row,col) = tmp_array[col];
          }
        
        }
      }
    else  // a row vector
      {
      arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
      
      out = X;
      op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
      }
    }
  
  }