diff --git a/include/armadillo_bits/fn_powext.hpp b/include/armadillo_bits/fn_powext.hpp index 8de2783a..8c816ee5 100644 --- a/include/armadillo_bits/fn_powext.hpp +++ b/include/armadillo_bits/fn_powext.hpp @@ -27,7 +27,7 @@ arma_inline typename enable_if2 < - ( is_arma_type::value && is_arma_type::value && is_same_type::value ), + ( is_arma_type::value && is_arma_type::value && is_same_type::yes ), const Glue >::result pow @@ -43,11 +43,31 @@ pow +template +arma_warn_unused +arma_inline +typename +enable_if2 + < + ( is_arma_type::value && is_arma_type::value && is_cx::yes && is_same_type::yes ), + const mtGlue + >::result +pow + ( + const T1& X, + const T2& Y + ) + { + arma_extra_debug_sigprint(); + + return mtGlue(X, Y); + } + + + // TODO: mat = pow(mat.each_col(), mat) (no promotion) // TODO: mat = pow(mat.each_row(), mat) (no promotion) -// TODO: cx_mat = pow(cx_mat, mat) (promotion; ? implement via mtGlue to allow preservation of vector type info) - // TODO: cx_mat = pow(cx_mat.each_col(), mat) (promotion) // TODO: cx_mat = pow(cx_mat.each_row(), mat) (promotion) diff --git a/include/armadillo_bits/glue_powext_bones.hpp b/include/armadillo_bits/glue_powext_bones.hpp index a978860c..99f6e2e3 100644 --- a/include/armadillo_bits/glue_powext_bones.hpp +++ b/include/armadillo_bits/glue_powext_bones.hpp @@ -1,3 +1,4 @@ + // SPDX-License-Identifier: Apache-2.0 // // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) @@ -34,4 +35,16 @@ class glue_powext +class glue_powext_cx + : public traits_glue_or + { + public: + + template inline static void apply(Mat& out, const mtGlue& X); + + template inline static void apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B); + }; + + + //! @} diff --git a/include/armadillo_bits/glue_powext_meat.hpp b/include/armadillo_bits/glue_powext_meat.hpp index dbd602bd..fe5b2566 100644 --- a/include/armadillo_bits/glue_powext_meat.hpp +++ b/include/armadillo_bits/glue_powext_meat.hpp @@ -83,4 +83,69 @@ glue_powext::apply(Mat& out, const Mat& A, const Mat& B) +// + + + +template +inline +void +glue_powext_cx::apply(Mat& out, const mtGlue& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const quasi_unwrap UA(X.A); + const quasi_unwrap UB(X.B); + + const Mat& A = UA.M; + const Mat< T>& B = UB.M; + + arma_debug_assert_same_size(A, B, "element-wise pow()"); + + // TODO: investigate use of openmp + + if(UA.is_alias(out) && (UA.has_subview)) + { + Mat tmp; + + glue_powext_cx::apply(tmp, A, B); + + out.steal_mem(tmp); + } + else + { + glue_powext_cx::apply(out, A, B); + } + } + + + +template +inline +void +glue_powext_cx::apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B) + { + arma_extra_debug_sigprint(); + + typedef typename std::complex eT; + + out.set_size(A.n_rows, A.n_cols); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + const T* B_mem = B.memptr(); + + for(uword i=0; i