max@0: // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) max@0: // Copyright (C) 2009-2011 Conrad Sanderson max@0: // max@0: // This file is part of the Armadillo C++ library. max@0: // It is provided without any warranty of fitness max@0: // for any purpose. You can redistribute this file max@0: // and/or modify it under the terms of the GNU max@0: // Lesser General Public License (LGPL) as published max@0: // by the Free Software Foundation, either version 3 max@0: // of the License or (at your option) any later version. max@0: // (see http://www.opensource.org/licenses for more info) max@0: max@0: max@0: //! \addtogroup glue_mixed max@0: //! @{ max@0: max@0: max@0: max@0: //! matrix multiplication with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_times::apply(Mat::eT>& out, const mtGlue::eT, T1, T2, glue_mixed_times>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: // TODO: extend the unwrap_check framework to handle mixed matrix types max@0: max@0: const unwrap tmp1(X.A); max@0: const unwrap tmp2(X.B); max@0: max@0: const Mat& A = tmp1.M; max@0: const Mat& B = tmp2.M; max@0: max@0: const bool A_is_alias = ( ((void *)&out) == ((void *)&A) ); max@0: const bool B_is_alias = ( ((void *)&out) == ((void *)&B) ); max@0: max@0: const Mat* AA_ptr = A_is_alias ? new Mat(A) : 0; max@0: const Mat* BB_ptr = B_is_alias ? new Mat(B) : 0; max@0: max@0: const Mat& AA = A_is_alias ? *AA_ptr : A; max@0: const Mat& BB = B_is_alias ? *BB_ptr : B; max@0: max@0: arma_debug_assert_mul_size(AA, BB, "multiplication"); max@0: max@0: out.set_size(AA.n_rows, BB.n_cols); max@0: max@0: gemm_mixed<>::apply(out, AA, BB); max@0: max@0: if(A_is_alias == true) max@0: { max@0: delete AA_ptr; max@0: } max@0: max@0: if(B_is_alias == true) max@0: { max@0: delete BB_ptr; max@0: } max@0: } max@0: max@0: max@0: max@0: //! matrix addition with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_plus::apply(Mat::eT>& out, const mtGlue::eT, T1, T2, glue_mixed_plus>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const Proxy A(X.A); max@0: const Proxy B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "addition"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) + upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! matrix subtraction with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_minus::apply(Mat::eT>& out, const mtGlue::eT, T1, T2, glue_mixed_minus>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const Proxy A(X.A); max@0: const Proxy B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "subtraction"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) - upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! element-wise matrix division with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_div::apply(Mat::eT>& out, const mtGlue::eT, T1, T2, glue_mixed_div>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const Proxy A(X.A); max@0: const Proxy B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "element-wise division"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) / upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! element-wise matrix multiplication with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_schur::apply(Mat::eT>& out, const mtGlue::eT, T1, T2, glue_mixed_schur>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const Proxy A(X.A); max@0: const Proxy B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "element-wise multiplication"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) * upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: // max@0: // max@0: // max@0: max@0: max@0: max@0: //! cube addition with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_plus::apply(Cube::eT>& out, const mtGlueCube::eT, T1, T2, glue_mixed_plus>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const ProxyCube A(X.A); max@0: const ProxyCube B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "addition"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) + upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! cube subtraction with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_minus::apply(Cube::eT>& out, const mtGlueCube::eT, T1, T2, glue_mixed_minus>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const ProxyCube A(X.A); max@0: const ProxyCube B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "subtraction"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) - upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! element-wise cube division with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_div::apply(Cube::eT>& out, const mtGlueCube::eT, T1, T2, glue_mixed_div>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const ProxyCube A(X.A); max@0: const ProxyCube B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "element-wise division"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) / upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! element-wise cube multiplication with different element types max@0: template max@0: inline max@0: void max@0: glue_mixed_schur::apply(Cube::eT>& out, const mtGlueCube::eT, T1, T2, glue_mixed_schur>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type eT1; max@0: typedef typename T2::elem_type eT2; max@0: max@0: typedef typename promote_type::result out_eT; max@0: max@0: promote_type::check(); max@0: max@0: const ProxyCube A(X.A); max@0: const ProxyCube B(X.B); max@0: max@0: arma_debug_assert_same_size(A, B, "element-wise multiplication"); max@0: max@0: out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); max@0: max@0: out_eT* out_mem = out.memptr(); max@0: const uword n_elem = out.n_elem; max@0: max@0: for(uword i=0; i::apply(A[i]) * upgrade_val::apply(B[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! @}