inline
void
op_stable_sort_index::apply(Mat<uword>& out, const mtOp<uword,T1,op_stable_sort_index>& in)
  {
  arma_extra_debug_sigprint();
  
  const Proxy<T1> P(in.m);
  
  if(P.get_n_elem() == 0)  { out.set_size(0,1); return; }
  
  const uword sort_type = in.aux_uword_a;
  
  bool all_non_nan = false;
  
  if(P.is_alias(out))
    {
    Mat<uword> out2;
    
    all_non_nan = op_stable_sort_index::apply_noalias(out2, P, sort_type);
    
    out.steal_mem(out2);
    }
  else
    {
    all_non_nan = op_stable_sort_index::apply_noalias(out, P, sort_type);
    }
  
  arma_debug_check( (all_non_nan == false), "stable_sort_index(): detected NaN" );
  }
arma_hot
inline
void
op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const uword dim = in.aux_uword_a;
  arma_debug_check( (dim > 1), "sum(): parameter 'dim' must be 0 or 1" );
  
  const Proxy<T1> P(in.m);
  
  if(P.is_alias(out) == false)
    {
    op_sum::apply_noalias(out, P, dim);
    }
  else
    {
    Mat<eT> tmp;
    
    op_sum::apply_noalias(tmp, P, dim);
    
    out.steal_mem(tmp);
    }
  }
Example #3
0
inline
void
op_nonzeros::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_nonzeros>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> P(X.m);
  
  if(P.get_n_elem() == 0)  { out.set_size(0,1); return; }
  
  if(P.is_alias(out))
    {
    Mat<eT> out2;
    
    op_nonzeros::apply_noalias(out2, P);
    
    out.steal_mem(out2);
    }
  else
    {
    op_nonzeros::apply_noalias(out, P);
    }
  }
inline
void
op_diagmat2::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat2>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const uword row_offset = X.aux_uword_a;
  const uword col_offset = X.aux_uword_b;
  
  const Proxy<T1> P(X.m);
  
  if(P.is_alias(out))
    {
    Mat<eT> tmp;
    
    op_diagmat2::apply(tmp, P, row_offset, col_offset);
    
    out.steal_mem(tmp);
    }
  else
    {
    op_diagmat2::apply(out, P, row_offset, col_offset);
    }
  }
inline
void
glue_max::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_max>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> PA(X.A);
  const Proxy<T2> PB(X.B);
  
  if(PA.is_alias(out) || PB.is_alias(out))
    {
    Mat<eT> tmp;
    
    glue_max::apply(tmp, PA, PB);
    
    out.steal_mem(tmp);
    }
  else
    {
    glue_max::apply(out, PA, PB);
    }
  }
inline
void
op_vectorise_row::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  if(P.is_alias(out) == false)
    {
    out.set_size( 1, P.get_n_elem() );
    
    eT* outmem = out.memptr();
    
    const uword n_rows = P.get_n_rows();
    const uword n_cols = P.get_n_cols();
    
    for(uword row=0; row < n_rows; ++row)
      {
      uword i,j;
      
      for(i=0, j=1; j < n_cols; i+=2, j+=2)
        {
        const eT tmp_i = P.at(row,i);
        const eT tmp_j = P.at(row,j);
        
        *outmem = tmp_i; outmem++;
        *outmem = tmp_j; outmem++;
        }
      
      if(i < n_cols)
        {
        *outmem = P.at(row,i); outmem++;
        }
      }
    }
  else  // we have aliasing
    {
    arma_extra_debug_print("op_vectorise_row::apply(): aliasing detected");
    
    Mat<eT> tmp;
    
    op_vectorise_row::apply_proxy(tmp, P);
    
    out.steal_mem(tmp);
    }
  }
