// Copyright (C) 2008-2015 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 Ryan Curtin //! \addtogroup operator_times //! @{ //! Base * scalar template arma_inline typename enable_if2< is_arma_type::value, const eOp >::result operator* (const T1& X, const typename T1::elem_type k) { arma_extra_debug_sigprint(); return eOp(X,k); } //! scalar * Base template arma_inline typename enable_if2< is_arma_type::value, const eOp >::result operator* (const typename T1::elem_type k, const T1& X) { arma_extra_debug_sigprint(); return eOp(X,k); // NOTE: order is swapped } //! non-complex Base * complex scalar template arma_inline typename enable_if2 < (is_arma_type::value && is_cx::no), const mtOp, T1, op_cx_scalar_times> >::result operator* ( const T1& X, const std::complex& k ) { arma_extra_debug_sigprint(); return mtOp, T1, op_cx_scalar_times>('j', X, k); } //! complex scalar * non-complex Base template arma_inline typename enable_if2 < (is_arma_type::value && is_cx::no), const mtOp, T1, op_cx_scalar_times> >::result operator* ( const std::complex& k, const T1& X ) { arma_extra_debug_sigprint(); return mtOp, T1, op_cx_scalar_times>('j', X, k); } //! scalar * trans(T1) template arma_inline const Op operator* (const typename T1::elem_type k, const Op& X) { arma_extra_debug_sigprint(); return Op(X.m, k); } //! trans(T1) * scalar template arma_inline const Op operator* (const Op& X, const typename T1::elem_type k) { arma_extra_debug_sigprint(); return Op(X.m, k); } //! Base * diagmat template arma_inline typename enable_if2 < (is_arma_type::value && is_same_type::value), const Glue, glue_times_diag> >::result operator* (const T1& X, const Op& Y) { arma_extra_debug_sigprint(); return Glue, glue_times_diag>(X, Y); } //! diagmat * Base template arma_inline typename enable_if2 < (is_arma_type::value && is_same_type::value), const Glue, T2, glue_times_diag> >::result operator* (const Op& X, const T2& Y) { arma_extra_debug_sigprint(); return Glue, T2, glue_times_diag>(X, Y); } //! diagmat * diagmat template inline Mat< typename promote_type::result > operator* (const Op& X, const Op& Y) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT1; typedef typename T2::elem_type eT2; typedef typename promote_type::result out_eT; promote_type::check(); const diagmat_proxy A(X.m); const diagmat_proxy B(Y.m); arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); Mat out(A.n_rows, B.n_cols, fill::zeros); const uword A_length = (std::min)(A.n_rows, A.n_cols); const uword B_length = (std::min)(B.n_rows, B.n_cols); const uword N = (std::min)(A_length, B_length); for(uword i=0; i::apply( A[i] ) * upgrade_val::apply( B[i] ); } return out; } //! multiplication of Base objects with same element type template arma_inline typename enable_if2 < is_arma_type::value && is_arma_type::value && is_same_type::value, const Glue >::result operator* (const T1& X, const T2& Y) { arma_extra_debug_sigprint(); return Glue(X, Y); } //! multiplication of Base objects with different element types template inline typename enable_if2 < (is_arma_type::value && is_arma_type::value && (is_same_type::no)), const mtGlue< typename promote_type::result, T1, T2, glue_mixed_times > >::result operator* ( const T1& X, const T2& Y ) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT1; typedef typename T2::elem_type eT2; typedef typename promote_type::result out_eT; promote_type::check(); return mtGlue( X, Y ); } //! sparse multiplied by scalar template inline typename enable_if2 < is_arma_sparse_type::value, SpOp >::result operator* ( const T1& X, const typename T1::elem_type k ) { arma_extra_debug_sigprint(); return SpOp(X, k); } template inline typename enable_if2 < is_arma_sparse_type::value, SpOp >::result operator* ( const typename T1::elem_type k, const T1& X ) { arma_extra_debug_sigprint(); return SpOp(X, k); } //! multiplication of two sparse objects template inline arma_hot typename enable_if2 < (is_arma_sparse_type::value && is_arma_sparse_type::value && is_same_type::value), const SpGlue >::result operator* ( const T1& x, const T2& y ) { arma_extra_debug_sigprint(); return SpGlue(x, y); } //! convert "(sparse + sparse) * scalar" to specialised operation "scalar * (sparse + sparse)" template inline const SpGlue operator* ( const SpGlue& X, const typename T1::elem_type k ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "scalar * (sparse + sparse)" to specialised operation template inline const SpGlue operator* ( const typename T1::elem_type k, const SpGlue& X ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "(sparse - sparse) * scalar" to specialised operation "scalar * (sparse - sparse)" template inline const SpGlue operator* ( const SpGlue& X, const typename T1::elem_type k ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "scalar * (sparse - sparse)" to specialised operation template inline const SpGlue operator* ( const typename T1::elem_type k, const SpGlue& X ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "(sparse*sparse) * scalar" to specialised operation "scalar * (sparse*sparse)" template inline const SpGlue operator* ( const SpGlue& X, const typename T1::elem_type k ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "scalar * (sparse*sparse)" to specialised operation template inline const SpGlue operator* ( const typename T1::elem_type k, const SpGlue& X ) { arma_extra_debug_sigprint(); return SpGlue(X.A, X.B, k); } //! convert "(scalar*sparse) * sparse" to specialised operation "scalar * (sparse*sparse)" template inline typename enable_if2 < is_arma_sparse_type::value, const SpGlue >::result operator* ( const SpOp& X, const T2& Y ) { arma_extra_debug_sigprint(); return SpGlue(X.m, Y, X.aux); } //! convert "sparse * (scalar*sparse)" to specialised operation "scalar * (sparse*sparse)" template inline typename enable_if2 < is_arma_sparse_type::value, const SpGlue >::result operator* ( const T1& X, const SpOp& Y ) { arma_extra_debug_sigprint(); return SpGlue(X, Y.m, Y.aux); } //! multiplication of one sparse and one dense object template inline typename enable_if2 < (is_arma_sparse_type::value && is_arma_type::value && is_same_type::value), Mat >::result operator* ( const T1& x, const T2& y ) { arma_extra_debug_sigprint(); const SpProxy pa(x); const Proxy pb(y); arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication"); Mat result(pa.get_n_rows(), pb.get_n_cols()); result.zeros(); if( (pa.get_n_nonzero() > 0) && (pb.get_n_elem() > 0) ) { typename SpProxy::const_iterator_type x_it = pa.begin(); typename SpProxy::const_iterator_type x_it_end = pa.end(); const uword result_n_cols = result.n_cols; while(x_it != x_it_end) { for(uword col = 0; col < result_n_cols; ++col) { result.at(x_it.row(), col) += (*x_it) * pb.at(x_it.col(), col); } ++x_it; } } return result; } //! multiplication of one dense and one sparse object template inline typename enable_if2 < (is_arma_type::value && is_arma_sparse_type::value && is_same_type::value), Mat >::result operator* ( const T1& x, const T2& y ) { arma_extra_debug_sigprint(); const Proxy pa(x); const SpProxy pb(y); arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication"); Mat result(pa.get_n_rows(), pb.get_n_cols()); result.zeros(); if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) ) { typename SpProxy::const_iterator_type y_col_it = pb.begin(); typename SpProxy::const_iterator_type y_col_it_end = pb.end(); const uword result_n_rows = result.n_rows; while(y_col_it != y_col_it_end) { for(uword row = 0; row < result_n_rows; ++row) { result.at(row, y_col_it.col()) += pa.at(row, y_col_it.row()) * (*y_col_it); } ++y_col_it; } } return result; } //! @}