comparison armadillo-3.900.4/include/armadillo_bits/operator_times.hpp @ 49:1ec0e2823891

Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author Chris Cannam
date Thu, 13 Jun 2013 10:25:24 +0100
parents
children
comparison
equal deleted inserted replaced
48:69251e11a913 49:1ec0e2823891
1 // Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2012 Conrad Sanderson
3 // Copyright (C) 2012 Ryan Curtin
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
9
10
11 //! \addtogroup operator_times
12 //! @{
13
14
15
16 //! Base * scalar
17 template<typename T1>
18 arma_inline
19 typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_times> >::result
20 operator*
21 (const T1& X, const typename T1::elem_type k)
22 {
23 arma_extra_debug_sigprint();
24
25 return eOp<T1, eop_scalar_times>(X,k);
26 }
27
28
29
30 //! scalar * Base
31 template<typename T1>
32 arma_inline
33 typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_times> >::result
34 operator*
35 (const typename T1::elem_type k, const T1& X)
36 {
37 arma_extra_debug_sigprint();
38
39 return eOp<T1, eop_scalar_times>(X,k); // NOTE: order is swapped
40 }
41
42
43
44 //! non-complex Base * complex scalar
45 template<typename T1>
46 arma_inline
47 typename
48 enable_if2
49 <
50 (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
51 const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
52 >::result
53 operator*
54 (
55 const T1& X,
56 const std::complex<typename T1::pod_type>& k
57 )
58 {
59 arma_extra_debug_sigprint();
60
61 return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X, k);
62 }
63
64
65
66 //! complex scalar * non-complex Base
67 template<typename T1>
68 arma_inline
69 typename
70 enable_if2
71 <
72 (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
73 const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
74 >::result
75 operator*
76 (
77 const std::complex<typename T1::pod_type>& k,
78 const T1& X
79 )
80 {
81 arma_extra_debug_sigprint();
82
83 return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X, k);
84 }
85
86
87
88 //! scalar * trans(T1)
89 template<typename T1>
90 arma_inline
91 const Op<T1, op_htrans2>
92 operator*
93 (const typename T1::elem_type k, const Op<T1, op_htrans>& X)
94 {
95 arma_extra_debug_sigprint();
96
97 return Op<T1, op_htrans2>(X.m, k);
98 }
99
100
101
102 //! trans(T1) * scalar
103 template<typename T1>
104 arma_inline
105 const Op<T1, op_htrans2>
106 operator*
107 (const Op<T1, op_htrans>& X, const typename T1::elem_type k)
108 {
109 arma_extra_debug_sigprint();
110
111 return Op<T1, op_htrans2>(X.m, k);
112 }
113
114
115
116 //! Base * diagmat
117 template<typename T1, typename T2>
118 arma_inline
119 typename
120 enable_if2
121 <
122 (is_arma_type<T1>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
123 const Glue<T1, Op<T2, op_diagmat>, glue_times_diag>
124 >::result
125 operator*
126 (const T1& X, const Op<T2, op_diagmat>& Y)
127 {
128 arma_extra_debug_sigprint();
129
130 return Glue<T1, Op<T2, op_diagmat>, glue_times_diag>(X, Y);
131 }
132
133
134
135 //! diagmat * Base
136 template<typename T1, typename T2>
137 arma_inline
138 typename
139 enable_if2
140 <
141 (is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
142 const Glue<Op<T1, op_diagmat>, T2, glue_times_diag>
143 >::result
144 operator*
145 (const Op<T1, op_diagmat>& X, const T2& Y)
146 {
147 arma_extra_debug_sigprint();
148
149 return Glue<Op<T1, op_diagmat>, T2, glue_times_diag>(X, Y);
150 }
151
152
153
154 //! diagmat * diagmat
155 template<typename T1, typename T2>
156 inline
157 Mat< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result >
158 operator*
159 (const Op<T1, op_diagmat>& X, const Op<T2, op_diagmat>& Y)
160 {
161 arma_extra_debug_sigprint();
162
163 typedef typename T1::elem_type eT1;
164 typedef typename T2::elem_type eT2;
165
166 typedef typename promote_type<eT1,eT2>::result out_eT;
167
168 promote_type<eT1,eT2>::check();
169
170 const diagmat_proxy<T1> A(X.m);
171 const diagmat_proxy<T2> B(Y.m);
172
173 arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_elem, B.n_elem, "matrix multiplication");
174
175 const uword N = A.n_elem;
176
177 Mat<out_eT> out(N,N);
178
179 out.zeros();
180
181 for(uword i=0; i<N; ++i)
182 {
183 out.at(i,i) = upgrade_val<eT1,eT2>::apply( A[i] ) * upgrade_val<eT1,eT2>::apply( B[i] );
184 }
185
186 return out;
187 }
188
189
190
191 //! multiplication of Base objects with same element type
192 template<typename T1, typename T2>
193 arma_inline
194 typename
195 enable_if2
196 <
197 is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
198 const Glue<T1, T2, glue_times>
199 >::result
200 operator*
201 (const T1& X, const T2& Y)
202 {
203 arma_extra_debug_sigprint();
204
205 return Glue<T1, T2, glue_times>(X, Y);
206 }
207
208
209
210 //! multiplication of Base objects with different element types
211 template<typename T1, typename T2>
212 inline
213 typename
214 enable_if2
215 <
216 (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
217 const mtGlue< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_times >
218 >::result
219 operator*
220 (
221 const T1& X,
222 const T2& Y
223 )
224 {
225 arma_extra_debug_sigprint();
226
227 typedef typename T1::elem_type eT1;
228 typedef typename T2::elem_type eT2;
229
230 typedef typename promote_type<eT1,eT2>::result out_eT;
231
232 promote_type<eT1,eT2>::check();
233
234 return mtGlue<out_eT, T1, T2, glue_mixed_times>( X, Y );
235 }
236
237
238
239 //! sparse multiplied by scalar
240 template<typename T1>
241 inline
242 typename
243 enable_if2
244 <
245 is_arma_sparse_type<T1>::value,
246 SpOp<T1,spop_scalar_times>
247 >::result
248 operator*
249 (
250 const T1& X,
251 const typename T1::elem_type k
252 )
253 {
254 arma_extra_debug_sigprint();
255
256 return SpOp<T1,spop_scalar_times>(X, k);
257 }
258
259
260
261 template<typename T1>
262 inline
263 typename
264 enable_if2
265 <
266 is_arma_sparse_type<T1>::value,
267 SpOp<T1,spop_scalar_times>
268 >::result
269 operator*
270 (
271 const typename T1::elem_type k,
272 const T1& X
273 )
274 {
275 arma_extra_debug_sigprint();
276
277 return SpOp<T1,spop_scalar_times>(X, k);
278 }
279
280
281
282 //! multiplication of two sparse objects
283 template<typename T1, typename T2>
284 inline
285 arma_hot
286 typename
287 enable_if2
288 <
289 (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
290 const SpGlue<T1,T2,spglue_times>
291 >::result
292 operator*
293 (
294 const T1& x,
295 const T2& y
296 )
297 {
298 arma_extra_debug_sigprint();
299
300 return SpGlue<T1,T2,spglue_times>(x, y);
301 }
302
303
304
305 //! convert "(sparse + sparse) * scalar" to specialised operation "scalar * (sparse + sparse)"
306 template<typename T1, typename T2>
307 inline
308 const SpGlue<T1,T2,spglue_plus2>
309 operator*
310 (
311 const SpGlue<T1,T2,spglue_plus>& X,
312 const typename T1::elem_type k
313 )
314 {
315 arma_extra_debug_sigprint();
316
317 return SpGlue<T1,T2,spglue_plus2>(X.A, X.B, k);
318 }
319
320
321
322 //! convert "scalar * (sparse + sparse)" to specialised operation
323 template<typename T1, typename T2>
324 inline
325 const SpGlue<T1,T2,spglue_plus2>
326 operator*
327 (
328 const typename T1::elem_type k,
329 const SpGlue<T1,T2,spglue_plus>& X
330 )
331 {
332 arma_extra_debug_sigprint();
333
334 return SpGlue<T1,T2,spglue_plus2>(X.A, X.B, k);
335 }
336
337
338
339 //! convert "(sparse - sparse) * scalar" to specialised operation "scalar * (sparse - sparse)"
340 template<typename T1, typename T2>
341 inline
342 const SpGlue<T1,T2,spglue_minus2>
343 operator*
344 (
345 const SpGlue<T1,T2,spglue_minus>& X,
346 const typename T1::elem_type k
347 )
348 {
349 arma_extra_debug_sigprint();
350
351 return SpGlue<T1,T2,spglue_minus2>(X.A, X.B, k);
352 }
353
354
355
356 //! convert "scalar * (sparse - sparse)" to specialised operation
357 template<typename T1, typename T2>
358 inline
359 const SpGlue<T1,T2,spglue_minus2>
360 operator*
361 (
362 const typename T1::elem_type k,
363 const SpGlue<T1,T2,spglue_minus>& X
364 )
365 {
366 arma_extra_debug_sigprint();
367
368 return SpGlue<T1,T2,spglue_minus2>(X.A, X.B, k);
369 }
370
371
372
373 //! convert "(sparse*sparse) * scalar" to specialised operation "scalar * (sparse*sparse)"
374 template<typename T1, typename T2>
375 inline
376 const SpGlue<T1,T2,spglue_times2>
377 operator*
378 (
379 const SpGlue<T1,T2,spglue_times>& X,
380 const typename T1::elem_type k
381 )
382 {
383 arma_extra_debug_sigprint();
384
385 return SpGlue<T1,T2,spglue_times2>(X.A, X.B, k);
386 }
387
388
389
390 //! convert "scalar * (sparse*sparse)" to specialised operation
391 template<typename T1, typename T2>
392 inline
393 const SpGlue<T1,T2,spglue_times2>
394 operator*
395 (
396 const typename T1::elem_type k,
397 const SpGlue<T1,T2,spglue_times>& X
398 )
399 {
400 arma_extra_debug_sigprint();
401
402 return SpGlue<T1,T2,spglue_times2>(X.A, X.B, k);
403 }
404
405
406
407 //! convert "(scalar*sparse) * sparse" to specialised operation "scalar * (sparse*sparse)"
408 template<typename T1, typename T2>
409 inline
410 typename
411 enable_if2
412 <
413 is_arma_sparse_type<T2>::value,
414 const SpGlue<T1,T2,spglue_times2>
415 >::result
416 operator*
417 (
418 const SpOp<T1,spop_scalar_times>& X,
419 const T2& Y
420 )
421 {
422 arma_extra_debug_sigprint();
423
424 return SpGlue<T1,T2,spglue_times2>(X.m, Y, X.aux);
425 }
426
427
428
429 //! convert "sparse * (scalar*sparse)" to specialised operation "scalar * (sparse*sparse)"
430 template<typename T1, typename T2>
431 inline
432 typename
433 enable_if2
434 <
435 is_arma_sparse_type<T1>::value,
436 const SpGlue<T1,T2,spglue_times2>
437 >::result
438 operator*
439 (
440 const T1& X,
441 const SpOp<T2,spop_scalar_times>& Y
442 )
443 {
444 arma_extra_debug_sigprint();
445
446 return SpGlue<T1,T2,spglue_times2>(X, Y.m, Y.aux);
447 }
448
449
450
451 //! multiplication of one sparse and one dense object
452 template<typename T1, typename T2>
453 inline
454 typename
455 enable_if2
456 <
457 (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
458 Mat<typename T1::elem_type>
459 >::result
460 operator*
461 (
462 const T1& x,
463 const T2& y
464 )
465 {
466 arma_extra_debug_sigprint();
467
468 const SpProxy<T1> pa(x);
469 const Proxy<T2> pb(y);
470
471 arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication");
472
473 Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols());
474 result.zeros();
475
476 if( (pa.get_n_nonzero() > 0) && (pb.get_n_elem() > 0) )
477 {
478 typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
479 typename SpProxy<T1>::const_iterator_type x_it_end = pa.end();
480
481 const uword result_n_cols = result.n_cols;
482
483 while(x_it != x_it_end)
484 {
485 for(uword col = 0; col < result_n_cols; ++col)
486 {
487 result.at(x_it.row(), col) += (*x_it) * pb.at(x_it.col(), col);
488 }
489
490 ++x_it;
491 }
492 }
493
494 return result;
495 }
496
497
498
499 //! multiplication of one dense and one sparse object
500 template<typename T1, typename T2>
501 inline
502 typename
503 enable_if2
504 <
505 (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
506 Mat<typename T1::elem_type>
507 >::result
508 operator*
509 (
510 const T1& x,
511 const T2& y
512 )
513 {
514 arma_extra_debug_sigprint();
515
516 const Proxy<T1> pa(x);
517 const SpProxy<T2> pb(y);
518
519 arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication");
520
521 Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols());
522 result.zeros();
523
524 if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) )
525 {
526 typename SpProxy<T2>::const_iterator_type y_col_it = pb.begin();
527 typename SpProxy<T2>::const_iterator_type y_col_it_end = pb.end();
528
529 const uword result_n_rows = result.n_rows;
530
531 while(y_col_it != y_col_it_end)
532 {
533 for(uword row = 0; row < result_n_rows; ++row)
534 {
535 result.at(row, y_col_it.col()) += pa.at(row, y_col_it.row()) * (*y_col_it);
536 }
537
538 ++y_col_it;
539 }
540 }
541
542 return result;
543 }
544
545
546
547 //! @}