1 /* 2 * Copyright (C) 2002 Zhendong Wan, Bradford Hovinen 3 * Copyright (C) 2013,2014 the LinBox group 4 * 5 * Written by Zhendong Wan <wan@mail.eecis.udel.edu>, 6 * Bradford Hovinen <bghovinen@math.uwaterloo.ca> 7 * Brice Boyer (briceboyer) <boyer.brice@gmail.com> 8 * 9 * ------------------------------------------------------------ 10 * 2002-11-26 Bradford Hovinen <bghovinen@math.uwaterloo.ca> 11 * 12 * Added detailed documentation, cleaned up the interface slightly, and added 13 * support for matrix traits. Added read, write, neg, negin, axpy, and 14 * matrix-vector and matrix-black box operations. 15 * ------------------------------------------------------------ 16 * 17 * 18 * ========LICENCE======== 19 * This file is part of the library LinBox. 20 * 21 * LinBox is free software: you can redistribute it and/or modify 22 * it under the terms of the GNU Lesser General Public 23 * License as published by the Free Software Foundation; either 24 * version 2.1 of the License, or (at your option) any later version. 25 * 26 * This library is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 * Lesser General Public License for more details. 30 * 31 * You should have received a copy of the GNU Lesser General Public 32 * License along with this library; if not, write to the Free Software 33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 34 * ========LICENCE======== 35 *. 36 */ 37 38 /** @file linbox/matrix/matrixdomain/matrix-domain.h 39 * @brief NO DOC 40 */ 41 42 #ifndef __LINBOX_matrixdomain_matrix_domain_H 43 #define __LINBOX_matrixdomain_matrix_domain_H 44 45 #include <linbox/linbox-config.h> 46 #include <iostream> 47 #include <vector> 48 49 #include "linbox/blackbox/archetype.h" 50 #include "linbox/matrix/matrix-traits.h" 51 // #include "linbox/vector/blas-vector.h" 52 53 namespace LinBox 54 { 55 56 57 /** Class of matrix arithmetic functions. 58 * 59 * This class encapuslated matrix-matrix and matrix-vector operations, roughly 60 * equivalent to BLAS levels 2 and 3. The arithmetic methods are parameterized 61 * by matrix type so that they may be used the same way with sparse matrices, 62 * dense matrices, and dense submatrices. Except where otherwise noted, they 63 * require the matrix inputs to meet the \ref BlasMatrix archetype. 64 * 65 * These methods are specialized so that they can run efficiently with different 66 * matrix representations. If a matrix has an efficient row iterator, but not an 67 * efficient column iterator, a specialization that makes use of the former will 68 * be selected. This allows a great deal of flexibility when dealing with sparse 69 * matrix arithmetic. 70 * 71 * For all of the arithmetic operations that output matrices, it is assumed that 72 * the output matrix has an efficient row iterator. In typical use, the output 73 * matrix will be a \ref BlasMatrix or a \ref BlasSubmatrix, which has 74 * efficient row and column iterators. In particular, one should not perform 75 * these arithmetic operations outputting to a \ref SparseMatrixBase. 76 * 77 * There are other restrictions. See the method-specific documentation for more 78 * details. 79 */ 80 template <class Field_ > 81 class MatrixDomain : public MVProductDomain<Field_> { 82 public: 83 typedef size_t Index; 84 typedef Field_ Field; 85 typedef typename Field::Element Element; 86 typedef Element Scalar; 87 //! @bug should be BlasVector 88 typedef typename Vector<Field>::Dense Rep_; 89 // typedef Rep_ DenseVector; 90 typedef BlasVector<Field_,Rep_> DenseVector; 91 typedef BlasMatrix<Field,Rep_> OwnMatrix; 92 typedef BlasSubmatrix<OwnMatrix> Matrix; 93 94 // MatrixDomain () {/*std::cerr << "MD def cstor" << std::endl;*/ } 95 init(const Field & F)96 void init(const Field & F) { _field = &F; _VD.init(F); } 97 MatrixDomain()98 MatrixDomain() {} 99 100 /// Constructor. 101 //! @param F field for MatrixDomain operations. MatrixDomain(const Field & F)102 MatrixDomain (const Field &F) : 103 _field (&F), _VD (F) 104 { /*std::cerr << "MD cstor " << this << std::endl;*/ } 105 106 /// Copy operator. 107 MatrixDomain& operator= (const MatrixDomain& MD) 108 { 109 _field = MD._field; 110 _VD = MD._VD; 111 return *this; 112 } 113 114 /** Retrieve the underlying field. 115 * Return a reference to the field that this matrix domain 116 * object uses 117 * @returns reference to field 118 */ 119 //@{ field()120 const Field &field () const 121 { 122 return *_field; 123 } 124 125 //@} 126 127 /** Print matrix. 128 * @param os Output stream to which matrix is written. 129 * @param A Matrix. 130 * @returns reference to os. 131 */ 132 template <class Matrix_> write(std::ostream & os,const Matrix_ & A)133 inline std::ostream &write (std::ostream &os, const Matrix_ &A) const 134 { 135 return A.write (os); 136 } 137 138 /** Read matrix. 139 * @param is Input stream from which matrix is read. 140 * @param A Matrix. 141 * @returns reference to is. 142 */ 143 template <class Matrix_> read(std::istream & is,Matrix_ & A)144 inline std::istream &read (std::istream &is, Matrix_ &A) const 145 { 146 return A.read (is, _field); 147 } 148 149 /** Matrix copy 150 * B <- A. 151 * Copy the contents of the matrix B to the matrix A 152 * 153 * Both matrices must support the same iterators, row or column. 154 * 155 * @param B Matrix B 156 * @param A Matrix A 157 * @returns Reference to B 158 */ 159 template <class Matrix1, class Matrix2> copy(Matrix1 & B,const Matrix2 & A)160 inline Matrix1 © (Matrix1 &B, const Matrix2 &A) const 161 { 162 return copySpecialized (B, A, 163 typename MatrixTraits<Matrix1>::MatrixCategory (), 164 typename MatrixTraits<Matrix2>::MatrixCategory ()); 165 } 166 /// B <-- A. They must already have the same shape. copy(Matrix & B,const Matrix & A)167 inline Matrix © (Matrix &B, const Matrix &A) const { 168 return B.copy(A); 169 } 170 171 /** Matrix swap 172 * B <--> A. They must already have the same shape. 173 * @returns Reference to B 174 */ swap(Matrix & B,Matrix & A)175 inline Matrix &swap(Matrix &B, Matrix &A) const { 176 return B.swap(A); 177 } 178 179 /** Matrix equality. 180 * Test whether the matrices A and B are equal 181 * @param A Input vector 182 * @param B Input vector 183 * @returns true if and only if the matrices A and B are equal 184 */ 185 template <class Matrix1, class Matrix2> areEqual(const Matrix1 & A,const Matrix2 & B)186 bool areEqual (const Matrix1 &A, const Matrix2 &B) const 187 { 188 return areEqualSpecialized (B, A, 189 typename MatrixTraits<Matrix1>::MatrixCategory (), 190 typename MatrixTraits<Matrix2>::MatrixCategory ()); 191 } 192 193 /** Matrix equality with zero. 194 * @param A Input matrix 195 * @returns true if and only if the matrix A is zero 196 */ 197 template <class Matrix_> isZero(const Matrix_ & A)198 inline bool isZero (const Matrix_ &A) const 199 { 200 return isZeroSpecialized (A, typename MatrixTraits<Matrix_>::MatrixCategory ()); 201 } 202 203 /** Matrix-matrix addition 204 * C <- A + B. 205 * 206 * Each of A, B, and C must support the same iterator, either row or 207 * column 208 * 209 * @param C Output matrix C 210 * @param A Input matrix A 211 * @param B Input matrix B 212 * @returns Reference to C 213 */ 214 template <class Matrix1, class Matrix2, class Matrix3> add(Matrix1 & C,const Matrix2 & A,const Matrix3 & B)215 inline Matrix1& add (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const 216 { 217 return addSpecialized (C, A, B, 218 typename MatrixTraits<Matrix1>::MatrixCategory (), 219 typename MatrixTraits<Matrix2>::MatrixCategory (), 220 typename MatrixTraits<Matrix3>::MatrixCategory ()); 221 } 222 223 /** Matrix-matrix in-place addition 224 * A <- A + B. 225 * 226 * Each of A and B must support the same iterator, either row or column 227 * 228 * @param A Input matrix A 229 * @param B Input matrix B 230 * @returns Reference to A 231 */ 232 template <class Matrix1, class Matrix2> addin(Matrix1 & A,const Matrix2 & B)233 inline Matrix1& addin (Matrix1 &A, const Matrix2 &B) const 234 { 235 return addinSpecialized (A, B, 236 typename MatrixTraits<Matrix1>::MatrixCategory (), 237 typename MatrixTraits<Matrix2>::MatrixCategory ()); 238 } 239 240 /** Matrix-matrix subtraction 241 * C <- A - B. 242 * 243 * Each of A, B, and C must support the same iterator, either row or 244 * column 245 * 246 * @param C Output matrix C 247 * @param A Input matrix A 248 * @param B Input matrix B 249 * @returns Reference to C 250 */ 251 template <class Matrix1, class Matrix2, class Matrix3> sub(Matrix1 & C,const Matrix2 & A,const Matrix3 & B)252 inline Matrix1 &sub (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const 253 { 254 return subSpecialized (C, A, B, 255 typename MatrixTraits<Matrix1>::MatrixCategory (), 256 typename MatrixTraits<Matrix2>::MatrixCategory (), 257 typename MatrixTraits<Matrix3>::MatrixCategory ()); 258 } 259 260 /** Matrix-matrix in-place subtraction 261 * A <- A - B. 262 * 263 * Each of A and B must support the same iterator, either row or column 264 * 265 * @param A Input matrix A 266 * @param B Input matrix B 267 * @returns Reference to A 268 */ 269 template <class Matrix1, class Matrix2> subin(Matrix1 & A,const Matrix2 & B)270 inline Matrix1 &subin (Matrix1 &A, const Matrix2 &B) const 271 { 272 return subinSpecialized (A, B, 273 typename MatrixTraits<Matrix1>::MatrixCategory (), 274 typename MatrixTraits<Matrix2>::MatrixCategory ()); 275 } 276 277 /** Matrix negate 278 * B <- -A. 279 * 280 * Each of A and B must support the same iterator, either row or column 281 * 282 * @param B Output matrix B 283 * @param A Input matrix A 284 * @returns reference to B 285 */ 286 template <class Matrix1, class Matrix2> neg(Matrix1 & B,const Matrix2 & A)287 inline Matrix1 &neg (Matrix1 &B, const Matrix2 &A) const 288 { 289 return negSpecialized (B, A, 290 typename MatrixTraits<Matrix1>::MatrixCategory (), 291 typename MatrixTraits<Matrix2>::MatrixCategory ()); 292 } 293 294 /** Matrix in-place negate 295 * A <- -A. 296 * @param A Input matrix A; result is stored here 297 */ 298 template <class Matrix_> negin(Matrix_ & A)299 inline Matrix_ &negin (Matrix_ &A) const 300 { 301 return neginSpecialized (A, typename MatrixTraits<Matrix_>::MatrixCategory ()); 302 } 303 304 /** Matrix-matrix multiply 305 * C <- A * B. 306 * 307 * C must support both row and column iterators, and the vector 308 * representations must be dense. Examples of supported matrices are 309 * \ref BlasMatrix and \ref BlasSubmatrix. 310 * 311 * Either A or B, or both, may have limited iterators. However, either A 312 * must support row iterators or B must support column iterators. If 313 * both A and B lack support for an iterator (either row or column), 314 * then C must support the same type of iterator as A and B. 315 * 316 * @param C Output matrix C 317 * @param A Input matrix A 318 * @param B Input matrix B 319 * @returns Reference to C 320 */ 321 template <class Matrix1, class Matrix2, class Matrix3> mul(Matrix1 & C,const Matrix2 & A,const Matrix3 & B)322 inline Matrix1 &mul (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const 323 { 324 return mulSpecialized (C, A, B, 325 typename MatrixTraits<Matrix1>::MatrixCategory (), 326 typename MatrixTraits<Matrix2>::MatrixCategory (), 327 typename MatrixTraits<Matrix3>::MatrixCategory ()); 328 } 329 330 /** Matrix-matrix in-place multiply on the left 331 * B <- A * B. 332 * 333 * B should support both row and column iterators, and must be dense. A 334 * must support row iterators. 335 * 336 * @param A Input matrix A 337 * @param B Input matrix B 338 * @returns Reference to B 339 */ 340 template <class Matrix1, class Matrix2> 341 inline Matrix2 &leftMulin (const Matrix1 &A, Matrix2 &B) const; 342 343 /** Matrix-matrix in-place multiply on the right 344 * A <- A * B. 345 * 346 * A should support both row and column iterators, and must be dense. B 347 * must support column iterators. 348 * 349 * @param A Input matrix A 350 * @param B Input matrix B 351 * @returns Reference to A 352 */ 353 template <class Matrix1, class Matrix2> 354 inline Matrix1 &rightMulin (Matrix1 &A, const Matrix2 &B) const; 355 356 /** Matrix-matrix in-place multiply 357 * A <- A * B. 358 * 359 * This is an alias for \ref rightMulin 360 * 361 * @param A Input matrix A 362 * @param B Input matrix B 363 * @returns Reference to A 364 */ 365 template <class Matrix1, class Matrix2> mulin(Matrix1 & A,const Matrix2 & B)366 inline Matrix1 &mulin (Matrix1 &A, const Matrix2 &B) const 367 { 368 return rightMulin (A, B); 369 } 370 371 /** Matrix-scalar multiply 372 * C <- B * a. 373 * 374 * Multiply B by the scalar element a and store the result in C. B and C 375 * must support the same iterators. 376 * 377 * @param C Output matrix C 378 * @param B Input matrix B 379 * @param a Input scalar a 380 * @returns Reference to C 381 */ 382 template <class Matrix1, class Matrix2> mul(Matrix1 & C,const Matrix2 & B,const typename Field::Element & a)383 inline Matrix1 &mul (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a) const 384 { 385 return mulSpecialized (C, B, a, 386 typename MatrixTraits<Matrix1>::MatrixCategory (), 387 typename MatrixTraits<Matrix2>::MatrixCategory ()); 388 } 389 390 /** Matrix-scalar in-place multiply 391 * B <- B * a. 392 * 393 * Multiply B by the scalar element a in-place. 394 * 395 * @param B Input matrix B 396 * @param a Input scalar a 397 * @returns Reference to B 398 */ 399 template <class Matrix_> mulin(Matrix_ & B,const typename Field::Element & a)400 inline Matrix_ &mulin (Matrix_ &B, const typename Field::Element &a) const 401 { 402 return mulinSpecialized (B, a, typename MatrixTraits<Matrix_>::MatrixCategory ()); 403 } 404 405 /** Matrix-matrix in-place axpy 406 * Y <- Y + A*X. 407 * 408 * This function combines \ref mul and \ref add, eliminating the need 409 * for an additional temporary in expressions of the form $Y = Y + 410 * AX$. Only one row of additional storage is required. Y may have 411 * either efficient row iterators or efficient column iterators, and the 412 * same restrictions on A and X apply as in \ref mul. 413 * 414 * Note that no out-of-place axpy is provided, since it gives no 415 * benefit. One may just as easily multiply into the result and call 416 * \ref addin. 417 * 418 * @param Y Input matrix Y; result is stored here 419 * @param A Input matrix A 420 * @param X Input matrix X 421 */ 422 template <class Matrix1, class Matrix2, class Matrix3> axpyin(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X)423 inline Matrix1 &axpyin (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const 424 { 425 return axpyinSpecialized (Y, A, X, 426 typename MatrixTraits<Matrix1>::MatrixCategory (), 427 typename MatrixTraits<Matrix2>::MatrixCategory (), 428 typename MatrixTraits<Matrix3>::MatrixCategory ()); 429 } 430 431 //! Y <- AX-Y 432 template <class Matrix1, class Matrix2, class Matrix3> axmyin(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X)433 inline Matrix1 &axmyin (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const 434 { 435 negin(Y); 436 axpyin(Y,A,X); 437 return Y; 438 } 439 440 // Y <- Y + aX 441 template <class Matrix1, class Matrix3> saxpyin(Matrix1 & Y,const Element & a,const Matrix3 & X)442 inline Matrix1 &saxpyin (Matrix1 &Y, const Element &a, const Matrix3 &X) const 443 { // a crude hack for now 444 Element x, y; 445 for (size_t i = 0; i < X.rowdim(); ++i) 446 for (size_t j = 0; j < X.coldim(); ++j) 447 Y.setEntry(i,j,field().axpyin(Y.getEntry(y,i,j), a, X.getEntry(x, i, j))); 448 return Y; 449 } 450 451 /*! General matrix multiply 452 * \f$ D \gets \alpha A B + \beta C\f$. 453 * @todo not efficient... 454 */ 455 template <class Matrix1, class Matrix2, class Matrix3> muladd(Matrix1 & D,const typename Field::Element & beta,const Matrix1 & C,const typename Field::Element & alpha,const Matrix2 & A,const Matrix3 & B)456 inline Matrix1 &muladd (Matrix1 & D, 457 const typename Field::Element & beta, 458 const Matrix1 & C, 459 const typename Field::Element & alpha, 460 const Matrix2 & A, 461 const Matrix3 & B) const 462 { 463 mul(D,A,B); // D = AB 464 mulin(D,alpha); // D = alpha D 465 Matrix1 CC(C); 466 mulin(CC,beta); // C = beta C 467 addin(D,CC); // D = D+C 468 return D; 469 } 470 471 /*! @todo Need documentation of these methods */ 472 //@{ 473 template<class Matrix1, class Matrix2> 474 Matrix1 &pow_apply (Matrix1 &M1, const Matrix2 &M2, unsigned long int k) const; 475 476 template<class Matrix1, class Matrix2> 477 Matrix1 &pow_horn (Matrix1 &M1, const Matrix2 &M2, unsigned long int k) const; 478 //@} 479 480 481 /*! @name Matrix-vector arithmetic operations 482 * These operations take a matrix satisfying the \ref DenseMatrix 483 * archetype and LinBox vectors as inputs. They involve matrix-vector 484 * product and matrix-vector AXPY 485 */ 486 //@{ 487 /** Matrix-vector multiply 488 * w <- A * v. 489 * 490 * The vectors v and w must be of the same representation (dense, sparse 491 * sequence, sparse associative, or sparse parallel), but they may be of 492 * different types. The matrix A may have any representation. 493 * 494 * @param w Output vector w 495 * @param A Input matrix A 496 * @param v Input vector v 497 * @returns Reference to w 498 */ 499 template <class Vector1, class Matrix_, class Vector2> vectorMul(Vector1 & w,const Matrix_ & A,const Vector2 & v)500 inline Vector1 &vectorMul (Vector1 &w, const Matrix_ &A, const Vector2 &v) const 501 { 502 return mulSpecialized (w, A, v, typename MatrixTraits<Matrix_>::MatrixCategory ()); 503 } 504 505 /** Matrix-vector in-place axpy 506 * \f$y \gets y + A x\f$. 507 * 508 * This function eliminates the requirement for temporary storage when 509 * one is computing an expression of the form given above. 510 * 511 * The vectors y and x must be of the same representation (dense, sparse 512 * sequence, sparse associative, or sparse parallel), but they may be of 513 * different types. The matrix A may have any representation. 514 * 515 * Note that out-of-place axpy is not provided since it provides no 516 * benefit -- one can use mul and then addin to exactly the same effect, 517 * with no additional storage or performance cost. 518 * 519 * @param y Input vector y; result is stored here 520 * @param A Input matrix A 521 * @param x Input vector x 522 */ 523 template <class Vector1, class Matrix_, class Vector2> vectorAxpyin(Vector1 & y,const Matrix_ & A,const Vector2 & x)524 inline Vector1 &vectorAxpyin (Vector1 &y, const Matrix_ &A, const Vector2 &x) const 525 { 526 return axpyinSpecialized (y, A, x, typename MatrixTraits<Matrix_>::MatrixCategory ()); 527 } 528 //@} 529 530 /*! @name Matrix-black box arithmetic operations 531 * These operations mimic the matrix-matrix arithmetic operations above, 532 * but one of the parameters is a \ref BlackboxArchetype. 533 */ 534 //@{ 535 /** Matrix-black box left-multiply 536 * C <- A * B. 537 * 538 * Both C and B must support column iterators 539 * 540 * @param C Output matrix 541 * @param A Black box for A 542 * @param B Matrix B 543 */ 544 template <class Matrix1, class Blackbox, class Matrix2> 545 inline Matrix1 &blackboxMulLeft (Matrix1 &C, const Blackbox &A, const Matrix2 &B) const; 546 547 /** Matrix-black box right-multiply 548 * C <- A * B. 549 * 550 * Both C and A must support row iterators 551 * 552 * @param C Output matrix 553 * @param A Matrix A 554 * @param B Black box for B 555 */ 556 template <class Matrix1, class Matrix2, class Blackbox> 557 inline Matrix1 &blackboxMulRight (Matrix1 &C, const Matrix2 &A, const Blackbox &B) const; 558 //@} 559 560 /*! @name Matrix permutations 561 * @brief 562 * These operations permute the rows or columns of a matrix based on 563 * the given permutation. They are intended for use with Gauss-Jordan 564 * elimination 565 */ 566 //@{ 567 /// Transposition. 568 typedef std::pair<unsigned int, unsigned int> Transposition; 569 /** Permutation. 570 * 571 * A permutation is represented as a vector of pairs, each 572 * pair representing a transposition. 573 */ 574 typedef std::vector<Transposition> Permutation; 575 576 577 /** Permute the rows of the given matrix. 578 * 579 * @param A Output matrix 580 * @param P_start Start of permutation 581 * @param P_end End of permutation 582 * @returns Reference to A 583 */ 584 template <class Matrix_, class Iterator> permuteRows(Matrix_ & A,Iterator P_start,Iterator P_end)585 inline Matrix_ &permuteRows (Matrix_ &A, 586 Iterator P_start, 587 Iterator P_end) const 588 { 589 return permuteRowsSpecialized (A, P_start, P_end, 590 typename MatrixTraits<Matrix_>::MatrixCategory ()); 591 } 592 593 /** Permute the columns of the given matrix. 594 * 595 * @param A Output matrix 596 * @param P_start Start of permutation 597 * @param P_end End of permutation 598 * @returns Reference to A 599 */ 600 template <class Matrix_, class Iterator> permuteColumns(Matrix_ & A,Iterator P_start,Iterator P_end)601 inline Matrix_ &permuteColumns (Matrix_ &A, 602 Iterator P_start, 603 Iterator P_end) const 604 { 605 return permuteColsSpecialized (A, P_start, P_end, 606 typename MatrixTraits<Matrix_>::MatrixCategory ()); 607 } 608 //@} 609 vectorDomain()610 const VectorDomain<Field> & vectorDomain() const 611 { 612 return _VD ; 613 } 614 protected: 615 616 // Specialized function implementations 617 template <class Matrix1, class Matrix2> Matrix1 ©Row (Matrix1 &B, const Matrix2 &A) const; 618 template <class Matrix1, class Matrix2> Matrix1 ©Col (Matrix1 &B, const Matrix2 &A) const; 619 620 template <class Matrix1, class Matrix2> copySpecialized(Matrix1 & B,const Matrix2 & A,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)621 inline Matrix1 ©Specialized (Matrix1 &B, const Matrix2 &A, 622 MatrixCategories::RowMatrixTag, 623 MatrixCategories::RowMatrixTag) const 624 { 625 return copyRow (B, A); 626 } 627 template <class Matrix1, class Matrix2> copySpecialized(Matrix1 & B,const Matrix2 & A,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)628 inline Matrix1 ©Specialized (Matrix1 &B, const Matrix2 &A, 629 MatrixCategories::ColMatrixTag, 630 MatrixCategories::ColMatrixTag) const 631 { 632 return copyCol (B, A); 633 } 634 template <class Matrix1, class Matrix2> copySpecialized(Matrix1 & B,const Matrix2 & A,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)635 inline Matrix1 ©Specialized (Matrix1 &B, const Matrix2 &A, 636 MatrixCategories::RowColMatrixTag, 637 MatrixCategories::RowColMatrixTag) const 638 { 639 return copyRow (B, A); 640 } 641 642 template <class Matrix1, class Matrix2> bool areEqualBB (const Matrix1 &A, const Matrix2 &B) const; 643 template <class Matrix1, class Matrix2> bool areEqualRow (const Matrix1 &A, const Matrix2 &B) const; 644 template <class Matrix1, class Matrix2> bool areEqualCol (const Matrix1 &A, const Matrix2 &B) const; 645 646 template <class Matrix1, class Matrix2> areEqualSpecialized(const Matrix1 & A,const Matrix2 & B,MatrixCategories::BlackboxTag,MatrixCategories::BlackboxTag)647 inline bool areEqualSpecialized (const Matrix1 &A, const Matrix2 &B, 648 MatrixCategories::BlackboxTag, 649 MatrixCategories::BlackboxTag) const 650 { 651 return areEqualBB(A, B); 652 } 653 template <class Matrix1, class Matrix2> areEqualSpecialized(const Matrix1 & A,const Matrix2 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)654 inline bool areEqualSpecialized (const Matrix1 &A, const Matrix2 &B, 655 MatrixCategories::RowMatrixTag, 656 MatrixCategories::RowMatrixTag) const 657 { 658 return areEqualRow (A, B); 659 } 660 template <class Matrix1, class Matrix2> areEqualSpecialized(const Matrix1 & A,const Matrix2 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)661 inline bool areEqualSpecialized (const Matrix1 &A, const Matrix2 &B, 662 MatrixCategories::ColMatrixTag, 663 MatrixCategories::ColMatrixTag) const 664 { 665 return areEqualCol (A, B); 666 } 667 template <class Matrix1, class Matrix2> areEqualSpecialized(const Matrix1 & A,const Matrix2 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)668 inline bool areEqualSpecialized (const Matrix1 &A, const Matrix2 &B, 669 MatrixCategories::RowColMatrixTag, 670 MatrixCategories::RowColMatrixTag) const 671 { 672 return areEqualRow (A, B); 673 } 674 675 template <class Matrix_> bool isZeroBB (const Matrix_ &v) const; 676 template <class Matrix_> bool isZeroRow (const Matrix_ &v) const; 677 template <class Matrix_> bool isZeroCol (const Matrix_ &v) const; 678 679 template <class Matrix_> isZeroSpecialized(const Matrix_ & A,MatrixCategories::BlackboxTag)680 bool isZeroSpecialized (const Matrix_ &A, MatrixCategories::BlackboxTag) const 681 { 682 return isZeroBB (A); 683 } 684 template <class Matrix_> isZeroSpecialized(const Matrix_ & A,MatrixCategories::RowMatrixTag)685 bool isZeroSpecialized (const Matrix_ &A, MatrixCategories::RowMatrixTag) const 686 { 687 return isZeroRow (A); 688 } 689 template <class Matrix_> isZeroSpecialized(const Matrix_ & A,MatrixCategories::ColMatrixTag)690 bool isZeroSpecialized (const Matrix_ &A, MatrixCategories::ColMatrixTag) const 691 { 692 return isZeroCol (A); 693 } 694 template <class Matrix_> isZeroSpecialized(const Matrix_ & A,MatrixCategories::RowColMatrixTag)695 bool isZeroSpecialized (const Matrix_ &A, MatrixCategories::RowColMatrixTag) const 696 { 697 return isZeroRow (A); 698 } 699 700 template <class Matrix1, class Matrix2, class Matrix3> 701 Matrix1& addRow (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 702 template <class Matrix1, class Matrix2, class Matrix3> 703 Matrix1& addCol (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 704 705 template <class Matrix1, class Matrix2, class Matrix3> addSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)706 Matrix1& addSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 707 MatrixCategories::RowMatrixTag, 708 MatrixCategories::RowMatrixTag, 709 MatrixCategories::RowMatrixTag) const 710 { 711 return addRow (C, A, B); 712 } 713 template <class Matrix1, class Matrix2, class Matrix3> addSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)714 Matrix1& addSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 715 MatrixCategories::ColMatrixTag, 716 MatrixCategories::ColMatrixTag, 717 MatrixCategories::ColMatrixTag) const 718 { 719 return addCol (C, A, B); 720 } 721 template <class Matrix1, class Matrix2, class Matrix3> addSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)722 Matrix1& addSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 723 MatrixCategories::RowColMatrixTag, 724 MatrixCategories::RowColMatrixTag, 725 MatrixCategories::RowColMatrixTag) const 726 { 727 return addRow (C, A, B); 728 } 729 730 template <class Matrix1, class Matrix2> Matrix1& addinRow (Matrix1 &A, const Matrix2 &B) const; 731 template <class Matrix1, class Matrix2> Matrix1& addinCol (Matrix1 &A, const Matrix2 &B) const; 732 733 template <class Matrix1, class Matrix2> addinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)734 inline Matrix1& addinSpecialized (Matrix1 &A, const Matrix2 &B, 735 MatrixCategories::RowMatrixTag, 736 MatrixCategories::RowMatrixTag) const 737 { 738 return addinRow (A, B); 739 } 740 template <class Matrix1, class Matrix2> addinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)741 inline Matrix1& addinSpecialized (Matrix1 &A, const Matrix2 &B, 742 MatrixCategories::ColMatrixTag, 743 MatrixCategories::ColMatrixTag) const 744 { 745 return addinCol (A, B); 746 } 747 template <class Matrix1, class Matrix2> addinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)748 inline Matrix1& addinSpecialized (Matrix1 &A, const Matrix2 &B, 749 MatrixCategories::RowColMatrixTag, 750 MatrixCategories::RowColMatrixTag) const 751 { 752 return addinRow (A, B); 753 } 754 755 template <class Matrix1, class Matrix2, class Matrix3> 756 Matrix1& subRow (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 757 template <class Matrix1, class Matrix2, class Matrix3> 758 Matrix1& subCol (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 759 760 template <class Matrix1, class Matrix2, class Matrix3> subSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)761 Matrix1& subSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 762 MatrixCategories::RowMatrixTag, 763 MatrixCategories::RowMatrixTag, 764 MatrixCategories::RowMatrixTag) const 765 { 766 return subRow (C, A, B); 767 } 768 template <class Matrix1, class Matrix2, class Matrix3> subSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)769 Matrix1& subSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 770 MatrixCategories::ColMatrixTag, 771 MatrixCategories::ColMatrixTag, 772 MatrixCategories::ColMatrixTag) const 773 { 774 return subCol (C, A, B); 775 } 776 template <class Matrix1, class Matrix2, class Matrix3> subSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)777 Matrix1& subSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 778 MatrixCategories::RowColMatrixTag, 779 MatrixCategories::RowColMatrixTag, 780 MatrixCategories::RowColMatrixTag) const 781 { 782 return subRow (C, A, B); 783 } 784 785 template <class Matrix1, class Matrix2> Matrix1& subinRow (Matrix1 &A, const Matrix2 &B) const; 786 template <class Matrix1, class Matrix2> Matrix1& subinCol (Matrix1 &A, const Matrix2 &B) const; 787 788 template <class Matrix1, class Matrix2> subinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)789 Matrix1& subinSpecialized (Matrix1 &A, const Matrix2 &B, 790 MatrixCategories::RowMatrixTag, 791 MatrixCategories::RowMatrixTag) const 792 { 793 return subinRow (A, B); 794 } 795 template <class Matrix1, class Matrix2> subinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)796 Matrix1& subinSpecialized (Matrix1 &A, const Matrix2 &B, 797 MatrixCategories::ColMatrixTag, 798 MatrixCategories::ColMatrixTag) const 799 { 800 return subinCol (A, B); 801 } 802 template <class Matrix1, class Matrix2> subinSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)803 Matrix1& subinSpecialized (Matrix1 &A, const Matrix2 &B, 804 MatrixCategories::RowColMatrixTag, 805 MatrixCategories::RowColMatrixTag) const 806 { 807 return subinRow (A, B); 808 } 809 810 template <class Matrix1, class Matrix2> Matrix1& negRow (Matrix1 &A, const Matrix2 &B) const; 811 template <class Matrix1, class Matrix2> Matrix1& negCol (Matrix1 &A, const Matrix2 &B) const; 812 813 template <class Matrix1, class Matrix2> negSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)814 inline Matrix1& negSpecialized (Matrix1 &A, const Matrix2 &B, 815 MatrixCategories::RowMatrixTag, 816 MatrixCategories::RowMatrixTag) const 817 { 818 return negRow (A, B); 819 } 820 template <class Matrix1, class Matrix2> negSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)821 inline Matrix1& negSpecialized (Matrix1 &A, const Matrix2 &B, 822 MatrixCategories::ColMatrixTag, 823 MatrixCategories::ColMatrixTag) const 824 { 825 return negCol (A, B); 826 } 827 template <class Matrix1, class Matrix2> negSpecialized(Matrix1 & A,const Matrix2 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)828 inline Matrix1& negSpecialized (Matrix1 &A, const Matrix2 &B, 829 MatrixCategories::RowColMatrixTag, 830 MatrixCategories::RowColMatrixTag) const 831 { 832 return negRow (A, B); 833 } 834 835 template <class Matrix_> Matrix_ &neginRow (Matrix_ &A) const; 836 template <class Matrix_> Matrix_ &neginCol (Matrix_ &A) const; 837 838 template <class Matrix_> neginSpecialized(Matrix_ & A,MatrixCategories::RowMatrixTag)839 Matrix_ &neginSpecialized (Matrix_ &A, MatrixCategories::RowMatrixTag) const 840 { 841 return neginRow (A); 842 } 843 template <class Matrix_> neginSpecialized(Matrix_ & A,MatrixCategories::ColMatrixTag)844 Matrix_ &neginSpecialized (Matrix_ &A, MatrixCategories::ColMatrixTag) const 845 { 846 return neginCol (A); 847 } 848 template <class Matrix_> neginSpecialized(Matrix_ & A,MatrixCategories::RowColMatrixTag)849 Matrix_ &neginSpecialized (Matrix_ &A, MatrixCategories::RowColMatrixTag) const 850 { 851 return neginRow (A); 852 } 853 854 template <class Matrix1, class Matrix2, class Matrix3> 855 Matrix1 &mulRowRowCol (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 856 template <class Matrix1, class Matrix2, class Matrix3> 857 Matrix1 &mulColRowCol (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 858 template <class Matrix1, class Matrix2, class Matrix3> 859 Matrix1 &mulRowRowRow (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 860 template <class Matrix1, class Matrix2, class Matrix3> 861 Matrix1 &mulColColCol (Matrix1 &C, const Matrix2 &A, const Matrix3 &B) const; 862 863 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::BlackboxTag)864 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 865 MatrixCategories::RowMatrixTag, 866 MatrixCategories::RowMatrixTag, 867 MatrixCategories::BlackboxTag) const 868 { 869 return blackboxMulRight(C, A, B); 870 } 871 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::ColMatrixTag,MatrixCategories::BlackboxTag,MatrixCategories::ColMatrixTag)872 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 873 MatrixCategories::ColMatrixTag, 874 MatrixCategories::BlackboxTag, 875 MatrixCategories::ColMatrixTag) const 876 { 877 return blackboxMulLeft(C, A, B); 878 } 879 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)880 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 881 MatrixCategories::RowMatrixTag, 882 MatrixCategories::RowMatrixTag, 883 MatrixCategories::ColMatrixTag) const 884 { 885 return mulRowRowCol (C, A, B); 886 } 887 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::ColMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)888 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 889 MatrixCategories::ColMatrixTag, 890 MatrixCategories::RowMatrixTag, 891 MatrixCategories::ColMatrixTag) const 892 { 893 return mulColRowCol (C, A, B); 894 } 895 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)896 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 897 MatrixCategories::RowColMatrixTag, 898 MatrixCategories::RowMatrixTag, 899 MatrixCategories::ColMatrixTag) const 900 { 901 return mulRowRowCol (C, A, B); 902 } 903 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)904 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 905 MatrixCategories::RowMatrixTag, 906 MatrixCategories::RowMatrixTag, 907 MatrixCategories::RowMatrixTag) const 908 { 909 return mulRowRowRow (C, A, B); 910 } 911 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)912 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 913 MatrixCategories::ColMatrixTag, 914 MatrixCategories::ColMatrixTag, 915 MatrixCategories::ColMatrixTag) const 916 { 917 return mulColColCol (C, A, B); 918 } 919 template <class Matrix1, class Matrix2, class Matrix3> mulSpecialized(Matrix1 & C,const Matrix2 & A,const Matrix3 & B,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)920 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &A, const Matrix3 &B, 921 MatrixCategories::RowColMatrixTag, 922 MatrixCategories::RowColMatrixTag, 923 MatrixCategories::RowColMatrixTag) const 924 { 925 return mulRowRowCol (C, A, B); 926 } 927 928 template <class Matrix1, class Matrix2> 929 Matrix1 &mulRow (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a) const; 930 template <class Matrix1, class Matrix2> 931 Matrix1 &mulCol (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a) const; 932 933 template <class Matrix1, class Matrix2> mulSpecialized(Matrix1 & C,const Matrix2 & B,const typename Field::Element & a,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)934 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a, 935 MatrixCategories::RowMatrixTag, 936 MatrixCategories::RowMatrixTag) const 937 { 938 return mulRow (C, B, a); 939 } 940 template <class Matrix1, class Matrix2> mulSpecialized(Matrix1 & C,const Matrix2 & B,const typename Field::Element & a,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)941 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a, 942 MatrixCategories::ColMatrixTag, 943 MatrixCategories::ColMatrixTag) const 944 { 945 return mulCol (C, B, a); 946 } 947 template <class Matrix1, class Matrix2> mulSpecialized(Matrix1 & C,const Matrix2 & B,const typename Field::Element & a,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)948 Matrix1 &mulSpecialized (Matrix1 &C, const Matrix2 &B, const typename Field::Element &a, 949 MatrixCategories::RowColMatrixTag, 950 MatrixCategories::RowColMatrixTag) const 951 { 952 return mulRow (C, B, a); 953 } 954 955 template <class Matrix_> Matrix_ &mulinRow (Matrix_ &B, const typename Field::Element &a) const; 956 template <class Matrix_> Matrix_ &mulinCol (Matrix_ &B, const typename Field::Element &a) const; 957 958 template <class Matrix_> mulinSpecialized(Matrix_ & B,const typename Field::Element & a,MatrixCategories::RowMatrixTag)959 Matrix_ &mulinSpecialized (Matrix_ &B, const typename Field::Element &a, 960 MatrixCategories::RowMatrixTag) const 961 { 962 return mulinRow (B, a); 963 } 964 template <class Matrix_> mulinSpecialized(Matrix_ & B,const typename Field::Element & a,MatrixCategories::ColMatrixTag)965 Matrix_ &mulinSpecialized (Matrix_ &B, const typename Field::Element &a, 966 MatrixCategories::ColMatrixTag) const 967 { 968 return mulinCol (B, a); 969 } 970 template <class Matrix_> mulinSpecialized(Matrix_ & B,const typename Field::Element & a,MatrixCategories::RowColMatrixTag)971 Matrix_ &mulinSpecialized (Matrix_ &B, const typename Field::Element &a, 972 MatrixCategories::RowColMatrixTag) const 973 { 974 return mulinRow (B, a); 975 } 976 977 template <class Matrix1, class Matrix2, class Matrix3> 978 Matrix1 &axpyinRowRowCol (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const; 979 template <class Matrix1, class Matrix2, class Matrix3> 980 Matrix1 &axpyinColRowCol (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const; 981 template <class Matrix1, class Matrix2, class Matrix3> 982 Matrix1 &axpyinRowRowRow (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const; 983 template <class Matrix1, class Matrix2, class Matrix3> 984 Matrix1 &axpyinColColCol (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X) const; 985 986 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)987 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 988 MatrixCategories::RowMatrixTag, 989 MatrixCategories::RowMatrixTag, 990 MatrixCategories::ColMatrixTag) const 991 { 992 return axpyinRowRowCol (Y, A, X); 993 } 994 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::ColMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)995 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 996 MatrixCategories::ColMatrixTag, 997 MatrixCategories::RowMatrixTag, 998 MatrixCategories::ColMatrixTag) const 999 { 1000 return axpyinColRowCol (Y, A, X); 1001 } 1002 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::RowColMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::ColMatrixTag)1003 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 1004 MatrixCategories::RowColMatrixTag, 1005 MatrixCategories::RowMatrixTag, 1006 MatrixCategories::ColMatrixTag) const 1007 { 1008 return axpyinRowRowCol (Y, A, X); 1009 } 1010 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag,MatrixCategories::RowMatrixTag)1011 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 1012 MatrixCategories::RowMatrixTag, 1013 MatrixCategories::RowMatrixTag, 1014 MatrixCategories::RowMatrixTag) const 1015 { 1016 return axpyinRowRowRow (Y, A, X); 1017 } 1018 1019 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag,MatrixCategories::ColMatrixTag)1020 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 1021 MatrixCategories::ColMatrixTag, 1022 MatrixCategories::ColMatrixTag, 1023 MatrixCategories::ColMatrixTag) const 1024 { 1025 return axpyinColColCol (Y, A, X); 1026 } 1027 1028 template <class Matrix1, class Matrix2, class Matrix3> axpyinSpecialized(Matrix1 & Y,const Matrix2 & A,const Matrix3 & X,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag,MatrixCategories::RowColMatrixTag)1029 Matrix1 &axpyinSpecialized (Matrix1 &Y, const Matrix2 &A, const Matrix3 &X, 1030 MatrixCategories::RowColMatrixTag, 1031 MatrixCategories::RowColMatrixTag, 1032 MatrixCategories::RowColMatrixTag) const 1033 { 1034 return axpyinRowRowCol (Y, A, X); 1035 } 1036 1037 template <class Vector1, class Matrix_, class Vector2> 1038 Vector1 &mulRowSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1039 VectorCategories::DenseVectorTag) const; 1040 template <class Vector1, class Matrix_, class Vector2> 1041 Vector1 &mulRowSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1042 VectorCategories::SparseSequenceVectorTag) const; 1043 template <class Vector1, class Matrix_, class Vector2> 1044 Vector1 &mulRowSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1045 VectorCategories::SparseAssociativeVectorTag) const; 1046 template <class Vector1, class Matrix_, class Vector2> 1047 Vector1 &mulRowSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1048 VectorCategories::SparseParallelVectorTag) const; 1049 1050 template <class Vector1, class Matrix_, class Vector2> mulColSpecialized(Vector1 & w,const Matrix_ & A,const Vector2 & v,VectorCategories::DenseVectorTag,VectorCategories::DenseVectorTag)1051 Vector1 &mulColSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1052 VectorCategories::DenseVectorTag, 1053 VectorCategories::DenseVectorTag) const 1054 { 1055 return this->mulColDense (_VD, w, A, v); 1056 } 1057 template <class Vector1, class Matrix_, class Vector2> 1058 Vector1 &mulColSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1059 VectorCategories::DenseVectorTag, 1060 VectorCategories::SparseSequenceVectorTag) const; 1061 template <class Vector1, class Matrix_, class Vector2> 1062 Vector1 &mulColSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1063 VectorCategories::DenseVectorTag, 1064 VectorCategories::SparseAssociativeVectorTag) const; 1065 template <class Vector1, class Matrix_, class Vector2> 1066 Vector1 &mulColSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1067 VectorCategories::DenseVectorTag, 1068 VectorCategories::SparseParallelVectorTag) const; 1069 1070 template <class Vector1, class Matrix_, class Vector2> mulColSpecialized(Vector1 & w,const Matrix_ & A,const Vector2 & v,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1071 inline Vector1 &mulColSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1072 VectorCategories::GenericVectorTag, 1073 VectorCategories::GenericVectorTag) const 1074 { 1075 DenseVector y(field()); 1076 1077 VectorWrapper::ensureDim (y, w.size ()); 1078 1079 VectorWrapper::ensureDim (y, w.size ()); 1080 1081 vectorMul (y, A, v); 1082 _VD.copy (w, y); 1083 1084 return w; 1085 } 1086 1087 template <class Vector1, class Matrix_, class Vector2> mulSpecialized(Vector1 & w,const Matrix_ & A,const Vector2 & v,MatrixCategories::RowMatrixTag)1088 Vector1 &mulSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1089 MatrixCategories::RowMatrixTag) const 1090 { 1091 return mulRowSpecialized (w, A, v, typename VectorTraits<Vector1>::VectorCategory ()); 1092 } 1093 template <class Vector1, class Matrix_, class Vector2> mulSpecialized(Vector1 & w,const Matrix_ & A,const Vector2 & v,MatrixCategories::ColMatrixTag)1094 Vector1 &mulSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1095 MatrixCategories::ColMatrixTag) const 1096 { 1097 return mulColSpecialized (w, A, v, 1098 typename VectorTraits<Vector1>::VectorCategory (), 1099 typename VectorTraits<Vector2>::VectorCategory ()); 1100 } 1101 template <class Vector1, class Matrix_, class Vector2> mulSpecialized(Vector1 & w,const Matrix_ & A,const Vector2 & v,MatrixCategories::RowColMatrixTag)1102 Vector1 &mulSpecialized (Vector1 &w, const Matrix_ &A, const Vector2 &v, 1103 MatrixCategories::RowColMatrixTag) const 1104 { 1105 return mulRowSpecialized (w, A, v, typename VectorTraits<Vector1>::VectorCategory ()); 1106 } 1107 1108 template <class Vector1, class Matrix_, class Vector2> 1109 Vector1 &axpyinRowSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1110 VectorCategories::DenseVectorTag) const; 1111 template <class Vector1, class Matrix_, class Vector2> 1112 Vector1 &axpyinRowSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1113 VectorCategories::SparseSequenceVectorTag) const; 1114 template <class Vector1, class Matrix_, class Vector2> 1115 Vector1 &axpyinRowSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1116 VectorCategories::SparseAssociativeVectorTag) const; 1117 template <class Vector1, class Matrix_, class Vector2> 1118 Vector1 &axpyinRowSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1119 VectorCategories::SparseParallelVectorTag) const; 1120 1121 template <class Vector1, class Matrix_, class Vector2> 1122 Vector1 &axpyinColSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1123 VectorCategories::DenseVectorTag) const; 1124 template <class Vector1, class Matrix_, class Vector2> 1125 Vector1 &axpyinColSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1126 VectorCategories::SparseSequenceVectorTag) const; 1127 template <class Vector1, class Matrix_, class Vector2> 1128 Vector1 &axpyinColSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1129 VectorCategories::SparseAssociativeVectorTag) const; 1130 template <class Vector1, class Matrix_, class Vector2> 1131 Vector1 &axpyinColSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1132 VectorCategories::SparseParallelVectorTag) const; 1133 1134 template <class Vector1, class Matrix_, class Vector2> axpyinSpecialized(Vector1 & y,const Matrix_ & A,const Vector2 & x,MatrixCategories::RowMatrixTag)1135 Vector1 &axpyinSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1136 MatrixCategories::RowMatrixTag) const 1137 { 1138 return axpyinRowSpecialized (y, A, x, typename VectorTraits<Vector1>::VectorCategory ()); 1139 } 1140 template <class Vector1, class Matrix_, class Vector2> axpyinSpecialized(Vector1 & y,const Matrix_ & A,const Vector2 & x,MatrixCategories::ColMatrixTag)1141 Vector1 &axpyinSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1142 MatrixCategories::ColMatrixTag) const 1143 { 1144 return axpyinColSpecialized (y, A, x, typename VectorTraits<Vector1>::VectorCategory ()); 1145 } 1146 template <class Vector1, class Matrix_, class Vector2> axpyinSpecialized(Vector1 & y,const Matrix_ & A,const Vector2 & x,MatrixCategories::RowColMatrixTag)1147 Vector1 &axpyinSpecialized (Vector1 &y, const Matrix_ &A, const Vector2 &x, 1148 MatrixCategories::RowColMatrixTag) const 1149 { 1150 return axpyinRowSpecialized (y, A, x, typename VectorTraits<Vector1>::VectorCategory ()); 1151 } 1152 1153 template <class Matrix_, class Iterator> 1154 inline Matrix_ &permuteRowsByRow (Matrix_ &A, 1155 Iterator P_start, 1156 Iterator P_end) const; 1157 1158 template <class Matrix_, class Iterator> 1159 inline Matrix_ &permuteRowsByCol (Matrix_ &A, 1160 Iterator P_start, 1161 Iterator P_end) const; 1162 1163 template <class Matrix_, class Iterator> permuteRowsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::RowColMatrixTag)1164 inline Matrix_ &permuteRowsSpecialized (Matrix_ &A, 1165 Iterator P_start, 1166 Iterator P_end, 1167 MatrixCategories::RowColMatrixTag) const 1168 { 1169 return permuteRowsByCol (A, P_start, P_end); 1170 } 1171 1172 template <class Matrix_, class Iterator> permuteRowsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::RowMatrixTag)1173 inline Matrix_ &permuteRowsSpecialized (Matrix_ &A, 1174 Iterator P_start, 1175 Iterator P_end, 1176 MatrixCategories::RowMatrixTag) const 1177 { 1178 return permuteRowsByRow (A, P_start, P_end); 1179 } 1180 1181 template <class Matrix_, class Iterator> permuteRowsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::ColMatrixTag)1182 inline Matrix_ &permuteRowsSpecialized (Matrix_ &A, 1183 Iterator P_start, 1184 Iterator P_end, 1185 MatrixCategories::ColMatrixTag) const 1186 { 1187 return permuteRowsByCol (A, P_start, P_end); 1188 } 1189 1190 template <class Matrix_, class Iterator> 1191 inline Matrix_ &permuteColsByRow (Matrix_ &A, 1192 Iterator P_start, 1193 Iterator P_end) const; 1194 1195 template <class Matrix_, class Iterator> 1196 inline Matrix_ &permuteColsByCol (Matrix_ &A, 1197 Iterator P_start, 1198 Iterator P_end) const; 1199 1200 template <class Matrix_, class Iterator> permuteColsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::RowColMatrixTag)1201 inline Matrix_ &permuteColsSpecialized (Matrix_ &A, 1202 Iterator P_start, 1203 Iterator P_end, 1204 MatrixCategories::RowColMatrixTag) const 1205 { 1206 return permuteColsByRow (A, P_start, P_end); 1207 } 1208 1209 template <class Matrix_, class Iterator> permuteColsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::RowMatrixTag)1210 inline Matrix_ &permuteColsSpecialized (Matrix_ &A, 1211 Iterator P_start, 1212 Iterator P_end, 1213 MatrixCategories::RowMatrixTag) const 1214 { 1215 return permuteColsByRow (A, P_start, P_end); 1216 } 1217 1218 template <class Matrix_, class Iterator> permuteColsSpecialized(Matrix_ & A,Iterator P_start,Iterator P_end,MatrixCategories::ColMatrixTag)1219 inline Matrix_ &permuteColsSpecialized (Matrix_ &A, 1220 Iterator P_start, 1221 Iterator P_end, 1222 MatrixCategories::ColMatrixTag) const 1223 { 1224 return permuteColsByCol (A, P_start, P_end); 1225 } 1226 1227 const Field *_field; 1228 VectorDomain<Field> _VD; 1229 }; //MatrixDomain 1230 1231 } 1232 1233 #include "linbox/matrix/matrixdomain/matrix-domain.inl" 1234 1235 #endif // __LINBOX_matrix_domain_H 1236 1237 // Local Variables: 1238 // mode: C++ 1239 // tab-width: 4 1240 // indent-tabs-mode: nil 1241 // c-basic-offset: 4 1242 // End: 1243 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s 1244