max@0
|
1 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
|
max@0
|
2 // Copyright (C) 2009-2011 Conrad Sanderson
|
max@0
|
3 //
|
max@0
|
4 // This file is part of the Armadillo C++ library.
|
max@0
|
5 // It is provided without any warranty of fitness
|
max@0
|
6 // for any purpose. You can redistribute this file
|
max@0
|
7 // and/or modify it under the terms of the GNU
|
max@0
|
8 // Lesser General Public License (LGPL) as published
|
max@0
|
9 // by the Free Software Foundation, either version 3
|
max@0
|
10 // of the License or (at your option) any later version.
|
max@0
|
11 // (see http://www.opensource.org/licenses for more info)
|
max@0
|
12
|
max@0
|
13
|
max@0
|
14 //! \addtogroup glue_mixed
|
max@0
|
15 //! @{
|
max@0
|
16
|
max@0
|
17
|
max@0
|
18
|
max@0
|
19 //! matrix multiplication with different element types
|
max@0
|
20 template<typename T1, typename T2>
|
max@0
|
21 inline
|
max@0
|
22 void
|
max@0
|
23 glue_mixed_times::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_times>& X)
|
max@0
|
24 {
|
max@0
|
25 arma_extra_debug_sigprint();
|
max@0
|
26
|
max@0
|
27 typedef typename T1::elem_type eT1;
|
max@0
|
28 typedef typename T2::elem_type eT2;
|
max@0
|
29
|
max@0
|
30 // TODO: extend the unwrap_check framework to handle mixed matrix types
|
max@0
|
31
|
max@0
|
32 const unwrap<T1> tmp1(X.A);
|
max@0
|
33 const unwrap<T2> tmp2(X.B);
|
max@0
|
34
|
max@0
|
35 const Mat<eT1>& A = tmp1.M;
|
max@0
|
36 const Mat<eT2>& B = tmp2.M;
|
max@0
|
37
|
max@0
|
38 const bool A_is_alias = ( ((void *)&out) == ((void *)&A) );
|
max@0
|
39 const bool B_is_alias = ( ((void *)&out) == ((void *)&B) );
|
max@0
|
40
|
max@0
|
41 const Mat<eT1>* AA_ptr = A_is_alias ? new Mat<eT1>(A) : 0;
|
max@0
|
42 const Mat<eT2>* BB_ptr = B_is_alias ? new Mat<eT2>(B) : 0;
|
max@0
|
43
|
max@0
|
44 const Mat<eT1>& AA = A_is_alias ? *AA_ptr : A;
|
max@0
|
45 const Mat<eT2>& BB = B_is_alias ? *BB_ptr : B;
|
max@0
|
46
|
max@0
|
47 arma_debug_assert_mul_size(AA, BB, "multiplication");
|
max@0
|
48
|
max@0
|
49 out.set_size(AA.n_rows, BB.n_cols);
|
max@0
|
50
|
max@0
|
51 gemm_mixed<>::apply(out, AA, BB);
|
max@0
|
52
|
max@0
|
53 if(A_is_alias == true)
|
max@0
|
54 {
|
max@0
|
55 delete AA_ptr;
|
max@0
|
56 }
|
max@0
|
57
|
max@0
|
58 if(B_is_alias == true)
|
max@0
|
59 {
|
max@0
|
60 delete BB_ptr;
|
max@0
|
61 }
|
max@0
|
62 }
|
max@0
|
63
|
max@0
|
64
|
max@0
|
65
|
max@0
|
66 //! matrix addition with different element types
|
max@0
|
67 template<typename T1, typename T2>
|
max@0
|
68 inline
|
max@0
|
69 void
|
max@0
|
70 glue_mixed_plus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
|
max@0
|
71 {
|
max@0
|
72 arma_extra_debug_sigprint();
|
max@0
|
73
|
max@0
|
74 typedef typename T1::elem_type eT1;
|
max@0
|
75 typedef typename T2::elem_type eT2;
|
max@0
|
76
|
max@0
|
77 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
78
|
max@0
|
79 promote_type<eT1,eT2>::check();
|
max@0
|
80
|
max@0
|
81 const Proxy<T1> A(X.A);
|
max@0
|
82 const Proxy<T2> B(X.B);
|
max@0
|
83
|
max@0
|
84 arma_debug_assert_same_size(A, B, "addition");
|
max@0
|
85
|
max@0
|
86 out.set_size(A.get_n_rows(), A.get_n_cols());
|
max@0
|
87
|
max@0
|
88 out_eT* out_mem = out.memptr();
|
max@0
|
89 const uword n_elem = out.n_elem;
|
max@0
|
90
|
max@0
|
91 for(uword i=0; i<n_elem; ++i)
|
max@0
|
92 {
|
max@0
|
93 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) + upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
94 }
|
max@0
|
95 }
|
max@0
|
96
|
max@0
|
97
|
max@0
|
98
|
max@0
|
99 //! matrix subtraction with different element types
|
max@0
|
100 template<typename T1, typename T2>
|
max@0
|
101 inline
|
max@0
|
102 void
|
max@0
|
103 glue_mixed_minus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
|
max@0
|
104 {
|
max@0
|
105 arma_extra_debug_sigprint();
|
max@0
|
106
|
max@0
|
107 typedef typename T1::elem_type eT1;
|
max@0
|
108 typedef typename T2::elem_type eT2;
|
max@0
|
109
|
max@0
|
110 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
111
|
max@0
|
112 promote_type<eT1,eT2>::check();
|
max@0
|
113
|
max@0
|
114 const Proxy<T1> A(X.A);
|
max@0
|
115 const Proxy<T2> B(X.B);
|
max@0
|
116
|
max@0
|
117 arma_debug_assert_same_size(A, B, "subtraction");
|
max@0
|
118
|
max@0
|
119 out.set_size(A.get_n_rows(), A.get_n_cols());
|
max@0
|
120
|
max@0
|
121 out_eT* out_mem = out.memptr();
|
max@0
|
122 const uword n_elem = out.n_elem;
|
max@0
|
123
|
max@0
|
124 for(uword i=0; i<n_elem; ++i)
|
max@0
|
125 {
|
max@0
|
126 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) - upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
127 }
|
max@0
|
128 }
|
max@0
|
129
|
max@0
|
130
|
max@0
|
131
|
max@0
|
132 //! element-wise matrix division with different element types
|
max@0
|
133 template<typename T1, typename T2>
|
max@0
|
134 inline
|
max@0
|
135 void
|
max@0
|
136 glue_mixed_div::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
|
max@0
|
137 {
|
max@0
|
138 arma_extra_debug_sigprint();
|
max@0
|
139
|
max@0
|
140 typedef typename T1::elem_type eT1;
|
max@0
|
141 typedef typename T2::elem_type eT2;
|
max@0
|
142
|
max@0
|
143 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
144
|
max@0
|
145 promote_type<eT1,eT2>::check();
|
max@0
|
146
|
max@0
|
147 const Proxy<T1> A(X.A);
|
max@0
|
148 const Proxy<T2> B(X.B);
|
max@0
|
149
|
max@0
|
150 arma_debug_assert_same_size(A, B, "element-wise division");
|
max@0
|
151
|
max@0
|
152 out.set_size(A.get_n_rows(), A.get_n_cols());
|
max@0
|
153
|
max@0
|
154 out_eT* out_mem = out.memptr();
|
max@0
|
155 const uword n_elem = out.n_elem;
|
max@0
|
156
|
max@0
|
157 for(uword i=0; i<n_elem; ++i)
|
max@0
|
158 {
|
max@0
|
159 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) / upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
160 }
|
max@0
|
161 }
|
max@0
|
162
|
max@0
|
163
|
max@0
|
164
|
max@0
|
165 //! element-wise matrix multiplication with different element types
|
max@0
|
166 template<typename T1, typename T2>
|
max@0
|
167 inline
|
max@0
|
168 void
|
max@0
|
169 glue_mixed_schur::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
|
max@0
|
170 {
|
max@0
|
171 arma_extra_debug_sigprint();
|
max@0
|
172
|
max@0
|
173 typedef typename T1::elem_type eT1;
|
max@0
|
174 typedef typename T2::elem_type eT2;
|
max@0
|
175
|
max@0
|
176 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
177
|
max@0
|
178 promote_type<eT1,eT2>::check();
|
max@0
|
179
|
max@0
|
180 const Proxy<T1> A(X.A);
|
max@0
|
181 const Proxy<T2> B(X.B);
|
max@0
|
182
|
max@0
|
183 arma_debug_assert_same_size(A, B, "element-wise multiplication");
|
max@0
|
184
|
max@0
|
185 out.set_size(A.get_n_rows(), A.get_n_cols());
|
max@0
|
186
|
max@0
|
187 out_eT* out_mem = out.memptr();
|
max@0
|
188 const uword n_elem = out.n_elem;
|
max@0
|
189
|
max@0
|
190 for(uword i=0; i<n_elem; ++i)
|
max@0
|
191 {
|
max@0
|
192 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) * upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
193 }
|
max@0
|
194 }
|
max@0
|
195
|
max@0
|
196
|
max@0
|
197
|
max@0
|
198 //
|
max@0
|
199 //
|
max@0
|
200 //
|
max@0
|
201
|
max@0
|
202
|
max@0
|
203
|
max@0
|
204 //! cube addition with different element types
|
max@0
|
205 template<typename T1, typename T2>
|
max@0
|
206 inline
|
max@0
|
207 void
|
max@0
|
208 glue_mixed_plus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
|
max@0
|
209 {
|
max@0
|
210 arma_extra_debug_sigprint();
|
max@0
|
211
|
max@0
|
212 typedef typename T1::elem_type eT1;
|
max@0
|
213 typedef typename T2::elem_type eT2;
|
max@0
|
214
|
max@0
|
215 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
216
|
max@0
|
217 promote_type<eT1,eT2>::check();
|
max@0
|
218
|
max@0
|
219 const ProxyCube<T1> A(X.A);
|
max@0
|
220 const ProxyCube<T2> B(X.B);
|
max@0
|
221
|
max@0
|
222 arma_debug_assert_same_size(A, B, "addition");
|
max@0
|
223
|
max@0
|
224 out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
|
max@0
|
225
|
max@0
|
226 out_eT* out_mem = out.memptr();
|
max@0
|
227 const uword n_elem = out.n_elem;
|
max@0
|
228
|
max@0
|
229 for(uword i=0; i<n_elem; ++i)
|
max@0
|
230 {
|
max@0
|
231 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) + upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
232 }
|
max@0
|
233 }
|
max@0
|
234
|
max@0
|
235
|
max@0
|
236
|
max@0
|
237 //! cube subtraction with different element types
|
max@0
|
238 template<typename T1, typename T2>
|
max@0
|
239 inline
|
max@0
|
240 void
|
max@0
|
241 glue_mixed_minus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
|
max@0
|
242 {
|
max@0
|
243 arma_extra_debug_sigprint();
|
max@0
|
244
|
max@0
|
245 typedef typename T1::elem_type eT1;
|
max@0
|
246 typedef typename T2::elem_type eT2;
|
max@0
|
247
|
max@0
|
248 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
249
|
max@0
|
250 promote_type<eT1,eT2>::check();
|
max@0
|
251
|
max@0
|
252 const ProxyCube<T1> A(X.A);
|
max@0
|
253 const ProxyCube<T2> B(X.B);
|
max@0
|
254
|
max@0
|
255 arma_debug_assert_same_size(A, B, "subtraction");
|
max@0
|
256
|
max@0
|
257 out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
|
max@0
|
258
|
max@0
|
259 out_eT* out_mem = out.memptr();
|
max@0
|
260 const uword n_elem = out.n_elem;
|
max@0
|
261
|
max@0
|
262 for(uword i=0; i<n_elem; ++i)
|
max@0
|
263 {
|
max@0
|
264 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) - upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
265 }
|
max@0
|
266 }
|
max@0
|
267
|
max@0
|
268
|
max@0
|
269
|
max@0
|
270 //! element-wise cube division with different element types
|
max@0
|
271 template<typename T1, typename T2>
|
max@0
|
272 inline
|
max@0
|
273 void
|
max@0
|
274 glue_mixed_div::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
|
max@0
|
275 {
|
max@0
|
276 arma_extra_debug_sigprint();
|
max@0
|
277
|
max@0
|
278 typedef typename T1::elem_type eT1;
|
max@0
|
279 typedef typename T2::elem_type eT2;
|
max@0
|
280
|
max@0
|
281 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
282
|
max@0
|
283 promote_type<eT1,eT2>::check();
|
max@0
|
284
|
max@0
|
285 const ProxyCube<T1> A(X.A);
|
max@0
|
286 const ProxyCube<T2> B(X.B);
|
max@0
|
287
|
max@0
|
288 arma_debug_assert_same_size(A, B, "element-wise division");
|
max@0
|
289
|
max@0
|
290 out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
|
max@0
|
291
|
max@0
|
292 out_eT* out_mem = out.memptr();
|
max@0
|
293 const uword n_elem = out.n_elem;
|
max@0
|
294
|
max@0
|
295 for(uword i=0; i<n_elem; ++i)
|
max@0
|
296 {
|
max@0
|
297 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) / upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
298 }
|
max@0
|
299 }
|
max@0
|
300
|
max@0
|
301
|
max@0
|
302
|
max@0
|
303 //! element-wise cube multiplication with different element types
|
max@0
|
304 template<typename T1, typename T2>
|
max@0
|
305 inline
|
max@0
|
306 void
|
max@0
|
307 glue_mixed_schur::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
|
max@0
|
308 {
|
max@0
|
309 arma_extra_debug_sigprint();
|
max@0
|
310
|
max@0
|
311 typedef typename T1::elem_type eT1;
|
max@0
|
312 typedef typename T2::elem_type eT2;
|
max@0
|
313
|
max@0
|
314 typedef typename promote_type<eT1,eT2>::result out_eT;
|
max@0
|
315
|
max@0
|
316 promote_type<eT1,eT2>::check();
|
max@0
|
317
|
max@0
|
318 const ProxyCube<T1> A(X.A);
|
max@0
|
319 const ProxyCube<T2> B(X.B);
|
max@0
|
320
|
max@0
|
321 arma_debug_assert_same_size(A, B, "element-wise multiplication");
|
max@0
|
322
|
max@0
|
323 out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
|
max@0
|
324
|
max@0
|
325 out_eT* out_mem = out.memptr();
|
max@0
|
326 const uword n_elem = out.n_elem;
|
max@0
|
327
|
max@0
|
328 for(uword i=0; i<n_elem; ++i)
|
max@0
|
329 {
|
max@0
|
330 out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) * upgrade_val<eT1,eT2>::apply(B[i]);
|
max@0
|
331 }
|
max@0
|
332 }
|
max@0
|
333
|
max@0
|
334
|
max@0
|
335
|
max@0
|
336 //! @}
|