Example #7
0
inline
bool
eig_sym
  (
         Col<typename T1::pod_type>&     eigval,
         Mat<typename T1::elem_type>&    eigvec,
  const Base<typename T1::elem_type,T1>& X,
  const char* method =                   "dc",
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::elem_type eT;
  
  const char sig = (method != NULL) ? method[0] : char(0);
  
  arma_debug_check( ((sig != 's') && (sig != 'd')),         "eig_sym(): unknown method specified"                             );
  arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eig_sym(): parameter 'eigval' is an alias of parameter 'eigvec'" );
  
  const Proxy<T1> P(X.get_ref());
  
  const bool is_alias = P.is_alias(eigvec);
  
  Mat<eT>  eigvec_tmp;
  Mat<eT>& eigvec_out = (is_alias == false) ? eigvec : eigvec_tmp;
  
  bool status = false;
  
  if(sig == 'd')       { status = auxlib::eig_sym_dc(eigval, eigvec_out, P.Q); }
  
  if(status == false)  { status = auxlib::eig_sym(eigval, eigvec_out, P.Q);    }
  
  if(status == false)
    {
    eigval.reset();
    eigvec.reset();
    arma_debug_warn("eig_sym(): decomposition failed");
    }
  else
    {
    if(is_alias)  { eigvec.steal_mem(eigvec_tmp); }
    }
  
  return status;
  }
Example #8
0
inline
void
op_flipud::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in)
  {
  arma_extra_debug_sigprint();
  
  const Proxy<T1> P(in.m);
  
  if(is_Mat<typename Proxy<T1>::stored_type>::value || P.is_alias(out))
    {
    const unwrap<typename Proxy<T1>::stored_type> U(P.Q);
    
    op_flipud::apply_direct(out, U.M);
    }
  else
    {
    op_flipud::apply_proxy_noalias(out, P);
    }
  }
inline
void
op_ifft_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_ifft_cx>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> P(in.m);
  
  if(P.is_alias(out) == false)
    {
    op_fft_cx::apply_noalias<T1,true>(out, P, in.aux_uword_a, in.aux_uword_b);
    }
  else
    {
    Mat<eT> tmp;
    
    op_fft_cx::apply_noalias<T1,true>(tmp, P, in.aux_uword_a, in.aux_uword_b);
    
    out.steal_mem(tmp);
    }
  }
inline
void
op_clamp::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::elem_type, T1, op_clamp>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> P(in.m);
  
  if(P.is_alias(out) && (is_Mat<T1>::value == false))
    {
    Mat<eT> tmp;
    
    op_clamp::apply_noalias(tmp, P, in.aux, in.aux_out_eT);
    
    out.steal_mem(tmp);
    }
  else
    {
    op_clamp::apply_noalias(out, P, in.aux, in.aux_out_eT);
    }
  }
Example #11
0
inline
void
op_any::apply(Mat<uword>& out, const mtOp<uword, T1, op_any>& X)
  {
  arma_extra_debug_sigprint();
  
  const uword dim = X.aux_uword_a;
  
  const Proxy<T1> P(X.m);
  
  if(P.is_alias(out) == false)
    {
    op_any::apply_helper(out, P, dim);
    }
  else
    {
    Mat<uword> out2;
    
    op_any::apply_helper(out2, P, dim);
    
    out.steal_mem(out2);
    }
  }
inline
void
op_reshape::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const Proxy<T1> P(in.m);
  
  const uword in_n_rows = in.aux_uword_a;
  const uword in_n_cols = in.aux_uword_b;
  
  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
    {
    // not checking for aliasing here, as this might be an inplace reshape
    
    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
    
    op_reshape::apply_unwrap(out, tmp.M, in_n_rows, in_n_cols, uword(0));
    }
  else
    {
    if(P.is_alias(out))
      {
      Mat<eT> tmp;
      
      op_reshape::apply_proxy(tmp, P, in_n_rows, in_n_cols);
      
      out.steal_mem(tmp);
      }
    else
      {
      op_reshape::apply_proxy(out, P, in_n_rows, in_n_cols);
      }
    }
  }
