~ubuntu-branches/ubuntu/trusty/r-cran-rcpparmadillo/trusty

« back to all changes in this revision

Viewing changes to inst/include/armadillo_bits/glue_times_meat.hpp

  • Committer: Package Import Robot
  • Author(s): Dirk Eddelbuettel
  • Date: 2014-01-05 07:49:39 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20140105074939-dwxho57ujap094yj
Tags: 0.4.000-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
 
93
93
 
94
94
 
95
 
template<uword N>
96
 
template<typename T1, typename T2>
97
 
arma_hot
98
 
inline
99
 
void
100
 
glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
101
 
  {
102
 
  arma_extra_debug_sigprint();
103
 
  
104
 
  typedef typename T1::elem_type eT;
105
 
  
106
 
  const partial_unwrap_check<T1> tmp1(X.A, out);
107
 
  const partial_unwrap_check<T2> tmp2(X.B, out);
108
 
  
109
 
  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
110
 
  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
111
 
  
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);
114
 
  
115
 
  glue_times::apply
116
 
    <
117
 
    eT,
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)
121
 
    >
122
 
    (out, A, B, alpha);
123
 
  }
124
 
 
125
 
 
126
 
 
127
 
template<typename T1, typename T2>
128
 
arma_hot
129
 
inline
130
 
void
131
 
glue_times_redirect<2>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
132
 
  {
133
 
  arma_extra_debug_sigprint();
134
 
  
135
 
  typedef typename T1::elem_type eT;
136
 
  
137
 
  glue_times_redirect2_helper< is_supported_blas_type<eT>::value >::apply(out, X);
138
 
  }
139
 
 
140
 
 
141
 
 
 
95
template<bool is_eT_blas_type>
142
96
template<typename T1, typename T2, typename T3>
143
97
arma_hot
144
98
inline
145
99
void
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)
147
101
  {
148
102
  arma_extra_debug_sigprint();
149
103
  
150
104
  typedef typename T1::elem_type eT;
151
105
  
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)
154
 
  
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
157
108
  
158
109
  const partial_unwrap_check<T1> tmp1(X.A.A, out);
179
130
 
180
131
 
181
132
 
 
133
template<typename T1, typename T2, typename T3>
 
134
arma_hot
 
135
inline
 
136
void
 
137
glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
 
138
  {
 
139
  arma_extra_debug_sigprint();
 
140
  
 
141
  // TODO: investigate detecting inv(A)*B*C and replacing with solve(A,B)*C
 
142
  
 
143
  typedef typename T1::elem_type eT;
 
144
  
 
145
  if(strip_inv<T2>::do_inv == false)
 
146
    {
 
147
    // we have exactly 3 objects
 
148
    // hence we can safely expand X as X.A.A, X.A.B and X.B
 
149
    
 
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);
 
153
    
 
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;
 
157
    
 
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);
 
160
    
 
161
    glue_times::apply
 
162
      <
 
163
      eT,
 
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)
 
168
      >
 
169
      (out, A, B, C, alpha);
 
170
    }
 
171
  else
 
172
    {
 
173
    // replace A*inv(B)*C with A*solve(B,C)
 
174
    
 
175
    arma_extra_debug_print("glue_times_redirect<3>::apply(): detected A*inv(B)*C");
 
176
    
 
177
    const strip_inv<T2> B_strip(X.A.B);
 
178
    
 
179
    Mat<eT> B = B_strip.M;
 
180
    
 
181
    arma_debug_check( (B.is_square() == false), "inv(): given matrix is not square" );
 
182
    
 
183
    const unwrap<T3> C_tmp(X.B);
 
184
    const Mat<eT>& C = C_tmp.M;
 
185
    
 
186
    Mat<eT> solve_result;
 
187
    
 
188
    glue_solve::solve_direct( solve_result, B, C, B_strip.slow );
 
189
    
 
190
    const partial_unwrap_check<T1> tmp1(X.A.A, out);
 
191
    
 
192
    const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
 
193
    
 
194
    const bool use_alpha = partial_unwrap_check<T1>::do_times;
 
195
    const eT       alpha = use_alpha ? tmp1.get_val() : eT(0);
 
196
    
 
197
    glue_times::apply
 
198
      <
 
199
      eT,
 
200
      partial_unwrap_check<T1>::do_trans,
 
201
      false,
 
202
      partial_unwrap_check<T1>::do_times
 
203
      >
 
204
      (out, A, solve_result, alpha);
 
205
    }
 
206
  }
 
207
 
 
208
 
 
209
 
 
210
template<uword N>
 
211
template<typename T1, typename T2>
 
212
arma_hot
 
213
inline
 
214
void
 
215
glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
 
216
  {
 
217
  arma_extra_debug_sigprint();
 
218
  
 
219
  typedef typename T1::elem_type eT;
 
220
  
 
221
  const partial_unwrap_check<T1> tmp1(X.A, out);
 
222
  const partial_unwrap_check<T2> tmp2(X.B, out);
 
223
  
 
224
  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
 
225
  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
 
226
  
 
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);
 
229
  
 
230
  glue_times::apply
 
231
    <
 
232
    eT,
 
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)
 
236
    >
 
237
    (out, A, B, alpha);
 
238
  }
 
239
 
 
240
 
 
241
 
 
242
template<typename T1, typename T2>
 
243
arma_hot
 
244
inline
 
245
void
 
246
glue_times_redirect<2>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
 
247
  {
 
248
  arma_extra_debug_sigprint();
 
249
  
 
250
  typedef typename T1::elem_type eT;
 
251
  
 
252
  glue_times_redirect2_helper< is_supported_blas_type<eT>::value >::apply(out, X);
 
253
  }
 
254
 
 
255
 
 
256
 
 
257
template<typename T1, typename T2, typename T3>
 
258
arma_hot
 
259
inline
 
260
void
 
261
glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
 
262
  {
 
263
  arma_extra_debug_sigprint();
 
264
  
 
265
  typedef typename T1::elem_type eT;
 
266
  
 
267
  glue_times_redirect3_helper< is_supported_blas_type<eT>::value >::apply(out, X);
 
268
  }
 
269
 
 
270
 
 
271
 
182
272
template<typename T1, typename T2, typename T3, typename T4>
183
273
arma_hot
184
274
inline