1 /* 2 * Scythe Statistical Library Copyright (C) 2000-2002 Andrew D. Martin 3 * and Kevin M. Quinn; 2002-present Andrew D. Martin, Kevin M. Quinn, 4 * and Daniel Pemstein. All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify under the terms of the GNU General Public License as 8 * published by Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. See the text files 10 * COPYING and LICENSE, distributed with this source code, for further 11 * information. 12 * -------------------------------------------------------------------- 13 * scythe's/matrix.h 14 * 15 */ 16 17 /*! 18 * \file matrix.h 19 * \brief Definitions of Matrix and related classes and functions. 20 * 21 * This file contains the definitions of the Matrix, Matrix_base, and 22 * associated classes. It also contains a number of external 23 * functions that operate on Matrix objects, such as mathematical 24 * operators. 25 * 26 * Many of the arithmetic and logical operators in this file are 27 * implemented in terms of overloaded template definitions to provide 28 * both generic and default versions of each operation. Generic 29 * templates allow (and force) the user to fully specify the 30 * template type of the returned matrix object (row or column order, 31 * concrete or view) while default templates automatically return 32 * concrete matrices with the ordering of the first or only Matrix 33 * argument to the function. Furthermore, we overload binary 34 * functions to provide scalar by Matrix operations, in addition to 35 * basic Matrix by Matrix arithmetic and logic. Therefore, 36 * definitions for multiple versions appear in the functions list 37 * below. We adopt the convention of providing explicit documentation 38 * for only the most generic Matrix by Matrix version of each of these 39 * operators and describe the behavior of the various overloaded 40 * versions in these documents. 41 */ 42 43 44 #ifndef SCYTHE_MATRIX_H 45 #define SCYTHE_MATRIX_H 46 47 #include <climits> 48 #include <iostream> 49 #include <iomanip> 50 #include <string> 51 #include <sstream> 52 #include <fstream> 53 #include <iterator> 54 #include <algorithm> 55 //#include <numeric> 56 #include <functional> 57 #include <list> 58 59 #ifdef SCYTHE_COMPILE_DIRECT 60 #include "defs.h" 61 #include "algorithm.h" 62 #include "error.h" 63 #include "datablock.h" 64 #include "matrix_random_access_iterator.h" 65 #include "matrix_forward_iterator.h" 66 #include "matrix_bidirectional_iterator.h" 67 #ifdef SCYTHE_LAPACK 68 #include "lapack.h" 69 #endif 70 #else 71 #include "scythestat/defs.h" 72 #include "scythestat/algorithm.h" 73 #include "scythestat/error.h" 74 #include "scythestat/datablock.h" 75 #include "scythestat/matrix_random_access_iterator.h" 76 #include "scythestat/matrix_forward_iterator.h" 77 #include "scythestat/matrix_bidirectional_iterator.h" 78 #ifdef SCYTHE_LAPACK 79 #include "scythestat/lapack.h" 80 #endif 81 #endif 82 83 namespace scythe { 84 85 namespace { // make the uint typedef local to this file 86 /* Convenience typedefs */ 87 typedef unsigned int uint; 88 } 89 90 /* Forward declare the matrix multiplication functions for *= to use 91 * within Matrix proper . 92 */ 93 94 template <typename T_type, matrix_order ORDER, matrix_style STYLE, 95 matrix_order L_ORDER, matrix_style L_STYLE, 96 matrix_order R_ORDER, matrix_style R_STYLE> 97 Matrix<T_type, ORDER, STYLE> 98 operator* (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, 99 const Matrix<T_type, R_ORDER, R_STYLE>& rhs); 100 101 102 template <matrix_order L_ORDER, matrix_style L_STYLE, 103 matrix_order R_ORDER, matrix_style R_STYLE, typename T_type> 104 Matrix<T_type, L_ORDER, Concrete> 105 operator* (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, 106 const Matrix<T_type, R_ORDER, R_STYLE>& rhs); 107 108 /* forward declaration of the matrix class */ 109 template <typename T_type, matrix_order ORDER, matrix_style STYLE> 110 class Matrix; 111 112 /*! \brief A helper class for list-wise initialization. 113 * 114 * This class gets used behind the scenes to provide listwise 115 * initialization for Matrix objects. This documentation is mostly 116 * intended for developers. 117 * 118 * The Matrix class's assignment operator returns a ListInitializer 119 * object when passed a scalar. The assignment operator binds before 120 * the comma operator, so this happens first, no matter if there is 121 * one scalar, or a list of scalars on the right hand side of the 122 * assignment sign. The ListInitializer constructor keeps an iterator 123 * to the Matrix that created it and places the initial item at the 124 * head of a list. Then the ListInitializer comma operator gets 125 * called 0 or more times, appending items to the list. At this 126 * point the ListInitializer object gets destructed because the 127 * expression is done and it is just a temporary. All the action is 128 * in the destructor where the list is copied into the Matrix with 129 * R-style recycling. 130 * 131 * To handle chained assignments, such as A = B = C = 1.2 where A, 132 * B, and C are matrices, correctly, we encapsulate the Matrix 133 * population sequence that is typically called by the destructor in 134 * the private function populate, and make Matrix a friend of this 135 * class. The Matrix class contains an assignment operator for 136 * ListInitializer objects that calls this function. When a call 137 * like "A = B = C = 1.2" occurs the compiler first evaluates C = 138 * 1.2 and returns a ListInitializer object. Then, the 139 * ListInitializer assignment operator in the Matrix class (being 140 * called on B = (C = 1.2)) forces the ListInitializer object to 141 * populate C early (it would otherwise not occur until destruction 142 * at the end of th entire call) by calling the populate method and 143 * then does a simple Matrix assignment of B = C and the populated C 144 * and the chain of assignment proceeds from there in the usual 145 * fashion. 146 * 147 * Based on code in Blitz++ (http://www.oonumerics.org/blitz/) by 148 * Todd Veldhuizen. Blitz++ is distributed under the terms of the 149 * GNU GPL. 150 */ 151 152 template<typename T_elem, typename T_iter, 153 matrix_order O, matrix_style S> 154 class ListInitializer { 155 // An unbound friend 156 template <class T, matrix_order OO, matrix_style SS> 157 friend class Matrix; 158 159 public: ListInitializer(T_elem val,T_iter begin,T_iter end,Matrix<T_elem,O,S> * matrix)160 ListInitializer (T_elem val, T_iter begin, T_iter end, 161 Matrix<T_elem,O,S>* matrix) 162 : vals_ (), 163 iter_ (begin), 164 end_ (end), 165 matrix_ (matrix), 166 populated_ (false) 167 { 168 vals_.push_back(val); 169 } 170 ~ListInitializer()171 ~ListInitializer () 172 { 173 if (! populated_) 174 populate(); 175 } 176 177 ListInitializer &operator, (T_elem x) 178 { 179 vals_.push_back(x); 180 return *this; 181 } 182 183 private: populate()184 void populate () 185 { 186 typename std::list<T_elem>::iterator vi = vals_.begin(); 187 188 while (iter_ < end_) { 189 if (vi == vals_.end()) 190 vi = vals_.begin(); 191 *iter_ = *vi; 192 ++iter_; ++vi; 193 } 194 195 populated_ = true; 196 } 197 198 std::list<T_elem> vals_; 199 T_iter iter_; 200 T_iter end_; 201 Matrix<T_elem, O, S>* matrix_; 202 bool populated_; 203 }; 204 205 /*! \brief Matrix superclass. 206 * 207 * The Matrix_base class handles Matrix functionality that doesn't 208 * need to be templatized with respect to data type. This helps 209 * reduce code bloat by reducing replication of code for member 210 * functions that don't rely on templating. Furthermore, it 211 * hides all of the implementation details of indexing. The 212 * constructors of this class are protected and end-users should 213 * always work with full-fledged Matrix objects. 214 * 215 * The public functions in this class generally provide Matrix 216 * metadata like information on dimensionality and size. 217 */ 218 219 template <matrix_order ORDER = Col, matrix_style STYLE = Concrete> 220 class Matrix_base 221 { 222 protected: 223 /**** CONSTRUCTORS ****/ 224 225 /* Default constructor */ Matrix_base()226 Matrix_base () 227 : rows_ (0), 228 cols_ (0), 229 rowstride_ (0), 230 colstride_ (0), 231 storeorder_ (ORDER) 232 {} 233 234 /* Standard constructor */ Matrix_base(uint rows,uint cols)235 Matrix_base (uint rows, uint cols) 236 : rows_ (rows), 237 cols_ (cols), 238 storeorder_ (ORDER) 239 { 240 if (ORDER == Col) { 241 rowstride_ = 1; 242 colstride_ = rows; 243 } else { 244 rowstride_ = cols; 245 colstride_ = 1; 246 } 247 } 248 249 /* Copy constructors 250 * 251 * The first version handles matrices of the same order and 252 * style. The second handles matrices with different 253 * orders/styles. The same- templates are more specific, 254 * so they will always catch same- cases. 255 * 256 */ 257 Matrix_base(const Matrix_base & m)258 Matrix_base (const Matrix_base &m) 259 : rows_ (m.rows()), 260 cols_ (m.cols()), 261 rowstride_ (m.rowstride()), 262 colstride_ (m.colstride()) 263 { 264 if (STYLE == View) 265 storeorder_ = m.storeorder(); 266 else 267 storeorder_ = ORDER; 268 } 269 270 template <matrix_order O, matrix_style S> Matrix_base(const Matrix_base<O,S> & m)271 Matrix_base (const Matrix_base<O, S> &m) 272 : rows_ (m.rows()), 273 cols_ (m.cols()) 274 { 275 if (STYLE == View) { 276 storeorder_ = m.storeorder(); 277 rowstride_ = m.rowstride(); 278 colstride_ = m.colstride(); 279 } else { 280 storeorder_ = ORDER; 281 if (ORDER == Col) { 282 rowstride_ = 1; 283 colstride_ = rows_; 284 } else { 285 rowstride_ = cols_; 286 colstride_ = 1; 287 } 288 } 289 } 290 291 /* Submatrix constructor */ 292 template <matrix_order O, matrix_style S> Matrix_base(const Matrix_base<O,S> & m,uint x1,uint y1,uint x2,uint y2)293 Matrix_base (const Matrix_base<O, S> &m, 294 uint x1, uint y1, uint x2, uint y2) 295 : rows_ (x2 - x1 + 1), 296 cols_ (y2 - y1 + 1), 297 rowstride_ (m.rowstride()), 298 colstride_ (m.colstride()), 299 storeorder_ (m.storeorder()) 300 { 301 /* Submatrices always have to be views, but the whole 302 * concrete-view thing is just a policy maintained by the 303 * software. Therefore, we need to ensure this constructor 304 * only returns views. There's no neat way to do it but this 305 * is still a compile time check, even if it only reports at 306 * run-time. Of course, we should never get this far. 307 */ 308 if (STYLE == Concrete) { 309 SCYTHE_THROW(scythe_style_error, 310 "Tried to construct a concrete submatrix (Matrix_base)!"); 311 } 312 } 313 314 315 /**** DESTRUCTOR ****/ 316 ~Matrix_base()317 ~Matrix_base () 318 {} 319 320 /**** OPERRATORS ****/ 321 322 // I'm defining one just to make sure we don't get any subtle 323 // bugs from defaults being called. 324 Matrix_base& operator=(const Matrix_base& m) 325 { 326 SCYTHE_THROW(scythe_unexpected_default_error, 327 "Unexpected call to Matrix_base default assignment operator"); 328 } 329 330 /**** MODIFIERS ****/ 331 332 /* Make this Matrix_base an exact copy of the matrix passed in. 333 * Just like an assignment operator but can be called from a derived 334 * class w/out making the = optor public and doing something 335 * like 336 * *(dynamic_cast<Matrix_base *> (this)) = M; 337 * in the derived class. 338 * 339 * Works across styles, but should be used with care 340 */ 341 template <matrix_order O, matrix_style S> mimic(const Matrix_base<O,S> & m)342 inline void mimic (const Matrix_base<O, S> &m) 343 { 344 rows_ = m.rows(); 345 cols_ = m.cols(); 346 rowstride_ = m.rowstride(); 347 colstride_ = m.colstride(); 348 storeorder_ = m.storeorder(); 349 } 350 351 /* Reset the dimensions of this Matrix_base. 352 * 353 * TODO This function is a bit of an interface weakness. It 354 * assumes a resize always means a fresh matrix (concrete or 355 * view) with no slack between dims and strides. This happens to 356 * always be the case when it is called, but it tightly couples 357 * Matrix_base and extending classes. Not a big issue (since 358 * Matrix is probably the only class that will ever extend this) 359 * but something to maybe fix down the road. 360 */ resize(uint rows,uint cols)361 inline void resize (uint rows, uint cols) 362 { 363 rows_ = rows; 364 cols_ = cols; 365 366 if (ORDER == Col) { 367 rowstride_ = 1; 368 colstride_ = rows; 369 } else { 370 rowstride_ = cols; 371 colstride_ = 1; 372 } 373 374 storeorder_ = ORDER; 375 } 376 377 public: 378 /**** ACCESSORS ****/ 379 380 /*! \brief Returns the total number of elements in the Matrix. 381 * 382 * \see rows() 383 * \see cols() 384 * \see max_size() 385 */ size()386 inline uint size () const 387 { 388 return (rows() * cols()); 389 } 390 391 /*! \brief Returns the number of rows in the Matrix. 392 * 393 * \see size() 394 * \see cols() 395 */ rows()396 inline uint rows() const 397 { 398 return rows_; 399 } 400 401 /*! \brief Returns the number of columns in the Matrix. 402 * 403 * \see size() 404 * \see rows() 405 */ cols()406 inline uint cols () const 407 { 408 return cols_; 409 } 410 411 /*! \brief Check matrix ordering. 412 * 413 * This method returns the matrix_order of this Matrix. 414 * 415 * \see style() 416 * \see storeorder() 417 */ order()418 inline matrix_order order() const 419 { 420 return ORDER; 421 } 422 423 /*! \brief Check matrix style. 424 * 425 * This method returns the matrix_style of this Matrix. 426 * 427 * \see order() 428 * \see storeorder() 429 */ style()430 inline matrix_style style() const 431 { 432 return STYLE; 433 } 434 435 /*! \brief Returns the storage order of the underlying 436 * DataBlock. 437 * 438 * In view matrices, the storage order of the data may not be the 439 * same as the template ORDER. 440 * 441 * 442 * \see rowstride() 443 * \see colstride() 444 * \see order() 445 * \see style() 446 */ storeorder()447 inline matrix_order storeorder () const 448 { 449 return storeorder_; 450 } 451 452 /*! \brief Returns the in-memory distance between elements in 453 * successive rows of the matrix. 454 * 455 * \see colstride() 456 * \see storeorder() 457 */ rowstride()458 inline uint rowstride () const 459 { 460 return rowstride_; 461 } 462 463 /*! \brief Returns the in-memory distance between elements in 464 * successive columns of the matrix. 465 * 466 * \see rowstride() 467 * \see storeorder() 468 */ colstride()469 inline uint colstride () const 470 { 471 return colstride_; 472 } 473 474 /*! \brief Returns the maximum possible matrix size. 475 * 476 * Maximum matrix size is simply the highest available unsigned 477 * int on your system. 478 * 479 * \see size() 480 */ max_size()481 inline uint max_size () const 482 { 483 return UINT_MAX; 484 } 485 486 /*! \brief Returns true if this Matrix is 1x1. 487 * 488 * \see isNull() 489 */ isScalar()490 inline bool isScalar () const 491 { 492 return (rows() == 1 && cols() == 1); 493 } 494 495 /*! \brief Returns true if this Matrix is 1xm. 496 * 497 * \see isColVector() 498 * \see isVector() 499 */ isRowVector()500 inline bool isRowVector () const 501 { 502 return (rows() == 1); 503 } 504 505 /*! \brief Returns true if this Matrix is nx1. 506 * 507 * \see isRowVector() 508 * \see isVector() 509 */ isColVector()510 inline bool isColVector () const 511 { 512 return (cols() == 1); 513 } 514 515 /*! \brief Returns true if this Matrix is nx1 or 1xn. 516 * 517 * \see isRowVector() 518 * \see isColVector() 519 */ isVector()520 inline bool isVector () const 521 { 522 return (cols() == 1 || rows() == 1); 523 } 524 525 /*! \brief Returns true if this Matrix is nxn. 526 * 527 * Null and scalar matrices are both considered square. 528 * 529 * \see isNull() 530 * \see isScalar() 531 */ isSquare()532 inline bool isSquare () const 533 { 534 return (cols() == rows()); 535 } 536 537 /*! \brief Returns true if this Matrix has 0 elements. 538 * 539 * \see empty() 540 * \see isScalar() 541 */ isNull()542 inline bool isNull () const 543 { 544 return (rows() == 0); 545 } 546 547 /*! \brief Returns true if this Matrix has 0 elements. 548 * 549 * This function is identical to isNull() but conforms to STL 550 * container class conventions. 551 * 552 * \see isNull() 553 */ empty()554 inline bool empty () const 555 { 556 return (rows() == 0); 557 } 558 559 560 /**** HELPERS ****/ 561 562 /*! \brief Check if an index is in bounds. 563 * 564 * This function takes a single-argument index into a Matrix and 565 * returns true iff that index is within the bounds of the 566 * Matrix. This function is equivalent to the expression: 567 * \code 568 * i < M.size() 569 * \endcode 570 * for a given Matrix M. 571 * 572 * \param i The element index to check. 573 * 574 * \see inRange(uint, uint) 575 */ inRange(uint i)576 inline bool inRange (uint i) const 577 { 578 return (i < size()); 579 } 580 581 /*! \brief Check if an index is in bounds. 582 * 583 * This function takes a two-argument index into a Matrix and 584 * returns true iff that index is within the bounds of the 585 * Matrix. This function is equivalent to the expression: 586 * \code 587 * i < M.rows() && j < M.cols() 588 * \endcode 589 * for a given Matrix M. 590 * 591 * \param i The row value of the index to check. 592 * \param j The column value of the index to check. 593 * 594 * \see inRange(uint) 595 */ inRange(uint i,uint j)596 inline bool inRange (uint i, uint j) const 597 { 598 return (i < rows() && j < cols()); 599 } 600 601 protected: 602 /* These methods take offsets into a matrix and convert them 603 * into that actual position in the referenced memory block, 604 * taking stride into account. Protection is debatable. They 605 * could be useful to outside functions in the library but most 606 * callers should rely on the public () operator in the derived 607 * class or iterators. 608 * 609 * Note that these are very fast for concrete matrices but not 610 * so great for views. Of course, the type checks are done at 611 * compile time. 612 */ 613 614 /* Turn an index into a true offset into the data. */ index(uint i)615 inline uint index (uint i) const 616 { 617 if (STYLE == View) { 618 if (ORDER == Col) { 619 uint col = i / rows(); 620 uint row = i % rows(); 621 return (index(row, col)); 622 } else { 623 uint row = i / cols(); 624 uint col = i % cols(); 625 return (index(row, col)); 626 } 627 } else 628 return(i); 629 } 630 631 /* Turn an i, j into an index. */ index(uint row,uint col)632 inline uint index (uint row, uint col) const 633 { 634 if (STYLE == Concrete) { 635 if (ORDER == Col) 636 return (col * rows() + row); 637 else 638 return (row * cols() + col); 639 } else { // view 640 if (storeorder_ == Col) 641 return (col * colstride() + row); 642 else 643 return (row * rowstride() + col); 644 } 645 } 646 647 648 /**** INSTANCE VARIABLES ****/ 649 protected: 650 uint rows_; // # of rows 651 uint cols_; // # of cols 652 653 private: 654 /* The derived class shouldn't have to worry about this 655 * implementation detail. 656 */ 657 uint rowstride_; // the in-memory number of elements from the 658 uint colstride_; // beginning of one column(row) to the next 659 matrix_order storeorder_; // The in-memory storage order of this 660 // matrix. This will always be the 661 // same as ORDER for concrete 662 // matrices but views can look at 663 // matrices with storage orders that 664 // differ from their own. 665 // TODO storeorder is always known at 666 // compile time, so we could probably 667 // add a third template param to deal 668 // with this. That would speed up 669 // views a touch. Bit messy maybe. 670 }; 671 672 /**** MATRIX CLASS ****/ 673 674 /*! \brief An STL-compliant matrix container class. 675 * 676 * The Matrix class provides a matrix object with an interface similar 677 * to standard mathematical notation. The class provides a number 678 * of unary and binary operators for manipulating matrices. 679 * Operators provide such functionality as addition, multiplication, 680 * and access to specific elements within the Matrix. One can test 681 * two matrices for equality or use provided methods to test the 682 * size, shape, or symmetry of a given Matrix. In addition, we 683 * provide a number of facilities for saving, loading, and printing 684 * matrices. Other portions of the library provide functions for 685 * manipulating matrices. Most notably, la.h provides definitions 686 * of common linear algebra routines and ide.h defines functions 687 * that perform inversion and decomposition. 688 * 689 * This Matrix data structure sits at the core of the library. In 690 * addition to standard matrix operations, this class allows 691 * multiple matrices to view and modify the same underlying data. 692 * This ability provides an elegant way in which to access and 693 * modify submatrices such as isolated row vectors and greatly 694 * increases the overall flexibility of the class. In addition, we 695 * provide iterators (defined in matrix_random_access_iterator.h, 696 * matrix_forward_iterator.h, and matrix_bidirectional_iterator.h) 697 * that allow Matrix objects to interact seamlessly with the generic 698 * algorithms provided by the Standard Template Library (STL). 699 * 700 * The Matrix class uses template parameters to define multiple 701 * behaviors. Matrices are templated on data type, matrix_order, 702 * and matrix_style. 703 * 704 * Matrix objects can contain elements of any type. For the most 705 * part, uses will wish to fill their matrices with single or double 706 * precision floating point numbers, but matrices of integers, 707 * boolean values, complex numbers, and user-defined types are all 708 * possible and useful. Although the basic book-keeping methods in 709 * the Matrix class will support virtually any type, certain 710 * operators require that one or more mathematical operator be 711 * defined for the given type and many of the functions in the wider 712 * Scythe library expect, or even demand, matrices containing floating 713 * point numbers. 714 * 715 * There are two possible Matrix element orderings, row- or 716 * column-major. Differences in matrix ordering will be most 717 * noticeable at construction time. Constructors that build matrices 718 * from streams or other list-like structures will place elements 719 * into the matrix in its given order. In general, any method that 720 * processes a matrix in order will use the given matrix_order. For 721 * the most part, matrices of both orderings should exhibit the same 722 * performance, but when a trade-off must be made, we err on the 723 * side of column-major ordering. In one respect, this bias is very 724 * strong. If you enable LAPACK/BLAS support in with the 725 * SCYTHE_LAPACK compiler flag, the library will use these optimized 726 * fortran routines to perform a number of operations on column 727 * major matrices; we provide no LAPACK/BLAS support for row-major 728 * matrices. Operations on matrices with mismatched ordering are 729 * legal and supported, but not guaranteed to be as fast as 730 * same-order operations, especially when SCYTHE_LAPACK is enabled. 731 * 732 * There are also two possible styles of Matrix template, concrete 733 * and view. These two types of matrix provide distinct ways in 734 * which to interact with an underlying block of data. 735 * 736 * Concrete matrices behave like matrices in previous 737 * Scythe releases. They directly encapsulate a block of data and 738 * always process it in the same order as it is stored (their 739 * matrix_order always matches the underlying storage order). 740 * All copy constructions and assignments on 741 * concrete matrices make deep copies and it is not possible to use 742 * the reference() method to make a concrete Matrix a view of 743 * another Matrix. Furthermore, concrete matrices are guaranteed to 744 * have unit stride (That is, adjacent Matrix elements are stored 745 * adjacently in memory). 746 * 747 * Views, on the other hand, provide references to data blocks. 748 * More than one view can look at the same underlying block of data, 749 * possibly at different portions of the data at the same time. 750 * Furthermore, a view may look at the data block of a concrete 751 * matrix, perhaps accessing a single row vector or a small 752 * submatrix of a larger matrix. When you copy construct 753 * a view a deep copy is not made, rather the view simply provides 754 * access to the extant block of data underlying the copied object. 755 * Furthermore, when 756 * you assign to a view, you overwrite the data the view is 757 * currently pointing to, rather than generating a new data block. 758 * Together, these behaviors allow 759 * for matrices that view portions of other matrices 760 * (submatrices) and submatrix assignment. Views do not guarantee 761 * unit stride and may even logically access their elements in a 762 * different order than they are stored in memory. Copying between 763 * concretes and views is fully supported and often transparent to 764 * the user. 765 * 766 * There is a fundamental trade-off between concrete matrices and 767 * views. Concrete matrices are simpler to work with, but not 768 * as flexible as views. Because they always have unit stride, 769 * concrete matrices 770 * have fast iterators and access operators but, because they must 771 * always be copied deeply, they provide slow copies (for example, 772 * copy construction of a Matrix returned from a function wastes 773 * cycles). Views are more flexible but also somewhat more 774 * complicated to program with. Furthermore, because they cannot 775 * guarantee unit stride, their iterators and access operations are 776 * somewhat slower than those for concrete matrices. On the other 777 * hand, they provide very fast copies. The average Scythe user may 778 * find that she virtually never works with views directly (although 779 * they can be quite useful in certain situations) but they provide 780 * a variety of functionality underneath the hood of the library and 781 * underpin many common operations. 782 * 783 * \note 784 * The Matrix interface is split between two classes: this Matrix 785 * class and Matrix_base, which Matrix extends. Matrix_base 786 * includes a range of accessors that provide the programmer with 787 * information about such things as the dimensionality of Matrix 788 * objects. 789 */ 790 791 template <typename T_type = double, matrix_order ORDER = Col, 792 matrix_style STYLE = Concrete> 793 class Matrix : public Matrix_base<ORDER, STYLE>, 794 public DataBlockReference<T_type> 795 { 796 public: 797 /**** TYPEDEFS ****/ 798 799 /* Iterator types */ 800 801 /*! \brief Random Access Iterator type. 802 * 803 * This typedef for matrix_random_access_iterator provides a 804 * convenient shorthand for the default, and most general, 805 * Matrix iterator type. 806 * 807 * \see const_iterator 808 * \see reverse_iterator 809 * \see const_reverse_iterator 810 * \see forward_iterator 811 * \see const_forward_iterator 812 * \see reverse_forward_iterator 813 * \see const_reverse_forward_iterator 814 * \see bidirectional_iterator 815 * \see const_bidirectional_iterator 816 * \see reverse_bidirectional_iterator 817 * \see const_reverse_bidirectional_iterator 818 */ 819 typedef matrix_random_access_iterator<T_type, ORDER, ORDER, STYLE> 820 iterator; 821 822 /*! \brief Const Random Access Iterator type. 823 * 824 * This typedef for const_matrix_random_access_iterator provides 825 * a convenient shorthand for the default, and most general, 826 * Matrix const iterator type. 827 * 828 * \see iterator 829 * \see reverse_iterator 830 * \see const_reverse_iterator 831 * \see forward_iterator 832 * \see const_forward_iterator 833 * \see reverse_forward_iterator 834 * \see const_reverse_forward_iterator 835 * \see bidirectional_iterator 836 * \see const_bidirectional_iterator 837 * \see reverse_bidirectional_iterator 838 * \see const_reverse_bidirectional_iterator 839 */ 840 typedef const_matrix_random_access_iterator<T_type, ORDER, ORDER, 841 STYLE> const_iterator; 842 843 /*! \brief Reverse Random Access Iterator type. 844 * 845 * This typedef uses std::reverse_iterator to describe a 846 * reversed matrix_random_access_iterator type. This is the 847 * reverse of iterator. 848 * 849 * \see iterator 850 * \see const_iterator 851 * \see const_reverse_iterator 852 * \see forward_iterator 853 * \see const_forward_iterator 854 * \see reverse_forward_iterator 855 * \see const_reverse_forward_iterator 856 * \see bidirectional_iterator 857 * \see const_bidirectional_iterator 858 * \see reverse_bidirectional_iterator 859 * \see const_reverse_bidirectional_iterator 860 */ 861 typedef typename 862 std::reverse_iterator<matrix_random_access_iterator<T_type, 863 ORDER, ORDER, STYLE> > reverse_iterator; 864 865 /*! \brief Reverse Const Random Access Iterator type. 866 * 867 * This typedef uses std::reverse_iterator to describe a 868 * reversed const_matrix_random_access_iterator type. This is 869 * the reverse of const_iterator. 870 * 871 * \see iterator 872 * \see const_iterator 873 * \see reverse_iterator 874 * \see forward_iterator 875 * \see const_forward_iterator 876 * \see reverse_forward_iterator 877 * \see const_reverse_forward_iterator 878 * \see bidirectional_iterator 879 * \see const_bidirectional_iterator 880 * \see reverse_bidirectional_iterator 881 * \see const_reverse_bidirectional_iterator 882 */ 883 typedef typename 884 std::reverse_iterator<const_matrix_random_access_iterator 885 <T_type, ORDER, ORDER, STYLE> > 886 const_reverse_iterator; 887 888 /*! \brief Forward Iterator type. 889 * 890 * This typedef for matrix_forward_iterator provides 891 * a convenient shorthand for a fast (when compared to 892 * matrix_random_access_iterator) Matrix iterator type. 893 * 894 * \see iterator 895 * \see const_iterator 896 * \see reverse_iterator 897 * \see const_reverse_iterator 898 * \see const_forward_iterator 899 * \see reverse_forward_iterator 900 * \see const_reverse_forward_iterator 901 * \see bidirectional_iterator 902 * \see const_bidirectional_iterator 903 * \see reverse_bidirectional_iterator 904 * \see const_reverse_bidirectional_iterator 905 */ 906 typedef matrix_forward_iterator<T_type, ORDER, ORDER, STYLE> 907 forward_iterator; 908 909 /*! \brief Const Forward Iterator type. 910 * 911 * This typedef for const_matrix_forward_iterator provides a 912 * convenient shorthand for a fast (when compared to 913 * const_matrix_random_access_iterator) const Matrix iterator 914 * type. 915 * 916 * \see iterator 917 * \see const_iterator 918 * \see reverse_iterator 919 * \see const_reverse_iterator 920 * \see forward_iterator 921 * \see reverse_forward_iterator 922 * \see const_reverse_forward_iterator 923 * \see bidirectional_iterator 924 * \see const_bidirectional_iterator 925 * \see reverse_bidirectional_iterator 926 * \see const_reverse_bidirectional_iterator 927 */ 928 typedef const_matrix_forward_iterator<T_type, ORDER, ORDER, STYLE> 929 const_forward_iterator; 930 931 /*! \brief Bidirectional Iterator type. 932 * 933 * This typedef for matrix_bidirectional_iterator provides 934 * a convenient shorthand for a compromise (with speed and 935 * flexibility between matrix_random_access_iterator and 936 * matrix_forward_iterator) Matrix iterator type. 937 * 938 * \see iterator 939 * \see const_iterator 940 * \see reverse_iterator 941 * \see const_reverse_iterator 942 * \see forward_iterator 943 * \see const_forward_iterator 944 * \see reverse_forward_iterator 945 * \see const_reverse_forward_iterator 946 * \see const_bidirectional_iterator 947 * \see reverse_bidirectional_iterator 948 * \see const_reverse_bidirectional_iterator 949 */ 950 typedef matrix_bidirectional_iterator<T_type, ORDER, ORDER, STYLE> 951 bidirectional_iterator; 952 953 /*! \brief Const Bidirectional Iterator type. 954 * 955 * This typedef for const_matrix_bidirectional_iterator provides 956 * a convenient shorthand for a compromise (with speed and 957 * flexibility between const_matrix_random_access_iterator and 958 * const_matrix_forward_iterator) const Matrix iterator type. 959 * 960 * \see iterator 961 * \see const_iterator 962 * \see reverse_iterator 963 * \see const_reverse_iterator 964 * \see forward_iterator 965 * \see const_forward_iterator 966 * \see reverse_forward_iterator 967 * \see const_reverse_forward_iterator 968 * \see bidirectional_iterator 969 * \see reverse_bidirectional_iterator 970 * \see const_reverse_bidirectional_iterator 971 */ 972 typedef const_matrix_bidirectional_iterator<T_type, ORDER, ORDER, 973 STYLE> const_bidirectional_iterator; 974 975 /*! \brief Const Bidirectional Iterator type. 976 * 977 * This typedef uses std::reverse_iterator to describe a 978 * reversed matrix_bidirectional_iterator type. This is 979 * the reverse of bidirectional_iterator. 980 * 981 * \see iterator 982 * \see const_iterator 983 * \see reverse_iterator 984 * \see const_reverse_iterator 985 * \see forward_iterator 986 * \see const_forward_iterator 987 * \see reverse_forward_iterator 988 * \see const_reverse_forward_iterator 989 * \see bidirectional_iterator 990 * \see const_bidirectional_iterator 991 * \see const_reverse_bidirectional_iterator 992 */ 993 typedef typename 994 std::reverse_iterator<matrix_bidirectional_iterator<T_type, 995 ORDER, ORDER, STYLE> > reverse_bidirectional_iterator; 996 997 /*! \brief Reverse Const Bidirectional Iterator type. 998 * 999 * This typedef uses std::reverse_iterator to describe a 1000 * reversed const_matrix_bidirectional_iterator type. This is 1001 * the reverse of const_bidirectional_iterator. 1002 * 1003 * \see iterator 1004 * \see const_iterator 1005 * \see reverse_iterator 1006 * \see const_reverse_iterator 1007 * \see forward_iterator 1008 * \see const_forward_iterator 1009 * \see reverse_forward_iterator 1010 * \see const_reverse_forward_iterator 1011 * \see bidirectional_iterator 1012 * \see const_bidirectional_iterator 1013 * \see reverse_bidirectional_iterator 1014 */ 1015 typedef typename 1016 std::reverse_iterator<const_matrix_bidirectional_iterator 1017 <T_type, ORDER, ORDER, STYLE> > 1018 const_reverse_bidirectional_iterator; 1019 1020 /*!\brief The Matrix' element type. 1021 * 1022 * This typedef describes the element type (T_type) of this 1023 * Matrix. 1024 */ 1025 typedef T_type ttype; 1026 1027 private: 1028 /* Some convenience typedefs */ 1029 typedef DataBlockReference<T_type> DBRef; 1030 typedef Matrix_base<ORDER, STYLE> Base; 1031 1032 public: 1033 /**** CONSTRUCTORS ****/ 1034 1035 /*! \brief Default constructor. 1036 * 1037 * The default constructor creates an empty/null matrix. Using 1038 * null matrices in operations will typically cause errors; this 1039 * constructor exists primarily for initialization within 1040 * aggregate types. 1041 * 1042 * \see Matrix(T_type) 1043 * \see Matrix(uint, uint, bool, T_type) 1044 * \see Matrix(uint, uint, T_iterator) 1045 * \see Matrix(const std::string&) 1046 * \see Matrix(const Matrix&) 1047 * \see Matrix(const Matrix<T_type, O, S> &) 1048 * \see Matrix(const Matrix<S_type, O, S> &) 1049 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1050 * 1051 * \b Example: 1052 * \include example.matrix.constructor.default.cc 1053 */ Matrix()1054 Matrix () 1055 : Base (), 1056 DBRef () 1057 { 1058 } 1059 1060 /*! \brief Parameterized type constructor. 1061 * 1062 * Creates a 1x1 matrix (scalar). 1063 * 1064 * \param element The scalar value of the constructed Matrix. 1065 * 1066 * \see Matrix() 1067 * \see Matrix(uint, uint, bool, T_type) 1068 * \see Matrix(uint, uint, T_iterator) 1069 * \see Matrix(const std::string&) 1070 * \see Matrix(const Matrix&) 1071 * \see Matrix(const Matrix<T_type, O, S> &) 1072 * \see Matrix(const Matrix<S_type, O, S> &) 1073 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1074 * 1075 * \throw scythe_alloc_error (Level 1) 1076 * 1077 * \b Example: 1078 * \include example.matrix.constructor.ptype.cc 1079 */ Matrix(T_type element)1080 Matrix (T_type element) 1081 : Base (1, 1), 1082 DBRef (1) 1083 { 1084 data_[Base::index(0)] = element; // ALWAYS use index() 1085 } 1086 1087 /*! \brief Standard constructor. 1088 * 1089 * The standard constructor creates a rowsXcols Matrix, filled 1090 * with zeros by default. Optionally, you can leave the Matrix 1091 * uninitialized, or choose a different fill value. 1092 * 1093 * \param rows The number of rows in the Matrix. 1094 * \param cols The number of columns in the Matrix. 1095 * \param fill Indicates whether or not the Matrix should be 1096 * initialized. 1097 * \param fill_value The scalar value to fill the Matrix with 1098 * when fill == true. 1099 * 1100 * \see Matrix() 1101 * \see Matrix(T_type) 1102 * \see Matrix(uint, uint, T_iterator) 1103 * \see Matrix(const std::string&) 1104 * \see Matrix(const Matrix&) 1105 * \see Matrix(const Matrix<T_type, O, S> &) 1106 * \see Matrix(const Matrix<S_type, O, S> &) 1107 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1108 * 1109 * \throw scythe_alloc_error (Level 1) 1110 * 1111 * \b Example: 1112 * \include example.matrix.constructor.standard.cc 1113 */ 1114 Matrix (uint rows, uint cols, bool fill = true, 1115 T_type fill_value = 0) Base(rows,cols)1116 : Base (rows, cols), 1117 DBRef (rows * cols) 1118 { 1119 // TODO Might use iterator here for abstraction. 1120 if (fill) 1121 for (uint i = 0; i < Base::size(); ++i) 1122 data_[Base::index(i)] = fill_value; // we know data contig 1123 } 1124 1125 /*! \brief Iterator constructor. 1126 * 1127 * Creates a \a rows X \a cols matrix, filling it sequentially 1128 * (based on this template's matrix_order) with values 1129 * referenced by the input iterator \a it. Pointers are a form 1130 * of input iterator, so one can use this constructor to 1131 * initialize a matrix object from a c-style array. The caller 1132 * is responsible for supplying an iterator that won't be 1133 * exhausted too soon. 1134 * 1135 * \param rows The number of rows in the Matrix. 1136 * \param cols The number of columns in the Matrix. 1137 * \param it The input iterator to read from. 1138 * 1139 * \see Matrix() 1140 * \see Matrix(T_type) 1141 * \see Matrix(uint, uint, bool, T_type) 1142 * \see Matrix(const std::string&) 1143 * \see Matrix(const Matrix&) 1144 * \see Matrix(const Matrix<T_type, O, S> &) 1145 * \see Matrix(const Matrix<S_type, O, S> &) 1146 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1147 * 1148 * \throw scythe_alloc_error (Level 1) 1149 * 1150 * \b Example: 1151 * \include example.matrix.constructor.iterator.cc 1152 */ 1153 template <typename T_iterator> Matrix(uint rows,uint cols,T_iterator it)1154 Matrix (uint rows, uint cols, T_iterator it) 1155 : Base (rows, cols), 1156 DBRef (rows * cols) 1157 { 1158 // TODO again, should probably use iterator 1159 for (uint i = 0; i < Base::size(); ++i) { 1160 data_[Base::index(i)] = *it; // we know data_ is contig 1161 ++it; 1162 } 1163 } 1164 1165 /*! \brief File constructor. 1166 * 1167 * Constructs a matrix from the contents of a file. The 1168 * standard input file format is a simple rectangular text file 1169 * with one matrix row per line and spaces delimiting values in 1170 * a row. Optionally, one can also use Scythe's old file format 1171 * which is a space-delimited, row-major ordered, list of values 1172 * with row and column lengths in the first two slots. 1173 * 1174 * \param path The path of the input file. 1175 * \param oldstyle Whether or not to use Scythe's old file format. 1176 * 1177 * \see Matrix() 1178 * \see Matrix(T_type) 1179 * \see Matrix(uint, uint, bool, T_type) 1180 * \see Matrix(uint, uint, T_iterator) 1181 * \see Matrix(const Matrix&) 1182 * \see Matrix(const Matrix<T_type, O, S> &) 1183 * \see Matrix(const Matrix<S_type, O, S> &) 1184 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1185 * \see save(const std::string&) 1186 * 1187 * \throw scythe_alloc_error (Level 1) 1188 * \throw scythe_file_error (Level 1) 1189 * \throw scythe_bounds_error (Level 3) 1190 * 1191 * \b Example: 1192 * \include example.matrix.constructor.file.cc 1193 */ 1194 Matrix (const std::string& path, bool oldstyle=false) Base()1195 : Base (), 1196 DBRef () 1197 { 1198 std::ifstream file(path.c_str()); 1199 SCYTHE_CHECK_10(! file, scythe_file_error, 1200 "Could not open file " << path); 1201 1202 if (oldstyle) { 1203 uint rows, cols; 1204 file >> rows >> cols; 1205 resize(rows, cols); 1206 std::copy(std::istream_iterator<T_type> (file), 1207 std::istream_iterator<T_type>(), begin_f<Row>()); 1208 } else { 1209 std::string row; 1210 1211 unsigned int cols = -1; 1212 std::vector<std::vector<T_type> > vals; 1213 unsigned int rows = 0; 1214 while (std::getline(file, row)) { 1215 std::vector<T_type> column; 1216 std::istringstream rowstream(row); 1217 std::copy(std::istream_iterator<T_type> (rowstream), 1218 std::istream_iterator<T_type>(), 1219 std::back_inserter(column)); 1220 1221 if (cols == -1) 1222 cols = (unsigned int) column.size(); 1223 1224 SCYTHE_CHECK_10(cols != column.size(), scythe_file_error, 1225 "Row " << (rows + 1) << " of input file has " 1226 << column.size() << " elements, but should have " << cols); 1227 1228 vals.push_back(column); 1229 rows++; 1230 } 1231 1232 resize(rows, cols); 1233 for (unsigned int i = 0; i < rows; ++i) 1234 operator()(i, _) = Matrix<T_type>(1, cols, vals[i].begin()); 1235 } 1236 } 1237 1238 /* Copy constructors. Uses template args to set up correct 1239 * behavior for both concrete and view matrices. The branches 1240 * are no-ops and get optimized away at compile time. 1241 * 1242 * We have to define this twice because we must explicitly 1243 * override the default copy constructor; otherwise it is the 1244 * most specific template in a lot of cases and causes ugliness. 1245 */ 1246 1247 /*! \brief Default copy constructor. 1248 * 1249 * Copy constructing a concrete Matrix makes an exact copy of M 1250 * in a new data block. On the other hand, copy constructing a 1251 * view Matrix generates a new Matrix object that references (or 1252 * views) M's existing data block. 1253 * 1254 * \param M The Matrix to copy or make a view of. 1255 * 1256 * \see Matrix() 1257 * \see Matrix(T_type) 1258 * \see Matrix(uint, uint, bool, T_type) 1259 * \see Matrix(uint, uint, T_iterator) 1260 * \see Matrix(const std::string&) 1261 * \see Matrix(const Matrix<T_type, O, S> &) 1262 * \see Matrix(const Matrix<S_type, O, S> &) 1263 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1264 * \see copy() 1265 * \see copy(const Matrix<T_type, O, S> &) 1266 * \see reference(const Matrix<T_type, O, S> &) 1267 * 1268 * \throw scythe_alloc_error (Level 1) 1269 * 1270 * \b Example: 1271 * \include example.matrix.constructor.copy.cc 1272 */ 1273 Matrix(const Matrix & M)1274 Matrix (const Matrix& M) 1275 : Base (M), // this call deals with concrete-view conversions 1276 DBRef () 1277 { 1278 if (STYLE == Concrete) { 1279 this->referenceNew(M.size()); 1280 scythe::copy<ORDER,ORDER>(M, *this); 1281 } else // STYLE == View 1282 this->referenceOther(M); 1283 } 1284 1285 /*! \brief Cross order and/or style copy constructor. 1286 * 1287 * Copy constructing a concrete Matrix makes an exact copy of M 1288 * in a new data block. On the other hand, copy constructing a 1289 * view Matrix generates a new Matrix object that references (or 1290 * views) M's existing data block. 1291 * 1292 * This version of the copy constructor extends Matrix(const 1293 * Matrix &) by allowing the user to make concrete copies and 1294 * views of matrices that have matrix_order or matrix_style that 1295 * does not match that of the constructed Matrix. That is, this 1296 * constructor makes it possible to create views of concrete 1297 * matrices and concrete copies of views, row-major copies of 1298 * col-major matrices, and so on. 1299 * 1300 * \param M The Matrix to copy or make a view of. 1301 * 1302 * \see Matrix() 1303 * \see Matrix(T_type) 1304 * \see Matrix(uint, uint, bool, T_type) 1305 * \see Matrix(uint, uint, T_iterator) 1306 * \see Matrix(const std::string&) 1307 * \see Matrix(const Matrix&) 1308 * \see Matrix(const Matrix<S_type, O, S> &) 1309 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1310 * \see copy() 1311 * \see copy(const Matrix<T_type, O, S> &) 1312 * \see reference(const Matrix<T_type, O, S> &) 1313 * 1314 * \throw scythe_alloc_error (Level 1) 1315 * 1316 * \b Example: 1317 * \include example.matrix.constructor.crosscopy.cc 1318 */ 1319 1320 template <matrix_order O, matrix_style S> Matrix(const Matrix<T_type,O,S> & M)1321 Matrix (const Matrix<T_type, O, S> &M) 1322 : Base (M), // this call deals with concrete-view conversions 1323 DBRef () 1324 { 1325 if (STYLE == Concrete) { 1326 this->referenceNew(M.size()); 1327 scythe::copy<ORDER,ORDER> (M, *this); 1328 } else // STYLE == View 1329 this->referenceOther(M); 1330 } 1331 1332 /*! \brief Cross type copy constructor 1333 * 1334 * The type conversion copy constructor takes a reference to an 1335 * existing matrix containing elements of a different type than 1336 * the constructed matrix and creates a copy. This constructor 1337 * will only work if it is possible to cast elements from the 1338 * copied matrix to the type of elements in the constructed 1339 * matrix. 1340 * 1341 * This constructor always creates a deep copy of the existing 1342 * matrix, even if the constructed matrix is a view. It is 1343 * impossible for a matrix view with one element type to 1344 * reference the data block of a matrix containing elements of a 1345 * different type. 1346 * 1347 * \param M The Matrix to copy. 1348 * 1349 * \see Matrix() 1350 * \see Matrix(T_type) 1351 * \see Matrix(uint, uint, bool, T_type) 1352 * \see Matrix(uint, uint, T_iterator) 1353 * \see Matrix(const std::string&) 1354 * \see Matrix(const Matrix&) 1355 * \see Matrix(const Matrix<T_type, O, S> &) 1356 * \see Matrix(const Matrix<T_type, O, S>&, uint, uint, uint, uint) 1357 * 1358 * \throw scythe_alloc_error (Level 1) 1359 * 1360 * \b Example: 1361 * \include example.matrix.constructor.convcopy.cc 1362 */ 1363 template <typename S_type, matrix_order O, matrix_style S> Matrix(const Matrix<S_type,O,S> & M)1364 Matrix (const Matrix<S_type, O, S> &M) 1365 : Base(M), // this call deal with concrete-view conversions 1366 DBRef (M.size()) 1367 { 1368 scythe::copy<ORDER,ORDER> (M, *this); 1369 } 1370 1371 /*! \brief Submatrix constructor 1372 * 1373 * The submatrix constructor takes a reference to an existing 1374 * matrix and a set of indices, and generates a new Matrix 1375 * object referencing the submatrix described by the indices. 1376 * One can only construct a submatrix with a view template and 1377 * this constructor will throw an error if one tries to use it 1378 * to construct a concrete matrix. 1379 * 1380 * \note 1381 * The submatrix-returning operators provide the same 1382 * functionality as this constructor with less obtuse syntax. 1383 * Users should generally employ these methods instead of this 1384 * constructor. 1385 * 1386 * \param M The Matrix to view. 1387 * \param x1 The first row coordinate, \a x1 <= \a x2. 1388 * \param y1 The first column coordinate, \a y1 <= \a y2. 1389 * \param x2 The second row coordinate, \a x2 > \a x1. 1390 * \param y2 The second column coordinate, \a y2 > \a y1. 1391 * 1392 * \see Matrix() 1393 * \see Matrix(T_type) 1394 * \see Matrix(uint, uint, bool, T_type) 1395 * \see Matrix(uint, uint, T_iterator) 1396 * \see Matrix(const std::string&) 1397 * \see Matrix(const Matrix&) 1398 * \see Matrix(const Matrix<T_type, O, S> &) 1399 * \see Matrix(const Matrix<S_type, O, S> &) 1400 * \see operator()(uint, uint, uint, uint) 1401 * \see operator()(uint, uint, uint, uint) const 1402 * \see operator()(all_elements, uint) 1403 * \see operator()(all_elements, uint) const 1404 * \see operator()(uint, all_elements) 1405 * \see operator()(uint, all_elements) const 1406 * \see reference(const Matrix<T_type, O, S> &) 1407 * 1408 * \throw scythe_style_error (Level 0) 1409 * \throw scythe_alloc_error (Level 1) 1410 */ 1411 template <matrix_order O, matrix_style S> Matrix(const Matrix<T_type,O,S> & M,uint x1,uint y1,uint x2,uint y2)1412 Matrix (const Matrix<T_type, O, S> &M, 1413 uint x1, uint y1, uint x2, uint y2) 1414 : Base(M, x1, y1, x2, y2), 1415 DBRef(M, Base::index(x1, y1)) 1416 { 1417 /* Submatrices always have to be views, but the whole 1418 * concrete-view thing is just a policy maintained by the 1419 * software. Therefore, we need to ensure this constructor 1420 * only returns views. There's no neat way to do it but this 1421 * is still a compile time check, even if it only reports at 1422 * run-time. 1423 */ 1424 if (STYLE == Concrete) { 1425 SCYTHE_THROW(scythe_style_error, 1426 "Tried to construct a concrete submatrix (Matrix)!"); 1427 } 1428 } 1429 1430 public: 1431 /**** DESTRUCTOR ****/ 1432 1433 /*!\brief Destructor. 1434 */ ~Matrix()1435 ~Matrix() {} 1436 1437 /**** COPY/REFERENCE METHODS ****/ 1438 1439 /* Make this matrix a view of another's data. If this matrix's 1440 * previous datablock is not viewed by any other object it is 1441 * deallocated. Concrete matrices cannot be turned into views 1442 * at run-time! Therefore, we generate an error here if *this 1443 * is concrete. 1444 */ 1445 1446 /*!\brief View another Matrix's data. 1447 * 1448 * This modifier makes this matrix a view of another's data. 1449 * The action detaches the Matrix from its current view; if no 1450 * other Matrix views the detached DataBlock, it will be 1451 * deallocated. 1452 * 1453 * Concrete matrices cannot convert into views at 1454 * run time. Therefore, it is an error to invoke this method on 1455 * a concrete Matrix. 1456 * 1457 * \param M The Matrix to view. 1458 * 1459 * \see Matrix(const Matrix&) 1460 * \see Matrix(const Matrix<T_type, O, S> &) 1461 * \see Matrix(const Matrix<S_type, O, S> &) 1462 * \see copy() 1463 * \see copy(const Matrix<T_type, O, S> &) 1464 * 1465 * \throw scythe_style_error (Level 0) 1466 * 1467 * \b Example: 1468 * \include example.matrix.reference.cc 1469 */ 1470 template <matrix_order O, matrix_style S> reference(const Matrix<T_type,O,S> & M)1471 inline void reference (const Matrix<T_type, O, S> &M) 1472 { 1473 if (STYLE == Concrete) { 1474 SCYTHE_THROW(scythe_style_error, 1475 "Concrete matrices cannot reference other matrices"); 1476 } else { 1477 this->referenceOther(M); 1478 this->mimic(M); 1479 } 1480 } 1481 1482 /*!\brief Create a copy of this matrix. 1483 * 1484 * Creates a deep copy of this Matrix. The returned concrete 1485 * matrix references a newly created DataBlock that contains 1486 * values that are identical to, but distinct from, the values 1487 * contained in the original Matrix. 1488 * 1489 * \see Matrix(const Matrix&) 1490 * \see Matrix(const Matrix<T_type, O, S> &) 1491 * \see Matrix(const Matrix<S_type, O, S> &) 1492 * \see copy(const Matrix<T_type, O, S> &) 1493 * \see reference(const Matrix<T_type, O, S> &) 1494 * 1495 * \throw scythe_alloc_error (Level 1) 1496 * 1497 * \b Example: 1498 * \include example.matrix.copy.cc 1499 */ copy()1500 inline Matrix<T_type, ORDER, Concrete> copy () const 1501 { 1502 Matrix<T_type, ORDER> res (Base::rows(), Base::cols(), false); 1503 std::copy(begin_f(), end_f(), res.begin_f()); 1504 1505 return res; 1506 } 1507 1508 /* Make this matrix a copy of another. The matrix retains its 1509 * own order and style in this case, because that can't change 1510 * at run time. 1511 */ 1512 /*!\brief Make this Matrix a copy of another. 1513 * 1514 * Converts this Matrix into a deep copy of another Matrix. 1515 * This Matrix retains its own matrix_order and matrix_style but 1516 * contains copies of M's elements and becomes the same size and 1517 * shape as M. Calling this method automatically detaches this 1518 * Matrix from its previous DataBlock before copying. 1519 * 1520 * \param M The Matrix to copy. 1521 * 1522 * \see Matrix(const Matrix&) 1523 * \see Matrix(const Matrix<T_type, O, S> &) 1524 * \see Matrix(const Matrix<S_type, O, S> &) 1525 * \see copy() 1526 * \see reference(const Matrix<T_type, O, S> &) 1527 * \see detach() 1528 * 1529 * \throw scythe_alloc_error (Level 1) 1530 * 1531 * \b Example: 1532 * \include example.matrix.copyother.cc 1533 */ 1534 template <matrix_order O, matrix_style S> copy(const Matrix<T_type,O,S> & M)1535 inline void copy (const Matrix<T_type, O, S>& M) 1536 { 1537 resize2Match(M); 1538 scythe::copy<ORDER,ORDER> (M, *this); 1539 } 1540 1541 /**** INDEXING OPERATORS ****/ 1542 1543 /*! \brief Access or modify an element in this Matrix. 1544 * 1545 * This indexing operator allows the caller to access or modify 1546 * the ith (indexed in this Matrix's matrix_order) element of 1547 * this Matrix, indexed from 0 to n - 1, where n is the number 1548 * of elements in the Matrix. 1549 * 1550 * \param i The index of the element to access/modify. 1551 * 1552 * \see operator[](uint) const 1553 * \see operator()(uint) 1554 * \see operator()(uint) const 1555 * \see operator()(uint, uint) 1556 * \see operator()(uint, uint) const 1557 * 1558 * \throw scythe_bounds_error (Level 3) 1559 */ 1560 inline T_type& operator[] (uint i) 1561 { 1562 SCYTHE_CHECK_30 (! Base::inRange(i), scythe_bounds_error, 1563 "Index " << i << " out of range"); 1564 1565 return data_[Base::index(i)]; 1566 } 1567 1568 /*! \brief Access an element in this Matrix. 1569 * 1570 * This indexing operator allows the caller to access 1571 * the ith (indexed in this Matrix's matrix_order) element of 1572 * this Matrix, indexed from 0 to n - 1, where n is the number 1573 * of elements in the Matrix. 1574 * 1575 * \param i The index of the element to access. 1576 * 1577 * \see operator[](uint) 1578 * \see operator()(uint) 1579 * \see operator()(uint) const 1580 * \see operator()(uint, uint) 1581 * \see operator()(uint, uint) const 1582 * 1583 * \throw scythe_bounds_error (Level 3) 1584 */ 1585 inline T_type& operator[] (uint i) const 1586 { 1587 SCYTHE_CHECK_30 (! Base::inRange(i), scythe_bounds_error, 1588 "Index " << i << " out of range"); 1589 1590 return data_[Base::index(i)]; 1591 } 1592 1593 /*! \brief Access or modify an element in this Matrix. 1594 * 1595 * This indexing operator allows the caller to access or modify 1596 * the ith (indexed in this Matrix's matrix_order) element of 1597 * this Matrix, indexed from 0 to n - 1, where n is the number 1598 * of elements in the Matrix. 1599 * 1600 * \param i The index of the element to access/modify. 1601 * 1602 * \see operator[](uint) 1603 * \see operator[](uint) const 1604 * \see operator()(uint) const 1605 * \see operator()(uint, uint) 1606 * \see operator()(uint, uint) const 1607 * 1608 * \throw scythe_bounds_error (Level 3) 1609 */ operator()1610 inline T_type& operator() (uint i) 1611 { 1612 SCYTHE_CHECK_30 (! Base::inRange(i), scythe_bounds_error, 1613 "Index " << i << " out of range"); 1614 1615 return data_[Base::index(i)]; 1616 } 1617 1618 /*! \brief Access an element in this Matrix. 1619 * 1620 * This indexing operator allows the caller to access 1621 * the ith (indexed in this Matrix's matrix_order) element of 1622 * this Matrix, indexed from 0 to n - 1, where n is the number 1623 * of elements in the Matrix. 1624 * 1625 * \param i The index of the element to access. 1626 * 1627 * \see operator[](uint) 1628 * \see operator[](uint) const 1629 * \see operator()(uint) 1630 * \see operator()(uint, uint) 1631 * \see operator()(uint, uint) const 1632 * 1633 * \throw scythe_bounds_error (Level 3) 1634 */ operator()1635 inline T_type& operator() (uint i) const 1636 { 1637 SCYTHE_CHECK_30 (! Base::inRange(i), scythe_bounds_error, 1638 "Index " << i << " out of range"); 1639 1640 return data_[Base::index(i)]; 1641 } 1642 1643 /*! \brief Access or modify an element in this Matrix. 1644 * 1645 * This indexing operator allows the caller to access or modify 1646 * the (i, j)th element of 1647 * this Matrix, where i is an element of 0, 1, ..., rows - 1 and 1648 * j is an element of 0, 1, ..., columns - 1. 1649 * 1650 * \param i The row index of the element to access/modify. 1651 * \param j The column index of the element to access/modify. 1652 * 1653 * \see operator[](uint) 1654 * \see operator[](uint) const 1655 * \see operator()(uint) 1656 * \see operator()(uint) const 1657 * \see operator()(uint, uint) const 1658 * 1659 * \throw scythe_bounds_error (Level 3) 1660 */ operator()1661 inline T_type& operator() (uint i, uint j) 1662 { 1663 SCYTHE_CHECK_30 (! Base::inRange(i, j), scythe_bounds_error, 1664 "Index (" << i << ", " << j << ") out of range"); 1665 1666 return data_[Base::index(i, j)]; 1667 } 1668 1669 /*! \brief Access an element in this Matrix. 1670 * 1671 * This indexing operator allows the caller to access 1672 * the (i, j)th element of 1673 * this Matrix, where i is an element of 0, 1, ..., rows - 1 and 1674 * j is an element of 0, 1, ..., columns - 1. 1675 * 1676 * \param i The row index of the element to access. 1677 * \param j The column index of the element to access. 1678 * 1679 * \see operator[](uint) 1680 * \see operator[](uint) const 1681 * \see operator()(uint) 1682 * \see operator()(uint) const 1683 * \see operator() (uint, uint) 1684 * 1685 * \throw scythe_bounds_error (Level 3) 1686 */ operator()1687 inline T_type& operator() (uint i, uint j) const 1688 { 1689 SCYTHE_CHECK_30 (! Base::inRange(i, j), scythe_bounds_error, 1690 "Index (" << i << ", " << j << ") out of range"); 1691 1692 return data_[Base::index(i, j)]; 1693 } 1694 1695 /**** SUBMATRIX OPERATORS ****/ 1696 1697 1698 /* Submatrices are always views. An extra (but relatively 1699 * cheap) copy constructor call is made when mixing and matching 1700 * orders like 1701 * 1702 * Matrix<> A; 1703 * ... 1704 * Matrix<double, Row> B = A(2, 2, 4, 4); 1705 * 1706 * It is technically possible to get around this, by providing 1707 * templates of each function of the form 1708 * template <matrix_order O> 1709 * Matrix<T_type, O, View> operator() (...) 1710 * 1711 * but the syntax to call them (crappy return type inference): 1712 * 1713 * Matrix<double, Row> B = A.template operator()<Row>(2, 2, 4, 4) 1714 * 1715 * is such complete gibberish that I don't think this is worth 1716 * the slight optimization. 1717 */ 1718 1719 /*! \brief Returns a view of a submatrix. 1720 * 1721 * This operator returns a rectangular submatrix view of this 1722 * Matrix with its upper left corner at (x1, y1) and its lower 1723 * right corner at (x2, y2). 1724 * 1725 * \param x1 The upper row of the submatrix. 1726 * \param y1 The leftmost column of the submatrix. 1727 * \param x2 The lowest row of the submatrix. 1728 * \param y2 The rightmost column of the submatrix. 1729 * 1730 * \see operator()(uint, uint, uint, uint) const 1731 * \see operator()(all_elements, uint) 1732 * \see operator()(all_elements, uint) const 1733 * \see operator()(uint, all_elements) 1734 * \see operator()(uint, all_elements) const 1735 * 1736 * \throw scythe_bounds_error (Level 2) 1737 * 1738 * \b Example: 1739 * \include example.matrix.submatrix.cc 1740 */ 1741 inline Matrix<T_type, ORDER, View> operator()1742 operator() (uint x1, uint y1, uint x2, uint y2) 1743 { 1744 SCYTHE_CHECK_20 (! Base::inRange(x1, y1) 1745 || ! Base::inRange(x2, y2) 1746 || x1 > x2 || y1 > y2, 1747 scythe_bounds_error, 1748 "Submatrix (" << x1 << ", " << y1 << ") ; (" 1749 << x2 << ", " << y2 << ") out of range or ill-formed"); 1750 1751 return (Matrix<T_type, ORDER, View>(*this, x1, y1, x2, y2)); 1752 } 1753 1754 /*! \brief Returns a view of a submatrix. 1755 * 1756 * This operator returns a rectangular submatrix view of this 1757 * Matrix with its upper left corner at (x1, y1) and its lower 1758 * right corner at (x2, y2). 1759 * 1760 * \param x1 The upper row of the submatrix. 1761 * \param y1 The leftmost column of the submatrix. 1762 * \param x2 The lowest row of the submatrix. 1763 * \param y2 The rightmost column of the submatrix. 1764 * 1765 * \see operator()(uint, uint, uint, uint) 1766 * \see operator()(all_elements, uint) 1767 * \see operator()(all_elements, uint) const 1768 * \see operator()(uint, all_elements) 1769 * \see operator()(uint, all_elements) const 1770 * 1771 * \throw scythe_bounds_error (Level 2) 1772 */ 1773 inline Matrix<T_type, ORDER, View> operator()1774 operator() (uint x1, uint y1, uint x2, uint y2) const 1775 { 1776 SCYTHE_CHECK_20 (! Base::inRange(x1, y1) 1777 || ! Base::inRange(x2, y2) 1778 || x1 > x2 || y1 > y2, 1779 scythe_bounds_error, 1780 "Submatrix (" << x1 << ", " << y1 << ") ; (" 1781 << x2 << ", " << y2 << ") out of range or ill-formed"); 1782 1783 return (Matrix<T_type, ORDER, View>(*this, x1, y1, x2, y2)); 1784 } 1785 1786 /*! \brief Returns a view of a column vector. 1787 * 1788 * This operator returns a vector view of column j in this Matrix. 1789 * 1790 * \param a An all_elements object signifying whole vector access. 1791 * \param j The column to view. 1792 * 1793 * \see operator()(uint, uint, uint, uint) 1794 * \see operator()(uint, uint, uint, uint) const 1795 * \see operator()(all_elements, uint) const 1796 * \see operator()(uint, all_elements) 1797 * \see operator()(uint, all_elements) const 1798 * 1799 * \throw scythe_bounds_error (Level 2) 1800 * 1801 * \b Example: 1802 * \include example.matrix.vector.cc 1803 */ 1804 inline Matrix<T_type, ORDER, View> operator()1805 operator() (const all_elements a, uint j) 1806 { 1807 SCYTHE_CHECK_20 (j >= Base::cols(), scythe_bounds_error, 1808 "Column vector index " << j << " out of range"); 1809 1810 return (Matrix<T_type, ORDER, View> 1811 (*this, 0, j, Base::rows() - 1, j)); 1812 } 1813 1814 /*! \brief Returns a view of a column vector. 1815 * 1816 * This operator returns a vector view of column j in this Matrix. 1817 * 1818 * \param a An all_elements object signifying whole vector access. 1819 * \param j The column to view. 1820 * 1821 * \see operator()(uint, uint, uint, uint) 1822 * \see operator()(uint, uint, uint, uint) const 1823 * \see operator()(all_elements, uint) 1824 * \see operator()(uint, all_elements) 1825 * \see operator()(uint, all_elements) const 1826 * 1827 * \throw scythe_bounds_error (Level 2) 1828 */ 1829 inline Matrix<T_type, ORDER, View> operator()1830 operator() (const all_elements a, uint j) const 1831 { 1832 SCYTHE_CHECK_20 (j >= Base::cols(), scythe_bounds_error, 1833 "Column vector index " << j << " out of range"); 1834 1835 return (Matrix<T_type, ORDER, View> 1836 (*this, 0, j, Base::rows() - 1, j)); 1837 } 1838 1839 /*! \brief Returns a view of a row vector. 1840 * 1841 * This operator returns a vector view of row i in this Matrix. 1842 * 1843 * \param i The row to view. 1844 * \param b An all_elements object signifying whole vector access. 1845 * 1846 * \see operator()(uint, uint, uint, uint) 1847 * \see operator()(uint, uint, uint, uint) const 1848 * \see operator()(all_elements, uint) 1849 * \see operator()(all_elements, uint) const 1850 * \see operator()(uint, all_elements) const 1851 * 1852 * \throw scythe_bounds_error (Level 2) 1853 * 1854 * \b Example: 1855 * \include example.matrix.vector.cc 1856 */ 1857 inline Matrix<T_type, ORDER, View> operator()1858 operator() (uint i, const all_elements b) 1859 { 1860 SCYTHE_CHECK_20 (i >= Base::rows(), scythe_bounds_error, 1861 "Row vector index " << i << " out of range"); 1862 1863 return (Matrix<T_type, ORDER, View> 1864 (*this, i, 0, i, Base::cols() - 1)); 1865 } 1866 1867 /*! \brief Returns a view of a row vector. 1868 * 1869 * This operator returns a vector view of row i in this Matrix. 1870 * 1871 * \param i The row to view. 1872 * \param b An all_elements object signifying whole vector access. 1873 * 1874 * \see operator()(uint, uint, uint, uint) 1875 * \see operator()(uint, uint, uint, uint) const 1876 * \see operator()(all_elements, uint) 1877 * \see operator()(all_elements, uint) const 1878 * \see operator()(uint, all_elements) 1879 * 1880 * \throw scythe_bounds_error (Level 2) 1881 */ 1882 inline Matrix<T_type, ORDER, View> operator()1883 operator() (uint i, const all_elements b) const 1884 { 1885 SCYTHE_CHECK_20 (i >= Base::rows(), scythe_bounds_error, 1886 "Row vector index " << i << " out of range"); 1887 return (Matrix<T_type, ORDER, View> 1888 (*this, i, 0, i, Base::cols() - 1)); 1889 } 1890 1891 /*! \brief Returns single element in matrix as scalar type 1892 * 1893 * This method converts a matrix object to a single scalar 1894 * element of whatever type the matrix is composed of. The 1895 * method simply returns the element at position zero; if error 1896 * checking is turned on the method with throw an error if the 1897 * matrix is not, in fact, 1x1. 1898 * 1899 * \throw scythe_conformation_error (Level 1) 1900 */ 1901 1902 /**** ASSIGNMENT OPERATORS ****/ 1903 1904 /* 1905 * As with the copy constructor, we need to 1906 * explicitly define the same-order-same-style assignment 1907 * operator or the default operator will take over. 1908 * 1909 * TODO With views, it may be desirable to auto-grow (and, 1910 * technically, detach) views to the null matrix. This means 1911 * you can write something like: 1912 * 1913 * Matrix<double, Col, View> X; 1914 * X = ... 1915 * 1916 * and not run into trouble because you didn't presize. Still, 1917 * not sure this won't encourage silly mistakes...need to think 1918 * about it. 1919 */ 1920 1921 /*! \brief Assign the contents of one Matrix to another. 1922 * 1923 * Like copy construction, assignment works differently for 1924 * concrete matrices than it does for views. When you assign to 1925 * a concrete Matrix it resizes itself to match the right hand 1926 * side Matrix and copies over the values. Like all resizes, 1927 * this causes this Matrix to detach() from its original 1928 * DataBlock. This means that any views attached to this Matrix 1929 * will no longer view this Matrix's data after the assignment; 1930 * they will continue to view this Matrix's previous DataBlock. 1931 * When you assign to a view it first checks that 1932 * the right hand side conforms to its dimensions (by default, 1933 * see below), and then copies the right hand side values over 1934 * into its current DataBlock, overwriting the current contents. 1935 * 1936 * Scythe also supports a slightly different model of view 1937 * assignment. If the user compiled her program with the 1938 * SCYTHE_VIEW_ASSIGNMENT_RECYCLE flag set then it is possible 1939 * to copy into a view that is not of the same size as the 1940 * Matrix on the right hand side of the equation. In this case, 1941 * the operator copies elements from the right hand side 1942 * object into this matrix until either this matrix runs out of 1943 * room, or the right hand side one does. In the latter case, 1944 * the operator starts over at the beginning of the right hand 1945 * side object, recycling its values as many times as necessary 1946 * to fill the left hand side object. The 1947 * SCYTHE_VIEW_ASSIGNMENT_RECYCLE flag does not affect the 1948 * behavior of the concrete matrices in any way. 1949 * 1950 * \param M The Matrix to copy. 1951 * 1952 * \see operator=(const Matrix<T_type, O, S>&) 1953 * \see operator=(T_type x) 1954 * \see operator=(ListInitializer<T_type, ITERATOR, O, S>) 1955 * \see Matrix(const Matrix&) 1956 * \see Matrix(const Matrix<T_type, O, S> &) 1957 * \see Matrix(const Matrix<S_type, O, S> &) 1958 * \see copy() 1959 * \see copy(const Matrix<T_type, O, S> &) 1960 * \see reference(const Matrix<T_type, O, S> &) 1961 * \see resize(uint, uint, bool) 1962 * \see detach() 1963 * 1964 * \throw scythe_conformation_error (Level 1) 1965 * \throw scythe_alloc_error (Level 1) 1966 * 1967 * \b Example: 1968 * \include example.matrix.operator.assignment.cc 1969 */ 1970 Matrix& operator= (const Matrix& M) 1971 { 1972 if (STYLE == Concrete) { 1973 resize2Match(M); 1974 scythe::copy<ORDER,ORDER> (M, *this); 1975 } else { 1976 #ifndef SCYTHE_VIEW_ASSIGNMENT_RECYCLE 1977 SCYTHE_CHECK_10 (Base::size() != M.size(), 1978 scythe_conformation_error, 1979 "LHS has dimensions (" << Base::rows() 1980 << ", " << Base::cols() 1981 << ") while RHS has dimensions (" << M.rows() << ", " 1982 << M.cols() << ")"); 1983 1984 scythe::copy<ORDER,ORDER> (M, *this); 1985 #else 1986 copy_recycle<ORDER,ORDER>(M, *this); 1987 #endif 1988 } 1989 1990 return *this; 1991 } 1992 1993 /*! \brief Assign the contents of one Matrix to another. 1994 * 1995 * Like copy construction, assignment works differently for 1996 * concrete matrices than it does for views. When you assign to 1997 * a concrete Matrix it resizes itself to match the right hand 1998 * side Matrix and copies over the values. Like all resizes, 1999 * this causes this Matrix to detach() from its original 2000 * DataBlock. When you assign to a view it first checks that 2001 * the right hand side conforms to its dimensions, and then 2002 * copies the right hand side values over into its current 2003 * DataBlock, overwriting the current contents. 2004 * 2005 * Scythe also supports a slightly different model of view 2006 * assignment. If the user compiled her program with the 2007 * SCYTHE_VIEW_ASSIGNMENT_RECYCLE flag set then it is possible 2008 * to copy into a view that is not of the same size as the 2009 * Matrix on the right hand side of the equation. In this case, 2010 * the operator copies elements from the right hand side 2011 * object into this matrix until either this matrix runs out of 2012 * room, or the right hand side one does. In the latter case, 2013 * the operator starts over at the beginning of the right hand 2014 * side object, recycling its values as many times as necessary 2015 * to fill the left hand side object. The 2016 * SCYTHE_VIEW_ASSIGNMENT_RECYCLE flag does not affect the 2017 * behavior of the concrete matrices in any way. 2018 * 2019 * This version of the assignment operator handles assignments 2020 * between matrices of different matrix_order and/or 2021 * matrix_style. 2022 * 2023 * \param M The Matrix to copy. 2024 * 2025 * \see operator=(const Matrix&) 2026 * \see operator=(T_type x) 2027 * \see operator=(ListInitializer<T_type, ITERATOR, O, S>) 2028 * \see Matrix(const Matrix&) 2029 * \see Matrix(const Matrix<T_type, O, S> &) 2030 * \see Matrix(const Matrix<S_type, O, S> &) 2031 * \see copy() 2032 * \see copy(const Matrix<T_type, O, S> &) 2033 * \see reference(const Matrix<T_type, O, S> &) 2034 * \see resize(uint, uint, bool) 2035 * \see detach() 2036 * 2037 * \throw scythe_conformation_error (Level 1) 2038 * \throw scythe_alloc_error (Level 1) 2039 * 2040 * \b Example: 2041 * \include example.matrix.operator.assignment.cc 2042 */ 2043 template <matrix_order O, matrix_style S> 2044 Matrix &operator= (const Matrix<T_type, O, S> &M) 2045 { 2046 if (STYLE == Concrete) { 2047 resize2Match(M); 2048 scythe::copy<ORDER,ORDER> (M, *this); 2049 } else { 2050 #ifndef SCYTHE_VIEW_ASSIGNMENT_RECYCLE 2051 SCYTHE_CHECK_10 (Base::size() != M.size(), 2052 scythe_conformation_error, 2053 "LHS has dimensions (" << Base::rows() 2054 << ", " << Base::cols() 2055 << ") while RHS has dimensions (" << M.rows() << ", " 2056 << M.cols() << ")"); 2057 2058 scythe::copy<ORDER,ORDER> (M, *this); 2059 #else 2060 copy_recycle<ORDER,ORDER>(M, *this); 2061 #endif 2062 } 2063 2064 return *this; 2065 } 2066 2067 /* List-wise initialization behavior is a touch complicated. 2068 * List needs to be less than or equal to matrix in size and it 2069 * is copied into the matrix with R-style recycling. 2070 * 2071 * The one issue is that, if you want true assignment of a 2072 * scalar to a concrete matrix (resize the matrix to a scalar) 2073 * you need to be explicit: 2074 * 2075 * Matrix<> A(2, 2); 2076 * double x = 3; 2077 * ... 2078 * A = Matrix<>(x); // -> 3 2079 * 2080 * A = x; // -> 3 3 2081 * // 3 3 2082 */ 2083 2084 /*! \brief Copy values in a comma-separated list into this Matrix. 2085 * 2086 * This assignment operator allows the user to copy the values in 2087 * a bare, comma-separated, list into this Matrix. The list 2088 * should have no more elements in it than the Matrix has 2089 * elements. If the list has fewer elements than the Matrix, it 2090 * will be recycled until the Matrix is full. 2091 * 2092 * If you wish to convert a concrete Matrix to a scalar-valued 2093 * Matrix object you need to explicitly promote the scalar to a 2094 * Matrix, using the parameterized type constructor 2095 * (Matrix(T_type)). 2096 * 2097 * \param x The first element in the list. 2098 * 2099 * \see operator=(const Matrix&) 2100 * \see operator=(const Matrix<T_type, O, S>&) 2101 * \see operator=(ListInitializer<T_type, ITERATOR, O, S>) 2102 * \see Matrix(const Matrix&) 2103 * \see Matrix(const Matrix<T_type, O, S> &) 2104 * \see Matrix(const Matrix<S_type, O, S> &) 2105 * \see copy() 2106 * \see copy(const Matrix<T_type, O, S> &) 2107 * \see reference(const Matrix<T_type, O, S> &) 2108 * \see resize(uint, uint, bool) 2109 * \see detach() 2110 * 2111 * \b Example: 2112 * \include example.matrix.operator.assignment.cc 2113 */ 2114 ListInitializer<T_type, iterator, ORDER, STYLE> 2115 operator=(T_type x) 2116 { 2117 return (ListInitializer<T_type, iterator, ORDER, STYLE> 2118 (x, begin(),end(), this)); 2119 } 2120 2121 /*! \brief A special assignment operator. 2122 * 2123 * This assignment operator provides the necessary glue to allow 2124 * chained assignments of matrices where the last assignment is 2125 * achieved through list initialization. This allows users to 2126 * write code like 2127 * \code 2128 * Matrix<> A, B, C; 2129 * Matrix<> D(4, 4, false); 2130 * A = B = C = (D = 1, 2, 3, 4); 2131 * \endcode 2132 * where the assignment in the parentheses technically returns a 2133 * ListInitializer object, not a Matrix object. The details of 2134 * this mechanism are not important for the average user and the 2135 * distinction can safely be ignored. 2136 * 2137 * \note 2138 * The parentheses in the code above are necessary because of 2139 * the precedence of the assignment operator. 2140 * 2141 * \see operator=(const Matrix&) 2142 * \see operator=(const Matrix<T_type, O, S>&) 2143 * \see operator=(T_type x) 2144 * 2145 * \b Example: 2146 * \include example.matrix.operator.assignment.cc 2147 */ 2148 template <typename ITERATOR, matrix_order O, matrix_style S> 2149 Matrix &operator=(ListInitializer<T_type, ITERATOR, O, S> li) 2150 { 2151 li.populate(); 2152 *this = *(li.matrix_); 2153 return *this; 2154 } 2155 2156 /**** ARITHMETIC OPERATORS ****/ 2157 2158 private: 2159 /* Reusable chunk of code for element-wise operator 2160 * assignments. Updates are done in-place except for the 1x1 by 2161 * nXm case, which forces a resize. 2162 */ 2163 template <typename OP, matrix_order O, matrix_style S> 2164 inline Matrix& elementWiseOperatorAssignment(const Matrix<T_type,O,S> & M,OP op)2165 elementWiseOperatorAssignment (const Matrix<T_type, O, S>& M, 2166 OP op) 2167 { 2168 SCYTHE_CHECK_10 (Base::size() != 1 && M.size() != 1 && 2169 (Base::rows () != M.rows() || Base::cols() != M.cols()), 2170 scythe_conformation_error, 2171 "Matrices with dimensions (" << Base::rows() 2172 << ", " << Base::cols() 2173 << ") and (" << M.rows() << ", " << M.cols() 2174 << ") are not conformable"); 2175 2176 using std::placeholders::_1; 2177 if (Base::size() == 1) { // 1x1 += nXm 2178 T_type tmp = (*this)(0); 2179 resize2Match(M); 2180 std::transform(M.template begin_f<ORDER>(), M.template end_f<ORDER>(), 2181 begin_f(), std::bind(op,tmp,_1)); 2182 } else if (M.size() == 1) { // nXm += 1x1 2183 std::transform(begin_f(), end_f(), begin_f(), 2184 std::bind(op, _1, M(0))); 2185 } else { // nXm += nXm 2186 std::transform(begin_f(), end_f(), M.template begin_f<ORDER>(), 2187 begin_f(), op); 2188 } 2189 2190 return *this; 2191 } 2192 2193 public: 2194 /*! \brief Add another Matrix to this Matrix. 2195 * 2196 * This operator sums this Matrix with another and places the 2197 * result into this Matrix. The two matrices must have the same 2198 * dimensions or one of the matrices must be 1x1. 2199 * 2200 * \param M The Matrix to add to this one. 2201 * 2202 * \see operator+=(T_type) 2203 * \see operator-=(const Matrix<T_type, O, S> &) 2204 * \see operator%=(const Matrix<T_type, O, S> &) 2205 * \see operator/=(const Matrix<T_type, O, S> &) 2206 * \see operator^=(const Matrix<T_type, O, S> &) 2207 * \see operator*=(const Matrix<T_type, O, S> &) 2208 * \see kronecker(const Matrix<T_type, O, S> &) 2209 * 2210 * \throw scythe_conformation_error (Level 1) 2211 * \throw scythe_alloc_error (Level 1) 2212 */ 2213 template <matrix_order O, matrix_style S> 2214 inline Matrix& operator+= (const Matrix<T_type, O, S> &M) 2215 { 2216 return elementWiseOperatorAssignment(M, std::plus<T_type> ()); 2217 } 2218 2219 /*! \brief Add a scalar to this Matrix. 2220 * 2221 * This operator sums each element of this Matrix with the 2222 * scalar \a x and places the result into this Matrix. 2223 * 2224 * \param x The scalar to add to each element. 2225 * 2226 * \see operator+=(const Matrix<T_type, O, S> &) 2227 * \see operator-=(T_type) 2228 * \see operator%=(T_type) 2229 * \see operator/=(T_type) 2230 * \see operator^=(T_type) 2231 * \see kronecker(T_type) 2232 * 2233 * \throw scythe_conformation_error (Level 1) 2234 */ 2235 inline Matrix& operator+= (T_type x) 2236 { 2237 return elementWiseOperatorAssignment(Matrix(x), 2238 std::plus<T_type> ()); 2239 } 2240 2241 /*! \brief Subtract another Matrix from this Matrix. 2242 * 2243 * This operator subtracts another Matrix from this one and 2244 * places the result into this Matrix. The two matrices must 2245 * have the same dimensions or one of the matrices must be 1x1. 2246 * 2247 * \param M The Matrix to subtract from this one. 2248 * 2249 * \see operator-=(T_type) 2250 * \see operator+=(const Matrix<T_type, O, S> &) 2251 * \see operator%=(const Matrix<T_type, O, S> &) 2252 * \see operator/=(const Matrix<T_type, O, S> &) 2253 * \see operator^=(const Matrix<T_type, O, S> &) 2254 * \see operator*=(const Matrix<T_type, O, S> &) 2255 * \see kronecker(const Matrix<T_type, O, S> &) 2256 * 2257 * \throw scythe_conformation_error (Level 1) 2258 * \throw scythe_alloc_error (Level 1) 2259 */ 2260 template <matrix_order O, matrix_style S> 2261 inline Matrix& operator-= (const Matrix<T_type, O, S> &M) 2262 { 2263 return elementWiseOperatorAssignment(M, std::minus<T_type> ()); 2264 } 2265 2266 /*! \brief Subtract a scalar from this Matrix. 2267 * 2268 * This operator subtracts \a x from each element of this 2269 * Matrix and places the result into this Matrix. 2270 * 2271 * \param x The scalar to subtract from each element. 2272 * 2273 * \see operator-=(const Matrix<T_type, O, S> &) 2274 * \see operator+=(T_type) 2275 * \see operator%=(T_type) 2276 * \see operator/=(T_type) 2277 * \see operator^=(T_type) 2278 * \see kronecker(T_type) 2279 * 2280 * \throw scythe_conformation_error (Level 1) 2281 */ 2282 inline Matrix& operator-= (T_type x) 2283 { 2284 return elementWiseOperatorAssignment(Matrix(x), 2285 std::minus<T_type> ()); 2286 } 2287 2288 /*! \brief Multiply the elements of this Matrix with another's. 2289 * 2290 * This operator multiplies the elements of this Matrix with 2291 * another's and places the result into this Matrix. The two 2292 * matrices must have the same dimensions, or one of the 2293 * matrices must be 1x1. 2294 * 2295 * This operator performs element-by-element multiplication 2296 * (calculates the Hadamard product), not conventional matrix 2297 * multiplication. 2298 * 2299 * \param M The Matrix to multiply with this one. 2300 * 2301 * \see operator%=(T_type) 2302 * \see operator+=(const Matrix<T_type, O, S> &) 2303 * \see operator-=(const Matrix<T_type, O, S> &) 2304 * \see operator/=(const Matrix<T_type, O, S> &) 2305 * \see operator^=(const Matrix<T_type, O, S> &) 2306 * \see operator*=(const Matrix<T_type, O, S> &) 2307 * \see kronecker(const Matrix<T_type, O, S> &) 2308 * 2309 * \throw scythe_conformation_error (Level 1) 2310 * \throw scythe_alloc_error (Level 1) 2311 */ 2312 template <matrix_order O, matrix_style S> 2313 inline Matrix& operator%= (const Matrix<T_type, O, S> &M) 2314 { 2315 return elementWiseOperatorAssignment(M, 2316 std::multiplies<T_type> ()); 2317 } 2318 2319 /*! \brief Multiply this Matrix by a scalar. 2320 * 2321 * This operator multiplies each element of this 2322 * Matrix with \a x and places the result into this Matrix. 2323 * 2324 * \param x The scalar to multiply each element by. 2325 * 2326 * \see operator%=(const Matrix<T_type, O, S> &) 2327 * \see operator+=(T_type) 2328 * \see operator-=(T_type) 2329 * \see operator/=(T_type) 2330 * \see operator^=(T_type) 2331 * \see kronecker(T_type) 2332 * 2333 * \throw scythe_conformation_error (Level 1) 2334 */ 2335 inline Matrix& operator%= (T_type x) 2336 { 2337 return elementWiseOperatorAssignment(Matrix(x), 2338 std::multiplies<T_type> ()); 2339 } 2340 2341 /*! \brief Divide the elements of this Matrix by another's. 2342 * 2343 * This operator divides the elements of this Matrix by 2344 * another's and places the result into this Matrix. The two 2345 * matrices must have the same dimensions, or one of the 2346 * Matrices must be 1x1. 2347 * 2348 * \param M The Matrix to divide this one by. 2349 * 2350 * \see operator/=(T_type) 2351 * \see operator+=(const Matrix<T_type, O, S> &) 2352 * \see operator-=(const Matrix<T_type, O, S> &) 2353 * \see operator%=(const Matrix<T_type, O, S> &) 2354 * \see operator^=(const Matrix<T_type, O, S> &) 2355 * \see operator*=(const Matrix<T_type, O, S> &) 2356 * \see kronecker(const Matrix<T_type, O, S> &) 2357 * 2358 * \throw scythe_conformation_error (Level 1) 2359 * \throw scythe_alloc_error (Level 1) 2360 */ 2361 template <matrix_order O, matrix_style S> 2362 inline Matrix& operator/= (const Matrix<T_type, O, S> &M) 2363 { 2364 return elementWiseOperatorAssignment(M, std::divides<T_type>()); 2365 } 2366 2367 /*! \brief Divide this Matrix by a scalar. 2368 * 2369 * This operator divides each element of this 2370 * Matrix by \a x and places the result into this Matrix. 2371 * 2372 * \param x The scalar to divide each element by. 2373 * 2374 * \see operator/=(const Matrix<T_type, O, S> &) 2375 * \see operator+=(T_type) 2376 * \see operator-=(T_type) 2377 * \see operator%=(T_type) 2378 * \see operator^=(T_type) 2379 * \see kronecker(T_type) 2380 * 2381 * \throw scythe_conformation_error (Level 1) 2382 */ 2383 inline Matrix& operator/= (T_type x) 2384 { 2385 return elementWiseOperatorAssignment(Matrix(x), 2386 std::divides<T_type> ()); 2387 } 2388 2389 /*! \brief Exponentiate the elements of this Matrix by another's. 2390 * 2391 * This operator exponentiates the elements of this Matrix by 2392 * another's and places the result into this Matrix. The two 2393 * matrices must have the same dimensions, or one of the 2394 * Matrices must be 1x1. 2395 * 2396 * \param M The Matrix to exponentiate this one by. 2397 * 2398 * \see operator^=(T_type) 2399 * \see operator+=(const Matrix<T_type, O, S> &) 2400 * \see operator-=(const Matrix<T_type, O, S> &) 2401 * \see operator%=(const Matrix<T_type, O, S> &) 2402 * \see operator^=(const Matrix<T_type, O, S> &) 2403 * \see operator*=(const Matrix<T_type, O, S> &) 2404 * \see kronecker(const Matrix<T_type, O, S> &) 2405 * 2406 * \throw scythe_conformation_error (Level 1) 2407 * \throw scythe_alloc_error (Level 1) 2408 */ 2409 template <matrix_order O, matrix_style S> 2410 inline Matrix& operator^= (const Matrix<T_type, O, S> &M) 2411 { 2412 return elementWiseOperatorAssignment(M, 2413 exponentiate<T_type>()); 2414 } 2415 2416 /*! \brief Exponentiate this Matrix by a scalar. 2417 * 2418 * This operator exponentiates each element of this 2419 * Matrix by \a x and places the result into this Matrix. 2420 * 2421 * \param x The scalar to exponentiate each element by. 2422 * 2423 * \see operator^=(const Matrix<T_type, O, S> &) 2424 * \see operator+=(T_type) 2425 * \see operator-=(T_type) 2426 * \see operator%=(T_type) 2427 * \see operator/=(T_type) 2428 * \see kronecker(T_type) 2429 * 2430 * \throw scythe_conformation_error (Level 1) 2431 */ 2432 inline Matrix& operator^= (T_type x) 2433 { 2434 return elementWiseOperatorAssignment(Matrix(x), 2435 exponentiate<T_type> ()); 2436 } 2437 2438 /* Matrix mult always disengages views because it generally 2439 * requires a resize. We force a disengage in the one place it 2440 * isn't absolutely necessary(this->size()==1), for consistency. 2441 */ 2442 2443 /*! \brief Multiply this Matrix by another. 2444 * 2445 * This operator multiplies this Matrix by another and places 2446 * the result into this Matrix. The two matrices must conform; 2447 * this Matrix must have as many columns as the right hand side 2448 * Matrix has rows. 2449 * 2450 * Matrix multiplication always causes a Matrix to detach() from 2451 * its current view, because it generally requires a resize(). 2452 * Even when it is not absolutely necessary to detach() the 2453 * Matrix, this function will do so to maintain consistency. 2454 * 2455 * Scythe will use LAPACK/BLAS routines to multiply concrete 2456 * column-major matrices of double-precision floating point 2457 * numbers if LAPACK/BLAS is available and you compile your 2458 * program with the SCYTHE_LAPACK flag enabled. 2459 * 2460 * \param M The Matrix to multiply this one by. 2461 * 2462 * \see operator*=(T_type) 2463 * \see operator+=(const Matrix<T_type, O, S> &) 2464 * \see operator-=(const Matrix<T_type, O, S> &) 2465 * \see operator%=(const Matrix<T_type, O, S> &) 2466 * \see operator/=(const Matrix<T_type, O, S> &) 2467 * \see operator^=(const Matrix<T_type, O, S> &) 2468 * \see kronecker(const Matrix<T_type, O, S> &) 2469 * 2470 * \throw scythe_conformation_error (Level 1) 2471 * \throw scythe_alloc_error (Level 1) 2472 */ 2473 template <matrix_order O, matrix_style S> 2474 Matrix& operator*= (const Matrix<T_type, O, S>& M) 2475 { 2476 /* Farm out the work to the plain old * operator and make this 2477 * matrix a reference (the only reference) to the result. We 2478 * always have to create a new matrix here, so there is no 2479 * speed-up from using *=. 2480 */ 2481 2482 /* This saves a copy over 2483 * *this = (*this) * M; 2484 * if we're concrete 2485 */ 2486 Matrix<T_type, ORDER> res = (*this) * M; 2487 this->referenceOther(res); 2488 this->mimic(res); 2489 2490 return *this; 2491 } 2492 2493 /*! \brief Multiply this Matrix by a scalar. 2494 * 2495 * This operator multiplies each element of this 2496 * Matrix with \a x and places the result into this Matrix. 2497 * 2498 * \note This method is identical in behavior to 2499 * operator%=(T_type). It also slightly overgeneralizes matrix 2500 * multiplication but makes life easy on the user by allowing 2501 * the matrix multiplication operator to work for basic scaler 2502 * multiplications. 2503 * 2504 * \param x The scalar to multiply each element by. 2505 * 2506 * \see operator*=(const Matrix<T_type, O, S> &) 2507 * \see operator+=(T_type) 2508 * \see operator-=(T_type) 2509 * \see operator%=(T_type) 2510 * \see operator/=(T_type) 2511 * \see operator^=(T_type) 2512 * \see kronecker(T_type) 2513 * 2514 * \throw scythe_conformation_error (Level 1) 2515 */ 2516 inline Matrix& operator*= (T_type x) 2517 { 2518 return elementWiseOperatorAssignment(Matrix(x), 2519 std::multiplies<T_type> ()); 2520 } 2521 2522 /*! \brief Kronecker multiply this Matrix by another. 2523 * 2524 * This method computes the Kronecker product of this Matrix and 2525 * \a M, and sets the value of this Matrix to the result. 2526 * 2527 * Kronecker multiplication always causes a Matrix to detach() 2528 * from its current view, because it generally requires a 2529 * resize(). 2530 * 2531 * \note This method would have been implemented as an operator 2532 * if we had any reasonable operator choices left. 2533 * 2534 * \param M The Matrix to Kronecker multiply this one by. 2535 * 2536 * \see kronecker(T_type) 2537 * \see operator+=(const Matrix<T_type, O, S> &) 2538 * \see operator-=(const Matrix<T_type, O, S> &) 2539 * \see operator%=(const Matrix<T_type, O, S> &) 2540 * \see operator/=(const Matrix<T_type, O, S> &) 2541 * \see operator^=(const Matrix<T_type, O, S> &) 2542 * \see operator*=(const Matrix<T_type, O, S> &) 2543 * 2544 * \throw scythe_alloc_error (Level 1) 2545 */ kronecker(const Matrix<T_type,O,S> & M)2546 template <matrix_order O, matrix_style S> Matrix& kronecker 2547 (const Matrix<T_type, O, S>& M) { uint totalrows = 2548 Base::rows() * M.rows(); uint totalcols = Base::cols() * 2549 M.cols(); 2550 // Even if we're a view, make this guy concrete. 2551 Matrix<T_type,ORDER> res(totalrows, totalcols, false); 2552 2553 /* TODO: This the most natural way to write this in scythe 2554 * (with a small optimization based on ordering) but probably 2555 * not the fastest because it uses submatrix assignments. 2556 * Optimizations should be considered. 2557 */ 2558 forward_iterator it = begin_f(); 2559 if (ORDER == Row) { 2560 for (uint row = 0; row < totalrows; row += M.rows()) { 2561 for (uint col = 0; col < totalcols; col += M.cols()){ 2562 res(row, col, row + M.rows() - 1, col + M.cols() - 1) 2563 = (*it) * M; 2564 it++; 2565 } 2566 } 2567 } else { 2568 for (uint col = 0; col < totalcols; col += M.cols()) { 2569 for (uint row = 0; row < totalrows; row += M.rows()){ 2570 res(row, col, row + M.rows() - 1, col + M.cols() - 1) 2571 = (*it) * M; 2572 it++; 2573 } 2574 } 2575 } 2576 2577 this->referenceOther(res); 2578 this->mimic(res); 2579 2580 return *this; 2581 } 2582 2583 /*! \brief Kronecker multiply this Matrix by a scalar. 2584 * 2585 * This method Kronecker multiplies this Matrix with some scalar, 2586 * \a x. This is a degenerate case of Kronecker 2587 * multiplication, simply multiplying every element in the 2588 * Matrix by \a x. 2589 * 2590 * \note This method is identical in behavior to 2591 * operator%=(T_type) and operator*=(T_type). 2592 * 2593 * \param x The scalar to Kronecker multiply this Matrix by. 2594 * 2595 * \see kronecker(const Matrix<T_type, O, S> &) 2596 * \see operator+=(T_type) 2597 * \see operator-=(T_type) 2598 * \see operator%=(T_type) 2599 * \see operator/=(T_type) 2600 * \see operator^=(T_type) 2601 * \see operator*=(T_type) 2602 * 2603 */ kronecker(T_type x)2604 inline Matrix& kronecker (T_type x) 2605 { 2606 return elementWiseOperatorAssignment(Matrix(x), 2607 std::multiplies<T_type> ()); 2608 } 2609 2610 /* Logical assignment operators */ 2611 2612 /*! \brief Logically AND this Matrix with another. 2613 * 2614 * This operator computes the element-wise logical AND of this 2615 * Matrix and another and places the result into this Matrix. 2616 * That is, after the operation, an element in this Matrix will 2617 * evaluate to true (or the type-specific analog of true, 2618 * typically 1) iff the corresponding element previously 2619 * residing in this Matrix and the corresponding element in \a M 2620 * both evaluate to true. The two matrices must have the same 2621 * dimensions, or one of the Matrices must be 1x1. 2622 * 2623 * \param M The Matrix to AND with this one. 2624 * 2625 * \see operator&=(T_type) 2626 * \see operator|=(const Matrix<T_type, O, S> &) 2627 * 2628 * \throw scythe_conformation_error (Level 1) 2629 * \throw scythe_alloc_error (Level 1) 2630 */ 2631 template <matrix_order O, matrix_style S> 2632 inline Matrix& operator&= (const Matrix<T_type, O, S> &M) 2633 { 2634 return elementWiseOperatorAssignment(M, 2635 std::logical_and<T_type>()); 2636 } 2637 2638 /*! \brief Logically AND this Matrix with a scalar. 2639 * 2640 * This operator computes the element-wise logical AND of this 2641 * Matrix and a scalar. That is, after the operation, an 2642 * element in this Matrix will evaluate to true (or the 2643 * type-specific analog of true, typically 1) iff the 2644 * corresponding element previously residing in this Matrix and 2645 * \a x both evaluate to true. 2646 * 2647 * \param x The scalar to AND with each element. 2648 * 2649 * \see operator&=(const Matrix<T_type, O, S> &) 2650 * \see operator|=(T_type) 2651 * 2652 * \throw scythe_conformation_error (Level 1) 2653 */ 2654 inline Matrix& operator&= (T_type x) 2655 { 2656 return elementWiseOperatorAssignment(Matrix(x), 2657 std::logical_and<T_type> ()); 2658 } 2659 2660 /*! \brief Logically OR this Matrix with another. 2661 * 2662 * This operator computes the element-wise logical OR of this 2663 * Matrix and another and places the result into this Matrix. 2664 * That is, after the operation, an element in this Matrix will 2665 * evaluate to true (or the type-specific analog of true, 2666 * typically 1) if the corresponding element previously 2667 * residing in this Matrix or the corresponding element in \a M 2668 * evaluate to true. The two matrices must have the same 2669 * dimensions, or one of the Matrices must be 1x1. 2670 * 2671 * \param M The Matrix to OR with this one. 2672 * 2673 * \see operator|=(T_type) 2674 * \see operator&=(const Matrix<T_type, O, S> &) 2675 * 2676 * \throw scythe_conformation_error (Level 1) 2677 * \throw scythe_alloc_error (Level 1) 2678 */ 2679 template <matrix_order O, matrix_style S> 2680 inline Matrix& operator|= (const Matrix<T_type, O, S> &M) 2681 { 2682 return elementWiseOperatorAssignment(M, 2683 std::logical_or<T_type>()); 2684 } 2685 2686 /*! \brief Logically OR this Matrix with a scalar. 2687 * 2688 * This operator computes the element-wise logical OR of this 2689 * Matrix and a scalar. That is, after the operation, an 2690 * element in this Matrix will evaluate to true (or the 2691 * type-specific analog of true, typically 1) if the 2692 * corresponding element previously residing in this Matrix or 2693 * \a x evaluate to true. 2694 * 2695 * \param x The scalar to OR with each element. 2696 * 2697 * \see operator|=(const Matrix<T_type, O, S> &) 2698 * \see operator&=(T_type) 2699 * 2700 * \throw scythe_conformation_error (Level 1) 2701 */ 2702 inline Matrix& operator|= (T_type x) 2703 { 2704 return elementWiseOperatorAssignment(Matrix(x), 2705 std::logical_or<T_type> ()); 2706 } 2707 2708 /**** MODIFIERS ****/ 2709 2710 /* Resize a matrix view. resize() takes dimensions as 2711 * parameters while resize2Match() takes a matrix reference and 2712 * uses its dimensions. 2713 */ 2714 2715 /*! \brief Resize or reshape a Matrix. 2716 * 2717 * This modifier resizes this Matrix to the given dimensions. 2718 * Matrix contents after a resize is undefined (junk) unless the 2719 * preserve flag is set to true. In this case, the old contents 2720 * of the Matrix remains at the same indices it occupied in the 2721 * old Matrix. Any excess capacity is junk. 2722 * 2723 * Resizing a Matrix ALWAYS disengages it from its current view, 2724 * even if the dimensions passed to resize are the same as the 2725 * current Matrix's dimensions. Resized matrices point to new, 2726 * uninitialized data blocks (technically, the Matrix might 2727 * recycle its current block if it is the only Matrix viewing 2728 * the block, but callers cannot rely on this). It is important 2729 * to realize that concrete matrices behave just like views in 2730 * this respect. Any views to a concrete Matrix will be 2731 * pointing to a different underlying data block than the 2732 * concrete Matrix after the concrete Matrix is resized. 2733 * 2734 * \param rows The number of rows in the resized Matrix. 2735 * \param cols The number of columns in the resized Matrix. 2736 * \param preserve Whether or not to retain the current contents 2737 * of the Matrix. 2738 * 2739 * \see resize2Match(const Matrix<T_type, O, S>&, bool) 2740 * \see detach() 2741 * 2742 * \throw scythe_alloc_error (Level 1) 2743 */ 2744 void resize (uint rows, uint cols, bool preserve=false) 2745 { 2746 if (preserve) { 2747 /* TODO Optimize this case. It is rather clunky. */ 2748 Matrix<T_type, ORDER, View> tmp(*this); 2749 this->referenceNew(rows * cols); 2750 Base::resize(rows, cols); 2751 uint min_cols = std::min(Base::cols(), tmp.cols()); 2752 uint min_rows = std::min(Base::rows(), tmp.rows()); 2753 2754 // TODO use iterators here perhaps 2755 if (ORDER == Col) { 2756 for (uint j = 0; j < min_cols; ++j) 2757 for (uint i = 0; i < min_rows; ++i) 2758 (*this)(i, j) = tmp(i, j); 2759 } else { 2760 for (uint i = 0; i < min_rows; ++i) 2761 for (uint j = 0; j < min_cols; ++j) 2762 (*this)(i, j) = tmp(i, j); 2763 } 2764 } else { 2765 this->referenceNew(rows * cols); 2766 Base::resize(rows, cols); 2767 } 2768 } 2769 2770 /*!\brief Resize a Matrix to match another. 2771 * 2772 * This modifier resizes this Matrix to match the dimensions of 2773 * the argument. In all other respects, it behaves just like 2774 * resize(). 2775 * 2776 * \param M The Matrix providing the dimensions to mimic. 2777 * \param preserve Whether or not to train the current contents 2778 * of the Matrix. 2779 * 2780 * \see resize(uint, uint, bool) 2781 * \see detach() 2782 * 2783 * \throw scythe_alloc_error (Level 1) 2784 */ 2785 template <typename T, matrix_order O, matrix_style S> 2786 inline void resize2Match(const Matrix<T, O, S> &M, 2787 bool preserve=false) 2788 { 2789 resize(M.rows(), M.cols(), preserve); 2790 } 2791 2792 /* Copy this matrix to a new datablock in contiguous storage */ 2793 /*! \brief Copy the contents of this Matrix to a new DataBlock. 2794 * 2795 * The detach method copies the data viewed by this Matrix to a 2796 * fresh DataBlock, detaches this Matrix from its old block and 2797 * attaches it to the new block. The old DataBlock will be 2798 * deallocated if no other matrices view the block after this 2799 * one detaches. 2800 * 2801 * This method can be used to ensure that this Matrix is the 2802 * sole viewer of its DataBlock. It also ensures that the 2803 * underlying data is stored contiguously in memory. 2804 * 2805 * \see copy() 2806 * \see resize(uint, uint, bool) 2807 * 2808 * \throw scythe_alloc_error (Level 1) 2809 */ detach()2810 inline void detach () 2811 { 2812 resize2Match(*this, true); 2813 } 2814 2815 /* Swap operator: sort of a dual copy constructor. Part of the 2816 * standard STL container interface. We only support swaps 2817 * between matrices of like order and style because things get 2818 * hairy otherwise. The behavior of this for concrete matrices 2819 * is a little hairy in any case. 2820 * 2821 * Matrix<> A, B; 2822 * ... // fill in A and B 2823 * Matrix<double, Col, View> v1 = A(_, 1); 2824 * A.swap(B); 2825 * Matrix<double, Col, View> v2 = B(_, 1); 2826 * 2827 * v1 == v2; // evaluates to true 2828 * 2829 */ 2830 2831 /*! \brief Swap this Matrix with another. 2832 * 2833 * This modifier is much like a dual copy constructor and is 2834 * part of the Standard Template Library (STL) 2835 * interface for container objects. It is only possible to swap 2836 * two matrices of the same matrix_order and matrix_style. When 2837 * two matrices are swapped, they trade their underlying 2838 * DataBlock and dimensions. This behavior is perfectly natural 2839 * for views, but my seem somewhat surprising for concrete 2840 * matrices. When two concrete matrices are swapped, any views 2841 * that referenced either matrices' DataBlock will reference the 2842 * other matrices' DataBlock after the swap. 2843 * 2844 * \param M - The Matrix to swap with. 2845 */ swap(Matrix & M)2846 inline void swap (Matrix &M) 2847 { 2848 Matrix tmp = *this; 2849 2850 /* This are just reference() calls, but we do this explicitly 2851 * here to avoid throwing errors on the concrete case. While 2852 * having a concrete matrix reference another matrix is 2853 * generally a bad idea, it is safe when the referenced matrix 2854 * is concrete, has the same order, and gets deallocated (or 2855 * redirected at another block) like here. 2856 */ 2857 2858 this->referenceOther(M); 2859 this->mimic(M); 2860 2861 M.referenceOther(tmp); 2862 M.mimic(tmp); 2863 } 2864 2865 /**** ACCESSORS ****/ 2866 2867 /* Accessors that don't access the data itself (that don't rely 2868 * on T_type) are in Matrix_base 2869 */ 2870 2871 /* Are all the elements of this Matrix == 0 */ 2872 2873 /*! \brief Returns true if every element in this Matrix equals 0. 2874 * 2875 * The return value of this method is undefined for null 2876 * matrices. 2877 * 2878 * \see empty() 2879 * \see isNull() 2880 */ isZero()2881 inline bool isZero () const 2882 { 2883 const_forward_iterator last = end_f(); 2884 using std::placeholders::_1; 2885 return (last == std::find_if(begin_f(), last, 2886 std::bind(std::not_equal_to<T_type>(), 0, _1))); 2887 } 2888 2889 /* M(i,j) == 0 when i != j */ 2890 /*! \brief Returns true if this Matrix is square and its 2891 * off-diagonal elements are all 0. 2892 * 2893 * The return value of this method is undefined for null 2894 * matrices. 2895 * 2896 * \see isSquare() 2897 * \see isIdentity() 2898 * \see isLowerTriangular() 2899 * \see isUpperTriangular() 2900 */ isDiagonal()2901 inline bool isDiagonal() const 2902 { 2903 if (! Base::isSquare()) 2904 return false; 2905 /* Always travel in order. It would be nice to use iterators 2906 * here, but we'd need to take views and their iterators are 2907 * too slow at the moment. 2908 * TODO redo with views and iterators if optimized. 2909 */ 2910 if (ORDER == Row) { 2911 for (uint i = 0; i < Base::rows(); ++i) { 2912 for (uint j = 0; j < Base::cols(); ++j) { 2913 if (i != j && (*this)(i, j) != 0) 2914 return false; 2915 } 2916 } 2917 } else { // ORDER == Col 2918 for (uint j = 0; j < Base::cols(); ++j) { 2919 for (uint i = 0; i < Base::rows(); ++i) { 2920 if (i != j && (*this)(i, j) != 0) 2921 return false; 2922 } 2923 } 2924 } 2925 return true; 2926 } 2927 2928 /* M(I, j) == 0 when i!= j and 1 when i == j */ 2929 /*! \brief Returns true if this Matrix is diagonal and its 2930 * diagonal elements are all 1s. 2931 * 2932 * The return value of this method is undefined for null 2933 * matrices. 2934 * 2935 * \see isSquare() 2936 * \see isDiagonal() 2937 * \see isLowerTriangular() 2938 * \see isUpperTriangular() 2939 */ isIdentity()2940 inline bool isIdentity () const 2941 { 2942 if (! Base::isSquare()) 2943 return false; 2944 // TODO redo with views and iterator if optimized 2945 if (ORDER == Row) { 2946 for (uint i = 0; i < Base::rows(); ++i) { 2947 for (uint j = 0; j < Base::cols(); ++j) { 2948 if (i != j) { 2949 if ((*this)(i,j) != 0) 2950 return false; 2951 } else if ((*this)(i,j) != 1) 2952 return false; 2953 } 2954 } 2955 } else { // ORDER == Col 2956 for (uint j = 0; j < Base::rows(); ++j) { 2957 for (uint i = 0; i < Base::cols(); ++i) { 2958 if (i != j) { 2959 if ((*this)(i,j) != 0) 2960 return false; 2961 } else if ((*this)(i,j) != 1) 2962 return false; 2963 } 2964 } 2965 } 2966 return true; 2967 } 2968 2969 /* M(i,j) == 0 when i < j */ 2970 /*! \brief Returns true if all of this Matrix's above-diagonal 2971 * elements equal 0. 2972 * 2973 * The return value of this method is undefined for null 2974 * matrices. 2975 * 2976 * \see isDiagonal() 2977 * \see isUpperTriangular 2978 */ isLowerTriangular()2979 inline bool isLowerTriangular () const 2980 { 2981 if (! Base::isSquare()) 2982 return false; 2983 // TODO view+iterator if optimized 2984 if (ORDER == Row) { 2985 for (uint i = 0; i < Base::rows(); ++i) 2986 for (uint j = i + 1; j < Base::cols(); ++j) 2987 if ((*this)(i,j) != 0) 2988 return false; 2989 } else { 2990 for (uint j = 0; j < Base::cols(); ++j) 2991 for (uint i = 0; i < j; ++i) 2992 if ((*this)(i,j) != 0) 2993 return false; 2994 } 2995 return true; 2996 } 2997 2998 /* M(i,j) == 0 when i > j */ 2999 /*! \brief Returns true if all of this Matrix's below-diagonal 3000 * elements equal 0. 3001 * 3002 * The return value of this method is undefined for null 3003 * matrices. 3004 * 3005 * \see isDiagonal() 3006 * \see isLowerTriangular 3007 */ isUpperTriangular()3008 inline bool isUpperTriangular () const 3009 { 3010 if (! Base::isSquare()) 3011 return false; 3012 // TODO view+iterator if optimized 3013 if (ORDER == Row) { 3014 for (uint i = 0; i < Base::rows(); ++i) 3015 for (uint j = 0; j < i; ++j) 3016 if ((*this)(i,j) != 0) 3017 return false; 3018 } else { 3019 for (uint j = 0; j < Base::cols(); ++j) 3020 for (uint i = j + 1; i < Base::rows(); ++i) 3021 if ((*this)(i,j) != 0) 3022 return false; 3023 } 3024 return true; 3025 } 3026 3027 /*! \brief Returns true if this Matrix is square and has no 3028 * inverse. 3029 * 3030 * \see isSquare() 3031 * \see operator~() 3032 */ isSingular()3033 inline bool isSingular() const 3034 { 3035 if (! Base::isSquare() || Base::isNull()) 3036 return false; 3037 if ((~(*this)) == (T_type) 0) 3038 return true; 3039 return false; 3040 } 3041 3042 /* Square and t(M) = M(inv(M) * t(M) == I */ 3043 /*! Returns true if this Matrix is equal to its transpose. 3044 * 3045 * A Matrix is symmetric when \f$M^T = M\f$ or, equivalently, 3046 * \f$M^{-1} M^T = I\f$. In simple terms, this means that the 3047 * (i,j)th element of the Matrix is equal to the (j, i)th 3048 * element for all i, j. 3049 * 3050 * \see isSkewSymmetric() 3051 */ isSymmetric()3052 inline bool isSymmetric () const 3053 { 3054 if (! Base::isSquare()) 3055 return false; 3056 // No point in order optimizing here 3057 for (uint i = 1; i < Base::rows(); ++i) 3058 for (uint j = 0; j < i; ++j) 3059 if ((*this)(i, j) != (*this)(j, i)) 3060 return false; 3061 3062 return true; 3063 } 3064 3065 /* The matrix is square and t(A) = -A */ 3066 /*! Returns true if this Matrix is equal to its negated 3067 * transpose. 3068 * 3069 * A Matrix is skew symmetric when \f$-M^T = M\f$ or, 3070 * equivalently, \f$-M^{-1} M^T = I\f$. In simple terms, this 3071 * means that the (i, j)th element of the Matrix is equal to the 3072 * negation of the (j, i)th element for all i, j. 3073 * 3074 * \see isSymmetric() 3075 */ isSkewSymmetric()3076 inline bool isSkewSymmetric () const 3077 { 3078 if (! Base::isSquare()) 3079 return false; 3080 // No point in order optimizing here 3081 for (uint i = 1; i < Base::rows(); ++i) 3082 for (uint j = 0; j < i; ++j) 3083 if ((*this)(i, j) != 0 - (*this)(j, i)) 3084 return false; 3085 3086 return true; 3087 } 3088 3089 /*! \brief Test Matrix equality. 3090 * 3091 * This method returns true if all of \a M's elements are equal 3092 * to those in this Matrix. To be equal, two matrices must 3093 * be of the same dimension. Matrices with differing 3094 * matrix_order or matrix_style may equal one another. 3095 * 3096 * \param M The Matrix to test equality with. 3097 * 3098 * \see equals(T_type x) const 3099 * \see operator==(const Matrix<T_type, L_ORDER, L_STYLE>& lhs, const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 3100 */ 3101 template <matrix_order O, matrix_style S> 3102 inline bool equals(const Matrix<T_type,O,S> & M)3103 equals(const Matrix<T_type, O, S>& M) const 3104 { 3105 if (data_ == M.getArray() && STYLE == Concrete && S == Concrete) 3106 return true; 3107 else if (data_ == M.getArray() && Base::rows() == M.rows() 3108 && Base::cols() == M.cols()) { 3109 return true; 3110 } else if (this->isNull() && M.isNull()) 3111 return true; 3112 else if (Base::rows() != M.rows() || Base::cols() != M.cols()) 3113 return false; 3114 3115 return std::equal(begin_f(), end_f(), 3116 M.template begin_f<ORDER>()); 3117 } 3118 3119 /*! \brief Test Matrix equality. 3120 * 3121 * This method returns true if all of the elements in this 3122 * Matrix are equal to \a x. 3123 * 3124 * \param x The scalar value to test equality with. 3125 * 3126 * \see equals(const Matrix<T_type, O, S>& M) const 3127 * \see operator==(const Matrix<T_type, L_ORDER, L_STYLE>& lhs, const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 3128 */ 3129 inline bool equals(T_type x)3130 equals(T_type x) const 3131 { 3132 using std::placeholders::_1; 3133 const_forward_iterator last = end_f(); 3134 return (last == std::find_if(begin_f(), last, 3135 std::bind(std::not_equal_to<T_type>(), x, _1))); 3136 } 3137 3138 3139 /**** OTHER UTILITIES ****/ 3140 3141 /*! \brief Returns a pointer to this Matrix's internal data 3142 * array. 3143 * 3144 * This method returns a pointer to the internal data array 3145 * contained within the DataBlock that this Matrix references. 3146 * 3147 * \warning It is generally a bad idea to use this method. We 3148 * provide it only for convenience. Please note that, when 3149 * working with views, the internal data array may not even be 3150 * stored in this Matrix's matrix_order. Furthermore, data 3151 * encapsulated by a view will generally not be contiguous 3152 * within the data array. It this is a concrete Matrix, 3153 * getArray() will always return a pointer to a data array 3154 * ordered like this Matrix and in contiguous storage. 3155 */ getArray()3156 inline T_type* getArray () const 3157 { 3158 return data_; 3159 } 3160 3161 /*! \brief Saves a Matrix to disk. 3162 * 3163 * This method writes the contents of this Matrix to the file 3164 * specified by \a path. The user can control file overwriting 3165 * with \a flag. The parameter \a header controls the output 3166 * style. When one sets \a header to true the Matrix is written 3167 * as a space-separated list of values, with the number of rows 3168 * and columns placed in the first two positions in the list. 3169 * If header is set to false, the file is written as a space 3170 * separated ascii block, with end-of-lines indicating ends of 3171 * rows. The Matrix is always written out in row-major order. 3172 * 3173 * \param path The name of the file to write. 3174 * \param flag Overwrite flag taking values 'a': append, 'o': 3175 * overwrite, or 'n': do not replace. 3176 * \param header Boolean value indicating whether to write as a 3177 * flat list with dimension header or as a rectangular block. 3178 * 3179 * \see Matrix(const std::string& file) 3180 * \see operator>>(std::istream& is, Matrix<T,O,S>& M) 3181 * 3182 * \throw scythe_invalid_arg (Level 0) 3183 * \throw scythe_file_error (Level 0) 3184 */ 3185 inline void 3186 save (const std::string& path, const char flag = 'n', 3187 const bool header = false) const 3188 { 3189 std::ofstream out; 3190 if (flag == 'n') { 3191 std::fstream temp(path.c_str(), std::ios::in); 3192 if (! temp) 3193 out.open(path.c_str(), std::ios::out); 3194 else { 3195 temp.close(); 3196 SCYTHE_THROW(scythe_file_error, "Cannot overwrite file " 3197 << path << " when flag = n"); 3198 } 3199 } else if (flag == 'o') 3200 out.open(path.c_str(), std::ios::out | std::ios::trunc); 3201 else if (flag == 'a') 3202 out.open(path.c_str(), std::ios::out | std::ios::app); 3203 else 3204 SCYTHE_THROW(scythe_invalid_arg, "Invalid flag: " << flag); 3205 3206 if (! out) 3207 SCYTHE_THROW(scythe_file_error, 3208 "Could not open file " << path); 3209 3210 if (header) { 3211 out << Base::rows() << " " << Base::cols(); 3212 for (uint i = 0; i < Base::size(); ++i) 3213 out << " " << (*this)[i]; 3214 out << std::endl; 3215 } else { 3216 for (uint i = 0; i < Base::rows(); ++i) { 3217 for (uint j = 0; j < Base::cols(); ++j) 3218 out << (*this)(i,j) << " "; 3219 out << "\n"; 3220 } 3221 } 3222 out.close(); 3223 } 3224 3225 3226 /**** ITERATOR FACTORIES ****/ 3227 3228 /* TODO Write some cpp macro code to reduce this to something 3229 * manageable. 3230 */ 3231 3232 /* Random Access Iterator Factories */ 3233 3234 /* Generalized versions */ 3235 3236 /*! \brief Get an iterator pointing to the start of a Matrix. 3237 * 3238 * This is a factory that returns a random_access_iterator that 3239 * points to the first element in the given Matrix. 3240 * 3241 * This is a general template of this function. It allows the 3242 * user to generate iterators that iterate over the given Matrix 3243 * in any order through an explicit template instantiation. 3244 */ 3245 template <matrix_order I_ORDER> 3246 inline 3247 matrix_random_access_iterator<T_type, I_ORDER, ORDER, STYLE> begin()3248 begin () 3249 { 3250 return matrix_random_access_iterator<T_type, I_ORDER, ORDER, 3251 STYLE>(*this); 3252 } 3253 3254 /*! \brief Get an iterator pointing to the start of a Matrix. 3255 * 3256 * This is a factory that returns a 3257 * const_random_access_iterator that 3258 * points to the first element in the given Matrix. 3259 * 3260 * This is a general template of this function. It allows the 3261 * user to generate iterators that iterate over the given Matrix 3262 * in any order through an explicit template instantiation. 3263 */ 3264 template <matrix_order I_ORDER> 3265 inline 3266 const_matrix_random_access_iterator<T_type, I_ORDER, ORDER, STYLE> begin()3267 begin() const 3268 { 3269 return const_matrix_random_access_iterator<T_type, I_ORDER, 3270 ORDER, STYLE> 3271 (*this); 3272 } 3273 3274 /*! \brief Get an iterator pointing to the end of a Matrix. 3275 * 3276 * This is a factory that returns a 3277 * matrix_random_access_iterator that 3278 * points to just after the last element in the given Matrix. 3279 * 3280 * This is a general template of this function. It allows the 3281 * user to generate iterators that iterate over the given Matrix 3282 * in any order through an explicit template instantiation. 3283 */ 3284 template <matrix_order I_ORDER> 3285 inline 3286 matrix_random_access_iterator<T_type, I_ORDER, ORDER, STYLE> end()3287 end () 3288 { 3289 return (begin<I_ORDER>() + Base::size()); 3290 } 3291 3292 /*! \brief Get an iterator pointing to the end of a Matrix. 3293 * 3294 * This is a factory that returns an 3295 * const_matrix_random_access_iterator that 3296 * points to just after the last element in the given Matrix. 3297 * 3298 * This is a general template of this function. It allows the 3299 * user to generate iterators that iterate over the given Matrix 3300 * in any order through an explicit template instantiation. 3301 */ 3302 template <matrix_order I_ORDER> 3303 inline 3304 const_matrix_random_access_iterator<T_type, I_ORDER, ORDER, STYLE> end()3305 end () const 3306 { 3307 return (begin<I_ORDER>() + Base::size()); 3308 } 3309 3310 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3311 * 3312 * This is a factory that returns a reverse 3313 * matrix_random_access_iterator that 3314 * points to the last element in the given Matrix. 3315 * 3316 * This is a general template of this function. It allows the 3317 * user to generate iterators that iterate over the given Matrix 3318 * in any order through an explicit template instantiation. 3319 */ 3320 template <matrix_order I_ORDER> 3321 inline std::reverse_iterator<matrix_random_access_iterator<T_type, 3322 I_ORDER, ORDER, STYLE> > rbegin()3323 rbegin() 3324 { 3325 return std::reverse_iterator<matrix_random_access_iterator 3326 <T_type, I_ORDER, ORDER, STYLE> > 3327 (end<I_ORDER>()); 3328 } 3329 3330 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3331 * 3332 * This is a factory that returns a reverse 3333 * const_matrix_random_access_iterator that points to the last 3334 * element in the given Matrix. 3335 * 3336 * This is a general template of this function. It allows the 3337 * user to generate iterators that iterate over the given Matrix 3338 * in any order through an explicit template instantiation. 3339 */ 3340 template <matrix_order I_ORDER> 3341 inline 3342 std::reverse_iterator<const_matrix_random_access_iterator 3343 <T_type, I_ORDER, ORDER, STYLE> > rbegin()3344 rbegin() const 3345 { 3346 return std::reverse_iterator<const_matrix_random_access_iterator 3347 <T_type, I_ORDER, ORDER, STYLE> > 3348 (end<I_ORDER>()); 3349 } 3350 3351 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3352 * 3353 * This is a factory that returns a reverse 3354 * matrix_random_access_iterator 3355 * that points to the just before the first element in the given 3356 * Matrix. 3357 * 3358 * This is a general template of this function. It allows the 3359 * user to generate iterators that iterate over the given Matrix 3360 * in any order through an explicit template instantiation. 3361 */ 3362 template <matrix_order I_ORDER> 3363 inline std::reverse_iterator<matrix_random_access_iterator 3364 <T_type, I_ORDER, ORDER, STYLE> > rend()3365 rend() 3366 { 3367 return std::reverse_iterator<matrix_random_access_iterator 3368 <T_type, I_ORDER, ORDER, STYLE> > 3369 (begin<I_ORDER>()); 3370 } 3371 3372 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3373 * 3374 * This is a factory that returns a reverse 3375 * const_matrix_random_access_iterator that points to the just 3376 * before the first element in the given Matrix. 3377 * 3378 * This is a general template of this function. It allows the 3379 * user to generate iterators that iterate over the given Matrix 3380 * in any order through an explicit template instantiation. 3381 */ 3382 template <matrix_order I_ORDER> 3383 inline 3384 std::reverse_iterator<const_matrix_random_access_iterator 3385 <T_type, I_ORDER, ORDER, STYLE> > rend()3386 rend() const 3387 { 3388 return std::reverse_iterator<const_matrix_random_access_iterator 3389 <T_type, I_ORDER, ORDER, STYLE> > 3390 (begin<I_ORDER>()); 3391 } 3392 3393 /* Specific versions --- the generalized versions force you 3394 * choose the ordering explicitly. These definitions set up 3395 * in-order iteration as a default */ 3396 3397 /*! \brief Get an iterator pointing to the start of a Matrix. 3398 * 3399 * This is a factory that returns a Matrix::iterator that 3400 * points to the first element in the given Matrix. 3401 * 3402 * This is the default template of this function. It allows the 3403 * user to generate iterators of a given Matrix without 3404 * explicitly stating the order of iteration. The iterator 3405 * returned by this function always iterates in the same order 3406 * as the given Matrix' matrix_order. 3407 */ begin()3408 inline iterator begin () 3409 { 3410 return iterator(*this); 3411 } 3412 3413 /*! \brief Get an iterator pointing to the start of a Matrix. 3414 * 3415 * This is a factory that returns a Matrix::const_iterator that 3416 * points to the first element in the given Matrix. 3417 * 3418 * This is the default template of this function. It allows the 3419 * user to generate iterators of a given Matrix without 3420 * explicitly stating the order of iteration. The iterator 3421 * returned by this function always iterates in the same order 3422 * as the given Matrix' matrix_order. 3423 */ begin()3424 inline const_iterator begin() const 3425 { 3426 return const_iterator (*this); 3427 } 3428 3429 /*! \brief Get an iterator pointing to the end of a Matrix. 3430 * 3431 * This is a factory that returns an Matrix::iterator that 3432 * points to just after the last element in the given Matrix. 3433 * 3434 * This is the default template of this function. It allows the 3435 * user to generate iterators of a given Matrix without 3436 * explicitly stating the order of iteration. The iterator 3437 * returned by this function always iterates in the same order 3438 * as the given Matrix' matrix_order. 3439 */ end()3440 inline iterator end () 3441 { 3442 return (begin() + Base::size()); 3443 } 3444 3445 /*! \brief Get an iterator pointing to the end of a Matrix. 3446 * 3447 * This is a factory that returns an Matrix::const_iterator that 3448 * points to just after the last element in the given Matrix. 3449 * 3450 * This is the default template of this function. It allows the 3451 * user to generate iterators of a given Matrix without 3452 * explicitly stating the order of iteration. The iterator 3453 * returned by this function always iterates in the same order 3454 * as the given Matrix' matrix_order. 3455 */ 3456 inline end()3457 const_iterator end () const 3458 { 3459 return (begin() + Base::size()); 3460 } 3461 3462 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3463 * 3464 * This is a factory that returns a Matrix::reverse_iterator that 3465 * points to the last element in the given Matrix. 3466 * 3467 * This is the default template of this function. It allows the 3468 * user to generate iterators of a given Matrix without 3469 * explicitly stating the order of iteration. The iterator 3470 * returned by this function always iterates in the same order 3471 * as the given Matrix' matrix_order. 3472 */ rbegin()3473 inline reverse_iterator rbegin() 3474 { 3475 return reverse_iterator (end()); 3476 } 3477 3478 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3479 * 3480 * This is a factory that returns a 3481 * Matrix::const_reverse_iterator that points to the last 3482 * element in the given Matrix. 3483 * 3484 * This is the default template of this function. It allows the 3485 * user to generate iterators of a given Matrix without 3486 * explicitly stating the order of iteration. The iterator 3487 * returned by this function always iterates in the same order 3488 * as the given Matrix' matrix_order. 3489 */ rbegin()3490 inline const_reverse_iterator rbegin() const 3491 { 3492 return const_reverse_iterator (end()); 3493 } 3494 3495 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3496 * 3497 * This is a factory that returns a Matrix::reverse_iterator 3498 * that points to the just before the first element in the given 3499 * Matrix. 3500 * 3501 * This is the default template of this function. It allows the 3502 * user to generate iterators of a given Matrix without 3503 * explicitly stating the order of iteration. The iterator 3504 * returned by this function always iterates in the same order 3505 * as the given Matrix' matrix_order. 3506 */ rend()3507 inline reverse_iterator rend() 3508 { 3509 return reverse_iterator (begin()); 3510 } 3511 3512 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3513 * 3514 * This is a factory that returns a Matrix::const_reverse_iterator 3515 * that points to the just before the first element in the given 3516 * Matrix. 3517 * 3518 * This is the default template of this function. It allows the 3519 * user to generate iterators of a given Matrix without 3520 * explicitly stating the order of iteration. The iterator 3521 * returned by this function always iterates in the same order 3522 * as the given Matrix' matrix_order. 3523 */ rend()3524 inline const_reverse_iterator rend() const 3525 { 3526 return const_reverse_iterator (begin()); 3527 } 3528 3529 /* Forward Iterator Factories */ 3530 3531 /* Generalized versions */ 3532 3533 /*! \brief Get an iterator pointing to the start of a Matrix. 3534 * 3535 * This is a factory that returns a matrix_forward_iterator that 3536 * points to the first element in the given Matrix. 3537 * 3538 * This is a general template of this function. It allows the 3539 * user to generate iterators that iterate over the given Matrix 3540 * in any order through an explicit template instantiation. 3541 */ 3542 template <matrix_order I_ORDER> 3543 inline 3544 matrix_forward_iterator<T_type, I_ORDER, ORDER, STYLE> begin_f()3545 begin_f () 3546 { 3547 return matrix_forward_iterator<T_type, I_ORDER, ORDER, 3548 STYLE>(*this); 3549 } 3550 3551 /*! \brief Get an iterator pointing to the start of a Matrix. 3552 * 3553 * This is a factory that returns a 3554 * const_matrix_forward_iterator that 3555 * points to the first element in the given Matrix. 3556 * 3557 * This is a general template of this function. It allows the 3558 * user to generate iterators that iterate over the given Matrix 3559 * in any order through an explicit template instantiation. 3560 */ 3561 template <matrix_order I_ORDER> 3562 inline 3563 const_matrix_forward_iterator <T_type, I_ORDER, ORDER, STYLE> begin_f()3564 begin_f () const 3565 { 3566 return const_matrix_forward_iterator <T_type, I_ORDER, 3567 ORDER, STYLE> 3568 (*this); 3569 } 3570 3571 /*! \brief Get an iterator pointing to the end of a Matrix. 3572 * 3573 * This is a factory that returns an matrix_forward_iterator that 3574 * points to just after the last element in the given Matrix. 3575 * 3576 * This is a general template of this function. It allows the 3577 * user to generate iterators that iterate over the given Matrix 3578 * in any order through an explicit template instantiation. 3579 */ 3580 template <matrix_order I_ORDER> 3581 inline 3582 matrix_forward_iterator<T_type, I_ORDER, ORDER, STYLE> end_f()3583 end_f () 3584 { 3585 return (begin_f<I_ORDER>().set_end()); 3586 } 3587 3588 /*! \brief Get an iterator pointing to the end of a Matrix. 3589 * 3590 * This is a factory that returns an 3591 * const_matrix_forward_iterator that points to just after the 3592 * last element in the given Matrix. 3593 * 3594 * This is a general template of this function. It allows the 3595 * user to generate iterators that iterate over the given Matrix 3596 * in any order through an explicit template instantiation. 3597 */ 3598 template <matrix_order I_ORDER> 3599 inline 3600 const_matrix_forward_iterator<T_type, I_ORDER, ORDER, STYLE> end_f()3601 end_f () const 3602 { 3603 return (begin_f<I_ORDER>().set_end()); 3604 } 3605 3606 /* Default Versions */ 3607 3608 /*! \brief Get an iterator pointing to the start of a Matrix. 3609 * 3610 * This is a factory that returns a Matrix::forward_iterator that 3611 * points to the first element in the given Matrix. 3612 * 3613 * This is the default template of this function. It allows the 3614 * user to generate iterators of a given Matrix without 3615 * explicitly stating the order of iteration. The iterator 3616 * returned by this function always iterates in the same order 3617 * as the given Matrix' matrix_order. 3618 */ begin_f()3619 inline forward_iterator begin_f () 3620 { 3621 return forward_iterator(*this); 3622 } 3623 3624 /*! \brief Get an iterator pointing to the start of a Matrix. 3625 * 3626 * This is a factory that returns a 3627 * Matrix::const_forward_iterator that points to the first 3628 * element in the given Matrix. 3629 * 3630 * This is the default template of this function. It allows the 3631 * user to generate iterators of a given Matrix without 3632 * explicitly stating the order of iteration. The iterator 3633 * returned by this function always iterates in the same order 3634 * as the given Matrix' matrix_order. 3635 */ begin_f()3636 inline const_forward_iterator begin_f () const 3637 { 3638 return const_forward_iterator (*this); 3639 } 3640 3641 /*! \brief Get an iterator pointing to the end of a Matrix. 3642 * 3643 * This is a factory that returns an Matrix::forward_iterator that 3644 * points to just after the last element in the given Matrix. 3645 * 3646 * This is the default template of this function. It allows the 3647 * user to generate iterators of a given Matrix without 3648 * explicitly stating the order of iteration. The iterator 3649 * returned by this function always iterates in the same order 3650 * as the given Matrix' matrix_order. 3651 */ end_f()3652 inline forward_iterator end_f () 3653 { 3654 return (begin_f().set_end()); 3655 } 3656 3657 /*! \brief Get an iterator pointing to the end of a Matrix. 3658 * 3659 * This is a factory that returns an 3660 * Matrix::const_forward_iterator that points to just after the 3661 * last element in the given Matrix. 3662 * 3663 * This is the default template of this function. It allows the 3664 * user to generate iterators of a given Matrix without 3665 * explicitly stating the order of iteration. The iterator 3666 * returned by this function always iterates in the same order 3667 * as the given Matrix' matrix_order. 3668 */ 3669 inline end_f()3670 const_forward_iterator end_f () const 3671 { 3672 return (begin_f().set_end()); 3673 } 3674 3675 /* Bidirectional Iterator Factories */ 3676 3677 /* Generalized versions */ 3678 3679 /*! \brief Get an iterator pointing to the start of a Matrix. 3680 * 3681 * This is a factory that returns a 3682 * matrix_bidirectional_iterator that 3683 * points to the first element in the given Matrix. 3684 * 3685 * This is a general template of this function. It allows the 3686 * user to generate iterators that iterate over the given Matrix 3687 * in any order through an explicit template instantiation. 3688 */ 3689 template <matrix_order I_ORDER> 3690 inline 3691 matrix_bidirectional_iterator<T_type, I_ORDER, ORDER, STYLE> begin_bd()3692 begin_bd () 3693 { 3694 return matrix_bidirectional_iterator<T_type, I_ORDER, ORDER, 3695 STYLE>(*this); 3696 } 3697 3698 /*! \brief Get an iterator pointing to the start of a Matrix. 3699 * 3700 * This is a factory that returns a 3701 * const_matrix_bidirectional_iterator that points to the first 3702 * element in the given Matrix. 3703 * 3704 * This is a general template of this function. It allows the 3705 * user to generate iterators that iterate over the given Matrix 3706 * in any order through an explicit template instantiation. 3707 */ 3708 template <matrix_order I_ORDER> 3709 inline 3710 const_matrix_bidirectional_iterator<T_type, I_ORDER, ORDER, STYLE> begin_bd()3711 begin_bd () const 3712 { 3713 return const_matrix_bidirectional_iterator<T_type, I_ORDER, 3714 ORDER, STYLE> 3715 (*this); 3716 } 3717 3718 /*! \brief Get an iterator pointing to the end of a Matrix. 3719 * 3720 * This is a factory that returns an 3721 * matrix_bidirectional_iterator that points to just after the 3722 * last element in the given Matrix. 3723 * 3724 * This is a general template of this function. It allows the 3725 * user to generate iterators that iterate over the given Matrix 3726 * in any order through an explicit template instantiation. 3727 */ 3728 template <matrix_order I_ORDER> 3729 inline 3730 matrix_bidirectional_iterator<T_type, I_ORDER, ORDER, STYLE> end_bd()3731 end_bd () 3732 { 3733 return (begin_bd<I_ORDER>().set_end()); 3734 } 3735 3736 /*! \brief Get an iterator pointing to the end of a Matrix. 3737 * 3738 * This is a factory that returns an 3739 * const_matrix_bidirectional_iterator that points to just after 3740 * the last element in the given Matrix. 3741 * 3742 * This is a general template of this function. It allows the 3743 * user to generate iterators that iterate over the given Matrix 3744 * in any order through an explicit template instantiation. 3745 */ 3746 template <matrix_order I_ORDER> 3747 inline 3748 const_matrix_bidirectional_iterator<T_type, I_ORDER, ORDER, STYLE> end_bd()3749 end_bd () const 3750 { 3751 return (begin_bd<I_ORDER>().set_end()); 3752 } 3753 3754 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3755 * 3756 * This is a factory that returns a reverse 3757 * matrix_bidirectional_iterator that points to the last element 3758 * in the given Matrix. 3759 * 3760 * This is a general template of this function. It allows the 3761 * user to generate iterators that iterate over the given Matrix 3762 * in any order through an explicit template instantiation. 3763 */ 3764 template <matrix_order I_ORDER> 3765 inline std::reverse_iterator<matrix_bidirectional_iterator<T_type, 3766 I_ORDER, ORDER, STYLE> > rbegin_bd()3767 rbegin_bd () 3768 { 3769 return std::reverse_iterator<matrix_bidirectional_iterator 3770 <T_type, I_ORDER, ORDER, STYLE> > 3771 (end_bd<I_ORDER>()); 3772 } 3773 3774 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3775 * 3776 * This is a factory that returns a reverse 3777 * const_matrix_bidirectional_iterator that points to the last 3778 * element in the given Matrix. 3779 * 3780 * This is a general template of this function. It allows the 3781 * user to generate iterators that iterate over the given Matrix 3782 * in any order through an explicit template instantiation. 3783 */ 3784 template <matrix_order I_ORDER> 3785 inline 3786 std::reverse_iterator<const_matrix_bidirectional_iterator 3787 <T_type, I_ORDER, ORDER, STYLE> > rbegin_bd()3788 rbegin_bd () const 3789 { 3790 return std::reverse_iterator<const_matrix_bidirectional_iterator 3791 <T_type, I_ORDER, ORDER, STYLE> > 3792 (end_bd<I_ORDER>()); 3793 } 3794 3795 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3796 * 3797 * This is a factory that returns a reverse 3798 * matrix_bidirectional_iterator that points to the just before 3799 * the first element in the given 3800 * Matrix. 3801 * 3802 * This is a general template of this function. It allows the 3803 * user to generate iterators that iterate over the given Matrix 3804 * in any order through an explicit template instantiation. 3805 */ 3806 template <matrix_order I_ORDER> 3807 inline std::reverse_iterator<matrix_bidirectional_iterator 3808 <T_type, I_ORDER, ORDER, STYLE> > rend_bd()3809 rend_bd () 3810 { 3811 return std::reverse_iterator<matrix_bidirectional_iterator 3812 <T_type, I_ORDER, ORDER, STYLE> > 3813 (begin_bd<I_ORDER>()); 3814 } 3815 3816 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3817 * 3818 * This is a factory that returns a reverse 3819 * const_matrix_bidirectional_iterator that points to the just 3820 * before the first element in the given Matrix. 3821 * 3822 * This is a general template of this function. It allows the 3823 * user to generate iterators that iterate over the given Matrix 3824 * in any order through an explicit template instantiation. 3825 */ 3826 template <matrix_order I_ORDER> 3827 inline 3828 std::reverse_iterator<const_matrix_bidirectional_iterator 3829 <T_type, I_ORDER, ORDER, STYLE> > rend_bd()3830 rend_bd () const 3831 { 3832 return std::reverse_iterator<const_matrix_bidirectional_iterator 3833 <T_type, I_ORDER, ORDER, STYLE> > 3834 (begin_bd<I_ORDER>()); 3835 } 3836 3837 /* Specific versions --- the generalized versions force you 3838 * choose the ordering explicitly. These definitions set up 3839 * in-order iteration as a default */ 3840 3841 /*! \brief Get an iterator pointing to the start of a Matrix. 3842 * 3843 * This is a factory that returns a 3844 * Matrix::bidirectional_iterator that points to the first 3845 * element in the given Matrix. 3846 * 3847 * This is the default template of this function. It allows the 3848 * user to generate iterators of a given Matrix without 3849 * explicitly stating the order of iteration. The iterator 3850 * returned by this function always iterates in the same order 3851 * as the given Matrix' matrix_order. 3852 */ begin_bd()3853 inline bidirectional_iterator begin_bd () 3854 { 3855 return bidirectional_iterator(*this); 3856 } 3857 3858 /*! \brief Get an iterator pointing to the start of a Matrix. 3859 * 3860 * This is a factory that returns a 3861 * Matrix::const_bidirectional_iterator that points to the first 3862 * element in the given Matrix. 3863 * 3864 * This is the default template of this function. It allows the 3865 * user to generate iterators of a given Matrix without 3866 * explicitly stating the order of iteration. The iterator 3867 * returned by this function always iterates in the same order 3868 * as the given Matrix' matrix_order. 3869 */ begin_bd()3870 inline const_bidirectional_iterator begin_bd() const 3871 { 3872 return const_bidirectional_iterator (*this); 3873 } 3874 3875 /*! \brief Get an iterator pointing to the end of a Matrix. 3876 * 3877 * This is a factory that returns an 3878 * Matrix::bidirectional_iterator that points to just after the 3879 * last element in the given Matrix. 3880 * 3881 * This is the default template of this function. It allows the 3882 * user to generate iterators of a given Matrix without 3883 * explicitly stating the order of iteration. The iterator 3884 * returned by this function always iterates in the same order 3885 * as the given Matrix' matrix_order. 3886 */ end_bd()3887 inline bidirectional_iterator end_bd () 3888 { 3889 return (begin_bd().set_end()); 3890 } 3891 3892 /*! \brief Get an iterator pointing to the end of a Matrix. 3893 * 3894 * This is a factory that returns an Matrix::const_bidirectional 3895 * iterator that points to just after the last element in the 3896 * given Matrix. 3897 * 3898 * This is the default template of this function. It allows the 3899 * user to generate iterators of a given Matrix without 3900 * explicitly stating the order of iteration. The iterator 3901 * returned by this function always iterates in the same order 3902 * as the given Matrix' matrix_order. 3903 */ 3904 inline end_bd()3905 const_bidirectional_iterator end_bd () const 3906 { 3907 return (begin_bd().set_end()); 3908 } 3909 3910 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3911 * 3912 * This is a factory that returns a 3913 * Matrix::reverse_bidirectional_iterator that points to the 3914 * last element in the given Matrix. 3915 * 3916 * This is the default template of this function. It allows the 3917 * user to generate iterators of a given Matrix without 3918 * explicitly stating the order of iteration. The iterator 3919 * returned by this function always iterates in the same order 3920 * as the given Matrix' matrix_order. 3921 */ rbegin_bd()3922 inline reverse_bidirectional_iterator rbegin_bd() 3923 { 3924 return reverse_bidirectional_iterator (end_bd()); 3925 } 3926 3927 /*! \brief Get a reverse iterator pointing to the end of a Matrix. 3928 * 3929 * This is a factory that returns a 3930 * Matrix::const_reverse_bidirectional_iterator that points to 3931 * the last element in the given Matrix. 3932 * 3933 * This is the default template of this function. It allows the 3934 * user to generate iterators of a given Matrix without 3935 * explicitly stating the order of iteration. The iterator 3936 * returned by this function always iterates in the same order 3937 * as the given Matrix' matrix_order. 3938 */ rbegin_bd()3939 inline const_reverse_bidirectional_iterator rbegin_bd () const 3940 { 3941 return const_reverse_bidirectional_iterator (end_bd()); 3942 } 3943 3944 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3945 * 3946 * This is a factory that returns a 3947 * Matrix::reverse_bidirectional_iterator that points to the 3948 * just before the first element in the given Matrix. 3949 * 3950 * This is the default template of this function. It allows the 3951 * user to generate iterators of a given Matrix without 3952 * explicitly stating the order of iteration. The iterator 3953 * returned by this function always iterates in the same order 3954 * as the given Matrix' matrix_order. 3955 */ rend_bd()3956 inline reverse_bidirectional_iterator rend_bd () 3957 { 3958 return reverse_bidirectional_iterator (begin_bd()); 3959 } 3960 3961 /*! \brief Get a reverse iterator pointing to the start of a Matrix. 3962 * 3963 * This is a factory that returns a 3964 * Matrix::const_reverse_bidirectional_iterator that points to 3965 * the just before the first element in the given Matrix. 3966 * 3967 * This is the default template of this function. It allows the 3968 * user to generate iterators of a given Matrix without 3969 * explicitly stating the order of iteration. The iterator 3970 * returned by this function always iterates in the same order 3971 * as the given Matrix' matrix_order. 3972 */ rend_bd()3973 inline const_reverse_iterator rend_bd () const 3974 { 3975 return const_reverse_bidirectiona_iterator (begin_bd()); 3976 } 3977 3978 protected: 3979 /**** INSTANCE VARIABLES ****/ 3980 3981 /* I know the point of C++ is to force you to write 20 times 3982 * more code than should be necessary but "using" inherited ivs 3983 * is just stupid. 3984 */ 3985 using DBRef::data_; // refer to inherited data pointer directly 3986 using Base::rows_; // " # of rows directly 3987 using Base::cols_; // " # of cols directly 3988 3989 }; // end class Matrix 3990 3991 /**** EXTERNAL OPERATORS ****/ 3992 3993 /* External operators include a range of binary matrix operations 3994 * such as tests for equality, and arithmetic. Style 3995 * (concrete/view) of the returned matrix is that of the left hand 3996 * side parameter by default 3997 * 3998 * There is also a question of the ordering of the returned matrix. 3999 * We adopt the convention of returning a matrix ordered like that 4000 * of the left hand side argument, by default. 4001 * 4002 * Whenever there is only one matrix argument (lhs is scalar) we use 4003 * its order and style as the default. 4004 * 4005 * A general template version of each operator also exists and users 4006 * can coerce the return type to whatever they prefer using some 4007 * ugly syntax; ex: 4008 * 4009 * Matrix<> A; ... Matrix<double, Row> B = operator*<Row,Concrete> 4010 * (A, A); 4011 * 4012 * In general, the matrix class copy constructor will quietly 4013 * convert whatever matrix template is returned to the type of the 4014 * matrix it is being copied into on return, but one might want to 4015 * specify the type for objects that only exist for a second (ex: 4016 * (operator*<Row,Concrete>(A, A)).begin()). Also, note that the 4017 * fact that we return concrete matrices by default does not 4018 * preclude the user from taking advantage of fast view copies. It 4019 * is the template type of the object being copy-constructed that 4020 * matters---in terms of underlying implementation all matrices are 4021 * views, concrete matrices just maintain a particular policy. 4022 * 4023 * TODO Consider the best type for scalar args to these functions. 4024 * For the most part, these will be primitives---doubles mostly. 4025 * Passing these by reference is probably less efficient than 4026 * passing by value. But, for user-defined types pass-by-reference 4027 * might be the way to go and the cost in this case will be much 4028 * higher than the value-reference trade-off for primitives. Right 4029 * now we use pass-by-reference but we might reconsider... 4030 */ 4031 4032 /**** ARITHMETIC OPERATORS ****/ 4033 4034 /* These macros provide templates for the basic definitions required 4035 * for all of the binary operators. Each operator requires 6 4036 * definitions. First, a general matrix definition must be 4037 * provided. This definition can return a matrix of a different 4038 * style and order than its arguments but can only be called if its 4039 * template type is explicitly specified. The actual logic of the 4040 * operator should be specified within this function. The macros 4041 * provide definitions for the other 5 required templates, one 4042 * default matrix by matrix, general matrix by scalar, default 4043 * matrix by scalar, general scalar by matrix, default scalar by 4044 * matrix. The default versions call the more general versions with 4045 * such that they will return concrete matrices with order equal to 4046 * the left-hand (or only) matrix passed to the default version. 4047 * 4048 */ 4049 4050 #define SCYTHE_BINARY_OPERATOR_DMM(OP) \ 4051 template <matrix_order ORDER, matrix_style L_STYLE, \ 4052 matrix_order R_ORDER, matrix_style R_STYLE, \ 4053 typename T_type> \ 4054 inline Matrix<T_type, ORDER, Concrete> \ 4055 OP (const Matrix<T_type, ORDER, L_STYLE>& lhs, \ 4056 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4057 { \ 4058 return OP <T_type, ORDER, Concrete>(lhs, rhs); \ 4059 } 4060 4061 #define SCYTHE_BINARY_OPERATOR_GMS(OP) \ 4062 template <typename T_type, matrix_order ORDER, matrix_style STYLE, \ 4063 matrix_order L_ORDER, matrix_style L_STYLE> \ 4064 inline Matrix<T_type, ORDER, STYLE> \ 4065 OP (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, \ 4066 const typename Matrix<T_type>::ttype &rhs) \ 4067 { \ 4068 return (OP <T_type, ORDER, STYLE> \ 4069 (lhs, Matrix<T_type, L_ORDER>(rhs))); \ 4070 } 4071 4072 #define SCYTHE_BINARY_OPERATOR_DMS(OP) \ 4073 template <matrix_order ORDER, matrix_style L_STYLE, \ 4074 typename T_type> \ 4075 inline Matrix<T_type, ORDER, Concrete> \ 4076 OP (const Matrix<T_type, ORDER, L_STYLE>& lhs, \ 4077 const typename Matrix<T_type>::ttype &rhs) \ 4078 { \ 4079 return (OP <T_type, ORDER, Concrete> (lhs, rhs)); \ 4080 } 4081 4082 #define SCYTHE_BINARY_OPERATOR_GSM(OP) \ 4083 template <typename T_type, matrix_order ORDER, matrix_style STYLE, \ 4084 matrix_order R_ORDER, matrix_style R_STYLE> \ 4085 inline Matrix<T_type, ORDER, STYLE> \ 4086 OP (const typename Matrix<T_type>::ttype &lhs, \ 4087 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4088 { \ 4089 return (OP <T_type, ORDER, STYLE> \ 4090 (Matrix<T_type, R_ORDER>(lhs), rhs)); \ 4091 } 4092 4093 #define SCYTHE_BINARY_OPERATOR_DSM(OP) \ 4094 template <matrix_order ORDER, matrix_style R_STYLE, \ 4095 typename T_type> \ 4096 inline Matrix<T_type, ORDER, Concrete> \ 4097 OP (const typename Matrix<T_type>::ttype &lhs, \ 4098 const Matrix<T_type, ORDER, R_STYLE>& rhs) \ 4099 { \ 4100 return (OP <T_type, ORDER, Concrete> (lhs, rhs)); \ 4101 } 4102 4103 #define SCYTHE_BINARY_OPERATOR_DEFS(OP) \ 4104 SCYTHE_BINARY_OPERATOR_DMM(OP) \ 4105 SCYTHE_BINARY_OPERATOR_GMS(OP) \ 4106 SCYTHE_BINARY_OPERATOR_DMS(OP) \ 4107 SCYTHE_BINARY_OPERATOR_GSM(OP) \ 4108 SCYTHE_BINARY_OPERATOR_DSM(OP) 4109 4110 /* Matrix multiplication */ 4111 4112 /* General template version. Must be called with operator*<> syntax 4113 */ 4114 4115 /* We provide two symmetric algorithms for matrix multiplication, 4116 * one for col-major and the other for row-major matrices. They are 4117 * designed to minimize cache misses.The decision is based on the 4118 * return type of the template so, when using matrices of multiple 4119 * orders, this can get ugly. These optimizations only really start 4120 * paying dividends as matrices get big, because cache misses are 4121 * rare with smaller matrices. 4122 */ 4123 4124 /*! \brief Multiply two matrices. 4125 * 4126 * This operator multiplies the matrices \a lhs and \a rhs together, 4127 * returning the result in a new Matrix object. This operator is 4128 * overloaded to provide both Matrix by Matrix multiplication and 4129 * Matrix by scalar multiplication. In the latter case, the scalar 4130 * on the left- or right-hand side of the operator is promoted to a 4131 * 1x1 Matrix and then multiplied with the Matrix on the other side 4132 * of the operator. In either case, the matrices must conform; that 4133 * is, the number of columns in the left-hand side argument must 4134 * equal the number of rows in the right-hand side argument. The 4135 * one exception is when one matrix is a scalar. In this case we 4136 * allow Matrix by scalar multiplication with the "*" operator that 4137 * is comparable to element-by-element multiplication of a Matrix by 4138 * a scalar value, for convenience. 4139 * 4140 * In addition, we define multiple templates of the overloaded 4141 * operator to provide maximal flexibility when working with 4142 * matrices with differing matrix_order and/or matrix_style. Each 4143 * version of the overloaded operator (Matrix by Matrix, scalar by 4144 * Matrix, and Matrix by scalar) provides both a default and 4145 * general behavior, using templates. By default, the returned 4146 * Matrix is concrete and has the same matrix_order as the 4147 * left-hand (or only) Matrix argument. Alternatively, one may 4148 * coerce the matrix_order and matrix_style of the returned Matrix 4149 * to preferred values by using the full template declaration of 4150 * the operator. 4151 * 4152 * Scythe will use LAPACK/BLAS routines to multiply concrete 4153 * column-major matrices of double-precision floating point 4154 * numbers if LAPACK/BLAS is available and you compile your 4155 * program with the SCYTHE_LAPACK flag enabled. 4156 * 4157 * \param lhs The left-hand-side Matrix or scalar. 4158 * \param rhs The right-hand-side Matrix or scalar. 4159 * 4160 * \see operator*(const Matrix<T_type, L_ORDER, L_STYLE>& lhs, const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 4161 * \see operator*(const Matrix<T_type, ORDER, L_STYLE>& lhs, const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 4162 * \see operator*(const Matrix<T_type, L_ORDER, L_STYLE>& lhs, const T_type& rhs) 4163 * \see operator*(const Matrix<T_type, ORDER, L_STYLE>& lhs, const T_type& rhs) 4164 * \see operator*(const T_type& lhs, const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 4165 * \see operator*(const T_type& lhs, const Matrix<T_type, ORDER, R_STYLE>& rhs) 4166 * 4167 * \throw scythe_conformation_error (Level 1) 4168 * \throw scythe_alloc_error (Level 1) 4169 */ 4170 4171 template <typename T_type, matrix_order ORDER, matrix_style STYLE, 4172 matrix_order L_ORDER, matrix_style L_STYLE, 4173 matrix_order R_ORDER, matrix_style R_STYLE> 4174 inline Matrix<T_type, ORDER, STYLE> 4175 operator* (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, 4176 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 4177 { 4178 if (lhs.size() == 1 || rhs.size() == 1) 4179 return (lhs % rhs); 4180 4181 SCYTHE_CHECK_10 (lhs.cols() != rhs.rows(), 4182 scythe_conformation_error, 4183 "Matrices with dimensions (" << lhs.rows() 4184 << ", " << lhs.cols() 4185 << ") and (" << rhs.rows() << ", " << rhs.cols() 4186 << ") are not multiplication-conformable"); 4187 4188 Matrix<T_type, ORDER, Concrete> result (lhs.rows(), rhs.cols(), false); 4189 4190 T_type tmp; 4191 if (ORDER == Col) { // col-major optimized 4192 for (uint j = 0; j < rhs.cols(); ++j) { 4193 for (uint i = 0; i < lhs.rows(); ++i) 4194 result(i, j) = (T_type) 0; 4195 for (uint l = 0; l < lhs.cols(); ++l) { 4196 tmp = rhs(l, j); 4197 for (uint i = 0; i < lhs.rows(); ++i) 4198 result(i, j) += tmp * lhs(i, l); 4199 } 4200 } 4201 } else { // row-major optimized 4202 for (uint i = 0; i < lhs.rows(); ++i) { 4203 for (uint j = 0; j < rhs.cols(); ++j) 4204 result(i, j) = (T_type) 0; 4205 for (uint l = 0; l < rhs.rows(); ++l) { 4206 tmp = lhs(i, l); 4207 for (uint j = 0; j < rhs.cols(); ++j) 4208 result(i, j) += tmp * rhs(l,j); 4209 } 4210 } 4211 } 4212 4213 SCYTHE_VIEW_RETURN(T_type, ORDER, STYLE, result) 4214 } 4215 SCYTHE_BINARY_OPERATOR_DEFS(operator *)4216 SCYTHE_BINARY_OPERATOR_DEFS(operator*) 4217 4218 /*! \brief Kronecker multiply two matrices. 4219 * 4220 * This functions computes the Kronecker product of two Matrix 4221 * objects. This function is overloaded to provide both Matrix by 4222 * Matrix addition and Matrix by scalar addition. In the former 4223 * case, the dimensions of the two matrices must be the same. 4224 * 4225 * In addition, we define multiple templates of the overloaded 4226 * operator to provide maximal flexibility when working with 4227 * matrices with differing matrix_order and/or matrix_style. Each 4228 * version of the overloaded operator (Matrix by Matrix, scalar by 4229 * Matrix, and Matrix by scalar) provides both a default and 4230 * general behavior, using templates. By default, the returned 4231 * Matrix is concrete and has the same matrix_order as the 4232 * left-hand (or only) Matrix argument. Alternatively, one may 4233 * coerce the matrix_order and matrix_style of the returned Matrix 4234 * to preferred values by using the full template declaration of 4235 * the operator. 4236 * 4237 * \param lhs The left-hand-side Matrix or scalar. 4238 * \param rhs The right-hand-side Matrix or scalar. 4239 * 4240 * \throw scythe_conformation_error (Level 1) 4241 * \throw scythe_alloc_error (Level 1) 4242 */ 4243 template <typename T_type, matrix_order ORDER, matrix_style STYLE, 4244 matrix_order L_ORDER, matrix_style L_STYLE, 4245 matrix_order R_ORDER, matrix_style R_STYLE> 4246 inline Matrix<T_type, ORDER, STYLE> 4247 kronecker (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, 4248 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) 4249 { 4250 Matrix<T_type,ORDER,Concrete> res = lhs; 4251 res.kronecker(rhs); 4252 return (res); 4253 } 4254 4255 SCYTHE_BINARY_OPERATOR_DEFS(kronecker) 4256 4257 /* Macro definition for general return type templates of standard 4258 * binary operators (this handles, +, -, %, /, but not *) 4259 */ 4260 4261 #define SCYTHE_GENERAL_BINARY_OPERATOR(OP,FUNCTOR) \ 4262 template <typename T_type, matrix_order ORDER, matrix_style STYLE, \ 4263 matrix_order L_ORDER, matrix_style L_STYLE, \ 4264 matrix_order R_ORDER, matrix_style R_STYLE> \ 4265 inline Matrix<T_type, ORDER, STYLE> \ 4266 OP (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, \ 4267 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4268 { \ 4269 SCYTHE_CHECK_10(lhs.size() != 1 && rhs.size() != 1 && \ 4270 (lhs.rows() != rhs.rows() || lhs.cols() != rhs.cols()), \ 4271 scythe_conformation_error, \ 4272 "Matrices with dimensions (" << lhs.rows() \ 4273 << ", " << lhs.cols() \ 4274 << ") and (" << rhs.rows() << ", " << rhs.cols() \ 4275 << ") are not conformable"); \ 4276 \ 4277 using std::placeholders::_1; \ 4278 if (lhs.size() == 1) { \ 4279 Matrix<T_type,ORDER,Concrete> res(rhs.rows(),rhs.cols(),false); \ 4280 std::transform(rhs.begin_f(), rhs.end_f(), \ 4281 res.template begin_f<R_ORDER>(), \ 4282 std::bind(FUNCTOR<T_type>(),lhs(0),_1)); \ 4283 SCYTHE_VIEW_RETURN(T_type, ORDER, STYLE, res) \ 4284 } \ 4285 \ 4286 Matrix<T_type,ORDER,Concrete> res(lhs.rows(), lhs.cols(), false); \ 4287 \ 4288 if (rhs.size() == 1) { \ 4289 std::transform(lhs.begin_f(), lhs.end_f(), \ 4290 res.template begin_f<L_ORDER> (), \ 4291 std::bind(FUNCTOR<T_type>(),_1,rhs(0))); \ 4292 } else { \ 4293 std::transform(lhs.begin_f(), lhs.end_f(), \ 4294 rhs.template begin_f<L_ORDER>(), \ 4295 res.template begin_f<L_ORDER>(), \ 4296 FUNCTOR <T_type> ()); \ 4297 } \ 4298 \ 4299 SCYTHE_VIEW_RETURN(T_type, ORDER, STYLE, res) \ 4300 } 4301 4302 /* Addition operators */ 4303 4304 /*! \fn operator+(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4305 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4306 * 4307 * \brief Add two matrices. 4308 * 4309 * This operator adds the matrices \a lhs and \a rhs together, 4310 * returning the result in a new Matrix object. This operator is 4311 * overloaded to provide both Matrix by Matrix addition and 4312 * Matrix by scalar addition. In the former case, the dimensions of 4313 * the two matrices must be the same. 4314 * 4315 * In addition, we define multiple templates of the overloaded 4316 * operator to provide maximal flexibility when working with 4317 * matrices with differing matrix_order and/or matrix_style. Each 4318 * version of the overloaded operator (Matrix by Matrix, scalar by 4319 * Matrix, and Matrix by scalar) provides both a default and 4320 * general behavior, using templates. By default, the returned 4321 * Matrix is concrete and has the same matrix_order as the 4322 * left-hand (or only) Matrix argument. Alternatively, one may 4323 * coerce the matrix_order and matrix_style of the returned Matrix 4324 * to preferred values by using the full template declaration of 4325 * the operator. 4326 * 4327 * \param lhs The left-hand-side Matrix or scalar. 4328 * \param rhs The right-hand-side Matrix or scalar. 4329 * 4330 * \throw scythe_conformation_error (Level 1) 4331 * \throw scythe_alloc_error (Level 1) 4332 */ 4333 4334 SCYTHE_GENERAL_BINARY_OPERATOR (operator+, std::plus) 4335 SCYTHE_BINARY_OPERATOR_DEFS (operator+) 4336 4337 /* Subtraction operators */ 4338 4339 /*! \fn operator-(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4340 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4341 * 4342 * \brief Subtract two matrices. 4343 * 4344 * This operator subtracts the Matrix \a rhs from \a lhs, returning 4345 * the result in a new Matrix object. This operator is overloaded 4346 * to provide both Matrix by Matrix subtraction and Matrix by scalar 4347 * subtraction. In the former case, the dimensions of the two 4348 * matrices must be the same. 4349 * 4350 * In addition, we define multiple templates of the overloaded 4351 * operator to provide maximal flexibility when working with 4352 * matrices with differing matrix_order and/or matrix_style. Each 4353 * version of the overloaded operator (Matrix by Matrix, scalar by 4354 * Matrix, and Matrix by scalar) provides both a default and 4355 * general behavior, using templates. By default, the returned 4356 * Matrix is concrete and has the same matrix_order as the 4357 * left-hand (or only) Matrix argument. Alternatively, one may 4358 * coerce the matrix_order and matrix_style of the returned Matrix 4359 * to preferred values by using the full template declaration of 4360 * the operator. 4361 * 4362 * \param lhs The left-hand-side Matrix or scalar. 4363 * \param rhs The right-hand-side Matrix or scalar. 4364 * 4365 * \throw scythe_conformation_error (Level 1) 4366 * \throw scythe_alloc_error (Level 1) 4367 */ 4368 4369 SCYTHE_GENERAL_BINARY_OPERATOR (operator-, std::minus) 4370 SCYTHE_BINARY_OPERATOR_DEFS (operator-) 4371 4372 /* Element-by-element multiplication operators */ 4373 4374 /*! \fn operator%(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4375 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4376 * 4377 * \brief Element multiply two matrices. 4378 * 4379 * This operator multiplies the elements of the matrices \a lhs and 4380 * \a rhs together, returning the result in a new Matrix object. 4381 * This operator is overloaded to provide both Matrix by Matrix 4382 * element-wise multiplication and Matrix by scalar element-wise 4383 * multiplication. In the former case, the dimensions of the two 4384 * matrices must be the same. 4385 * 4386 * In addition, we define multiple templates of the overloaded 4387 * operator to provide maximal flexibility when working with 4388 * matrices with differing matrix_order and/or matrix_style. Each 4389 * version of the overloaded operator (Matrix by Matrix, scalar by 4390 * Matrix, and Matrix by scalar) provides both a default and 4391 * general behavior, using templates. By default, the returned 4392 * Matrix is concrete and has the same matrix_order as the 4393 * left-hand (or only) Matrix argument. Alternatively, one may 4394 * coerce the matrix_order and matrix_style of the returned Matrix 4395 * to preferred values by using the full template declaration of 4396 * the operator. 4397 * 4398 * \param lhs The left-hand-side Matrix or scalar. 4399 * \param rhs The right-hand-side Matrix or scalar. 4400 * 4401 * \throw scythe_conformation_error (Level 1) 4402 * \throw scythe_alloc_error (Level 1) 4403 */ 4404 4405 SCYTHE_GENERAL_BINARY_OPERATOR (operator%, std::multiplies) 4406 SCYTHE_BINARY_OPERATOR_DEFS(operator%) 4407 4408 /* Element-by-element division */ 4409 4410 /*! \fn operator/(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4411 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4412 * 4413 * \brief Divide two matrices. 4414 * 4415 * This operator divides the Matrix \a lhs from \a rhs, 4416 * returning the result in a new Matrix object. This operator is 4417 * overloaded to provide both Matrix by Matrix division and 4418 * Matrix by scalar division. In the former case, the dimensions of 4419 * the two matrices must be the same. 4420 * 4421 * In addition, we define multiple templates of the overloaded 4422 * operator to provide maximal flexibility when working with 4423 * matrices with differing matrix_order and/or matrix_style. Each 4424 * version of the overloaded operator (Matrix by Matrix, scalar by 4425 * Matrix, and Matrix by scalar) provides both a default and 4426 * general behavior, using templates. By default, the returned 4427 * Matrix is concrete and has the same matrix_order as the 4428 * left-hand (or only) Matrix argument. Alternatively, one may 4429 * coerce the matrix_order and matrix_style of the returned Matrix 4430 * to preferred values by using the full template declaration of 4431 * the operator. 4432 * 4433 * \param lhs The left-hand-side Matrix or scalar. 4434 * \param rhs The right-hand-side Matrix or scalar. 4435 * 4436 * \throw scythe_conformation_error (Level 1) 4437 * \throw scythe_alloc_error (Level 1) 4438 */ 4439 4440 SCYTHE_GENERAL_BINARY_OPERATOR (operator/, std::divides) 4441 SCYTHE_BINARY_OPERATOR_DEFS (operator/) 4442 4443 /* Element-by-element exponentiation */ 4444 4445 /*! \fn operator^(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4446 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4447 * 4448 * \brief Exponentiate one Matrix by another. 4449 * 4450 * This operator exponentiates the elements of Matrix \a lhs by 4451 * those in \a rhs, returning the result in a new Matrix object. 4452 * This operator is overloaded to provide both Matrix by Matrix 4453 * exponentiation and Matrix by scalar exponentiation. In the 4454 * former case, the dimensions of the two matrices must be the same. 4455 * 4456 * In addition, we define multiple templates of the overloaded 4457 * operator to provide maximal flexibility when working with 4458 * matrices with differing matrix_order and/or matrix_style. Each 4459 * version of the overloaded operator (Matrix by Matrix, scalar by 4460 * Matrix, and Matrix by scalar) provides both a default and 4461 * general behavior, using templates. By default, the returned 4462 * Matrix is concrete and has the same matrix_order as the 4463 * left-hand (or only) Matrix argument. Alternatively, one may 4464 * coerce the matrix_order and matrix_style of the returned Matrix 4465 * to preferred values by using the full template declaration of 4466 * the operator. 4467 * 4468 * \param lhs The left-hand-side Matrix or scalar. 4469 * \param rhs The right-hand-side Matrix or scalar. 4470 * 4471 * \throw scythe_conformation_error (Level 1) 4472 * \throw scythe_alloc_error (Level 1) 4473 */ 4474 4475 SCYTHE_GENERAL_BINARY_OPERATOR (operator^, exponentiate) 4476 SCYTHE_BINARY_OPERATOR_DEFS (operator^) 4477 4478 /* Negation operators */ 4479 4480 // General return type version 4481 /*! \brief Negate a Matrix. 4482 * 4483 * This unary operator returns the negation of \a M. This version 4484 * of the operator is a general template and can provide a Matrix 4485 * with any matrix_order or matrix_style as its return value. 4486 * 4487 * We also provide an overloaded default template that returns a 4488 * concrete matrix with the same matrix_order as \a M. 4489 * 4490 * \param M The Matrix to negate. 4491 * 4492 * \throw scythe_alloc_error (Level 1) 4493 */ 4494 template <typename T_type, matrix_order R_ORDER, matrix_style R_STYLE, 4495 matrix_order ORDER, matrix_style STYLE> 4496 inline Matrix<T_type, R_ORDER, R_STYLE> 4497 operator- (const Matrix<T_type, ORDER, STYLE>& M) 4498 { 4499 Matrix<T_type, R_ORDER, Concrete> result(M.rows(), M.cols(), false); 4500 std::transform(M.template begin_f<ORDER>(), 4501 M.template end_f<ORDER>(), 4502 result.template begin_f<R_ORDER>(), 4503 std::negate<T_type> ()); 4504 SCYTHE_VIEW_RETURN(T_type, R_ORDER, R_STYLE, result) 4505 } 4506 4507 // Default return type version 4508 template <matrix_order ORDER, matrix_style P_STYLE, typename T_type> 4509 inline Matrix<T_type, ORDER, Concrete> 4510 operator- (const Matrix<T_type, ORDER, P_STYLE>& M) 4511 { 4512 return operator-<T_type, ORDER, Concrete> (M); 4513 } 4514 4515 /* Unary not operators */ 4516 4517 /*! \brief Logically NOT a Matrix. 4518 * 4519 * This unary operator returns NOT \a M. This version of the 4520 * operator is a general template and can provide a boolean Matrix 4521 * with any matrix_order or matrix_style as its return value. 4522 * 4523 * We also provide a default template for this function that returns 4524 * a concrete boolean with the same matrix_order as \a M. 4525 * 4526 * \param M The Matrix to NOT. 4527 * 4528 * \see operator!(const Matrix<T_type, ORDER, P_STYLE>& M) 4529 * 4530 * \throw scythe_alloc_error (Level 1) 4531 */ 4532 template <matrix_order R_ORDER, matrix_style R_STYLE, typename T_type, 4533 matrix_order ORDER, matrix_style STYLE> 4534 inline Matrix<bool, R_ORDER, R_STYLE> 4535 operator! (const Matrix<T_type, ORDER, STYLE>& M) 4536 { 4537 Matrix<bool, R_ORDER, Concrete> result(M.rows(), M.cols(), false); 4538 std::transform(M.template begin_f<ORDER>(), 4539 M.template end_f<ORDER>(), 4540 result.template begin_f<R_ORDER>(), 4541 std::logical_not<T_type> ()); 4542 SCYTHE_VIEW_RETURN(T_type, R_ORDER, R_STYLE, result) 4543 } 4544 4545 // Default return type version 4546 template <typename T_type, matrix_order ORDER, matrix_style P_STYLE> 4547 inline Matrix<bool, ORDER, Concrete> 4548 operator! (const Matrix<T_type, ORDER, P_STYLE>& M) 4549 { 4550 return (operator!<ORDER, Concrete> (M)); 4551 } 4552 /**** COMPARISON OPERATORS ****/ 4553 4554 /* These macros are analogous to those above, except they return 4555 * only boolean matrices and use slightly different template 4556 * parameter orderings. Kind of redundant, but less confusing than 4557 * making omnibus macros that handle both cases. 4558 */ 4559 #define SCYTHE_GENERAL_BINARY_BOOL_OPERATOR(OP,FUNCTOR) \ 4560 template <matrix_order ORDER, matrix_style STYLE, typename T_type, \ 4561 matrix_order L_ORDER, matrix_style L_STYLE, \ 4562 matrix_order R_ORDER, matrix_style R_STYLE> \ 4563 inline Matrix<bool, ORDER, STYLE> \ 4564 OP (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, \ 4565 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4566 { \ 4567 SCYTHE_CHECK_10(lhs.size() != 1 && rhs.size() != 1 && \ 4568 (lhs.rows() != rhs.rows() || lhs.cols() != rhs.cols()), \ 4569 scythe_conformation_error, \ 4570 "Matrices with dimensions (" << lhs.rows() \ 4571 << ", " << lhs.cols() \ 4572 << ") and (" << rhs.rows() << ", " << rhs.cols() \ 4573 << ") are not conformable"); \ 4574 \ 4575 using std::placeholders::_1; \ 4576 if (lhs.size() == 1) { \ 4577 Matrix<bool,ORDER,Concrete> res(rhs.rows(),rhs.cols(),false); \ 4578 std::transform(rhs.begin_f(), rhs.end_f(), \ 4579 res.template begin_f<R_ORDER>(), \ 4580 std::bind(FUNCTOR <T_type>(), lhs(0), _1)); \ 4581 SCYTHE_VIEW_RETURN(T_type, ORDER, STYLE, res) \ 4582 } \ 4583 \ 4584 Matrix<bool,ORDER,Concrete> res(lhs.rows(), lhs.cols(), false); \ 4585 \ 4586 if (rhs.size() == 1) { \ 4587 std::transform(lhs.begin_f(), lhs.end_f(), \ 4588 res.template begin_f<L_ORDER> (), \ 4589 std::bind(FUNCTOR <T_type>(), _1, rhs(0))); \ 4590 } else { \ 4591 std::transform(lhs.begin_f(), lhs.end_f(), \ 4592 rhs.template begin_f<L_ORDER>(), \ 4593 res.template begin_f<L_ORDER>(), \ 4594 FUNCTOR <T_type> ()); \ 4595 } \ 4596 \ 4597 SCYTHE_VIEW_RETURN(T_type, ORDER, STYLE, res) \ 4598 } 4599 4600 #define SCYTHE_BINARY_BOOL_OPERATOR_DMM(OP) \ 4601 template <typename T_type, matrix_order ORDER, matrix_style L_STYLE,\ 4602 matrix_order R_ORDER, matrix_style R_STYLE> \ 4603 inline Matrix<bool, ORDER, Concrete> \ 4604 OP (const Matrix<T_type, ORDER, L_STYLE>& lhs, \ 4605 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4606 { \ 4607 return OP <ORDER, Concrete>(lhs, rhs); \ 4608 } 4609 4610 #define SCYTHE_BINARY_BOOL_OPERATOR_GMS(OP) \ 4611 template <matrix_order ORDER, matrix_style STYLE, typename T_type, \ 4612 matrix_order L_ORDER, matrix_style L_STYLE> \ 4613 inline Matrix<bool, ORDER, STYLE> \ 4614 OP (const Matrix<T_type, L_ORDER, L_STYLE>& lhs, \ 4615 const typename Matrix<T_type>::ttype &rhs) \ 4616 { \ 4617 return (OP <ORDER, STYLE> \ 4618 (lhs, Matrix<T_type, L_ORDER>(rhs))); \ 4619 } 4620 4621 #define SCYTHE_BINARY_BOOL_OPERATOR_DMS(OP) \ 4622 template <typename T_type, matrix_order ORDER, matrix_style L_STYLE>\ 4623 inline Matrix<bool, ORDER, Concrete> \ 4624 OP (const Matrix<T_type, ORDER, L_STYLE>& lhs, \ 4625 const typename Matrix<T_type>::ttype &rhs) \ 4626 { \ 4627 return (OP <ORDER, Concrete> (lhs, rhs)); \ 4628 } 4629 4630 #define SCYTHE_BINARY_BOOL_OPERATOR_GSM(OP) \ 4631 template <matrix_order ORDER, matrix_style STYLE, typename T_type, \ 4632 matrix_order R_ORDER, matrix_style R_STYLE> \ 4633 inline Matrix<bool, ORDER, STYLE> \ 4634 OP (const typename Matrix<T_type>::ttype &lhs, \ 4635 const Matrix<T_type, R_ORDER, R_STYLE>& rhs) \ 4636 { \ 4637 return (OP <ORDER, STYLE> \ 4638 (Matrix<T_type, R_ORDER>(lhs), rhs)); \ 4639 } 4640 4641 #define SCYTHE_BINARY_BOOL_OPERATOR_DSM(OP) \ 4642 template <typename T_type, matrix_order ORDER, matrix_style R_STYLE>\ 4643 inline Matrix<bool, ORDER, Concrete> \ 4644 OP (const typename Matrix<T_type>::ttype &lhs, \ 4645 const Matrix<T_type, ORDER, R_STYLE>& rhs) \ 4646 { \ 4647 return (OP <ORDER, Concrete> (lhs, rhs)); \ 4648 } 4649 4650 #define SCYTHE_BINARY_BOOL_OPERATOR_DEFS(OP) \ 4651 SCYTHE_BINARY_BOOL_OPERATOR_DMM(OP) \ 4652 SCYTHE_BINARY_BOOL_OPERATOR_GMS(OP) \ 4653 SCYTHE_BINARY_BOOL_OPERATOR_DMS(OP) \ 4654 SCYTHE_BINARY_BOOL_OPERATOR_GSM(OP) \ 4655 SCYTHE_BINARY_BOOL_OPERATOR_DSM(OP) 4656 4657 /* Element-wise Equality operator 4658 * See equals() method for straight equality checks 4659 */ 4660 4661 /*! \fn operator==(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4662 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4663 * 4664 * \brief Test Matrix equality. 4665 * 4666 * This operator compares the elements of \a lhs and \a rhs and 4667 * returns a boolean Matrix of true and false values, indicating 4668 * whether each pair of compared elements is equal. This operator 4669 * is overloaded to provide both Matrix by Matrix equality testing 4670 * and Matrix by scalar equality testing. In the former case, the 4671 * dimensions of the two matrices must be the same. The boolean 4672 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4673 * matches the dimensionality of the larger Matrix object when one 4674 * of the two parameters is a scalar or a 1x1 Matrix. 4675 * 4676 * In addition, we define multiple templates of the overloaded 4677 * operator to provide maximal flexibility when working with 4678 * matrices with differing matrix_order and/or matrix_style. Each 4679 * version of the overloaded operator (Matrix by Matrix, scalar by 4680 * Matrix, and Matrix by scalar) provides both a default and 4681 * general behavior, using templates. By default, the returned 4682 * Matrix is concrete and has the same matrix_order as the 4683 * left-hand (or only) Matrix argument. Alternatively, one may 4684 * coerce the matrix_order and matrix_style of the returned Matrix 4685 * to preferred values by using the full template declaration of 4686 * the operator. 4687 * 4688 * \param lhs The left-hand-side Matrix or scalar. 4689 * \param rhs The right-hand-side Matrix or scalar. 4690 * 4691 * \throw scythe_conformation_error (Level 1) 4692 * \throw scythe_alloc_error (Level 1) 4693 */ 4694 4695 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator==, std::equal_to) 4696 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator==) 4697 4698 /*! \fn operator!=(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4699 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4700 * 4701 * \brief Test Matrix equality. 4702 * 4703 * This operator compares the elements of \a lhs and \a rhs and 4704 * returns a boolean Matrix of true and false values, indicating 4705 * whether each pair of compared elements is not equal. This operator 4706 * is overloaded to provide both Matrix by Matrix inequality testing 4707 * and Matrix by scalar inequality testing. In the former case, the 4708 * dimensions of the two matrices must be the same. The boolean 4709 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4710 * matches the dimensionality of the larger Matrix object when one 4711 * of the two parameters is a scalar or a 1x1 Matrix. 4712 * 4713 * In addition, we define multiple templates of the overloaded 4714 * operator to provide maximal flexibility when working with 4715 * matrices with differing matrix_order and/or matrix_style. Each 4716 * version of the overloaded operator (Matrix by Matrix, scalar by 4717 * Matrix, and Matrix by scalar) provides both a default and 4718 * general behavior, using templates. By default, the returned 4719 * Matrix is concrete and has the same matrix_order as the 4720 * left-hand (or only) Matrix argument. Alternatively, one may 4721 * coerce the matrix_order and matrix_style of the returned Matrix 4722 * to preferred values by using the full template declaration of 4723 * the operator. 4724 * 4725 * \param lhs The left-hand-side Matrix or scalar. 4726 * \param rhs The right-hand-side Matrix or scalar. 4727 * 4728 * \throw scythe_conformation_error (Level 1) 4729 * \throw scythe_alloc_error (Level 1) 4730 */ 4731 4732 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator!=, std::not_equal_to) 4733 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator!=) 4734 4735 /*! \fn operator<(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4736 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4737 * 4738 * \brief Test Matrix inequality. 4739 * 4740 * This operator compares the elements of \a lhs and \a rhs and 4741 * returns a boolean Matrix of true and false values, indicating 4742 * whether each of the left-hand side elements is less than its 4743 * corresponding right hand side element. This operator is 4744 * overloaded to provide both Matrix by Matrix inequality testing 4745 * and Matrix by scalar inequality testing. In the former case, the 4746 * dimensions of the two matrices must be the same. The boolean 4747 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4748 * matches the dimensionality of the larger Matrix object when one 4749 * of the two parameters is a scalar or a 1x1 Matrix. 4750 * 4751 * In addition, we define multiple templates of the overloaded 4752 * operator to provide maximal flexibility when working with 4753 * matrices with differing matrix_order and/or matrix_style. Each 4754 * version of the overloaded operator (Matrix by Matrix, scalar by 4755 * Matrix, and Matrix by scalar) provides both a default and 4756 * general behavior, using templates. By default, the returned 4757 * Matrix is concrete and has the same matrix_order as the 4758 * left-hand (or only) Matrix argument. Alternatively, one may 4759 * coerce the matrix_order and matrix_style of the returned Matrix 4760 * to preferred values by using the full template declaration of 4761 * the operator. 4762 * 4763 * \param lhs The left-hand-side Matrix or scalar. 4764 * \param rhs The right-hand-side Matrix or scalar. 4765 * 4766 * \throw scythe_conformation_error (Level 1) 4767 * \throw scythe_alloc_error (Level 1) 4768 */ 4769 4770 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator<, std::less) 4771 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator<) 4772 4773 /*! \fn operator<=(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4774 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4775 * 4776 * \brief Test Matrix inequality. 4777 * 4778 * This operator compares the elements of \a lhs and \a rhs and 4779 * returns a boolean Matrix of true and false values, indicating 4780 * whether each of the left-hand side elements is less than 4781 * or equal to its 4782 * corresponding right hand side element. This operator is 4783 * overloaded to provide both Matrix by Matrix inequality testing 4784 * and Matrix by scalar inequality testing. In the former case, the 4785 * dimensions of the two matrices must be the same. The boolean 4786 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4787 * matches the dimensionality of the larger Matrix object when one 4788 * of the two parameters is a scalar or a 1x1 Matrix. 4789 * 4790 * In addition, we define multiple templates of the overloaded 4791 * operator to provide maximal flexibility when working with 4792 * matrices with differing matrix_order and/or matrix_style. Each 4793 * version of the overloaded operator (Matrix by Matrix, scalar by 4794 * Matrix, and Matrix by scalar) provides both a default and 4795 * general behavior, using templates. By default, the returned 4796 * Matrix is concrete and has the same matrix_order as the 4797 * left-hand (or only) Matrix argument. Alternatively, one may 4798 * coerce the matrix_order and matrix_style of the returned Matrix 4799 * to preferred values by using the full template declaration of 4800 * the operator. 4801 * 4802 * \param lhs The left-hand-side Matrix or scalar. 4803 * \param rhs The right-hand-side Matrix or scalar. 4804 * 4805 * \throw scythe_conformation_error (Level 1) 4806 * \throw scythe_alloc_error (Level 1) 4807 */ 4808 4809 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator<=, std::less_equal) 4810 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator<=) 4811 4812 /*! \fn operator>(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4813 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4814 * 4815 * \brief Test Matrix inequality. 4816 * 4817 * This operator compares the elements of \a lhs and \a rhs and 4818 * returns a boolean Matrix of true and false values, indicating 4819 * whether each of the left-hand side elements is greater than its 4820 * corresponding right hand side element. This operator is 4821 * overloaded to provide both Matrix by Matrix inequality testing 4822 * and Matrix by scalar inequality testing. In the former case, the 4823 * dimensions of the two matrices must be the same. The boolean 4824 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4825 * matches the dimensionality of the larger Matrix object when one 4826 * of the two parameters is a scalar or a 1x1 Matrix. 4827 * 4828 * In addition, we define multiple templates of the overloaded 4829 * operator to provide maximal flexibility when working with 4830 * matrices with differing matrix_order and/or matrix_style. Each 4831 * version of the overloaded operator (Matrix by Matrix, scalar by 4832 * Matrix, and Matrix by scalar) provides both a default and 4833 * general behavior, using templates. By default, the returned 4834 * Matrix is concrete and has the same matrix_order as the 4835 * left-hand (or only) Matrix argument. Alternatively, one may 4836 * coerce the matrix_order and matrix_style of the returned Matrix 4837 * to preferred values by using the full template declaration of 4838 * the operator. 4839 * 4840 * \param lhs The left-hand-side Matrix or scalar. 4841 * \param rhs The right-hand-side Matrix or scalar. 4842 * 4843 * \throw scythe_conformation_error (Level 1) 4844 * \throw scythe_alloc_error (Level 1) 4845 */ 4846 4847 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator>, std::greater) 4848 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator>) 4849 4850 /*! \fn operator>=(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4851 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4852 * 4853 * \brief Test Matrix inequality. 4854 * 4855 * This operator compares the elements of \a lhs and \a rhs and 4856 * returns a boolean Matrix of true and false values, indicating 4857 * whether each of the left-hand side elements is greater than 4858 * or equal to its 4859 * corresponding right hand side element. This operator is 4860 * overloaded to provide both Matrix by Matrix inequality testing 4861 * and Matrix by scalar inequality testing. In the former case, the 4862 * dimensions of the two matrices must be the same. The boolean 4863 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4864 * matches the dimensionality of the larger Matrix object when one 4865 * of the two parameters is a scalar or a 1x1 Matrix. 4866 * 4867 * In addition, we define multiple templates of the overloaded 4868 * operator to provide maximal flexibility when working with 4869 * matrices with differing matrix_order and/or matrix_style. Each 4870 * version of the overloaded operator (Matrix by Matrix, scalar by 4871 * Matrix, and Matrix by scalar) provides both a default and 4872 * general behavior, using templates. By default, the returned 4873 * Matrix is concrete and has the same matrix_order as the 4874 * left-hand (or only) Matrix argument. Alternatively, one may 4875 * coerce the matrix_order and matrix_style of the returned Matrix 4876 * to preferred values by using the full template declaration of 4877 * the operator. 4878 * 4879 * \param lhs The left-hand-side Matrix or scalar. 4880 * \param rhs The right-hand-side Matrix or scalar. 4881 * 4882 * \throw scythe_conformation_error (Level 1) 4883 * \throw scythe_alloc_error (Level 1) 4884 */ 4885 4886 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator>=, std::greater_equal) 4887 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator>=) 4888 4889 /*! \fn operator&(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4890 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4891 * 4892 * \brief Logically AND two matrices. 4893 * 4894 * This operator logically ANDs the elements of \a lhs and \a rhs 4895 * and returns a boolean Matrix of true and false values, with true 4896 * values in each position where both matrices' elements evaluate to 4897 * true (or the type specific analog to true, typically any non-zero 4898 * value). This operator is overloaded to provide both Matrix by 4899 * Matrix AND and Matrix by scalar AND. In the former case, the 4900 * dimensions of the two matrices must be the same. The boolean 4901 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4902 * matches the dimensionality of the larger Matrix object when one 4903 * of the two parameters is a scalar or a 1x1 Matrix. 4904 * 4905 * In addition, we define multiple templates of the overloaded 4906 * operator to provide maximal flexibility when working with 4907 * matrices with differing matrix_order and/or matrix_style. Each 4908 * version of the overloaded operator (Matrix by Matrix, scalar by 4909 * Matrix, and Matrix by scalar) provides both a default and 4910 * general behavior, using templates. By default, the returned 4911 * Matrix is concrete and has the same matrix_order as the 4912 * left-hand (or only) Matrix argument. Alternatively, one may 4913 * coerce the matrix_order and matrix_style of the returned Matrix 4914 * to preferred values by using the full template declaration of 4915 * the operator. 4916 * 4917 * \param lhs The left-hand-side Matrix or scalar. 4918 * \param rhs The right-hand-side Matrix or scalar. 4919 * 4920 * \throw scythe_conformation_error (Level 1) 4921 * \throw scythe_alloc_error (Level 1) 4922 */ 4923 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR(operator &,std::logical_and)4924 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator&, std::logical_and) 4925 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator&) 4926 4927 4928 /*! \fn operator|(const Matrix<T_type,L_ORDER,L_STYLE>&lhs, 4929 * const Matrix<T_type,R_ORDER,R_STYLE>&rhs) 4930 * 4931 * \brief Logically OR two matrices. 4932 * 4933 * This operator logically ORs the elements of \a lhs and \a rhs 4934 * and returns a boolean Matrix of true and false values, with true 4935 * values in each position where either Matrix's elements evaluate to 4936 * true (or the type specific analog to true, typically any non-zero 4937 * value). This operator is overloaded to provide both Matrix by 4938 * Matrix OR and Matrix by scalar OR. In the former case, the 4939 * dimensions of the two matrices must be the same. The boolean 4940 * Matrix returned has the same dimensions as \a lhs and \a rhs, or 4941 * matches the dimensionality of the larger Matrix object when one 4942 * of the two parameters is a scalar or a 1x1 Matrix. 4943 * 4944 * In addition, we define multiple templates of the overloaded 4945 * operator to provide maximal flexibility when working with 4946 * matrices with differing matrix_order and/or matrix_style. Each 4947 * version of the overloaded operator (Matrix by Matrix, scalar by 4948 * Matrix, and Matrix by scalar) provides both a default and 4949 * general behavior, using templates. By default, the returned 4950 * Matrix is concrete and has the same matrix_order as the 4951 * left-hand (or only) Matrix argument. Alternatively, one may 4952 * coerce the matrix_order and matrix_style of the returned Matrix 4953 * to preferred values by using the full template declaration of 4954 * the operator. 4955 * 4956 * \param lhs The left-hand-side Matrix or scalar. 4957 * \param rhs The right-hand-side Matrix or scalar. 4958 * 4959 * \throw scythe_conformation_error (Level 1) 4960 * \throw scythe_alloc_error (Level 1) 4961 */ 4962 4963 SCYTHE_GENERAL_BINARY_BOOL_OPERATOR (operator|, std::logical_or) 4964 SCYTHE_BINARY_BOOL_OPERATOR_DEFS (operator|) 4965 4966 /**** INPUT-OUTPUT ****/ 4967 4968 4969 /* This function simply copies values from an input stream into a 4970 * matrix. It relies on the iterators for bounds checking. 4971 */ 4972 4973 /*! \brief Populate a Matrix from a stream. 4974 * 4975 * This operator reads values from a stream and enters them into an 4976 * existing Matrix in order. 4977 * 4978 * \param is The istream to read from. 4979 * \param M The Matrix to populate. 4980 * 4981 * \see operator<<(std::ostream& os, const Matrix<T,O,S>& M) 4982 * \see Matrix::Matrix(const std::string& file) 4983 * 4984 * \throw scythe_bounds_error (Level 3) 4985 */ 4986 template <typename T, matrix_order O, matrix_style S> 4987 std::istream& operator>> (std::istream& is, Matrix<T,O,S>& M) 4988 { 4989 std::copy(std::istream_iterator<T> (is), std::istream_iterator<T>(), 4990 M.begin_f()); 4991 4992 return is; 4993 } 4994 4995 /* Writes a matrix to an ostream in readable format. This is 4996 * intended to be used to pretty-print to the terminal. 4997 */ 4998 4999 /*!\brief Write a Matrix to a stream. 5000 * 5001 * Writes a matrix to an ostream in a column-aligned format. This 5002 * operator is primarily intended for pretty-printing to the 5003 * terminal and uses two passes in order to correctly align the 5004 * output. If you wish to write a Matrix to disk, Matrix::save() is 5005 * probably a better option. 5006 * 5007 * \param os The ostream to write to. 5008 * \param M The Matrix to write out. 5009 * 5010 * \see operator>>(std::istream& is, Matrix<T,O,S>& M) 5011 * \see Matrix::save() 5012 */ 5013 template <typename T, matrix_order O, matrix_style S> 5014 std::ostream& operator<< (std::ostream& os, const Matrix<T,O,S>& M) 5015 { 5016 /* This function take two passes to figure out appropriate field 5017 * widths. Speed isn't really the point here. 5018 */ 5019 5020 // Store previous io settings 5021 std::ios_base::fmtflags preop = os.flags(); 5022 5023 uint mlen = os.width(); 5024 std::ostringstream oss; 5025 oss.precision(os.precision()); 5026 oss << std::setiosflags(std::ios::fixed); 5027 5028 typename Matrix<T,O,S>::const_forward_iterator last = M.end_f(); 5029 for (typename Matrix<T,O,S>::const_forward_iterator i = M.begin_f(); 5030 i != last; ++i) { 5031 oss.str(""); 5032 oss << (*i); 5033 if (oss.str().length() > mlen) 5034 mlen = oss.str().length(); 5035 } 5036 5037 5038 /* Write the stream */ 5039 // Change to a fixed with format. Users should control precision 5040 os << std::setiosflags(std::ios::fixed); 5041 5042 5043 for (uint i = 0; i < M.rows(); ++i) { 5044 Matrix<T, O, View> row = M(i, _); 5045 //for (uint i = 0; i < row.size(); ++i) 5046 // os << std::setw(mlen) << row[i] << " "; 5047 typename Matrix<T,O,View>::const_forward_iterator row_last 5048 = row.end_f(); 5049 for (typename 5050 Matrix<T,O,View>::forward_iterator el = row.begin_f(); 5051 el != row_last; ++el) { 5052 os << std::setw(mlen) << *el << " "; 5053 } 5054 os << std::endl; 5055 } 5056 5057 5058 // Restore pre-op flags 5059 os.flags(preop); 5060 5061 return os; 5062 } 5063 5064 #ifdef SCYTHE_LAPACK 5065 /* A template specialization of operator* for col-major, concrete 5066 * matrices of doubles that is only visible when a LAPACK library is 5067 * available. This function is an analog of the above function and 5068 * the above doxygen documentation serves for both. 5069 * 5070 * This needs to go below % so it can see the template definition 5071 * (since it isn't actually in the template itself. 5072 */ 5073 5074 template<> 5075 inline Matrix<> 5076 operator*<double,Col,Concrete,Col,Concrete> 5077 (const Matrix<>& lhs, const Matrix<>& rhs) 5078 { 5079 if (lhs.size() == 1 || rhs.size() == 1) 5080 return (lhs % rhs); 5081 5082 SCYTHE_DEBUG_MSG("Using lapack/blas for matrix multiplication"); 5083 SCYTHE_CHECK_10 (lhs.cols() != rhs.rows(), 5084 scythe_conformation_error, 5085 "Matrices with dimensions (" << lhs.rows() 5086 << ", " << lhs.cols() 5087 << ") and (" << rhs.rows() << ", " << rhs.cols() 5088 << ") are not multiplication-conformable"); 5089 5090 Matrix<> result (lhs.rows(), rhs.cols(), false); 5091 5092 // Get pointers to the internal arrays and set up some vars 5093 double* lhspnt = lhs.getArray(); 5094 double* rhspnt = rhs.getArray(); 5095 double* resultpnt = result.getArray(); 5096 const double one(1.0); 5097 const double zero(0.0); 5098 int rows = (int) lhs.rows(); 5099 int cols = (int) rhs.cols(); 5100 int innerDim = (int) rhs.rows(); 5101 5102 // Call the lapack routine. 5103 lapack::dgemm_("N", "N", &rows, &cols, &innerDim, &one, lhspnt, 5104 &rows, rhspnt, &innerDim, &zero, resultpnt, &rows); 5105 5106 return result; 5107 } 5108 #endif 5109 5110 } // end namespace scythe 5111 5112 #endif /* SCYTHE_MATRIX_H */ 5113