Example #13
0
arma_hot
inline
void
op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const uword dim = in.aux_uword_a;
  arma_debug_check( (dim > 1), "sum(): incorrect usage. dim must be 0 or 1");
  
  const Proxy<T1> P(in.m);
  
  typedef typename Proxy<T1>::stored_type P_stored_type;
  
  const bool is_alias = P.is_alias(out);
  
  if( (is_Mat<P_stored_type>::value == true) || is_alias )
    {
    const unwrap_check<P_stored_type> tmp(P.Q, is_alias);
    
    const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M;
    
    const uword X_n_rows = X.n_rows;
    const uword X_n_cols = X.n_cols;
    
    if(dim == 0)  // traverse across rows (i.e. find the sum in each column)
      {
      out.set_size(1, X_n_cols);
      
      eT* out_mem = out.memptr();
      
      for(uword col=0; col < X_n_cols; ++col)
        {
        out_mem[col] = arrayops::accumulate( X.colptr(col), X_n_rows );
        }
      }
    else  // traverse across columns (i.e. find the sum in each row)
      {
      out.set_size(X_n_rows, 1);
      
      eT* out_mem = out.memptr();
        
      for(uword row=0; row < X_n_rows; ++row)
        {
        eT val = eT(0);
        
        uword i,j;
        for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
          {
          val += X.at(row,i);
          val += X.at(row,j);
          }
        
        if(i < X_n_cols)
          {
          val += X.at(row,i);
          }
        
        out_mem[row] = val;
        }
      }
    }
  else
    {
    const uword P_n_rows = P.get_n_rows();
    const uword P_n_cols = P.get_n_cols();
    
    if(dim == 0)  // traverse across rows (i.e. find the sum in each column)
      {
      out.set_size(1, P_n_cols);
      
      eT* out_mem = out.memptr();
      
      for(uword col=0; col < P_n_cols; ++col)
        {
        eT val = eT(0);
        
        uword i,j;
        for(i=0, j=1; j < P_n_rows; i+=2, j+=2)
          {
          val += P.at(i,col);
          val += P.at(j,col);
          }
        
        if(i < P_n_rows)
          {
          val += P.at(i,col);
          }
        
        out_mem[col] = val;
        }
      }
    else  // traverse across columns (i.e. find the sum in each row)
      {
      out.set_size(P_n_rows, 1);
      
      eT* out_mem = out.memptr();
      
      for(uword row=0; row < P_n_rows; ++row)
        {
        eT val = eT(0);
        
        uword i,j;
        for(i=0, j=1; j < P_n_cols; i+=2, j+=2)
          {
          val += P.at(row,i);
          val += P.at(row,j);
          }
        
        if(i < P_n_cols)
          {
          val += P.at(row,i);
          }
        
        out_mem[row] = val;
        }
      }
    }
  }
