96
template<typename T1, typename T2>
100
glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
102
arma_extra_debug_sigprint();
104
typedef typename T1::elem_type eT;
106
const partial_unwrap_check<T1> tmp1(X.A, out);
107
const partial_unwrap_check<T2> tmp2(X.B, out);
109
const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
110
const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
112
const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times;
113
const eT alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
118
partial_unwrap_check<T1>::do_trans,
119
partial_unwrap_check<T2>::do_trans,
120
(partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times)
127
template<typename T1, typename T2>
131
glue_times_redirect<2>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
133
arma_extra_debug_sigprint();
135
typedef typename T1::elem_type eT;
137
glue_times_redirect2_helper< is_supported_blas_type<eT>::value >::apply(out, X);
95
template<bool is_eT_blas_type>
142
96
template<typename T1, typename T2, typename T3>
146
glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
100
glue_times_redirect3_helper<is_eT_blas_type>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
148
102
arma_extra_debug_sigprint();
150
104
typedef typename T1::elem_type eT;
152
// TODO: investigate detecting inv(A)*B*C and replacing with solve(A,B)*C
153
// TODO: investigate detecting A*inv(B)*C and replacing with A*solve(B,C)
155
// there is exactly 3 objects
106
// we have exactly 3 objects
156
107
// hence we can safely expand X as X.A.A, X.A.B and X.B
158
109
const partial_unwrap_check<T1> tmp1(X.A.A, out);
133
template<typename T1, typename T2, typename T3>
137
glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
139
arma_extra_debug_sigprint();
141
// TODO: investigate detecting inv(A)*B*C and replacing with solve(A,B)*C
143
typedef typename T1::elem_type eT;
145
if(strip_inv<T2>::do_inv == false)
147
// we have exactly 3 objects
148
// hence we can safely expand X as X.A.A, X.A.B and X.B
150
const partial_unwrap_check<T1> tmp1(X.A.A, out);
151
const partial_unwrap_check<T2> tmp2(X.A.B, out);
152
const partial_unwrap_check<T3> tmp3(X.B, out);
154
const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
155
const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
156
const typename partial_unwrap_check<T3>::stored_type& C = tmp3.M;
158
const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times;
159
const eT alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val()) : eT(0);
164
partial_unwrap_check<T1>::do_trans,
165
partial_unwrap_check<T2>::do_trans,
166
partial_unwrap_check<T3>::do_trans,
167
(partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times)
169
(out, A, B, C, alpha);
173
// replace A*inv(B)*C with A*solve(B,C)
175
arma_extra_debug_print("glue_times_redirect<3>::apply(): detected A*inv(B)*C");
177
const strip_inv<T2> B_strip(X.A.B);
179
Mat<eT> B = B_strip.M;
181
arma_debug_check( (B.is_square() == false), "inv(): given matrix is not square" );
183
const unwrap<T3> C_tmp(X.B);
184
const Mat<eT>& C = C_tmp.M;
186
Mat<eT> solve_result;
188
glue_solve::solve_direct( solve_result, B, C, B_strip.slow );
190
const partial_unwrap_check<T1> tmp1(X.A.A, out);
192
const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
194
const bool use_alpha = partial_unwrap_check<T1>::do_times;
195
const eT alpha = use_alpha ? tmp1.get_val() : eT(0);
200
partial_unwrap_check<T1>::do_trans,
202
partial_unwrap_check<T1>::do_times
204
(out, A, solve_result, alpha);
211
template<typename T1, typename T2>
215
glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
217
arma_extra_debug_sigprint();
219
typedef typename T1::elem_type eT;
221
const partial_unwrap_check<T1> tmp1(X.A, out);
222
const partial_unwrap_check<T2> tmp2(X.B, out);
224
const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
225
const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
227
const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times;
228
const eT alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
233
partial_unwrap_check<T1>::do_trans,
234
partial_unwrap_check<T2>::do_trans,
235
(partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times)
242
template<typename T1, typename T2>
246
glue_times_redirect<2>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
248
arma_extra_debug_sigprint();
250
typedef typename T1::elem_type eT;
252
glue_times_redirect2_helper< is_supported_blas_type<eT>::value >::apply(out, X);
257
template<typename T1, typename T2, typename T3>
261
glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
263
arma_extra_debug_sigprint();
265
typedef typename T1::elem_type eT;
267
glue_times_redirect3_helper< is_supported_blas_type<eT>::value >::apply(out, X);
182
272
template<typename T1, typename T2, typename T3, typename T4>