op_trimat_meat.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2010-2011 Conrad Sanderson
00003 // Copyright (C) 2011      Ryan Curtin
00004 // 
00005 // This file is part of the Armadillo C++ library.
00006 // It is provided without any warranty of fitness
00007 // for any purpose. You can redistribute this file
00008 // and/or modify it under the terms of the GNU
00009 // Lesser General Public License (LGPL) as published
00010 // by the Free Software Foundation, either version 3
00011 // of the License or (at your option) any later version.
00012 // (see http://www.opensource.org/licenses for more info)
00013 
00014 
00017 
00018 
00019 
00020 template<typename eT>
00021 inline
00022 void
00023 op_trimat::fill_zeros(Mat<eT>& out, const bool upper)
00024   {
00025   arma_extra_debug_sigprint();
00026   
00027   const uword N = out.n_rows;
00028   
00029   if(upper)
00030     {
00031     // upper triangular: set all elements below the diagonal to zero
00032     
00033     for(uword i=0; i<N; ++i)
00034       {
00035       eT* data = out.colptr(i);
00036       
00037       arrayops::inplace_set( &data[i+1], eT(0), (N-(i+1)) );
00038       }
00039     }
00040   else
00041     {
00042     // lower triangular: set all elements above the diagonal to zero
00043     
00044     for(uword i=1; i<N; ++i)
00045       {
00046       eT* data = out.colptr(i);
00047       
00048       arrayops::inplace_set( data, eT(0), i );
00049       }
00050     }
00051   }
00052 
00053 
00054 
00055 template<typename T1>
00056 inline
00057 void
00058 op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in)
00059   {
00060   arma_extra_debug_sigprint();
00061   
00062   typedef typename T1::elem_type eT;
00063   
00064   const unwrap<T1> tmp(in.m);
00065   const Mat<eT>& A = tmp.M;
00066   
00067   arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
00068   
00069   const uword  N     = A.n_rows;
00070   const bool upper = (in.aux_uword_a == 0);
00071   
00072   if(&out != &A)
00073     {
00074     out.copy_size(A);
00075     
00076     if(upper)
00077       {
00078       // upper triangular: copy the diagonal and the elements above the diagonal
00079       for(uword i=0; i<N; ++i)
00080         {
00081         const eT* A_data   = A.colptr(i);
00082               eT* out_data = out.colptr(i);
00083         
00084         arrayops::copy( out_data, A_data, i+1 );
00085         }
00086       }
00087     else
00088       {
00089       // lower triangular: copy the diagonal and the elements below the diagonal
00090       for(uword i=0; i<N; ++i)
00091         {
00092         const eT* A_data   = A.colptr(i);
00093               eT* out_data = out.colptr(i);
00094         
00095         arrayops::copy( &out_data[i], &A_data[i], N-i );
00096         }
00097       }
00098     }
00099   
00100   op_trimat::fill_zeros(out, upper);
00101   }
00102 
00103 
00104 
00105 template<typename T1>
00106 inline
00107 void
00108 op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<Op<T1, op_htrans>, op_trimat>& in)
00109   {
00110   arma_extra_debug_sigprint();
00111   
00112   typedef typename T1::elem_type eT;
00113   
00114   const unwrap<T1>   tmp(in.m.m);
00115   const Mat<eT>& A = tmp.M;
00116   
00117   const bool upper = (in.aux_uword_a == 0);
00118   
00119   op_trimat::apply_htrans(out, A, upper);
00120   }
00121 
00122 
00123 
00124 template<typename eT>
00125 inline
00126 void
00127 op_trimat::apply_htrans
00128   (
00129         Mat<eT>& out,
00130   const Mat<eT>& A,
00131   const bool     upper,
00132   const typename arma_not_cx<eT>::result* junk
00133   )
00134   {
00135   arma_extra_debug_sigprint();
00136   arma_ignore(junk);
00137   
00138   // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also
00139   // trimatu(trans(X)) = trans(trimatl(X)).  We want to avoid the creation of an
00140   // extra temporary.
00141   
00142   // It doesn't matter if the input and output matrices are the same; we will
00143   // pull data from the upper or lower triangular to the lower or upper
00144   // triangular (respectively) and then set the rest to 0, so overwriting issues
00145   // aren't present.
00146   
00147   arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
00148   
00149   const uword N = A.n_rows;
00150   
00151   if(&out != &A)
00152     {
00153     out.copy_size(A);
00154     }
00155   
00156   // We can't really get away with any array copy operations here,
00157   // unfortunately...
00158   
00159   if(upper)
00160     {
00161     // Upper triangular: but since we're transposing, we're taking the lower
00162     // triangular and putting it in the upper half.
00163     for(uword row = 0; row < N; ++row)
00164       {
00165       eT* out_colptr = out.colptr(row);
00166       
00167       for(uword col = 0; col <= row; ++col)
00168         {
00169         //out.at(col, row) = A.at(row, col);
00170         out_colptr[col] = A.at(row, col);
00171         }
00172       }
00173     }
00174   else
00175     {
00176     // Lower triangular: but since we're transposing, we're taking the upper
00177     // triangular and putting it in the lower half.
00178     for(uword row = 0; row < N; ++row)
00179       {
00180       for(uword col = row; col < N; ++col)
00181         {
00182         out.at(col, row) = A.at(row, col);
00183         }
00184       }
00185     }
00186   
00187   op_trimat::fill_zeros(out, upper);
00188   }
00189 
00190 
00191 
00192 template<typename eT>
00193 inline
00194 void
00195 op_trimat::apply_htrans
00196   (
00197         Mat<eT>& out,
00198   const Mat<eT>& A,
00199   const bool     upper,
00200   const typename arma_cx_only<eT>::result* junk
00201   )
00202   {
00203   arma_extra_debug_sigprint();
00204   arma_ignore(junk);
00205   
00206   arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
00207   
00208   const uword N = A.n_rows;
00209   
00210   if(&out != &A)
00211     {
00212     out.copy_size(A);
00213     }
00214   
00215   if(upper)
00216     {
00217     // Upper triangular: but since we're transposing, we're taking the lower
00218     // triangular and putting it in the upper half.
00219     for(uword row = 0; row < N; ++row)
00220       {
00221       eT* out_colptr = out.colptr(row);
00222       
00223       for(uword col = 0; col <= row; ++col)
00224         {
00225         //out.at(col, row) = std::conj( A.at(row, col) );
00226         out_colptr[col] = std::conj( A.at(row, col) );
00227         }
00228       }
00229     }
00230   else
00231     {
00232     // Lower triangular: but since we're transposing, we're taking the upper
00233     // triangular and putting it in the lower half.
00234     for(uword row = 0; row < N; ++row)
00235       {
00236       for(uword col = row; col < N; ++col)
00237         {
00238         out.at(col, row) = std::conj( A.at(row, col) );
00239         }
00240       }
00241     }
00242   
00243   op_trimat::fill_zeros(out, upper);
00244   }
00245 
00246 
00247 


armadillo_matrix
Author(s): Conrad Sanderson - NICTA (www.nicta.com.au), (Wrapper by Sjoerd van den Dries)
autogenerated on Tue Jan 7 2014 11:42:05