inline
void
op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  const uword dim = in.aux_uword_a;
  arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" );
  
  const Proxy<T1> P(in.m);
  
  typedef typename Proxy<T1>::stored_type P_stored_type;
  
  const bool is_alias = P.is_alias(out);
  
  if( (is_Mat<P_stored_type>::value == true) || is_alias )
    {
    const unwrap_check<P_stored_type> tmp(P.Q, is_alias);
    
    const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M;
    
    const uword X_n_rows = X.n_rows;
    const uword X_n_cols = X.n_cols;
    
    if(dim == 0)  // in each column
      {
      arma_extra_debug_print("op_median::apply(): dim = 0");
      
      out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols);
      
      if(X_n_rows > 0)
        {
        std::vector<eT> tmp_vec(X_n_rows);
        
        for(uword col=0; col < X_n_cols; ++col)
          {
          arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows );
          
          out[col] = op_median::direct_median(tmp_vec);
          }
        }
      }
    else  // in each row
      {
      arma_extra_debug_print("op_median::apply(): dim = 1");
      
      out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
      
      if(X_n_cols > 0)
        {
        std::vector<eT> tmp_vec(X_n_cols);
          
        for(uword row=0; row < X_n_rows; ++row)
          {
          for(uword col=0; col < X_n_cols; ++col)  { tmp_vec[col] = X.at(row,col); }
          
          out[row] = op_median::direct_median(tmp_vec);
          }
        }
      }
    }
  else
    {
    const uword P_n_rows = P.get_n_rows();
    const uword P_n_cols = P.get_n_cols();
    
    if(dim == 0)  // in each column
      {
      arma_extra_debug_print("op_median::apply(): dim = 0");
      
      out.set_size((P_n_rows > 0) ? 1 : 0, P_n_cols);
      
      if(P_n_rows > 0)
        {
        std::vector<eT> tmp_vec(P_n_rows);
        
        for(uword col=0; col < P_n_cols; ++col)
          {
          for(uword row=0; row < P_n_rows; ++row)  { tmp_vec[row] = P.at(row,col); }
          
          out[col] = op_median::direct_median(tmp_vec);
          }
        }
      }
    else  // in each row
      {
      arma_extra_debug_print("op_median::apply(): dim = 1");
      
      out.set_size(P_n_rows, (P_n_cols > 0) ? 1 : 0);
      
      if(P_n_cols > 0)
        {
        std::vector<eT> tmp_vec(P_n_cols);
          
        for(uword row=0; row < P_n_rows; ++row)
          {
          for(uword col=0; col < P_n_cols; ++col)  { tmp_vec[col] = P.at(row,col); }
          
          out[row] = op_median::direct_median(tmp_vec);
          }
        }
      }
    }
  }
inline
void
op_vectorise_col::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  
  if(P.is_alias(out) == false)
    {
    const uword N = P.get_n_elem();
    
    out.set_size(N, 1);
      
    if(is_Mat<typename Proxy<T1>::stored_type>::value == true)
      {
      const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
      
      arrayops::copy(out.memptr(), tmp.M.memptr(), N);
      }
    else
      {
      eT* outmem = out.memptr();
      
      if(Proxy<T1>::use_at == false)
        {
        // TODO: add handling of aligned access ?
        
        typename Proxy<T1>::ea_type A = P.get_ea();
        
        uword i,j;
        
        for(i=0, j=1; j < N; i+=2, j+=2)
          {
          const eT tmp_i = A[i];
          const eT tmp_j = A[j];
          
          outmem[i] = tmp_i;
          outmem[j] = tmp_j;
          }
        
        if(i < N)
          {
          outmem[i] = A[i];
          }
        }
      else
        {
        const uword n_rows = P.get_n_rows();
        const uword n_cols = P.get_n_cols();
        
        if(n_rows == 1)
          {
          for(uword i=0; i < n_cols; ++i)
            {
            outmem[i] = P.at(0,i);
            }
          }
        else
          {
          for(uword col=0; col < n_cols; ++col)
          for(uword row=0; row < n_rows; ++row)
            {
            *outmem = P.at(row,col);
            outmem++;
            }
          }
        }
      }
    }
  else  // we have aliasing
    {
    arma_extra_debug_print("op_vectorise_col::apply(): aliasing detected");
    
    if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
      {
      out.set_size(out.n_elem, 1);  // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same
      }
    else
      {
      Mat<eT> tmp;
      
      op_vectorise_col::apply_proxy(tmp, P);
      
      out.steal_mem(tmp);
      }
    }
  }
