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