annotate armadillo-3.900.4/include/armadillo_bits/operator_times.hpp @ 84:55a047986812 tip

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