comparison armadillo-2.4.4/include/armadillo_bits/glue_mixed_meat.hpp @ 0:8b6102e2a9b0

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