inline
void
subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
  {
  arma_extra_debug_sigprint();
  
  Mat<eT>& m_local = *m_ptr;
  
        eT* m_mem    = m_local.memptr();
  const u32 m_n_elem = m_local.n_elem;
  
  const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
  const umat& aa = tmp.M;
  
  arma_debug_check
    (
    ( aa.is_vec() == false ),
    "Mat::elem(): given object is not a vector"
    );
  
  const u32* aa_mem    = aa.memptr();
  const u32  aa_n_elem = aa.n_elem;
  
  const Proxy<T2> P(x.get_ref());
  
  arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
  
  if(P.is_alias(m) == false)
    {
    typename Proxy<T2>::ea_type X = P.get_ea();
    
    u32 i,j;
    for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
      {
      const u32 ii = aa_mem[i];
      const u32 jj = aa_mem[j];
      
      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; m_mem[jj]  = X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; }
      }
    
    if(i < aa_n_elem)
      {
      const u32 ii = aa_mem[i];
      
      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; }
      }
    }
  else
    {
    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing detected");
    
    const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, m_local);
    const Mat<eT>& M = tmp.M;
    
    const eT* X = M.memptr();
    
    u32 i,j;
    for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
      {
      const u32 ii = aa_mem[i];
      const u32 jj = aa_mem[j];
      
      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; m_mem[jj]  = X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; }
      }
    
    if(i < aa_n_elem)
      {
      const u32 ii = aa_mem[i];
      
      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; }
      }
    }
  }
Example #17
0
inline
void
diagview<eT>::operator/=(const Base<eT,T1>& o)
  {
  arma_extra_debug_sigprint();
  
  diagview<eT>& d = *this;
  
  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
  
  const uword d_n_elem     = d.n_elem;
  const uword d_row_offset = d.row_offset;
  const uword d_col_offset = d.col_offset;
    
  const Proxy<T1> P( o.get_ref() );
  
  arma_debug_check
    (
    ( (d_n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
    "diagview: given object has incompatible size"
    );
  
  const bool is_alias = P.is_alias(d_m);
  
  arma_extra_debug_warn(is_alias, "aliasing detected");
  
  if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::prefer_at_accessor) || (is_alias) )
    {
    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
    const Mat<eT>& x = tmp.M;
    
    const eT* x_mem = x.memptr();
    
    uword ii,jj;
    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
      {
      const eT tmp_i = x_mem[ii];
      const eT tmp_j = x_mem[jj];
      
      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= tmp_i;
      d_m.at( jj + d_row_offset,  jj + d_col_offset) /= tmp_j;
      }
    
    if(ii < d_n_elem)
      {
      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= x_mem[ii];
      }
    }
  else
    {
    typename Proxy<T1>::ea_type Pea = P.get_ea();
      
    uword ii,jj;
    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
      {
      const eT tmp_i = Pea[ii];
      const eT tmp_j = Pea[jj];
      
      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= tmp_i;
      d_m.at( jj + d_row_offset,  jj + d_col_offset) /= tmp_j;
      }
    
    if(ii < d_n_elem)
      {
      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= Pea[ii];
      }
    }
  }
