glue_cor_meat.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2009-2011 Conrad Sanderson
00003 // Copyright (C) 2009-2010 Dimitrios Bouzas
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 glue_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword norm_type)
00024   {
00025   arma_extra_debug_sigprint();
00026   
00027   if(A.is_empty() || B.is_empty() )
00028     {
00029     out.reset();
00030     return;
00031     }
00032   
00033   if(A.is_vec() && B.is_vec())
00034     {
00035     arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
00036     
00037     const eT* A_ptr = A.memptr();
00038     const eT* B_ptr = B.memptr();
00039     
00040     eT A_acc   = eT(0);
00041     eT B_acc   = eT(0);
00042     eT out_acc = eT(0);
00043     
00044     const uword N = A.n_elem;
00045     
00046     for(uword i=0; i<N; ++i)
00047       {
00048       const eT A_tmp = A_ptr[i];
00049       const eT B_tmp = B_ptr[i];
00050       
00051       A_acc += A_tmp;
00052       B_acc += B_tmp;
00053       
00054       out_acc += A_tmp * B_tmp;
00055       }
00056     
00057     out_acc -= (A_acc * B_acc)/eT(N);
00058     
00059     const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);    
00060     
00061     out.set_size(1,1);
00062     out[0] = out_acc/norm_val;
00063     
00064     const Mat<eT> stddev_A = (A.n_rows == 1) ? Mat<eT>(stddev(trans(A))) : Mat<eT>(stddev(A));
00065     const Mat<eT> stddev_B = (B.n_rows == 1) ? Mat<eT>(stddev(trans(B))) : Mat<eT>(stddev(B));
00066     
00067     out /= stddev_A * stddev_B;
00068     }
00069   else
00070     {
00071     arma_debug_assert_same_size(A, B, "cor()");
00072     
00073     const uword N = A.n_rows;
00074     const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
00075     
00076     out = trans(A) * B;
00077     out -= (trans(sum(A)) * sum(B))/eT(N);
00078     out /= norm_val;
00079     out /= trans(stddev(A)) * stddev(B);
00080     }
00081   }
00082 
00083 
00084 
00085 template<typename T>
00086 inline
00087 void
00088 glue_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type)
00089   {
00090   arma_extra_debug_sigprint();
00091   
00092   typedef typename std::complex<T> eT;
00093   
00094   if(A.is_empty() || B.is_empty() )
00095     {
00096     out.reset();
00097     return;
00098     }
00099   
00100   if(A.is_vec() && B.is_vec())
00101     {
00102     arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
00103     
00104     const eT* A_ptr = A.memptr();
00105     const eT* B_ptr = B.memptr();        
00106     
00107     eT A_acc   = eT(0);
00108     eT B_acc   = eT(0);
00109     eT out_acc = eT(0);
00110     
00111     const uword N = A.n_elem;
00112     
00113     for(uword i=0; i<N; ++i)
00114       {
00115       const eT A_tmp = A_ptr[i];
00116       const eT B_tmp = B_ptr[i];
00117       
00118       A_acc += A_tmp;
00119       B_acc += B_tmp;
00120       
00121       out_acc += std::conj(A_tmp) * B_tmp;
00122       }
00123     
00124     out_acc -= (std::conj(A_acc) * B_acc)/eT(N);
00125     
00126     const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
00127     
00128     out.set_size(1,1);
00129     out[0] = out_acc/norm_val;
00130     
00131     const Mat<T> stddev_A = (A.n_rows == 1) ? Mat<T>(stddev(trans(A))) : Mat<T>(stddev(A));
00132     const Mat<T> stddev_B = (B.n_rows == 1) ? Mat<T>(stddev(trans(B))) : Mat<T>(stddev(B));
00133     
00134     out /= conv_to< Mat<eT> >::from( stddev_A * stddev_B );
00135     }
00136   else
00137     {
00138     arma_debug_assert_same_size(A, B, "cor()");
00139     
00140     const uword N = A.n_rows;
00141     const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
00142     
00143     out = trans(A) * B;                     // out = strans(conj(A)) * B;
00144     out -= (trans(sum(A)) * sum(B))/eT(N);  // out -= (strans(conj(sum(A))) * sum(B))/eT(N);
00145     out /= norm_val;
00146     out /= conv_to< Mat<eT> >::from( trans(stddev(A)) * stddev(B) );
00147     }
00148   }
00149 
00150 
00151 
00152 template<typename T1, typename T2>
00153 inline
00154 void
00155 glue_cor::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X)
00156   {
00157   arma_extra_debug_sigprint();
00158   
00159   typedef typename T1::elem_type eT;
00160   
00161   const unwrap_check<T1> A_tmp(X.A, out);
00162   const unwrap_check<T2> B_tmp(X.B, out);
00163   
00164   const Mat<eT>& A = A_tmp.M;
00165   const Mat<eT>& B = B_tmp.M;
00166   
00167   const uword norm_type = X.aux_uword;
00168   
00169   if(&A != &B)
00170     {
00171     glue_cor::direct_cor(out, A, B, norm_type);
00172     }
00173   else
00174     {
00175     op_cor::direct_cor(out, A, norm_type);
00176     }
00177   }
00178 
00179 
00180 


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:04