// Copyright (C) 2009-2012 National ICT Australia (NICTA) // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. // ------------------------------------------------------------------- // // Written by Conrad Sanderson - http://conradsanderson.id.au // Written by Dimitrios Bouzas //! \addtogroup glue_cov //! @{ template inline void glue_cov::direct_cov(Mat& out, const Mat& A, const Mat& B, const uword norm_type) { arma_extra_debug_sigprint(); if(A.is_vec() && B.is_vec()) { arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" ); const eT* A_ptr = A.memptr(); const eT* B_ptr = B.memptr(); eT A_acc = eT(0); eT B_acc = eT(0); eT out_acc = eT(0); const uword N = A.n_elem; for(uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); out.set_size(1,1); out[0] = out_acc/norm_val; } else { arma_debug_assert_mul_size(A, B, true, false, "cov()"); const uword N = A.n_rows; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); out = trans(A) * B; out -= (trans(sum(A)) * sum(B))/eT(N); out /= norm_val; } } template inline void glue_cov::direct_cov(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat< std::complex >& B, const uword norm_type) { arma_extra_debug_sigprint(); typedef typename std::complex eT; if(A.is_vec() && B.is_vec()) { arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" ); const eT* A_ptr = A.memptr(); const eT* B_ptr = B.memptr(); eT A_acc = eT(0); eT B_acc = eT(0); eT out_acc = eT(0); const uword N = A.n_elem; for(uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); out.set_size(1,1); out[0] = out_acc/norm_val; } else { arma_debug_assert_mul_size(A, B, true, false, "cov()"); const uword N = A.n_rows; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); out = trans(A) * B; // out = strans(conj(A)) * B; out -= (trans(sum(A)) * sum(B))/eT(N); // out -= (strans(conj(sum(A))) * sum(B))/eT(N); out /= norm_val; } } template inline void glue_cov::apply(Mat& out, const Glue& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap_check A_tmp(X.A, out); const unwrap_check B_tmp(X.B, out); const Mat& A = A_tmp.M; const Mat& B = B_tmp.M; const uword norm_type = X.aux_uword; if(&A != &B) { glue_cov::direct_cov(out, A, B, norm_type); } else { op_cov::direct_cov(out, A, norm_type); } } //! @}