inline
void
subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
  {
  arma_extra_debug_sigprint();
  
  Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  
        eT*   m_mem    = m_local.memptr();
  const uword m_n_elem = m_local.n_elem;
  
  const unwrap_check_mixed<T1> aa_tmp(a.get_ref(), m_local);
  const umat& aa = aa_tmp.M;
  
  arma_debug_check
    (
    ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
    "Mat::elem(): given object is not a vector"
    );
  
  const uword* aa_mem    = aa.memptr();
  const uword  aa_n_elem = aa.n_elem;
  
  const Proxy<T2> P(x.get_ref());
  
  arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
  
  const bool is_alias = P.is_alias(m);
  
  if( (is_alias == false) && (Proxy<T2>::prefer_at_accessor == false) )
    {
    typename Proxy<T2>::ea_type X = P.get_ea();
    
    uword iq,jq;
    for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
      {
      const uword ii = aa_mem[iq];
      const uword jj = aa_mem[jq];
      
      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::yes) { m_mem[ii] =  X[iq]; m_mem[jj]  = X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
      }
    
    if(iq < aa_n_elem)
      {
      const uword ii = aa_mem[iq];
      
      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::yes) { m_mem[ii] =  X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::yes) { m_mem[ii] /= X[iq]; }
      }
    }
  else
    {
    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing or prefer_at_accessor detected");
    
    const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, is_alias);
    const Mat<eT>& M = tmp.M;
    
    const eT* X = M.memptr();
    
    uword iq,jq;
    for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
      {
      const uword ii = aa_mem[iq];
      const uword jj = aa_mem[jq];
      
      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::yes) { m_mem[ii] =  X[iq]; m_mem[jj]  = X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
      }
    
    if(iq < aa_n_elem)
      {
      const uword ii = aa_mem[iq];
      
      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
      
           if(is_same_type<op_type, op_subview_elem_equ          >::yes) { m_mem[ii] =  X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; }
      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::yes) { m_mem[ii] /= X[iq]; }
      }
    }
  }
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 Proxy<T1> P(X.m);
  
  const uword n_rows = P.get_n_rows();
  const uword n_cols = P.get_n_cols();
  
  const bool P_is_vec = (n_rows == 1) || (n_cols == 1);
  
  
  if(P.is_alias(out) == false)
    {
    if(P_is_vec)    // generate a diagonal matrix out of a vector
      {
      const uword N = (n_rows == 1) ? n_cols : n_rows;
      
      out.zeros(N, N);
      
      if(Proxy<T1>::prefer_at_accessor == false)
        {
        typename Proxy<T1>::ea_type P_ea = P.get_ea();
        
        for(uword i=0; i < N; ++i) { out.at(i,i) = P_ea[i]; }
        }
      else
        {
        if(n_rows == 1)
          {
          for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(0,i); }
          }
        else
          {
          for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,0); }
          }
        }
      }
    else   // generate a diagonal matrix out of a matrix
      {
      out.zeros(n_rows, n_cols);
      
      const uword N = (std::min)(n_rows, n_cols);
      
      for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,i); }
      }
    }
  else   // we have aliasing
    {
    if(P_is_vec)   // generate a diagonal matrix out of a vector
      {
      const uword N = (n_rows == 1) ? n_cols : n_rows;
      
      podarray<eT> tmp(N);
      eT* tmp_mem = tmp.memptr();
      
      if(Proxy<T1>::prefer_at_accessor == false)
        {
        typename Proxy<T1>::ea_type P_ea = P.get_ea();
        
        for(uword i=0; i < N; ++i) { tmp_mem[i] = P_ea[i]; }
        }
      else
        {
        if(n_rows == 1)
          {
          for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(0,i); }
          }
        else
          {
          for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(i,0); }
          }
        }
      
      out.zeros(N, N);
      
      for(uword i=0; i < N; ++i) { out.at(i,i) = tmp_mem[i]; }
      }
    else   // generate a diagonal matrix out of a matrix
      {
      const uword N = (std::min)(n_rows, n_cols);
      
      if( (Proxy<T1>::has_subview == false) && (Proxy<T1>::fake_mat == false) )
        {
        // NOTE: we have aliasing and it's not due to a subview, hence we're assuming that the output matrix already has the correct size
        
        for(uword i=0; i < n_cols; ++i)
          {
          if(i < N)
            {
            const eT val = P.at(i,i);
            
            arrayops::fill_zeros(out.colptr(i), n_rows);
            
            out.at(i,i) = val;
            }
          else
            {
            arrayops::fill_zeros(out.colptr(i), n_rows);
            }
          }
        }
      else
        {
        podarray<eT> tmp(N);
        eT* tmp_mem = tmp.memptr();
        
        for(uword i=0; i < N; ++i)  { tmp_mem[i] = P.at(i,i); }
        
        out.zeros(n_rows, n_cols);
        
        for(uword i=0; i < N; ++i)  { out.at(i,i) = tmp_mem[i]; }
        }
      }
    }
  }