1 ///////////////////////////////////////////////////////////////////////////////
2 //                                                                           //
3 // The Template Matrix/Vector Library for C++ was created by Mike Jarvis     //
4 // Copyright (C) 1998 - 2016                                                 //
5 // All rights reserved                                                       //
6 //                                                                           //
7 // The project is hosted at https://code.google.com/p/tmv-cpp/               //
8 // where you can find the current version and current documention.           //
9 //                                                                           //
10 // For concerns or problems with the software, Mike may be contacted at      //
11 // mike_jarvis17 [at] gmail.                                                 //
12 //                                                                           //
13 // This software is licensed under a FreeBSD license.  The file              //
14 // TMV_LICENSE should have bee included with this distribution.              //
15 // It not, you can get a copy from https://code.google.com/p/tmv-cpp/.       //
16 //                                                                           //
17 // Essentially, you can use this software however you want provided that     //
18 // you include the TMV_LICENSE file in any distribution that uses it.        //
19 //                                                                           //
20 ///////////////////////////////////////////////////////////////////////////////
21 
22 
23 //---------------------------------------------------------------------------
24 //
25 // This file defines the TMV Matrix class.
26 //
27 // The Matrix class and all associated functions are contained
28 // in the namespace tmv.  Alse, the Matrix class is a template,
29 // so for a Matrix of doubles, one would write tmv::Matrix<double>.
30 //
31 // An optional second template parameter specifies the known attributes
32 // of the matrix.  The valid attributes for a Matrix are:
33 // - ColMajor or RowMajor
34 // - CStyle or FortranStyle
35 // The defaults are ColMajor and CStyle if you do not specify otherwise.
36 //
37 // The attributes are treated as a bit field, so you | them together to
38 // get the complete value.  e.g.
39 // Matrix<double, ColMajor | FortranStyle>
40 //
41 // Also, you only need to specify things that differ from the default, so
42 // Matrix<T,RowMajor> means Matrix<T,RowMajor|CStyle>, and
43 // Matrix<T> means Matrix<T,ColMajor|CStyle>.
44 //
45 // The *Style attributes indicate whether to use C-style or Fotran-style
46 // indexing.
47 // With C-style (the default), the upper left corner of an MxN matrix is
48 // m(0,0), and the lower right is m(M-1,N-1).
49 // With Fortran-style, these are m(1,1) and m(M,N) respectively.
50 // Also, when a function takes an index range, i1,i2,
51 // then with C-style, this means elements from i1...i2-1 inclusive.
52 // With Fortran-style, this means i1..i2 inclusive.
53 //
54 // Constructors:
55 //
56 //    Matrix<T,A>(int colsize, int rowsize)
57 //        Makes a Matrix with column size = colsize and row size = rowsize
58 //        with _uninitialized_ values
59 //
60 //    Matrix<T,A>(int colsize, int rowsize, T x)
61 //        Makes a Matrix of size n with all values = x
62 //
63 //
64 // Special Constructors
65 //
66 //    MatrixView RowVectorViewOf(Vector& v)
67 //    MatrixView RowVectorViewOf(VectorView v)
68 //    ConstMatrixView RowVectorViewOf(const Vector& v)
69 //    ConstMatrixView RowVectorViewOf(const ConstVectorView& v)
70 //        Returns a 1xn MatrixView with v in the (only) row.
71 //        Unlike creating a Matrix with RowVector(v), this uses the same
72 //        data storage as the actual Vector v.
73 //        For a const Vector or a ConstVectorView, this returns a
74 //        ConstMatrixView.
75 //
76 //    MatrixView ColVectorViewOf(Vector& v)
77 //    MatrixView ColVectorViewOf(VectorView v)
78 //    ConstMatrixView ColVectorViewOf(const Vector& v)
79 //    ConstMatrixView ColVectorViewOf(const ConstVectorView& v)
80 //        Returns an nx1 MatrixView with v in the (only) column.
81 //
82 //    MatrixView MatrixViewOf(T* m, int colsize, int rowsize,
83 //            StorageType stor)
84 //    MatrixView MatrixViewOf(T* m, int colsize, int rowsize,
85 //            int stepi, int stepj)
86 //    ConstMatrixView MatrixViewOf(const T* m, int colsize, int rowsize,
87 //            StorageType stor)
88 //    ConstMatrixView MatrixViewOf(const T* m, int colsize, int rowsize,
89 //            int stepi, int stepj)
90 //        Returns a MatrixView of the elements in m, using the actual
91 //        elements m for the storage.  This is essentially the same as the
92 //        constructor with (const T*m), except that the data isn't duplicated.
93 //
94 // Access Functions
95 //
96 //    int colsize() const
97 //    int rowsize() const
98 //        Return the dimensions of the Matrix
99 //
100 //    T& operator()(int i, int j)
101 //    T operator()(int i, int j) const
102 //        Return the (i,j) element of the Matrix
103 //
104 //    VectorView& operator[](int i)
105 //    ConstVectorView& operator[](int i) const
106 //        Return the ith row of the Matrix as a Vector.
107 //        This allows for m[i][j] style access.
108 //
109 //    VectorView& row(int i, int j1, int j2)
110 //    ConstVectorView& row(int i, int j1, int j2) const
111 //        Return the ith row of the Matrix as a Vector
112 //        If j1,j2 are given, it returns the subVector from j1 to j2
113 //        (not including j2) within the row.
114 //
115 //    VectorView& col(int j, int i1, int i2)
116 //    ConstVectorView& col(int j) const
117 //        Return the jth column of the Matrix as a Vector
118 //        If i1,i2 are given, it returns the subVector from i1 to i2
119 //        (not including i2) within the column.
120 //
121 //    VectorView& diag()
122 //    ConstVectorView& diag() const
123 //        Return the diagonal of the Matrix as a Vector
124 //
125 //    VectorView& diag(int i, int j1, int j2)
126 //    ConstVectorView& diag(i, j1, j2) const
127 //        Return the super- or sub-diagonal i
128 //        If i > 0 return the super diagonal starting at m_0i
129 //        If i < 0 return the sub diagonal starting at m_|i|0
130 //        If j1,j2 are given, it returns the diagonal subVector
131 //        either from m_j1,i+j1 to m_j2,i+j2 (for i>0)
132 //        or from m_|i|+j1,j1 to m_|i|+j2,j2 (for i<0)
133 //
134 // Modifying Functions
135 //
136 //    Matrix& setZero()
137 //        Sets all elements to 0
138 //
139 //    Matrix& setAllTo(T x)
140 //        Sets all elements to x
141 //
142 //    Matrix& addToAll(T x)
143 //        Adds x to all elements
144 //
145 //    Matrix& clip(RT thresh)
146 //        Set to 0 all elements whose abolute value is < thresh
147 //
148 //    Matrix<T>& transposeSelf()
149 //        Transposes the elements of a square Matrix or subMatrix
150 //
151 //    Matrix& conjugateSelf()
152 //        Sets all elements to its conjugate
153 //
154 //    Matrix& setToIdentity(x = 1)
155 //        Set to Identity Matrix, or
156 //        with a parameter, set to x times Identity Matrix
157 //
158 //    Matrix& swapRows(i1, i2)
159 //        Swap two rows
160 //
161 //    Matrix& swapCols(j1, j2)
162 //        Swap two columns
163 //
164 //    Matrix& permuteRows(const int* p)
165 //    Matrix& permuteRows(const int* p, int i1, int i2)
166 //        Perform a series of row swaps (0,p[0]), (1,p[1])...
167 //        In the second case, only do (i1,p[i1)...(i2-1,p[i2-1])
168 //    Matrix& reversePermuteRows(const int* p)
169 //    Matrix& reversePermuteRows(const int* p, int i1, int i2)
170 //        The same, but perform the swaps in reverse order
171 //
172 //    Matrix& permuteCols(const int* p)
173 //    Matrix& permuteCols(const int* p, int j1, int j2)
174 //        Perform a series of column swaps (0,p[0]), (1,p[1])...
175 //        In the second case, only do (j1,p[j1)...(j2-1,p[j2-1])
176 //    Matrix& reversePermuteCols(const int* p)
177 //    Matrix& reversePermuteCols(const int* p, int j1, int j2)
178 //        The same, but perform the swaps in reverse order
179 //
180 //    void Swap(Matrix& m1, Matrix& m2)
181 //        Swap the values of two Matrices
182 //        The Matrices must be the same size
183 //
184 // MatrixViews:
185 //
186 //    As with VectorViews, we have both constant and mutable views of Matrices.
187 //    A ConstMatrixView object can only view the underlying Matrix object
188 //    whereas a MatrixView object can modify it as well.
189 //    For the below routines, a ConstMatrixView is returned from
190 //    ConstMatrixViews and const Matrix objects.
191 //    A MatrixView is returned from MatrixViews and (non-const) Matrix objects.
192 //
193 //    MatrixView subMatrix(int i1, int i2, int j1, int j2,
194 //            int istep=1, int jstep=1)
195 //        This member function will return a submatrix using rows i1 to i2
196 //        and columns j1 to j2 (not inclusive of i2,j2) which refers
197 //        to the same physical elements as the original.
198 //        Thus, to make the matrix:
199 //           ( 0 0 1 0 )
200 //           ( 0 0 0 1 )
201 //           ( 2 2 0 0 )
202 //           ( 2 2 0 0 )
203 //        you could write:
204 //           Matrix<int> A(4,4,0);
205 //           A.subMatrix(0,2,2,4).setToIdentity();
206 //           A.subMatrix(2,4,0,2).setAllTo(2);
207 //        The substep values allow you to space the elements of
208 //        the submatrix at steps larger than 1.
209 //        eg. To make an 8x8 checkerboard of 1's and 0's, you could write:
210 //           Matrix<int> A(8,8,0);
211 //           A.subMatrix(0,8,1,9,2,2) = 1;
212 //           A.subMatrix(1,9,0,8,2,2) = 1;
213 //        Note that in this case the i2,j2 values need to be the
214 //        "one past the end" value given the step size, so 9 here when
215 //        starting at 1.
216 //
217 //    VectorView subVector(int i, int j, int istep, int jstep, int size)
218 //        Returns a subVector which starts at position (i,j) in the
219 //        matrix, moves in the directions (istep,jstep) and has a length
220 //        of size.
221 //        For example, the cross-diagonal from the lower left to the upper
222 //        right of a 6x6 matrix could be accessed using:
223 //        m.subVector(5,0,-1,1,6)
224 //
225 //    UpperTriMatrixView upperTri()
226 //    LowerTriMatrixView lowerTri()
227 //        Returns a view of the upper or lower triangle portion of the Matrix.
228 //
229 //    UpperTriMatrixView unitUpperTri()
230 //    LowerTriMatrixView unitLowerTri()
231 //        Returns a view of the upper or lower triangle portion of the Matrix
232 //        with unit-diagonal elements, rather than what is in the matrix.
233 //
234 //    MatrixView colPair(int j1, int j2)
235 //        This returns an Mx2 submatrix which consists of the
236 //        columns j1 and j2.  This is useful for multiplying two
237 //        (not necessarily adjacent) columns of a matrix by a 2x2 matrix.
238 //
239 //    MatrixView rowPair(int i1, int i2)
240 //        Same as above, but two rows.
241 //
242 //    MatrixView colRange(int j1, int j2)
243 //        This is shorthand for subMatrix(0,m.colsize(),j1,j2)
244 //
245 //    MatrixView rowRange(int i1, int i2)
246 //        This is shorthand for subMatrix(i1,i2,0,m.rowsize())
247 //
248 //    MatrixView realPart()
249 //    MatrixView imagPart()
250 //        Returns a view to the real/imag elements of a complex Matrix.
251 //
252 //    MatrixView view()
253 //        Returns a view of a matrix.
254 //
255 //    MatrixView conjugate()
256 //        Returns a view to the conjugate of a Matrix.
257 //
258 //    MatrixView transpose()
259 //        Returns a view to the transpose of a Matrix.
260 //
261 //    MatrixView adjoint()
262 //        Returns a view to the adjoint (conjugate transpose) of a Matrix.
263 //        Note: Some people define the adjoint as the cofactor matrix.
264 //              This is not the same as our definition of the adjoint.
265 //
266 //    ConstVectorView constLinearView()
267 //    VectorView linearView()
268 //        Returns a VectorView with all the elements of the Matrix.
269 //        This is mostly used internally for things like MaxElement
270 //        and conjugateSelf, where the matrix structure is irrelevant,
271 //        and we just want to do something to all the elements.
272 //        The corrolary function canLinearize() returns whether this is
273 //        allowed.
274 //
275 // Functions of Matrixs:
276 //
277 //    Det(m)
278 //    m.det()
279 //        Returns the determinant of a Matrix.
280 //        Note: If the matrix is not square, the determinant is not
281 //              well defined.  The returned value is such that
282 //              conj(det) * det = det(adjoint(m) * m)
283 //              So for real nonsquare matrices, the sign is arbitrary,
284 //              and for complex nonsquare matrices, it is multiplied
285 //              by an arbitrary phase.
286 //
287 //    LogDet(m)
288 //    m.logDet(T* sign=0)
289 //        Returns the logarithm of the absolute value of the determinant.
290 //        For many large matrices, the determinant yields to overflow.
291 //        Hence, this function is provided, which stably calculates the
292 //        natural logarithm of the absolute value of the determinant.
293 //        The optional sign argument returns the sign of the determinant
294 //        if T is real, or the factor exp(it) factor by which exp(logdet)
295 //        would have to be multiplied to get the actual determinant.
296 //
297 //    Trace(m)
298 //    m.trace()
299 //        Returns the trace of a Matrix.
300 //        = sum_i ( a_ii )
301 //
302 //    SumElements(m)
303 //    m.sumElements()
304 //        Returns the sum of the elements of a Matrix.
305 //        = sum_ij ( a_ij )
306 //
307 //    SumAbsElements(m)
308 //    m.sumAbsElements()
309 //        Returns the sum of the absolute values of the elements of a Matrix.
310 //        = sum_ij |a_ij|
311 //
312 //    SumAbs2Elements(m)
313 //    m.sumAbs2Elements()
314 //        Returns the sum of the absolute values of the elements of a Matrix.
315 //        = sum_ij |real(a_ij)| + |imag(a_ij)|
316 //
317 //    Norm(m) or NormF(m)
318 //    m.norm() or m.normF()
319 //        Return the Frobenius norm of a Matrix.
320 //        = sqrt( sum_ij |a_ij|^2 )
321 //
322 //    NormSq(m)
323 //    m.normSq(RT scale = 1.)
324 //        Returns the square of norm().
325 //        = sum_ij |a_ij|^2
326 //
327 //    Norm1(m)
328 //    m.norm1()
329 //        Returns the 1-norm of a Matrix.
330 //        = max_j (sum_i |a_ij|)
331 //
332 //    Norm2(m)
333 //    m.norm2()
334 //        Returns the 2-norm of a Matrix.
335 //        = sqrt( Max Eigenvalue of (A.adjoint * A) )
336 //        = Maximum singular value
337 //        Note: This norm is costly to calculate if one is not
338 //              otherwise doing a singular value decomposition
339 //              of the Matrix.
340 //
341 //    NormInf(m)
342 //    m.normInf()
343 //        Returns the infinity-norm of a Matrix.
344 //        = max_i (sum_j |a_ij|)
345 //
346 //    m.makeInverse(minv)
347 //        Sets minv to the inverse of m if it exists.
348 //        If m is singular and square, and LU is set for dividing
349 //          (LU is default for square matrices)
350 //          then a run-time error will occur.
351 //        If m is singular or not square and SV is set
352 //          then the returned matrix is the pseudo-inverse which satisfies:
353 //          MXM = M
354 //          XMX = X
355 //          (MX)T = MX
356 //          (XM)T = XM
357 //        [If dividing using QR or QRP, all but the last of these will
358 //         be true.]
359 //
360 //    m.makeInverseATA(invata)
361 //        Sets invata to the Inverse of (A.adjoint * A) for matrix m = A
362 //        If Ax=b is solved for x, then (AT A)^-1 is the
363 //        covariance matrix of the least-squares solution x
364 //
365 //    m.inverse()
366 //    Inverse(m)
367 //        Returns an auxiliary object that delays the calculation of the
368 //        inverse until there is appropriate storage for it.
369 //        m.makeInverse(minv) is equivalent to minv = m.inverse().
370 //
371 // Operators:
372 //        Here we use m for a Matrix, v for a Vector and x for a Scalar.
373 //
374 //        You can also mix real and complex Vectors of the same
375 //        underlying type.  eg. Matrix<double> and Matrix<complex<double> >
376 //
377 //    -m
378 //
379 //    m = m
380 //
381 //    m += m
382 //    m + m
383 //    m += x
384 //    m + x
385 //    x + m
386 //
387 //    m -= m
388 //    m - m
389 //    m -= x
390 //    m - x
391 //    x - m
392 //
393 //    m *= x
394 //    m *= m
395 //    m * x
396 //    x * m
397 //    m * v
398 //    v * m
399 //    v *= m
400 //    m * m
401 //
402 //    m /= x
403 //    v /= m
404 //    v %= m
405 //    m /= m
406 //    m %= m
407 //    m / x
408 //    x / m
409 //    v / m
410 //    v % m
411 //    m / m
412 //    m % m
413 //
414 //    m == m
415 //    m != m
416 //
417 //       Most of these behave in the logical way for dealing with matrices.
418 //       Two comments about behavior that might not be obvious:
419 //
420 //       1) Vectors are either row or column Vectors as appropriate.
421 //          eg. For m*v, v is a column Vector, but for v*m, v is a row Vector
422 //
423 //       2) Sometimes x should be thought of a x*I, where I is an appropriately
424 //          sized identity matrix.  For example m-1 means m-I,
425 //          and m += 3 means m += 3*I (or equivalently, m.diag().addToAll(3)).
426 //
427 //       3) Division by a matrix can be from either the left or the right.
428 //          ie. v/m can mean either m^-1 v or v m^-1
429 //          The first case is the solution of mx=v, the second is of xm = v.
430 //          Since the first case is the way one generally poses a problem
431 //          for solving a set of equations, we take v/m to be left-division.
432 //          If you want right-division (v m^-1), then we supply the % operator
433 //          to do so.
434 //          ie. v%m means v m^-1
435 //          If you want to be more explicit, you can write:
436 //          v/m as m.inverse() * v and v%m as v * m.inverse().
437 //          In all cases, the actual calculation is delayed until there is
438 //          storage to put it.  (Unless you string too many calculations
439 //          together, in which case it will use a temporary.)
440 //
441 //
442 // I/O:
443 //
444 //    os << m
445 //        Writes m to ostream os in the following format:
446 //          colsize rowsize
447 //          m(0,0) m(0,1) m(0,2) ... m(0,rowsize)
448 //          m(1,0) m(1,1) m(1,2) ... m(1,rowsize)
449 //          ...
450 //          m(colsize,0) ...
451 //
452 //    is >> m
453 //        Reads m from istream is in the same format
454 //
455 //
456 // Division Control Functions:
457 //
458 //    There are a number of algorithms available for dividing
459 //    matrices.  We provide functions to allow you to
460 //    change the algorithm used by the code on the fly.
461 //    In particular, you can write:
462 //    m.divideUsing(dt)
463 //    where dt is LU, QR, QRP, or SV
464 //    (ie. anything but CH)
465 //    Each of these also has an in-place version whcih overwrites the
466 //    current Matrix memory with the decomposition needed for
467 //    doing the division.  Obviously, if you try to use the Matrix
468 //    after doing setDiv (implicitly or explicitly), the results will
469 //    be invalid.
470 //
471 //    The default method is LU (LU Decomposition) for square
472 //    matrices and QR (QR Decomposition) for non-square.
473 //
474 //    See the header comment to TMV_Divider.h for more info about
475 //    the different algorithms.
476 //
477 //    There are also shorthands for accessing the decomposition.
478 //    If dt = LU, and the decomposition has been set, then
479 //    lud() returns the LUDiv<T> class
480 //    If it is not set yet, or divideUsing was called with some other dt,
481 //    then lud() sets the divider to LU for you and returns the
482 //    LU decomposition class.
483 //
484 //    Likewise:
485 //    qrd(), qrpd(), svd() return the corresponding Divider classes.
486 //
487 
488 
489 #ifndef TMV_Matrix_H
490 #define TMV_Matrix_H
491 
492 #include "tmv/TMV_BaseMatrix.h"
493 #include "tmv/TMV_BaseTriMatrix.h"
494 #include "tmv/TMV_Vector.h"
495 #include "tmv/TMV_Permutation.h"
496 #include "tmv/TMV_Array.h"
497 #include "tmv/TMV_MIt.h"
498 #include <vector>
499 
500 namespace tmv {
501 
502     template <typename T1, typename T2>
503     inline void Copy(const GenMatrix<T1>& m1, MatrixView<T2> m2);
504 
505     template <typename T, typename Tm>
506     class QuotXM;
507 
508     template <typename T>
509     class LUDiv;
510 
511     template <typename T>
512     class QRDiv;
513 
514     template <typename T>
515     class QRPDiv;
516 
517     template <typename T>
518     class SVDiv;
519 
520     template <typename T>
521     class GenMatrix :
522         public BaseMatrix<T>,
523         public DivHelper<T>
524     {
525     public:
526 
527         typedef TMV_RealType(T) RT;
528         typedef TMV_ComplexType(T) CT;
529         typedef T value_type;
530         typedef RT real_type;
531         typedef CT complex_type;
532         typedef GenMatrix<T> type;
533         typedef Matrix<T> copy_type;
534         typedef ConstVectorView<T> const_vec_type;
535         typedef ConstMatrixView<T> const_view_type;
536         typedef const_view_type const_transpose_type;
537         typedef const_view_type const_conjugate_type;
538         typedef const_view_type const_adjoint_type;
539         typedef ConstMatrixView<RT> const_realpart_type;
540         typedef ConstUpperTriMatrixView<T> const_uppertri_type;
541         typedef ConstLowerTriMatrixView<T> const_lowertri_type;
542         typedef MatrixView<T> nonconst_type;
543         typedef CRMIt<type> const_rowmajor_iterator;
544         typedef CCMIt<type> const_colmajor_iterator;
545 
546         //
547         // Constructors
548         //
549 
GenMatrix()550         inline GenMatrix() {}
GenMatrix(const type &)551         inline GenMatrix(const type&) {}
~GenMatrix()552         virtual inline ~GenMatrix() {}
553 
554         //
555         // Access Functions
556         //
557 
558         using AssignableToMatrix<T>::colsize;
559         using AssignableToMatrix<T>::rowsize;
560 
row(ptrdiff_t i)561         inline const_vec_type row(ptrdiff_t i) const
562         {
563             TMVAssert(i>=0 && i<colsize());
564             return const_vec_type(
565                 cptr()+i*ptrdiff_t(stepi()),rowsize(),stepj(),ct());
566         }
567 
col(ptrdiff_t j)568         inline const_vec_type col(ptrdiff_t j) const
569         {
570             TMVAssert(j>=0 && j<rowsize());
571             return const_vec_type(
572                 cptr()+j*ptrdiff_t(stepj()),colsize(),stepi(),ct());
573         }
574 
diag()575         inline const_vec_type diag() const
576         {
577             return const_vec_type(
578                 cptr(),TMV_MIN(colsize(),rowsize()),stepi()+stepj(),ct());
579         }
580 
diag(ptrdiff_t i)581         inline const_vec_type diag(ptrdiff_t i) const
582         {
583             TMVAssert(i>=-colsize() && i<=rowsize());
584             const ptrdiff_t diagstep = stepi() + stepj();
585             if (i >= 0) {
586                 const ptrdiff_t diagsize = TMV_MIN(colsize(),rowsize()-i);
587                 return const_vec_type(
588                     cptr()+i*ptrdiff_t(stepj()),diagsize,diagstep,ct());
589             } else {
590                 const ptrdiff_t diagsize = TMV_MIN(colsize()+i,rowsize());
591                 return const_vec_type(
592                     cptr()-i*ptrdiff_t(stepi()),diagsize,diagstep,ct());
593             }
594         }
595 
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)596         inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
597         {
598             TMVAssert(i>=0 && i<colsize());
599             TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
600             return const_vec_type(
601                 cptr()+i*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),j2-j1,stepj(),ct());
602         }
603 
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)604         inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const
605         {
606             TMVAssert(j>=0 && j<rowsize());
607             TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
608             return const_vec_type(
609                 cptr()+i1*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),i2-i1,stepi(),ct());
610         }
611 
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)612         inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
613         {
614             TMVAssert(i>=-colsize() && i<=rowsize());
615             const ptrdiff_t diagstep = stepi() + stepj();
616             if (i >= 0) {
617                 TMVAssert(j1>=0 && j1-j2<=0 &&
618                           j2<=TMV_MIN(colsize(),rowsize()-i));
619                 return const_vec_type(
620                     cptr()+i*ptrdiff_t(stepj())+j1*diagstep,j2-j1, diagstep,ct());
621             } else {
622                 TMVAssert(j1>=0 && j1-j2<=0 &&
623                           j2<=TMV_MIN(colsize()+i,rowsize()));
624                 return const_vec_type(
625                     cptr()-i*ptrdiff_t(stepi())+j1*diagstep,j2-j1, diagstep,ct());
626             }
627         }
628 
operator()629         inline T operator()(ptrdiff_t i, ptrdiff_t j) const
630         {
631             TMVAssert(i>=0 && i<colsize());
632             TMVAssert(j>=0 && j<rowsize());
633             return cref(i,j);
634         }
635 
636         inline const_vec_type operator[](ptrdiff_t i) const
637         {
638             TMVAssert(i>=0 && i<colsize());
639             return row(i);
640         }
641 
642         template <typename T2>
isSameAs(const BaseMatrix<T2> &)643         inline bool isSameAs(const BaseMatrix<T2>&) const
644         { return false; }
645 
isSameAs(const type & m2)646         inline bool isSameAs(const type& m2) const
647         {
648             return
649                 this==&m2 ||
650                 ( cptr()==m2.cptr() &&
651                   rowsize()==m2.rowsize() && colsize()==m2.colsize() &&
652                   stepi()==m2.stepi() && stepj()==m2.stepj() && ct()==m2.ct()
653                 );
654         }
655 
assignToM(MatrixView<RT> m2)656         inline void assignToM(MatrixView<RT> m2) const
657         {
658             TMVAssert(m2.colsize() == colsize());
659             TMVAssert(m2.rowsize() == rowsize());
660             TMVAssert(isReal(T()));
661             if (!isSameAs(m2)) Copy(*this,m2);
662         }
663 
assignToM(MatrixView<CT> m2)664         inline void assignToM(MatrixView<CT> m2) const
665         {
666             TMVAssert(m2.colsize() == colsize());
667             TMVAssert(m2.rowsize() == rowsize());
668             if (!isSameAs(m2)) Copy(*this,m2);
669         }
670 
671         //
672         // subMatrix
673         //
674 
675         bool hasSubMatrix(
676             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const;
677 
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)678         inline const_view_type cSubMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
679         {
680             return const_view_type(
681                 cptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
682                 i2-i1,j2-j1,stepi(),stepj(),ct());
683         }
684 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)685         inline const_view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
686         {
687             TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1));
688             return cSubMatrix(i1,i2,j1,j2);
689         }
690 
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)691         inline const_view_type cSubMatrix(
692             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
693         {
694             return const_view_type(
695                 cptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
696                 (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(),ct());
697         }
698 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)699         inline const_view_type subMatrix(
700             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
701         {
702             TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep));
703             return cSubMatrix(i1,i2,j1,j2,istep,jstep);
704         }
705 
706         bool hasSubVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const;
707 
cSubVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)708         inline const_vec_type cSubVector(
709             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
710         {
711             return const_vec_type(
712                 cptr()+i*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),s,
713                 istep*stepi()+jstep*stepj(),ct());
714         }
715 
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)716         inline const_vec_type subVector(
717             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
718         {
719             TMVAssert(hasSubVector(i,j,istep,jstep,s));
720             return cSubVector(i,j,istep,jstep,s);
721         }
722 
unitUpperTri()723         inline const_uppertri_type unitUpperTri() const
724         {
725             TMVAssert(rowsize() <= colsize());
726             return const_uppertri_type(
727                 cptr(),rowsize(),stepi(),stepj(),UnitDiag,ct() );
728         }
729 
730         inline const_uppertri_type upperTri(DiagType dt=NonUnitDiag) const
731         {
732             TMVAssert(rowsize() <= colsize());
733             return const_uppertri_type(
734                 cptr(),rowsize(),stepi(),stepj(),dt,ct() );
735         }
736 
unitLowerTri()737         inline const_lowertri_type unitLowerTri() const
738         {
739             TMVAssert(colsize() <= rowsize());
740             return const_lowertri_type(
741                 cptr(),colsize(),stepi(),stepj(),UnitDiag,ct() );
742         }
743 
744         inline const_lowertri_type lowerTri(DiagType dt=NonUnitDiag) const
745         {
746             TMVAssert(colsize() <= rowsize());
747             return const_lowertri_type(
748                 cptr(),colsize(),stepi(),stepj(),dt,ct() );
749         }
750 
cColPair(ptrdiff_t j1,ptrdiff_t j2)751         inline const_view_type cColPair(ptrdiff_t j1, ptrdiff_t j2) const
752         {
753             return const_view_type(
754                 cptr()+j1*ptrdiff_t(stepj()),colsize(),2,stepi(),(j2-j1)*stepj(),ct());
755         }
756 
colPair(ptrdiff_t j1,ptrdiff_t j2)757         inline const_view_type colPair(ptrdiff_t j1, ptrdiff_t j2) const
758         {
759             TMVAssert(j1>=0 && j1<rowsize() && j2>=0 && j2<rowsize());
760             return cColPair(j1,j2);
761         }
762 
cRowPair(ptrdiff_t i1,ptrdiff_t i2)763         inline const_view_type cRowPair(ptrdiff_t i1, ptrdiff_t i2) const
764         {
765             return const_view_type(
766                 cptr()+i1*ptrdiff_t(stepi()),2,rowsize(),(i2-i1)*stepi(),stepj(),ct());
767         }
768 
rowPair(ptrdiff_t i1,ptrdiff_t i2)769         inline const_view_type rowPair(ptrdiff_t i1, ptrdiff_t i2) const
770         {
771             TMVAssert(i1>=0 && i1<colsize() && i2>=0 && i2<colsize());
772             return cRowPair(i1,i2);
773         }
774 
cColRange(ptrdiff_t j1,ptrdiff_t j2)775         inline const_view_type cColRange(ptrdiff_t j1, ptrdiff_t j2) const
776         {
777             return const_view_type(
778                 cptr()+j1*ptrdiff_t(stepj()),colsize(),j2-j1,
779                 stepi(),stepj(),ct(),(iscm()&&ls())?-1:0);
780         }
781 
colRange(ptrdiff_t j1,ptrdiff_t j2)782         inline const_view_type colRange(ptrdiff_t j1, ptrdiff_t j2) const
783         {
784             TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
785             return cColRange(j1,j2);
786         }
787 
cRowRange(ptrdiff_t i1,ptrdiff_t i2)788         inline const_view_type cRowRange(ptrdiff_t i1, ptrdiff_t i2) const
789         {
790             return const_view_type(
791                 cptr()+i1*ptrdiff_t(stepi()),i2-i1,rowsize(),
792                 stepi(),stepj(),ct(),(isrm()&&ls())?-1:0);
793         }
794 
rowRange(ptrdiff_t i1,ptrdiff_t i2)795         inline const_view_type rowRange(ptrdiff_t i1, ptrdiff_t i2) const
796         {
797             TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
798             return cRowRange(i1,i2);
799         }
800 
realPart()801         inline const_realpart_type realPart() const
802         {
803             return const_realpart_type(
804                 reinterpret_cast<const RT*>(cptr()),colsize(),rowsize(),
805                 isReal(T()) ? stepi() : 2*stepi(),
806                 isReal(T()) ? stepj() : 2*stepj(),NonConj);
807         }
808 
imagPart()809         inline const_realpart_type imagPart() const
810         {
811             TMVAssert(isComplex(T()));
812             return const_realpart_type(
813                 reinterpret_cast<const RT*>(cptr())+1,
814                 colsize(),rowsize(),2*stepi(),2*stepj(),NonConj);
815         }
816 
817         //
818         // Views
819         //
820 
view()821         inline const_view_type view() const
822         {
823             return const_view_type(
824                 cptr(),colsize(),rowsize(),stepi(),stepj(),ct(),ls());
825         }
826 
transpose()827         inline const_view_type transpose() const
828         {
829             return const_view_type(
830                 cptr(),rowsize(),colsize(),stepj(),stepi(),ct(),ls());
831         }
832 
conjugate()833         inline const_view_type conjugate() const
834         {
835             return const_view_type(
836                 cptr(),colsize(),rowsize(),
837                 stepi(),stepj(),TMV_ConjOf(T,ct()),ls());
838         }
839 
adjoint()840         inline const_view_type adjoint() const
841         {
842             return const_view_type(
843                 cptr(),rowsize(),colsize(),
844                 stepj(),stepi(),TMV_ConjOf(T,ct()),ls());
845         }
846 
constLinearView()847         inline const_vec_type constLinearView() const
848         {
849             TMVAssert(ls() != -1);
850             // To assure that next Assert has no effect
851 
852             TMVAssert(canLinearize());
853             TMVAssert(ls() == colsize()*rowsize());
854             return const_vec_type(cptr(),ls(),1,ct());
855         }
856 
nonConst()857         inline nonconst_type nonConst() const
858         {
859             return nonconst_type(
860                 const_cast<T*>(cptr()),colsize(),rowsize(),
861                 stepi(),stepj(),ct(),ls()
862                 TMV_FIRSTLAST1(cptr(),row(colsize()-1).end().getP()));
863         }
864 
865         //
866         // Functions of Matrix
867         //
868 
869         T det() const;
870 
871         RT logDet(T* sign=0) const;
872 
873         bool isSingular() const;
874 
trace()875         inline T trace() const
876         { return diag().sumElements(); }
877 
878         T sumElements() const;
879 
880         RT sumAbsElements() const;
881 
882         RT sumAbs2Elements() const;
883 
norm()884         inline RT norm() const
885         { return normF(); }
886 
887         RT normF() const;
888 
889         // normF()^2
890         RT normSq(const RT scale = RT(1)) const;
891 
892         // 1-norm = max_j (sum_i |a_ij|)
893         RT norm1() const;
894 
895         // inf-norm = max_i (sum_j |a_ij|)
normInf()896         inline RT normInf() const
897         { return transpose().norm1(); }
898 
899         // = max_i,j (|a_ij|)
900         RT maxAbsElement() const;
901 
902         // = max_i,j (|real(a_ij)|+|imag(a_ij)|)
903         RT maxAbs2Element() const;
904 
905         RT doNorm2() const;
norm2()906         inline RT norm2() const
907         {
908             if (this->divIsSet() && this->getDivType() == SV)
909                 return DivHelper<T>::norm2();
910             else return doNorm2();
911         }
912 
913         RT doCondition() const;
condition()914         inline RT condition() const
915         {
916             if (this->divIsSet() && this->getDivType() == SV)
917                 return DivHelper<T>::condition();
918             else return doCondition();
919         }
920 
921         // icpc gives a strange compiler error if I don't do this
922         // throwugh QInverse.  I think I should be able to just write:
923         // QuotXM<T,T> inverse() const;
924         // and then define this in TMV_Matrix.cpp, but that doesn't work.
925         QuotXM<T,T> QInverse() const;
inverse()926         inline QuotXM<T,T> inverse() const
927         { return QInverse(); }
928 
929         //
930         // Division Control
931         //
932 
933         void setDiv() const;
934 
divideUsing(DivType dt)935         inline void divideUsing(DivType dt) const
936         {
937             TMVAssert(dt == LU || dt == QR || dt == QRP || dt == SV);
938             DivHelper<T>::divideUsing(dt);
939         }
940 
lud()941         inline const LUDiv<T>& lud() const
942         {
943             divideUsing(LU);
944             setDiv();
945             TMVAssert(this->getDiv());
946             TMVAssert(divIsLUDiv());
947             return static_cast<const LUDiv<T>&>(*this->getDiv());
948         }
949 
qrd()950         inline const QRDiv<T>& qrd() const
951         {
952             divideUsing(QR);
953             setDiv();
954             TMVAssert(this->getDiv());
955             TMVAssert(divIsQRDiv());
956             return static_cast<const QRDiv<T>&>(*this->getDiv());
957         }
958 
qrpd()959         inline const QRPDiv<T>& qrpd() const
960         {
961             divideUsing(QRP);
962             setDiv();
963             TMVAssert(this->getDiv());
964             TMVAssert(divIsQRPDiv());
965             return static_cast<const QRPDiv<T>&>(*this->getDiv());
966         }
967 
svd()968         inline const SVDiv<T>& svd() const
969         {
970             divideUsing(SV);
971             setDiv();
972             TMVAssert(this->getDiv());
973             TMVAssert(divIsSVDiv());
974             return static_cast<const SVDiv<T>&>(*this->getDiv());
975         }
976 
977 
978         //
979         // I/O
980         //
981 
982         void write(const TMV_Writer& writer) const;
983 
984         virtual const T* cptr() const = 0;
985         virtual ptrdiff_t stepi() const = 0;
986         virtual ptrdiff_t stepj() const = 0;
987         virtual ptrdiff_t ls() const = 0;
isrm()988         virtual inline bool isrm() const { return stepj() == 1; }
iscm()989         virtual inline bool iscm() const { return stepi() == 1; }
isconj()990         virtual inline bool isconj() const
991         { return isComplex(T()) && ct()==Conj; }
992         virtual ConjType ct() const =0;
993 
994         virtual bool canLinearize() const = 0;
995         virtual T cref(ptrdiff_t i, ptrdiff_t j) const;
996 
rowstart(ptrdiff_t)997         inline ptrdiff_t rowstart(ptrdiff_t ) const { return 0; }
rowend(ptrdiff_t)998         inline ptrdiff_t rowend(ptrdiff_t ) const { return rowsize(); }
colstart(ptrdiff_t)999         inline ptrdiff_t colstart(ptrdiff_t ) const { return 0; }
colend(ptrdiff_t)1000         inline ptrdiff_t colend(ptrdiff_t ) const { return colsize(); }
1001 
rowmajor_begin()1002         inline const_rowmajor_iterator rowmajor_begin() const
1003         { return const_rowmajor_iterator(this,0,0); }
rowmajor_end()1004         inline const_rowmajor_iterator rowmajor_end() const
1005         { return const_rowmajor_iterator(this,colsize(),0); }
1006 
colmajor_begin()1007         inline const_colmajor_iterator colmajor_begin() const
1008         { return const_colmajor_iterator(this,0,0); }
colmajor_end()1009         inline const_colmajor_iterator colmajor_end() const
1010         { return const_colmajor_iterator(this,0,rowsize()); }
1011 
1012     protected :
1013 
getMatrix()1014         inline const BaseMatrix<T>& getMatrix() const { return *this; }
1015 
1016     private :
1017 
1018         type& operator=(const type&);
1019 
1020         bool divIsLUDiv() const;
1021         bool divIsQRDiv() const;
1022         bool divIsQRPDiv() const;
1023         bool divIsSVDiv() const;
1024 
1025     }; // GenMatrix
1026 
1027     template <typename T, int A>
1028     class ConstMatrixView : public GenMatrix<T>
1029     {
1030     public :
1031 
1032         typedef GenMatrix<T> base;
1033         typedef ConstMatrixView<T,A> type;
1034 
ConstMatrixView(const type & rhs)1035         inline ConstMatrixView(const type& rhs) :
1036             itsm(rhs.itsm), itscs(rhs.itscs), itsrs(rhs.itsrs),
1037             itssi(rhs.itssi), itssj(rhs.itssj),
1038             itsct(rhs.itsct), linsize(rhs.linsize)
1039         { TMVAssert(Attrib<A>::viewok); }
1040 
ConstMatrixView(const base & rhs)1041         inline ConstMatrixView(const base& rhs) :
1042             itsm(rhs.cptr()), itscs(rhs.colsize()), itsrs(rhs.rowsize()),
1043             itssi(rhs.stepi()), itssj(rhs.stepj()),
1044             itsct(rhs.ct()), linsize(rhs.ls())
1045         { TMVAssert(Attrib<A>::viewok); }
1046 
1047         inline ConstMatrixView(
1048             const T* _m, ptrdiff_t _cs, ptrdiff_t _rs, ptrdiff_t _si, ptrdiff_t _sj,
1049             ConjType _ct, ptrdiff_t _ls=0) :
itsm(_m)1050             itsm(_m), itscs(_cs), itsrs(_rs), itssi(_si), itssj(_sj),
1051             itsct(_ct), linsize(_ls)
1052         {
1053             TMVAssert(Attrib<A>::viewok);
1054             TMVAssert(linsize==0 || linsize==-1 ||
1055                       ((itssi==1 || itssj==1) && linsize == itscs*itsrs));
1056         }
1057 
~ConstMatrixView()1058         virtual inline ~ConstMatrixView()
1059         {
1060 #ifdef TMV_EXTRA_DEBUG
1061             const_cast<const T*&>(itsm) = 0;
1062 #endif
1063         }
1064 
colsize()1065         virtual inline ptrdiff_t colsize() const { return itscs; }
rowsize()1066         virtual inline ptrdiff_t rowsize() const { return itsrs; }
cptr()1067         virtual inline const T* cptr() const { return itsm; }
stepi()1068         virtual inline ptrdiff_t stepi() const { return itssi; }
stepj()1069         virtual inline ptrdiff_t stepj() const { return itssj; }
ct()1070         virtual inline ConjType ct() const { return itsct; }
ls()1071         virtual inline ptrdiff_t ls() const { return linsize; }
1072         using GenMatrix<T>::isrm;
1073         using GenMatrix<T>::iscm;
1074 
canLinearize()1075         virtual inline bool canLinearize() const
1076         {
1077             if (linsize == -1) {
1078                 if ( (stepi() == 1 && stepj() == colsize()) ||
1079                      (stepj() == 1 && stepi() == rowsize()) )
1080                     linsize = rowsize() * colsize();
1081                 else
1082                     linsize = 0;
1083             }
1084             TMVAssert(linsize == 0 ||
1085                       (this->isrm() && stepi() == rowsize()) ||
1086                       (this->iscm() && stepj() == colsize()));
1087             return linsize > 0;
1088         }
1089 
1090     protected :
1091 
1092         const T*const itsm;
1093         const ptrdiff_t itscs;
1094         const ptrdiff_t itsrs;
1095         const ptrdiff_t itssi;
1096         const ptrdiff_t itssj;
1097         const ConjType itsct;
1098 
1099         mutable ptrdiff_t linsize;
1100 
1101     private :
1102 
1103         type& operator=(const type&);
1104 
1105     }; // ConstMatrixView
1106 
1107     template <typename T>
1108     class ConstMatrixView<T,FortranStyle> :
1109         public ConstMatrixView<T,CStyle>
1110     {
1111     public :
1112 
1113         typedef TMV_RealType(T) RT;
1114         typedef GenMatrix<T> base;
1115         typedef ConstMatrixView<T,FortranStyle> type;
1116         typedef ConstMatrixView<T,CStyle> c_type;
1117         typedef ConstMatrixView<T,FortranStyle> const_view_type;
1118         typedef const_view_type const_transpose_type;
1119         typedef const_view_type const_conjugate_type;
1120         typedef const_view_type const_adjoint_type;
1121         typedef ConstVectorView<T,FortranStyle> const_vec_type;
1122         typedef ConstMatrixView<RT,FortranStyle> const_realpart_type;
1123         typedef ConstUpperTriMatrixView<T,FortranStyle> const_uppertri_type;
1124         typedef ConstLowerTriMatrixView<T,FortranStyle> const_lowertri_type;
1125         typedef MatrixView<T,FortranStyle> nonconst_type;
1126 
ConstMatrixView(const ConstMatrixView<T> & rhs)1127         inline ConstMatrixView(const ConstMatrixView<T>& rhs) : c_type(rhs) {}
1128 
ConstMatrixView(const GenMatrix<T> & rhs)1129         inline ConstMatrixView(const GenMatrix<T>& rhs) : c_type(rhs) {}
1130 
1131         inline ConstMatrixView(
1132             const T* _m, ptrdiff_t _cs, ptrdiff_t _rs, ptrdiff_t _si, ptrdiff_t _sj,
1133             ConjType _ct, ptrdiff_t linsize=0) :
c_type(_m,_cs,_rs,_si,_sj,_ct,linsize)1134             c_type(_m,_cs,_rs,_si,_sj,_ct,linsize) {}
1135 
~ConstMatrixView()1136         virtual inline ~ConstMatrixView() {}
1137 
1138 
1139         //
1140         // Access
1141         //
1142 
operator()1143         inline T operator()(ptrdiff_t i, ptrdiff_t j)
1144         {
1145             TMVAssert(i>0 && i<=this->colsize());
1146             TMVAssert(j>0 && j<=this->rowsize());
1147             return base::cref(i-1,j-1);
1148         }
1149 
row(ptrdiff_t i)1150         inline const_vec_type row(ptrdiff_t i) const
1151         {
1152             TMVAssert(i>0 && i<=this->colsize());
1153             return base::row(i-1);
1154         }
1155 
col(ptrdiff_t j)1156         inline const_vec_type col(ptrdiff_t j) const
1157         {
1158             TMVAssert(j>0 && j<=this->rowsize());
1159             return base::col(j-1);
1160         }
1161 
diag()1162         inline const_vec_type diag() const
1163         { return base::diag(); }
1164 
diag(ptrdiff_t i)1165         inline const_vec_type diag(ptrdiff_t i) const
1166         { return base::diag(i); }
1167 
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1168         inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
1169         {
1170             TMVAssert(i>0 && i<=this->colsize());
1171             TMVAssert(j1>0 && j1-j2<=0 && j2<=this->rowsize());
1172             return base::row(i-1,j1-1,j2);
1173         }
1174 
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)1175         inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const
1176         {
1177             TMVAssert(j>0 && j<=this->rowsize());
1178             TMVAssert(i1 > 0 && i1 <= i2 && i2 <= this->colsize());
1179             return base::col(j-1,i1-1,i2);
1180         }
1181 
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1182         inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
1183         {
1184             TMVAssert(j1 > 0);
1185             return base::diag(i,j1-1,j2);
1186         }
1187 
1188         inline const_vec_type operator[](ptrdiff_t i) const
1189         { return row(i); }
1190 
1191         //
1192         // subMatrix
1193         //
1194 
1195         bool hasSubMatrix(
1196             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const;
1197 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)1198         inline const_view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
1199         {
1200             TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1));
1201             return base::cSubMatrix(i1-1,i2,j1-1,j2);
1202         }
1203 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)1204         inline const_view_type subMatrix(
1205             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
1206         {
1207             TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep));
1208             return base::cSubMatrix(
1209                 i1-1,i2-1+istep,j1-1,j2-1+jstep,istep,jstep);
1210         }
1211 
1212         bool hasSubVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const;
1213 
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)1214         inline const_vec_type subVector(
1215             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
1216         {
1217             TMVAssert(hasSubVector(i,j,istep,jstep,s));
1218             return base::cSubVector(i-1,j-1,istep,jstep,s);
1219         }
1220 
unitUpperTri()1221         inline const_uppertri_type unitUpperTri() const
1222         { return base::upperTri(UnitDiag); }
1223 
1224         inline const_uppertri_type upperTri(DiagType dt=NonUnitDiag) const
1225         { return base::upperTri(dt); }
1226 
unitLowerTri()1227         inline const_lowertri_type unitLowerTri() const
1228         { return base::lowerTri(UnitDiag); }
1229 
1230         inline const_lowertri_type lowerTri(DiagType dt=NonUnitDiag) const
1231         { return base::lowerTri(dt); }
1232 
colPair(ptrdiff_t j1,ptrdiff_t j2)1233         inline const_view_type colPair(ptrdiff_t j1, ptrdiff_t j2) const
1234         {
1235             TMVAssert(j1 > 0 && j1 <= this->rowsize());
1236             TMVAssert(j2 > 0 && j2 <= this->rowsize());
1237             return base::cColPair(j1-1,j2-1);
1238         }
1239 
rowPair(ptrdiff_t i1,ptrdiff_t i2)1240         inline const_view_type rowPair(ptrdiff_t i1, ptrdiff_t i2) const
1241         {
1242             TMVAssert(i1 > 0 && i1 <= this->colsize());
1243             TMVAssert(i2 > 0 && i2 <= this->colsize());
1244             return base::cRowPair(i1-1,i2-1);
1245         }
1246 
colRange(ptrdiff_t j1,ptrdiff_t j2)1247         inline const_view_type colRange(ptrdiff_t j1, ptrdiff_t j2) const
1248         {
1249             TMVAssert(j1 > 0 && j1 <= j2 && j2 <= this->rowsize());
1250             return base::cColRange(j1-1,j2);
1251         }
1252 
rowRange(ptrdiff_t i1,ptrdiff_t i2)1253         inline const_view_type rowRange(ptrdiff_t i1, ptrdiff_t i2) const
1254         {
1255             TMVAssert(i1 > 0 && i1 <= i2 && i2 <= this->colsize());
1256             return base::cRowRange(i1-1,i2);
1257         }
1258 
realPart()1259         inline const_realpart_type realPart() const
1260         { return base::realPart(); }
1261 
imagPart()1262         inline const_realpart_type imagPart() const
1263         { return base::imagPart(); }
1264 
1265         //
1266         // Views
1267         //
1268 
view()1269         inline const_view_type view() const
1270         { return base::view(); }
1271 
transpose()1272         inline const_view_type transpose() const
1273         { return base::transpose(); }
1274 
conjugate()1275         inline const_view_type conjugate() const
1276         { return base::conjugate(); }
1277 
adjoint()1278         inline const_view_type adjoint() const
1279         { return base::adjoint(); }
1280 
constLinearView()1281         inline const_vec_type constLinearView() const
1282         { return base::constLinearView(); }
1283 
nonConst()1284         inline nonconst_type nonConst() const
1285         { return base::nonConst(); }
1286 
1287     private :
1288 
1289         type& operator=(const type&);
1290 
1291     }; // FortranStyle ConstMatrixView
1292 
1293     template <typename T, int A>
1294     class MatrixView : public GenMatrix<T>
1295     {
1296     public:
1297 
1298         typedef TMV_RealType(T) RT;
1299         typedef TMV_ComplexType(T) CT;
1300         typedef GenMatrix<T> base;
1301         typedef MatrixView<T,A> type;
1302         typedef MatrixView<T,A> view_type;
1303         typedef view_type transpose_type;
1304         typedef view_type conjugate_type;
1305         typedef view_type adjoint_type;
1306         typedef MatrixView<RT,A> realpart_type;
1307         typedef VectorView<T,A> vec_type;
1308         typedef UpperTriMatrixView<T,A> uppertri_type;
1309         typedef LowerTriMatrixView<T,A> lowertri_type;
1310         typedef typename RefHelper<T>::reference reference;
1311         typedef ConstMatrixView<T,A> const_view_type;
1312         typedef const_view_type const_transpose_type;
1313         typedef const_view_type const_conjugate_type;
1314         typedef const_view_type const_adjoint_type;
1315         typedef ConstMatrixView<RT,A> const_realpart_type;
1316         typedef ConstVectorView<T,A> const_vec_type;
1317         typedef ConstUpperTriMatrixView<T,A> const_uppertri_type;
1318         typedef ConstLowerTriMatrixView<T,A> const_lowertri_type;
1319         typedef RMIt<type> rowmajor_iterator;
1320         typedef CMIt<type> colmajor_iterator;
1321         typedef RMIt<const type> const_rowmajor_iterator;
1322         typedef CMIt<const type> const_colmajor_iterator;
1323 
1324         //
1325         // Constructors
1326         //
1327 
MatrixView(const type & rhs)1328         inline MatrixView(const type& rhs) :
1329             itsm(rhs.itsm), itscs(rhs.itscs), itsrs(rhs.itsrs),
1330             itssi(rhs.itssi), itssj(rhs.itssj),
1331             itsct(rhs.itsct), linsize(rhs.linsize)
1332             TMV_DEFFIRSTLAST(rhs._first,rhs._last)
1333         { TMVAssert(Attrib<A>::viewok); }
1334 
1335         inline MatrixView(
1336             T* _m, ptrdiff_t _cs, ptrdiff_t _rs, ptrdiff_t _si, ptrdiff_t _sj,
1337             ConjType _ct, ptrdiff_t _ls=0 TMV_PARAMFIRSTLAST(T) ) :
itsm(_m)1338             itsm(_m), itscs(_cs), itsrs(_rs), itssi(_si), itssj(_sj),
1339             itsct(_ct), linsize(_ls)
1340             TMV_DEFFIRSTLAST(_first,_last)
1341         {
1342             TMVAssert(Attrib<A>::viewok);
1343             TMVAssert(linsize==0 || linsize==-1 ||
1344                       ((itssi==1 || itssj==1) && linsize == itscs*itsrs));
1345         }
1346 
~MatrixView()1347         virtual inline ~MatrixView()
1348         {
1349             TMV_SETFIRSTLAST(0,0);
1350 #ifdef TMV_EXTRA_DEBUG
1351             const_cast<T*&>(itsm) = 0;
1352 #endif
1353         }
1354 
1355         //
1356         // Op=
1357         //
1358 
1359         inline type& operator=(const MatrixView<T,A>& m2)
1360         {
1361             TMVAssert(m2.colsize() == colsize());
1362             TMVAssert(m2.rowsize() == rowsize());
1363             m2.assignToM(*this);
1364             return *this;
1365         }
1366 
1367         inline type& operator=(const GenMatrix<RT>& m2)
1368         {
1369             TMVAssert(m2.colsize() == colsize());
1370             TMVAssert(m2.rowsize() == rowsize());
1371             m2.assignToM(*this);
1372             return *this;
1373         }
1374 
1375         inline type& operator=(const GenMatrix<CT>& m2)
1376         {
1377             TMVAssert(m2.colsize() == colsize());
1378             TMVAssert(m2.rowsize() == rowsize());
1379             TMVAssert(isComplex(T()));
1380             m2.assignToM(*this);
1381             return *this;
1382         }
1383 
1384         template <typename T2>
1385         inline type& operator=(const GenMatrix<T2>& m2)
1386         {
1387             TMVAssert(isComplex(T()) || isReal(T2()));
1388             Copy(m2,*this);
1389             return *this;
1390         }
1391 
1392         inline type& operator=(const T& x)
1393         { return setToIdentity(x); }
1394 
1395         inline type& operator=(const AssignableToMatrix<RT>& m2)
1396         {
1397             TMVAssert(colsize() == m2.colsize());
1398             TMVAssert(rowsize() == m2.rowsize());
1399             m2.assignToM(*this);
1400             return *this;
1401         }
1402 
1403         inline type& operator=(const AssignableToMatrix<CT>& m2)
1404         {
1405             TMVAssert(colsize() == m2.colsize());
1406             TMVAssert(rowsize() == m2.rowsize());
1407             TMVAssert(isComplex(T()));
1408             m2.assignToM(*this);
1409             return *this;
1410         }
1411 
1412         inline type& operator=(const Permutation& m2)
1413         {
1414             m2.assignToM(*this);
1415             return *this;
1416         }
1417 
1418         template <typename T2, ptrdiff_t M, ptrdiff_t N, int A2>
1419         inline type& operator=(const SmallMatrix<T2,M,N,A2>& m2)
1420         {
1421             TMVAssert(colsize() == M && rowsize() == N);
1422             TMVAssert(isComplex(T()) || isReal(T2()));
1423             Copy(m2.view(),*this);
1424             return *this;
1425         }
1426 
1427         typedef ListAssigner<T,rowmajor_iterator> MyListAssigner;
1428         inline MyListAssigner operator<<(const T& x)
1429         { return MyListAssigner(rowmajor_begin(),colsize()*rowsize(),x); }
1430 
1431         //
1432         // Access
1433         //
1434 
operator()1435         inline reference operator()(ptrdiff_t i,ptrdiff_t j)
1436         {
1437             TMVAssert(i>=0 && i<colsize());
1438             TMVAssert(j>=0 && j<rowsize());
1439             return ref(i,j);
1440         }
1441 
1442         inline vec_type operator[](ptrdiff_t i)
1443         {
1444             TMVAssert(i>=0 && i<colsize());
1445             return row(i);
1446         }
1447 
row(ptrdiff_t i)1448         inline vec_type row(ptrdiff_t i)
1449         {
1450             TMVAssert(i>=0 && i<colsize());
1451             return vec_type(
1452                 ptr()+i*ptrdiff_t(stepi()), rowsize(),stepj(),ct() TMV_FIRSTLAST );
1453         }
1454 
col(ptrdiff_t j)1455         inline vec_type col(ptrdiff_t j)
1456         {
1457             TMVAssert(j>=0 && j<rowsize());
1458             return vec_type(
1459                 ptr()+j*ptrdiff_t(stepj()), colsize(),stepi(),ct() TMV_FIRSTLAST );
1460         }
1461 
diag()1462         inline vec_type diag()
1463         {
1464             return vec_type(
1465                 ptr(), TMV_MIN(colsize(),rowsize()),stepi()+stepj(),ct()
1466                 TMV_FIRSTLAST);
1467         }
1468 
diag(ptrdiff_t i)1469         inline vec_type diag(ptrdiff_t i)
1470         {
1471             TMVAssert(i>=-colsize() && i<=rowsize());
1472             const ptrdiff_t diagstep = stepi() + stepj();
1473             if (i >= 0) {
1474                 const ptrdiff_t diagsize = TMV_MIN(colsize(),rowsize()-i);
1475                 return vec_type(
1476                     ptr()+i*ptrdiff_t(stepj()), diagsize,diagstep,ct() TMV_FIRSTLAST );
1477             } else {
1478                 const ptrdiff_t diagsize = TMV_MIN(colsize()+i,rowsize());
1479                 return vec_type(
1480                     ptr()-i*ptrdiff_t(stepi()), diagsize,diagstep,ct() TMV_FIRSTLAST );
1481             }
1482         }
1483 
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1484         inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
1485         {
1486             TMVAssert(i>=0 && i<colsize());
1487             TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
1488             return vec_type(
1489                 ptr()+i*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()), j2-j1,stepj(),ct() TMV_FIRSTLAST );
1490         }
1491 
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)1492         inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2)
1493         {
1494             TMVAssert(j>=0 && j<rowsize());
1495             TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
1496             return vec_type(
1497                 ptr()+i1*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()), i2-i1,stepi(),ct() TMV_FIRSTLAST );
1498         }
1499 
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1500         inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
1501         {
1502             TMVAssert(i>=-colsize() && i<=rowsize());
1503             const ptrdiff_t diagstep = stepi() + stepj();
1504             if (i >= 0) {
1505                 TMVAssert(
1506                     j1>=0 && j1-j2<=0 &&
1507                     j2<=TMV_MIN(colsize(),rowsize()-i));
1508                 return vec_type(
1509                     ptr()+i*ptrdiff_t(stepj())+j1*diagstep, j2-j1,diagstep,ct()
1510                     TMV_FIRSTLAST );
1511             } else {
1512                 TMVAssert(
1513                     j1>=0 && j1-j2<=0 &&
1514                     j2<=TMV_MIN(colsize()+i,rowsize()));
1515                 return vec_type(
1516                     ptr()-i*ptrdiff_t(stepi())+j1*diagstep, j2-j1,diagstep,ct()
1517                     TMV_FIRSTLAST );
1518             }
1519         }
1520 
1521         // Repeat the const versions:
operator()1522         inline T operator()(ptrdiff_t i,ptrdiff_t j) const
1523         { return base::operator()(i,j); }
1524         inline const_vec_type operator[](ptrdiff_t i) const
1525         { return base::operator[](i); }
row(ptrdiff_t i)1526         inline const_vec_type row(ptrdiff_t i) const
1527         { return base::row(i); }
col(ptrdiff_t j)1528         inline const_vec_type col(ptrdiff_t j) const
1529         { return base::col(j); }
diag()1530         inline const_vec_type diag() const
1531         { return base::diag(); }
diag(ptrdiff_t i)1532         inline const_vec_type diag(ptrdiff_t i) const
1533         { return base::diag(i); }
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1534         inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
1535         { return base::row(i,j1,j2); }
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)1536         inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const
1537         { return base::col(j,i1,i2); }
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)1538         inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
1539         { return base::diag(i,j1,j2); }
1540 
1541         //
1542         // Modifying Functions
1543         //
1544 
1545         type& setZero();
1546 
1547         type& setAllTo(const T& x);
1548 
1549         type& addToAll(const T& x);
1550 
1551         type& clip(RT thresh);
1552 
1553         type& transposeSelf();
1554 
1555         type& conjugateSelf();
1556 
1557         type& setToIdentity(const T& x=T(1));
1558 
swapRows(ptrdiff_t i1,ptrdiff_t i2)1559         inline type& swapRows(ptrdiff_t i1, ptrdiff_t i2)
1560         {
1561             TMVAssert(i1>=0 && i1 < colsize() &&
1562                       i2>=0 && i2 < colsize());
1563             if (i1!=i2) Swap(row(i1),row(i2));
1564             return *this;
1565         }
1566 
swapCols(ptrdiff_t j1,ptrdiff_t j2)1567         inline type& swapCols(ptrdiff_t j1, ptrdiff_t j2)
1568         {
1569             TMVAssert(j1>=0 && j1 < rowsize() &&
1570                       j2>=0 && j2 < rowsize());
1571             if (j1!=j2) Swap(col(j1),col(j2));
1572             return *this;
1573         }
1574 
1575         type& permuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2);
1576 
permuteRows(const ptrdiff_t * p)1577         inline type& permuteRows(const ptrdiff_t* p)
1578         { return permuteRows(p,0,colsize()); }
1579 
permuteCols(const ptrdiff_t * p,ptrdiff_t j1,ptrdiff_t j2)1580         inline type& permuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
1581         { transpose().permuteRows(p,j1,j2); return *this; }
1582 
permuteCols(const ptrdiff_t * p)1583         inline type& permuteCols(const ptrdiff_t* p)
1584         { return permuteCols(p,0,rowsize()); }
1585 
1586         type& reversePermuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2);
1587 
reversePermuteRows(const ptrdiff_t * p)1588         inline type& reversePermuteRows(const ptrdiff_t* p)
1589         { return reversePermuteRows(p,0,colsize()); }
1590 
reversePermuteCols(const ptrdiff_t * p,ptrdiff_t j1,ptrdiff_t j2)1591         inline type& reversePermuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
1592         { transpose().reversePermuteRows(p,j1,j2); return *this; }
1593 
reversePermuteCols(const ptrdiff_t * p)1594         inline type& reversePermuteCols(const ptrdiff_t* p)
1595         { return reversePermuteCols(p,0,rowsize()); }
1596 
1597         //
1598         // subMatrix
1599         //
1600 
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)1601         inline view_type cSubMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2)
1602         {
1603             return type(
1604                 ptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
1605                 i2-i1,j2-j1,stepi(),stepj(),ct() TMV_FIRSTLAST );
1606         }
1607 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)1608         inline view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2)
1609         {
1610             TMVAssert(base::hasSubMatrix(i1,i2,j1,j2,1,1));
1611             return cSubMatrix(i1,i2,j1,j2);
1612         }
1613 
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)1614         inline view_type cSubMatrix(
1615             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep)
1616         {
1617             return type(
1618                 ptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
1619                 (i2-i1)/istep, (j2-j1)/jstep, istep*stepi(), jstep*stepj(),ct()
1620                 TMV_FIRSTLAST );
1621         }
1622 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)1623         inline view_type subMatrix(
1624             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep)
1625         {
1626             TMVAssert(base::hasSubMatrix(i1,i2,j1,j2,istep,jstep));
1627             return cSubMatrix(i1,i2,j1,j2,istep,jstep);
1628         }
1629 
cSubVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t size)1630         inline vec_type cSubVector(
1631             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t size)
1632         {
1633             TMVAssert(size >= 0);
1634             return vec_type(
1635                 ptr()+i*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),size,
1636                 istep*stepi()+jstep*stepj(),ct()
1637                 TMV_FIRSTLAST );
1638         }
1639 
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t size)1640         inline vec_type subVector(
1641             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t size)
1642         {
1643             TMVAssert(size >= 0);
1644             TMVAssert(base::hasSubVector(i,j,istep,jstep,size));
1645             return cSubVector(i,j,istep,jstep,size);
1646         }
1647 
unitUpperTri()1648         inline uppertri_type unitUpperTri()
1649         {
1650             TMVAssert(rowsize() <= colsize());
1651             return uppertri_type(
1652                 ptr(),rowsize(),stepi(),stepj(),UnitDiag,ct()
1653                 TMV_FIRSTLAST);
1654         }
1655 
1656         inline uppertri_type upperTri(DiagType dt=NonUnitDiag)
1657         {
1658             TMVAssert(rowsize() <= colsize());
1659             return uppertri_type(
1660                 ptr(),rowsize(),stepi(),stepj(), dt,ct() TMV_FIRSTLAST);
1661         }
1662 
unitLowerTri()1663         inline lowertri_type unitLowerTri()
1664         {
1665             TMVAssert(colsize() <= rowsize());
1666             return lowertri_type(
1667                 ptr(),colsize(),stepi(),stepj(),UnitDiag,ct()
1668                 TMV_FIRSTLAST);
1669         }
1670 
1671         inline lowertri_type lowerTri(DiagType dt=NonUnitDiag)
1672         {
1673             TMVAssert(colsize() <= rowsize());
1674             return lowertri_type(
1675                 ptr(),colsize(),stepi(),stepj(),dt,ct() TMV_FIRSTLAST);
1676         }
1677 
cColPair(ptrdiff_t j1,ptrdiff_t j2)1678         inline view_type cColPair(ptrdiff_t j1, ptrdiff_t j2)
1679         {
1680             return type(
1681                 ptr()+j1*ptrdiff_t(stepj()),colsize(),2,stepi(),(j2-j1)*stepj(),ct()
1682                 TMV_FIRSTLAST );
1683         }
1684 
colPair(ptrdiff_t j1,ptrdiff_t j2)1685         inline view_type colPair(ptrdiff_t j1, ptrdiff_t j2)
1686         {
1687             TMVAssert(j1>=0 && j1<rowsize() && j2>=0 && j2<rowsize());
1688             return cColPair(j1,j2);
1689         }
1690 
cRowPair(ptrdiff_t i1,ptrdiff_t i2)1691         inline view_type cRowPair(ptrdiff_t i1, ptrdiff_t i2)
1692         {
1693             return type(
1694                 ptr()+i1*ptrdiff_t(stepi()),2,rowsize(),(i2-i1)*stepi(),stepj(),ct()
1695                 TMV_FIRSTLAST );
1696         }
1697 
rowPair(ptrdiff_t i1,ptrdiff_t i2)1698         inline view_type rowPair(ptrdiff_t i1, ptrdiff_t i2)
1699         {
1700             TMVAssert(i1>=0 && i1<colsize() && i2>=0 && i2<colsize());
1701             return cRowPair(i1,i2);
1702         }
1703 
cColRange(ptrdiff_t j1,ptrdiff_t j2)1704         inline view_type cColRange(ptrdiff_t j1, ptrdiff_t j2)
1705         {
1706             return type(
1707                 ptr()+j1*ptrdiff_t(stepj()),colsize(),j2-j1,
1708                 stepi(),stepj(),ct(),(this->iscm()&&ls())?-1:0
1709                 TMV_FIRSTLAST);
1710         }
1711 
colRange(ptrdiff_t j1,ptrdiff_t j2)1712         inline view_type colRange(ptrdiff_t j1, ptrdiff_t j2)
1713         {
1714             TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
1715             return cColRange(j1,j2);
1716         }
1717 
cRowRange(ptrdiff_t i1,ptrdiff_t i2)1718         inline view_type cRowRange(ptrdiff_t i1, ptrdiff_t i2)
1719         {
1720             return type(
1721                 ptr()+i1*ptrdiff_t(stepi()),i2-i1,rowsize(),
1722                 stepi(),stepj(),ct(),(this->isrm()&&ls())?-1:0
1723                 TMV_FIRSTLAST);
1724         }
1725 
rowRange(ptrdiff_t i1,ptrdiff_t i2)1726         inline view_type rowRange(ptrdiff_t i1, ptrdiff_t i2)
1727         {
1728             TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
1729             return cRowRange(i1,i2);
1730         }
1731 
realPart()1732         inline realpart_type realPart()
1733         {
1734             return realpart_type(
1735                 reinterpret_cast<RT*>(ptr()),colsize(),rowsize(),
1736                 isReal(T()) ? stepi() : 2*stepi(),
1737                 isReal(T()) ? stepj() : 2*stepj(), NonConj
1738 #ifdef TMVFLDEBUG
1739                 ,reinterpret_cast<const RT*>(_first)
1740                 ,reinterpret_cast<const RT*>(_last)
1741 #endif
1742             );
1743         }
1744 
imagPart()1745         inline realpart_type imagPart()
1746         {
1747             TMVAssert(isComplex(T()));
1748             return realpart_type(
1749                 reinterpret_cast<RT*>(ptr())+1,
1750                 colsize(),rowsize(),2*stepi(),2*stepj(),NonConj
1751 #ifdef TMVFLDEBUG
1752                 ,reinterpret_cast<const RT*>(_first)+1
1753                 ,reinterpret_cast<const RT*>(_last)+1
1754 #endif
1755             );
1756         }
1757 
1758         //
1759         // Views
1760         //
1761 
view()1762         inline view_type view()
1763         { return *this; }
1764 
transpose()1765         inline view_type transpose()
1766         {
1767             return type(
1768                 ptr(),rowsize(),colsize(),
1769                 stepj(),stepi(),ct(),ls() TMV_FIRSTLAST);
1770         }
1771 
conjugate()1772         inline view_type conjugate()
1773         {
1774             return type(
1775                 ptr(),colsize(),rowsize(),
1776                 stepi(),stepj(),TMV_ConjOf(T,ct()),ls() TMV_FIRSTLAST);
1777         }
1778 
adjoint()1779         inline view_type adjoint()
1780         {
1781             return type(
1782                 ptr(),rowsize(),colsize(),
1783                 stepj(),stepi(),TMV_ConjOf(T,ct()),ls()
1784                 TMV_FIRSTLAST);
1785         }
1786 
linearView()1787         inline vec_type linearView()
1788         {
1789             TMVAssert(ls() != -1);
1790             // To assure that next Assert has no effect
1791 
1792             TMVAssert(canLinearize());
1793             TMVAssert(ls() == colsize()*rowsize());
1794             return vec_type(ptr(),ls(),1,ct() TMV_FIRSTLAST );
1795         }
1796 
1797         // Repeat the const versions
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)1798         inline const_view_type cSubMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
1799         { return base::cSubMatrix(i1,i2,j1,j2); }
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)1800         inline const_view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
1801         { return base::subMatrix(i1,i2,j1,j2); }
cSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)1802         inline const_view_type cSubMatrix(
1803             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
1804         { return base::cSubMatrix(i1,i2,j1,j2,istep,jstep); }
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)1805         inline const_view_type subMatrix(
1806             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
1807         { return base::subMatrix(i1,i2,j1,j2,istep,jstep); }
cSubVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t size)1808         inline const_vec_type cSubVector(
1809             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t size) const
1810         { return base::cSubVector(i,j,istep,jstep,size); }
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t size)1811         inline const_vec_type subVector(
1812             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t size) const
1813         { return base::subVector(i,j,istep,jstep,size); }
unitUpperTri()1814         inline const_uppertri_type unitUpperTri() const
1815         { return base::unitUpperTri(); }
1816         inline const_uppertri_type upperTri(DiagType dt=NonUnitDiag) const
1817         { return base::upperTri(dt); }
unitLowerTri()1818         inline const_lowertri_type unitLowerTri() const
1819         { return base::unitLowerTri(); }
1820         inline const_lowertri_type lowerTri(DiagType dt=NonUnitDiag) const
1821         { return base::lowerTri(dt); }
cColPair(ptrdiff_t j1,ptrdiff_t j2)1822         inline const_view_type cColPair(ptrdiff_t j1, ptrdiff_t j2) const
1823         { return base::cColPair(j1,j2); }
colPair(ptrdiff_t j1,ptrdiff_t j2)1824         inline const_view_type colPair(ptrdiff_t j1, ptrdiff_t j2) const
1825         { return base::colPair(j1,j2); }
cRowPair(ptrdiff_t i1,ptrdiff_t i2)1826         inline const_view_type cRowPair(ptrdiff_t i1, ptrdiff_t i2) const
1827         { return base::cRowPair(i1,i2); }
rowPair(ptrdiff_t i1,ptrdiff_t i2)1828         inline const_view_type rowPair(ptrdiff_t i1, ptrdiff_t i2) const
1829         { return base::rowPair(i1,i2); }
cColRange(ptrdiff_t j1,ptrdiff_t j2)1830         inline const_view_type cColRange(ptrdiff_t j1, ptrdiff_t j2) const
1831         { return base::cColRange(j1,j2); }
colRange(ptrdiff_t j1,ptrdiff_t j2)1832         inline const_view_type colRange(ptrdiff_t j1, ptrdiff_t j2) const
1833         { return base::colRange(j1,j2); }
cRowRange(ptrdiff_t i1,ptrdiff_t i2)1834         inline const_view_type cRowRange(ptrdiff_t i1, ptrdiff_t i2) const
1835         { return base::cRowRange(i1,i2); }
rowRange(ptrdiff_t i1,ptrdiff_t i2)1836         inline const_view_type rowRange(ptrdiff_t i1, ptrdiff_t i2) const
1837         { return base::rowRange(i1,i2); }
realPart()1838         inline const_realpart_type realPart() const
1839         { return base::realPart(); }
imagPart()1840         inline const_realpart_type imagPart() const
1841         { return base::imagPart(); }
view()1842         inline const_view_type view() const
1843         { return base::view(); }
transpose()1844         inline const_view_type transpose() const
1845         { return base::transpose(); }
conjugate()1846         inline const_view_type conjugate() const
1847         { return base::conjugate(); }
adjoint()1848         inline const_view_type adjoint() const
1849         { return base::adjoint(); }
linearView()1850         inline const_vec_type linearView() const
1851         { return base::linearView(); }
1852 
1853         //
1854         // I/O
1855         //
1856 
1857         void read(const TMV_Reader& reader);
1858 
colsize()1859         virtual inline ptrdiff_t colsize() const { return itscs; }
rowsize()1860         virtual inline ptrdiff_t rowsize() const { return itsrs; }
cptr()1861         virtual inline const T* cptr() const { return itsm; }
ptr()1862         inline T* ptr() const { return itsm; }
stepi()1863         virtual inline ptrdiff_t stepi() const { return itssi; }
stepj()1864         virtual inline ptrdiff_t stepj() const { return itssj; }
ct()1865         virtual inline ConjType ct() const { return itsct; }
ls()1866         virtual inline ptrdiff_t ls() const { return linsize; }
1867 
canLinearize()1868         virtual inline bool canLinearize() const
1869         {
1870             if (linsize == -1) {
1871                 if ( (stepi() == 1 && stepj() == colsize()) ||
1872                      (stepj() == 1 && stepi() == rowsize()) )
1873                     linsize = rowsize() * colsize();
1874                 else
1875                     linsize = 0;
1876             }
1877             TMVAssert(linsize == 0 ||
1878                       (this->isrm() && stepi() == rowsize()) ||
1879                       (this->iscm() && stepj() == colsize()));
1880             return linsize > 0;
1881         }
1882 
1883         reference ref(ptrdiff_t i, ptrdiff_t j);
1884 
rowmajor_begin()1885         inline rowmajor_iterator rowmajor_begin()
1886         { return rowmajor_iterator(this,0,0); }
rowmajor_end()1887         inline rowmajor_iterator rowmajor_end()
1888         { return rowmajor_iterator(this,colsize(),0); }
1889 
colmajor_begin()1890         inline colmajor_iterator colmajor_begin()
1891         { return colmajor_iterator(this,0,0); }
colmajor_end()1892         inline colmajor_iterator colmajor_end()
1893         { return colmajor_iterator(this,0,rowsize()); }
1894 
rowmajor_begin()1895         inline const_rowmajor_iterator rowmajor_begin() const
1896         { return const_rowmajor_iterator(this,0,0); }
rowmajor_end()1897         inline const_rowmajor_iterator rowmajor_end() const
1898         { return const_rowmajor_iterator(this,colsize(),0); }
1899 
colmajor_begin()1900         inline const_colmajor_iterator colmajor_begin() const
1901         { return const_colmajor_iterator(this,0,0); }
colmajor_end()1902         inline const_colmajor_iterator colmajor_end() const
1903         { return const_colmajor_iterator(this,0,rowsize()); }
1904 
1905     protected:
1906 
1907         T*const itsm;
1908         const ptrdiff_t itscs;
1909         const ptrdiff_t itsrs;
1910         const ptrdiff_t itssi;
1911         const ptrdiff_t itssj;
1912         const ConjType itsct;
1913 
1914         mutable ptrdiff_t linsize;
1915 
1916 #ifdef TMVFLDEBUG
1917     public:
1918         const T* _first;
1919         const T* _last;
1920 #endif
1921 
1922     }; // MatrixView
1923 
1924     template <typename T>
1925     class MatrixView<T,FortranStyle> :
1926         public MatrixView<T,CStyle>
1927     {
1928     public:
1929 
1930         typedef TMV_RealType(T) RT;
1931         typedef TMV_ComplexType(T) CT;
1932         typedef MatrixView<T,FortranStyle> type;
1933         typedef ConstMatrixView<T,FortranStyle> const_type;
1934         typedef MatrixView<T,CStyle> c_type;
1935         typedef MatrixView<T,FortranStyle> view_type;
1936         typedef view_type transpose_type;
1937         typedef view_type conjugate_type;
1938         typedef view_type adjoint_type;
1939         typedef MatrixView<RT,FortranStyle> realpart_type;
1940         typedef VectorView<T,FortranStyle> vec_type;
1941         typedef UpperTriMatrixView<T,FortranStyle> uppertri_type;
1942         typedef LowerTriMatrixView<T,FortranStyle> lowertri_type;
1943         typedef ConstMatrixView<T,FortranStyle> const_view_type;
1944         typedef const_view_type const_transpose_type;
1945         typedef const_view_type const_conjugate_type;
1946         typedef const_view_type const_adjoint_type;
1947         typedef ConstMatrixView<RT,FortranStyle> const_realpart_type;
1948         typedef ConstVectorView<T,FortranStyle> const_vec_type;
1949         typedef ConstUpperTriMatrixView<T,FortranStyle> const_uppertri_type;
1950         typedef ConstLowerTriMatrixView<T,FortranStyle> const_lowertri_type;
1951         typedef typename RefHelper<T>::reference reference;
1952 
1953         //
1954         // Constructors
1955         //
1956 
MatrixView(const type & rhs)1957         inline MatrixView(const type& rhs) : c_type(rhs) {}
MatrixView(const c_type & rhs)1958         inline MatrixView(const c_type& rhs) : c_type(rhs) {}
1959 
1960         inline MatrixView(
1961             T* _m, ptrdiff_t _cs, ptrdiff_t _rs, ptrdiff_t _si, ptrdiff_t _sj,
1962             ConjType _ct, ptrdiff_t _ls=0 TMV_PARAMFIRSTLAST(T) ) :
c_type(_m,_cs,_rs,_si,_sj,_ct,_ls TMV_FIRSTLAST1 (_first,_last))1963             c_type(_m,_cs,_rs,_si,_sj,_ct,_ls TMV_FIRSTLAST1(_first,_last) )
1964         {}
1965 
~MatrixView()1966         virtual inline ~MatrixView() {}
1967 
1968         //
1969         // Op=
1970         //
1971 
1972         inline type& operator=(const type& m2)
1973         { c_type::operator=(m2); return *this; }
1974 
1975         inline type& operator=(const c_type& m2)
1976         { c_type::operator=(m2); return *this; }
1977 
1978         inline type& operator=(const GenMatrix<RT>& m2)
1979         { c_type::operator=(m2); return *this; }
1980 
1981         inline type& operator=(const GenMatrix<CT>& m2)
1982         { c_type::operator=(m2); return *this; }
1983 
1984         template <typename T2>
1985         inline type& operator=(const GenMatrix<T2>& m2)
1986         { c_type::operator=(m2); return *this; }
1987 
1988         inline type& operator=(const T& x)
1989         { c_type::operator=(x); return *this; }
1990 
1991         inline type& operator=(const AssignableToMatrix<RT>& m2)
1992         { c_type::operator=(m2); return *this; }
1993 
1994         inline type& operator=(const AssignableToMatrix<CT>& m2)
1995         { c_type::operator=(m2); return *this; }
1996 
1997         template <typename T2, ptrdiff_t M, ptrdiff_t N, int A2>
1998         inline type& operator=(const SmallMatrix<T2,M,N,A2>& m2)
1999         { c_type::operator=(m2); return *this; }
2000 
2001         typedef typename c_type::MyListAssigner MyListAssigner;
2002         inline MyListAssigner operator<<(const T& x)
2003         { return c_type::operator<<(x); }
2004 
2005         //
2006         // Access
2007         //
2008 
operator()2009         inline reference operator()(ptrdiff_t i,ptrdiff_t j)
2010         {
2011             TMVAssert(i > 0 && i <= this->colsize());
2012             TMVAssert(j > 0 && j <= this->rowsize());
2013             return c_type::ref(i-1,j-1);
2014         }
2015 
2016         inline vec_type operator[](ptrdiff_t i)
2017         {
2018             TMVAssert(i>0 && i<=this->colsize());
2019             return row(i);
2020         }
2021 
row(ptrdiff_t i)2022         inline vec_type row(ptrdiff_t i)
2023         {
2024             TMVAssert(i>0 && i<=this->colsize());
2025             return c_type::row(i-1);
2026         }
2027 
col(ptrdiff_t j)2028         inline vec_type col(ptrdiff_t j)
2029         {
2030             TMVAssert(j>0 && j<=this->rowsize());
2031             return c_type::col(j-1);
2032         }
2033 
diag()2034         inline vec_type diag()
2035         { return c_type::diag(); }
2036 
diag(ptrdiff_t i)2037         inline vec_type diag(ptrdiff_t i)
2038         { return c_type::diag(i); }
2039 
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)2040         inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
2041         {
2042             TMVAssert(i>0 && i<=this->colsize());
2043             TMVAssert(j1>0 && j1-j2<=0 && j2<=this->rowsize());
2044             return c_type::row(i-1,j1-1,j2);
2045         }
2046 
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)2047         inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2)
2048         {
2049             TMVAssert(j>0 && j<=this->rowsize());
2050             TMVAssert(i1>0 && i1-i2<=0 && i2<=this->colsize());
2051             return c_type::col(j-1,i1-1,i2);
2052         }
2053 
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)2054         inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
2055         {
2056             TMVAssert(j1 > 0);
2057             return c_type::diag(i,j1-1,j2);
2058         }
2059 
operator()2060         inline T operator()(ptrdiff_t i,ptrdiff_t j) const
2061         {
2062             TMVAssert(i > 0 && i <= this->colsize());
2063             TMVAssert(j > 0 && j <= this->rowsize());
2064             return c_type::cref(i-1,j-1);
2065         }
2066 
2067         inline const_vec_type operator[](ptrdiff_t i) const
2068         {
2069             TMVAssert(i>0 && i<=this->colsize());
2070             return row(i);
2071         }
2072 
row(ptrdiff_t i)2073         inline const_vec_type row(ptrdiff_t i) const
2074         {
2075             TMVAssert(i>0 && i<=this->colsize());
2076             return c_type::row(i-1);
2077         }
2078 
col(ptrdiff_t j)2079         inline const_vec_type col(ptrdiff_t j) const
2080         {
2081             TMVAssert(j>0 && j<=this->rowsize());
2082             return c_type::col(j-1);
2083         }
2084 
diag()2085         inline const_vec_type diag() const
2086         { return c_type::diag(); }
2087 
diag(ptrdiff_t i)2088         inline const_vec_type diag(ptrdiff_t i) const
2089         { return c_type::diag(i); }
2090 
row(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)2091         inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
2092         {
2093             TMVAssert(i>0 && i<=this->colsize());
2094             TMVAssert(j1>0 && j1-j2<=0 && j2<=this->rowsize());
2095             return c_type::row(i-1,j1-1,j2);
2096         }
2097 
col(ptrdiff_t j,ptrdiff_t i1,ptrdiff_t i2)2098         inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const
2099         {
2100             TMVAssert(j>0 && j<=this->rowsize());
2101             TMVAssert(i1>0 && i1-i2<=0 && i2<=this->colsize());
2102             return c_type::col(j-1,i1-1,i2);
2103         }
2104 
diag(ptrdiff_t i,ptrdiff_t j1,ptrdiff_t j2)2105         inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
2106         {
2107             TMVAssert(j1 > 0);
2108             return c_type::diag(i,j1-1,j2);
2109         }
2110 
2111         //
2112         // Modifying Functions
2113         //
2114 
setZero()2115         inline type& setZero()
2116         { c_type::setZero(); return *this; }
2117 
setAllTo(const T & x)2118         inline type& setAllTo(const T& x)
2119         { c_type::setAllTo(x); return *this; }
2120 
addToAll(const T & x)2121         inline type& addToAll(const T& x)
2122         { c_type::addToAll(x); return *this; }
2123 
clip(RT thresh)2124         inline type& clip(RT thresh)
2125         { c_type::clip(thresh); return *this; }
2126 
transposeSelf()2127         inline type& transposeSelf()
2128         { c_type::transposeSelf(); return *this; }
2129 
conjugateSelf()2130         inline type& conjugateSelf()
2131         { c_type::conjugateSelf(); return *this; }
2132 
2133         inline type& setToIdentity(const T& x=T(1))
2134         { c_type::setToIdentity(x); return *this; }
2135 
swapRows(ptrdiff_t i1,ptrdiff_t i2)2136         inline type& swapRows(ptrdiff_t i1, ptrdiff_t i2)
2137         {
2138             TMVAssert(i1 > 0 && i1 <= this->colsize());
2139             TMVAssert(i2 > 0 && i2 <= this->colsize());
2140             if (i1 != i2)
2141                 c_type::swapRows(i1-1,i2-1);
2142             return *this;
2143         }
2144 
swapCols(ptrdiff_t j1,ptrdiff_t j2)2145         inline type& swapCols(ptrdiff_t j1, ptrdiff_t j2)
2146         {
2147             TMVAssert(j1 > 0 && j1 <= this->rowsize());
2148             TMVAssert(j2 > 0 && j2 <= this->rowsize());
2149             if (j1 != j2)
2150                 c_type::swapCols(j1-1,j2-1);
2151             return *this;
2152         }
2153 
permuteRows(const ptrdiff_t * p,ptrdiff_t i1,ptrdiff_t i2)2154         inline type& permuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2)
2155         {
2156             TMVAssert(i1>0);
2157             c_type::permuteRows(p,i1-1,i2);
2158             return *this;
2159         }
2160 
permuteRows(const ptrdiff_t * p)2161         inline type& permuteRows(const ptrdiff_t* p)
2162         { c_type::permuteRows(p); return *this; }
2163 
permuteCols(const ptrdiff_t * p,ptrdiff_t j1,ptrdiff_t j2)2164         inline type& permuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
2165         { transpose().permuteRows(p,j1,j2); return *this; }
2166 
permuteCols(const ptrdiff_t * p)2167         inline type& permuteCols(const ptrdiff_t* p)
2168         { transpose().permuteRows(p); return *this; }
2169 
reversePermuteRows(const ptrdiff_t * p,ptrdiff_t i1,ptrdiff_t i2)2170         inline type& reversePermuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2)
2171         {
2172             TMVAssert(i1>0);
2173             c_type::reversePermuteRows(p,i1-1,i2);
2174             return *this;
2175         }
2176 
reversePermuteRows(const ptrdiff_t * p)2177         inline type& reversePermuteRows(const ptrdiff_t* p)
2178         { c_type::reversePermuteRows(p); return *this; }
2179 
reversePermuteCols(const ptrdiff_t * p,ptrdiff_t j1,ptrdiff_t j2)2180         inline type& reversePermuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
2181         { transpose().reversePermuteRows(p,j1,j2); return *this; }
2182 
reversePermuteCols(const ptrdiff_t * p)2183         inline type& reversePermuteCols(const ptrdiff_t* p)
2184         { transpose().reversePermuteRows(p); return *this; }
2185 
2186         //
2187         // subMatrix
2188         //
2189 
hasSubMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)2190         inline bool hasSubMatrix(
2191             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
2192         {
2193             return const_type(*this).hasSubMatrix(
2194                 i1,i2,j1,j2,istep,jstep);
2195         }
2196 
hasSubVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)2197         inline bool hasSubVector(
2198             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
2199         { return const_type(*this).hasSubVector(i,j,istep,jstep,s); }
2200 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)2201         inline view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2)
2202         {
2203             TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1));
2204             return c_type::cSubMatrix(i1-1,i2,j1-1,j2);
2205         }
2206 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)2207         inline view_type subMatrix(
2208             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep)
2209         {
2210             TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep));
2211             return c_type::cSubMatrix(
2212                 i1-1,i2-1+istep,j1-1,j2-1+jstep,istep,jstep);
2213         }
2214 
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)2215         inline vec_type subVector(
2216             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s)
2217         {
2218             TMVAssert(hasSubVector(i,j,istep,jstep,s));
2219             return c_type::cSubVector(i-1,j-1,istep,jstep,s);
2220         }
2221 
unitUpperTri()2222         inline uppertri_type unitUpperTri()
2223         { return c_type::upperTri(UnitDiag); }
2224 
2225         inline uppertri_type upperTri(DiagType dt=NonUnitDiag)
2226         { return c_type::upperTri(dt); }
2227 
unitLowerTri()2228         inline lowertri_type unitLowerTri()
2229         { return c_type::lowerTri(UnitDiag); }
2230 
2231         inline lowertri_type lowerTri(DiagType dt=NonUnitDiag)
2232         { return c_type::lowerTri(dt); }
2233 
colPair(ptrdiff_t j1,ptrdiff_t j2)2234         inline view_type colPair(ptrdiff_t j1, ptrdiff_t j2)
2235         {
2236             TMVAssert(j1 > 0 && j1 <= this->rowsize());
2237             TMVAssert(j2 > 0 && j2 <= this->rowsize());
2238             return c_type::cColPair(j1-1,j2-1);
2239         }
2240 
rowPair(ptrdiff_t i1,ptrdiff_t i2)2241         inline view_type rowPair(ptrdiff_t i1, ptrdiff_t i2)
2242         {
2243             TMVAssert(i1 > 0 && i1 <= this->rowsize());
2244             TMVAssert(i2 > 0 && i2 <= this->rowsize());
2245             return c_type::cRowPair(i1-1,i2-1);
2246         }
2247 
colRange(ptrdiff_t j1,ptrdiff_t j2)2248         inline view_type colRange(ptrdiff_t j1, ptrdiff_t j2)
2249         {
2250             TMVAssert(j1 > 0 && j1 <= j2 && j2 <= this->rowsize());
2251             return c_type::cColRange(j1-1,j2);
2252         }
2253 
rowRange(ptrdiff_t i1,ptrdiff_t i2)2254         inline view_type rowRange(ptrdiff_t i1, ptrdiff_t i2)
2255         {
2256             TMVAssert(i1 > 0 && i1 <= i2 && i2 <= this->colsize());
2257             return c_type::cRowRange(i1-1,i2);
2258         }
2259 
realPart()2260         inline realpart_type realPart()
2261         { return c_type::realPart(); }
2262 
imagPart()2263         inline realpart_type imagPart()
2264         { return c_type::imagPart(); }
2265 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2)2266         inline const_view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
2267         {
2268             TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1));
2269             return c_type::cSubMatrix(i1-1,i2,j1-1,j2);
2270         }
2271 
subMatrix(ptrdiff_t i1,ptrdiff_t i2,ptrdiff_t j1,ptrdiff_t j2,ptrdiff_t istep,ptrdiff_t jstep)2272         inline const_view_type subMatrix(
2273             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
2274         {
2275             TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep));
2276             return c_type::cSubMatrix(
2277                 i1-1,i2-1+istep,j1-1,j2-1+jstep,istep,jstep);
2278         }
2279 
subVector(ptrdiff_t i,ptrdiff_t j,ptrdiff_t istep,ptrdiff_t jstep,ptrdiff_t s)2280         inline const_vec_type subVector(
2281             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
2282         {
2283             TMVAssert(hasSubVector(i,j,istep,jstep,s));
2284             return c_type::cSubVector(i-1,j-1,istep,jstep,s);
2285         }
2286 
unitUpperTri()2287         inline const_uppertri_type unitUpperTri() const
2288         { return c_type::upperTri(UnitDiag); }
2289 
2290         inline const_uppertri_type upperTri(DiagType dt=NonUnitDiag) const
2291         { return c_type::upperTri(dt); }
2292 
unitLowerTri()2293         inline const_lowertri_type unitLowerTri() const
2294         { return c_type::lowerTri(UnitDiag); }
2295 
2296         inline const_lowertri_type lowerTri(DiagType dt=NonUnitDiag) const
2297         { return c_type::lowerTri(dt); }
2298 
colPair(ptrdiff_t j1,ptrdiff_t j2)2299         inline const_view_type colPair(ptrdiff_t j1, ptrdiff_t j2) const
2300         {
2301             TMVAssert(j1 > 0 && j1 <= this->rowsize());
2302             TMVAssert(j2 > 0 && j2 <= this->rowsize());
2303             return c_type::cColPair(j1-1,j2-1);
2304         }
2305 
rowPair(ptrdiff_t i1,ptrdiff_t i2)2306         inline const_view_type rowPair(ptrdiff_t i1, ptrdiff_t i2) const
2307         {
2308             TMVAssert(i1 > 0 && i1 <= this->rowsize());
2309             TMVAssert(i2 > 0 && i2 <= this->rowsize());
2310             return c_type::cRowPair(i1-1,i2-1);
2311         }
2312 
colRange(ptrdiff_t j1,ptrdiff_t j2)2313         inline const_view_type colRange(ptrdiff_t j1, ptrdiff_t j2) const
2314         {
2315             TMVAssert(j1 > 0 && j1 <= j2 && j2 <= this->rowsize());
2316             return c_type::cColRange(j1-1,j2);
2317         }
2318 
rowRange(ptrdiff_t i1,ptrdiff_t i2)2319         inline const_view_type rowRange(ptrdiff_t i1, ptrdiff_t i2) const
2320         {
2321             TMVAssert(i1 > 0 && i1 <= i2 && i2 <= this->colsize());
2322             return c_type::cRowRange(i1-1,i2);
2323         }
2324 
realPart()2325         inline const_realpart_type realPart() const
2326         { return c_type::realPart(); }
2327 
imagPart()2328         inline const_realpart_type imagPart() const
2329         { return c_type::imagPart(); }
2330 
2331 
2332         //
2333         // Views
2334         //
2335 
view()2336         inline view_type view()
2337         { return c_type::view(); }
2338 
transpose()2339         inline view_type transpose()
2340         { return c_type::transpose(); }
2341 
conjugate()2342         inline view_type conjugate()
2343         { return c_type::conjugate(); }
2344 
adjoint()2345         inline view_type adjoint()
2346         { return c_type::adjoint(); }
2347 
linearView()2348         inline vec_type linearView()
2349         { return c_type::linearView(); }
2350 
view()2351         inline const_view_type view() const
2352         { return c_type::view(); }
2353 
transpose()2354         inline const_view_type transpose() const
2355         { return c_type::transpose(); }
2356 
conjugate()2357         inline const_view_type conjugate() const
2358         { return c_type::conjugate(); }
2359 
adjoint()2360         inline const_view_type adjoint() const
2361         { return c_type::adjoint(); }
2362 
linearView()2363         inline const_vec_type linearView() const
2364         { return c_type::linearView(); }
2365 
2366     }; // FortranStyle MatrixView
2367 
2368     template <ptrdiff_t S, class M>
2369     struct MatrixIterHelper;
2370 
2371     template <class M>
2372     struct MatrixIterHelper<RowMajor,M>
2373     {
2374         typedef typename M::value_type T;
2375         typedef VIt<T,1,NonConj> rowmajor_iterator;
2376         typedef CVIt<T,1,NonConj> const_rowmajor_iterator;
2377 
2378         static rowmajor_iterator rowmajor_begin(M* m)
2379         { return rowmajor_iterator(m->ptr(),1); }
2380         static rowmajor_iterator rowmajor_end(M* m)
2381         { return rowmajor_iterator(m->ptr()+m->ls(),1); }
2382 
2383         static const_rowmajor_iterator rowmajor_begin(const M* m)
2384         { return const_rowmajor_iterator(m->cptr(),1); }
2385         static const_rowmajor_iterator rowmajor_end(const M* m)
2386         { return const_rowmajor_iterator(m->cptr()+m->ls(),1); }
2387 
2388         typedef CMIt<M> colmajor_iterator;
2389         typedef CCMIt<M> const_colmajor_iterator;
2390 
2391         static colmajor_iterator colmajor_begin(M* m)
2392         { return colmajor_iterator(m,0,0); }
2393         static colmajor_iterator colmajor_end(M* m)
2394         { return colmajor_iterator(m,0,m->rowsize()); }
2395 
2396         static const_colmajor_iterator colmajor_begin(const M* m)
2397         { return const_colmajor_iterator(m,0,0); }
2398         static const_colmajor_iterator colmajor_end(const M* m)
2399         { return const_colmajor_iterator(m,0,m->rowsize()); }
2400 
2401     };
2402 
2403     template <class M>
2404     struct MatrixIterHelper<ColMajor,M>
2405     {
2406         typedef RMIt<M> rowmajor_iterator;
2407         typedef CRMIt<M> const_rowmajor_iterator;
2408 
2409         static rowmajor_iterator rowmajor_begin(M* m)
2410         { return rowmajor_iterator(m,0,0); }
2411         static rowmajor_iterator rowmajor_end(M* m)
2412         { return rowmajor_iterator(m,m->colsize(),0); }
2413 
2414         static const_rowmajor_iterator rowmajor_begin(const M* m)
2415         { return const_rowmajor_iterator(m,0,0); }
2416         static const_rowmajor_iterator rowmajor_end(const M* m)
2417         { return const_rowmajor_iterator(m,m->colsize(),0); }
2418 
2419         typedef typename M::value_type T;
2420         typedef VIt<T,1,NonConj> colmajor_iterator;
2421         typedef CVIt<T,1,NonConj> const_colmajor_iterator;
2422 
2423         static colmajor_iterator colmajor_begin(M* m)
2424         { return colmajor_iterator(m->ptr(),1); }
2425         static colmajor_iterator colmajor_end(M* m)
2426         { return colmajor_iterator(m->ptr()+m->ls(),1); }
2427 
2428         static const_colmajor_iterator colmajor_begin(const M* m)
2429         { return const_colmajor_iterator(m->cptr(),1); }
2430         static const_colmajor_iterator colmajor_end(const M* m)
2431         { return const_colmajor_iterator(m->cptr()+m->ls(),1); }
2432 
2433     };
2434 
2435     template <typename T, int A>
2436     class Matrix :
2437         public GenMatrix<T>
2438     {
2439     public:
2440 
2441         enum { S = A & AllStorageType };
2442         enum { I = A & FortranStyle };
2443 
2444         typedef TMV_RealType(T) RT;
2445         typedef TMV_ComplexType(T) CT;
2446         typedef Matrix<T,A> type;
2447         typedef ConstMatrixView<T,I> const_view_type;
2448         typedef const_view_type const_transpose_type;
2449         typedef const_view_type const_conjugate_type;
2450         typedef const_view_type const_adjoint_type;
2451         typedef ConstMatrixView<RT,I> const_realpart_type;
2452         typedef ConstVectorView<T,I> const_vec_type;
2453         typedef ConstUpperTriMatrixView<T,I> const_uppertri_type;
2454         typedef ConstLowerTriMatrixView<T,I> const_lowertri_type;
2455         typedef MatrixView<T,I> view_type;
2456         typedef view_type transpose_type;
2457         typedef view_type conjugate_type;
2458         typedef view_type adjoint_type;
2459         typedef MatrixView<RT,I> realpart_type;
2460         typedef VectorView<T,I> vec_type;
2461         typedef UpperTriMatrixView<T,I> uppertri_type;
2462         typedef LowerTriMatrixView<T,I> lowertri_type;
2463         typedef T& reference;
2464         typedef typename MatrixIterHelper<S,type>::rowmajor_iterator
2465             rowmajor_iterator;
2466         typedef typename MatrixIterHelper<S,type>::const_rowmajor_iterator
2467             const_rowmajor_iterator;
2468         typedef typename MatrixIterHelper<S,type>::colmajor_iterator
2469             colmajor_iterator;
2470         typedef typename MatrixIterHelper<S,type>::const_colmajor_iterator
2471             const_colmajor_iterator;
2472 
2473         //
2474         // Constructors
2475         //
2476 
2477 #define NEW_SIZE(cs,rs) \
2478         linsize((cs)*(rs)), \
2479         itsm(linsize), itscs(cs), itsrs(rs) \
2480         TMV_DEFFIRSTLAST(itsm.get(),itsm.get()+linsize)
2481 
2482         inline Matrix() : NEW_SIZE(0,0)
2483         {
2484             TMVAssert(Attrib<A>::matrixok);
2485         }
2486 
2487         inline Matrix(ptrdiff_t _colsize, ptrdiff_t _rowsize) :
2488             NEW_SIZE(_colsize,_rowsize)
2489         {
2490             TMVAssert(Attrib<A>::matrixok);
2491             TMVAssert(_colsize >= 0 && _rowsize >= 0);
2492 #ifdef TMV_EXTRA_DEBUG
2493             setAllTo(T(888));
2494 #endif
2495         }
2496 
2497         inline Matrix(ptrdiff_t _colsize, ptrdiff_t _rowsize, const T& x) :
2498             NEW_SIZE(_colsize,_rowsize)
2499         {
2500             TMVAssert(Attrib<A>::matrixok);
2501             TMVAssert(_colsize >= 0 && _rowsize >= 0);
2502             setAllTo(x);
2503         }
2504 
2505         inline Matrix(const type& rhs) : NEW_SIZE(rhs.colsize(),rhs.rowsize())
2506         {
2507             TMVAssert(Attrib<A>::matrixok);
2508             std::copy(rhs.cptr(),rhs.cptr()+linsize,itsm.get());
2509         }
2510 
2511         inline Matrix(const GenMatrix<RT>& rhs) :
2512             NEW_SIZE(rhs.colsize(),rhs.rowsize())
2513         {
2514             TMVAssert(Attrib<A>::matrixok);
2515             rhs.assignToM(view());
2516         }
2517 
2518         inline Matrix(const GenMatrix<CT>& rhs) :
2519             NEW_SIZE(rhs.colsize(),rhs.rowsize())
2520         {
2521             TMVAssert(Attrib<A>::matrixok);
2522             TMVAssert(isComplex(T()));
2523             rhs.assignToM(view());
2524         }
2525 
2526         template <typename T2>
2527         inline Matrix(const GenMatrix<T2>& rhs) :
2528             NEW_SIZE(rhs.colsize(),rhs.rowsize())
2529         {
2530             TMVAssert(Attrib<A>::matrixok);
2531             TMVAssert(isComplex(T()) || isReal(T2()));
2532             Copy(rhs,view());
2533         }
2534 
2535         inline Matrix(const AssignableToMatrix<RT>& m2) :
2536             NEW_SIZE(m2.colsize(),m2.rowsize())
2537         {
2538             TMVAssert(Attrib<A>::matrixok);
2539             m2.assignToM(view());
2540         }
2541 
2542         inline Matrix(const AssignableToMatrix<CT>& m2) :
2543             NEW_SIZE(m2.colsize(),m2.rowsize())
2544         {
2545             TMVAssert(Attrib<A>::matrixok);
2546             TMVAssert(isComplex(T()));
2547             m2.assignToM(view());
2548         }
2549 
2550         inline Matrix(const Permutation& m2) :
2551             NEW_SIZE(m2.colsize(),m2.rowsize())
2552         {
2553             TMVAssert(Attrib<A>::matrixok);
2554             m2.assignToM(view());
2555         }
2556 
2557         template <typename T2, ptrdiff_t M, ptrdiff_t N, int A2>
2558         inline Matrix(const SmallMatrix<T2,M,N,A2>& rhs) :
2559             NEW_SIZE(rhs.colsize(),rhs.rowsize())
2560         {
2561             TMVAssert(Attrib<A>::matrixok);
2562             TMVAssert(isComplex(T()) || isReal(T2()));
2563             Copy(rhs.view(),view());
2564         }
2565 
2566 
2567 #undef NEW_SIZE
2568 
2569         virtual inline ~Matrix()
2570         {
2571 #ifdef TMV_EXTRA_DEBUG
2572             setAllTo(T(999));
2573 #endif
2574         }
2575 
2576         //
2577         // Op=
2578         //
2579 
2580         inline type& operator=(const Matrix<T,A>& m2)
2581         {
2582             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2583             if (&m2 != this)
2584                 std::copy(m2.cptr(),m2.cptr()+linsize,itsm.get());
2585             return *this;
2586         }
2587 
2588         inline type& operator=(const GenMatrix<RT>& m2)
2589         {
2590             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2591             m2.assignToM(view());
2592             return *this;
2593         }
2594 
2595         inline type& operator=(const GenMatrix<CT>& m2)
2596         {
2597             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2598             TMVAssert(isComplex(T()));
2599             m2.assignToM(view());
2600             return *this;
2601         }
2602 
2603         template <typename T2>
2604         inline type& operator=(const GenMatrix<T2>& m2)
2605         {
2606             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2607             TMVAssert(isComplex(T()) || isReal(T2()));
2608             Copy(m2,view());
2609             return *this;
2610         }
2611 
2612         inline type& operator=(const T& x)
2613         { return setToIdentity(x); }
2614 
2615         inline type& operator=(const AssignableToMatrix<RT>& m2)
2616         {
2617             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2618             m2.assignToM(view());
2619             return *this;
2620         }
2621 
2622         inline type& operator=(const AssignableToMatrix<CT>& m2)
2623         {
2624             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2625             TMVAssert(isComplex(T()));
2626             m2.assignToM(view());
2627             return *this;
2628         }
2629 
2630         inline type& operator=(const Permutation& m2)
2631         {
2632             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2633             m2.assignToM(view());
2634             return *this;
2635         }
2636 
2637         template <typename T2, ptrdiff_t M, ptrdiff_t N, int A2>
2638         inline type& operator=(const SmallMatrix<T2,M,N,A2>& m2)
2639         {
2640             TMVAssert(m2.colsize() == colsize() && m2.rowsize() == rowsize());
2641             TMVAssert(isComplex(T()) || isReal(T2()));
2642             Copy(m2.view(),view());
2643             return *this;
2644         }
2645 
2646         typedef ListAssigner<T,rowmajor_iterator> MyListAssigner;
2647         inline MyListAssigner operator<<(const T& x)
2648         {
2649             TMVAssert(linsize == colsize() * rowsize());
2650             return MyListAssigner(rowmajor_begin(),linsize,x);
2651         }
2652 
2653         //
2654         // Access
2655         //
2656 
2657         inline T operator()(ptrdiff_t i,ptrdiff_t j) const
2658         {
2659             if (I == int(CStyle)) {
2660                 TMVAssert(i>=0 && i < colsize());
2661                 TMVAssert(j>=0 && j < rowsize());
2662                 return cref(i,j);
2663             } else {
2664                 TMVAssert(i > 0 && i <= colsize());
2665                 TMVAssert(j > 0 && j <= rowsize());
2666                 return cref(i-1,j-1);
2667             }
2668         }
2669 
2670         inline T& operator()(ptrdiff_t i,ptrdiff_t j)
2671         {
2672             if (I == int(CStyle)) {
2673                 TMVAssert(i>=0 && i < colsize());
2674                 TMVAssert(j>=0 && j < rowsize());
2675                 return ref(i,j);
2676             } else {
2677                 TMVAssert(i > 0 && i <= colsize());
2678                 TMVAssert(j > 0 && j <= rowsize());
2679                 return ref(i-1,j-1);
2680             }
2681         }
2682 
2683         inline const_vec_type row(ptrdiff_t i) const
2684         {
2685             if (I == int(FortranStyle)) { TMVAssert(i>0 && i<=colsize()); --i; }
2686             else TMVAssert(i>=0 && i<colsize());
2687             return const_vec_type(
2688                 itsm.get()+i*ptrdiff_t(stepi()),rowsize(),stepj(),NonConj);
2689         }
2690 
2691         inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
2692         {
2693             if (I == int(FortranStyle)) {
2694                 TMVAssert(i>0 && i<=colsize()); --i;
2695                 TMVAssert(j1>0 && j1-j2<=0 && j2<=rowsize()); --j1;
2696             } else {
2697                 TMVAssert(i>=0 && i<colsize());
2698                 TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
2699             }
2700             return const_vec_type(
2701                 itsm.get()+i*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),j2-j1,stepj(),NonConj);
2702         }
2703 
2704         inline const_vec_type operator[](ptrdiff_t i) const
2705         { return row(i); }
2706 
2707         inline const_vec_type col(ptrdiff_t j) const
2708         {
2709             if (I == int(FortranStyle)) { TMVAssert(j>0 && j<=rowsize()); --j; }
2710             else TMVAssert(j>=0 && j<rowsize());
2711             return const_vec_type(
2712                 itsm.get()+j*ptrdiff_t(stepj()),colsize(),stepi(),NonConj);
2713         }
2714 
2715         inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const
2716         {
2717             if (I == int(FortranStyle)) {
2718                 TMVAssert(j>0 && j<=rowsize()); --j;
2719                 TMVAssert(i1>0 && i1-i2<=0 && i2<=colsize()); --i1;
2720             } else {
2721                 TMVAssert(j>=0 && j<rowsize());
2722                 TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
2723             }
2724             return const_vec_type(
2725                 itsm.get()+i1*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),i2-i1,stepi(),NonConj);
2726         }
2727 
2728         inline const_vec_type diag() const
2729         {
2730             return const_vec_type(
2731                 itsm.get(),TMV_MIN(colsize(),rowsize()),
2732                 stepi()+stepj(),NonConj);
2733         }
2734 
2735         inline const_vec_type diag(ptrdiff_t i) const
2736         {
2737             TMVAssert(i>=-colsize() && i<=rowsize());
2738             const ptrdiff_t diagstep = stepi() + stepj();
2739             if (i >= 0) {
2740                 const ptrdiff_t diagsize = TMV_MIN(colsize(),rowsize()-i);
2741                 return const_vec_type(
2742                     itsm.get()+i*ptrdiff_t(stepj()),diagsize,diagstep,NonConj);
2743             } else {
2744                 const ptrdiff_t diagsize = TMV_MIN(colsize()+i,rowsize());
2745                 return const_vec_type(
2746                     itsm.get()-i*ptrdiff_t(stepi()),diagsize,diagstep,NonConj);
2747             }
2748         }
2749 
2750         inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const
2751         {
2752             if (I == int(FortranStyle)) {
2753                 TMVAssert(j1 > 0 && j1-j2<=0);
2754                 --j1;
2755             } else {
2756                 TMVAssert( j1>=0 && j1-j2<=0);
2757             }
2758             TMVAssert(i>=-colsize() && i<=rowsize());
2759             const ptrdiff_t diagstep = stepi() + 1;
2760             if (i >= 0) {
2761                 TMVAssert(j2<=TMV_MIN(colsize(),rowsize()-i));
2762                 return const_vec_type(
2763                     itsm.get()+i*ptrdiff_t(stepj())+j1*diagstep,j2-j1,diagstep,NonConj);
2764             } else {
2765                 TMVAssert(j2<=TMV_MIN(colsize()+i,rowsize()));
2766                 return const_vec_type(
2767                     itsm.get()-i*ptrdiff_t(stepi())+j1*diagstep,j2-j1,diagstep,NonConj);
2768             }
2769         }
2770 
2771         inline vec_type row(ptrdiff_t i)
2772         {
2773             if (I == int(FortranStyle)) {
2774                 TMVAssert(i>0 && i<=colsize());
2775                 --i;
2776             } else {
2777                 TMVAssert(i>=0 && i<colsize());
2778             }
2779             return vec_type(
2780                 ptr()+i*ptrdiff_t(stepi()),rowsize(),stepj(),NonConj TMV_FIRSTLAST);
2781         }
2782 
2783         inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
2784         {
2785             if (I == int(FortranStyle)) {
2786                 TMVAssert(i>0 && i<=colsize());
2787                 --i;
2788                 TMVAssert(j1>0 && j1-j2<=0 && j2<=rowsize());
2789                 --j1;
2790             } else {
2791                 TMVAssert(i>=0 && i<colsize());
2792                 TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
2793             }
2794             return vec_type(
2795                 ptr()+i*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
2796                 j2-j1,stepj(),NonConj TMV_FIRSTLAST);
2797         }
2798 
2799         inline vec_type operator[](ptrdiff_t i)
2800         { return row(i); }
2801 
2802         inline vec_type col(ptrdiff_t j)
2803         {
2804             if (I == int(FortranStyle)) {
2805                 TMVAssert(j>0 && j<=rowsize());
2806                 --j;
2807             } else {
2808                 TMVAssert(j>=0 && j<rowsize());
2809             }
2810             return vec_type(
2811                 ptr()+j*ptrdiff_t(stepj()),colsize(),stepi(),NonConj TMV_FIRSTLAST);
2812         }
2813 
2814         inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2)
2815         {
2816             if (I == int(FortranStyle)) {
2817                 TMVAssert(j>0 && j<=rowsize()); --j;
2818                 TMVAssert(i1>0 && i1-i2<=0 && i2<=colsize()); --i1;
2819             } else {
2820                 TMVAssert(j>=0 && j<rowsize());
2821                 TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
2822             }
2823             return vec_type(
2824                 ptr()+i1*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),
2825                 i2-i1,stepi(),NonConj TMV_FIRSTLAST);
2826         }
2827 
2828         inline vec_type diag()
2829         {
2830             return vec_type(
2831                 ptr(),TMV_MIN(colsize(),rowsize()),stepi()+stepj(),NonConj
2832                 TMV_FIRSTLAST);
2833         }
2834 
2835         inline vec_type diag(ptrdiff_t i)
2836         {
2837             TMVAssert(i>=-colsize() && i<=rowsize());
2838             const ptrdiff_t diagstep = stepi() + stepj();
2839             if (i >= 0) {
2840                 const ptrdiff_t diagsize = TMV_MIN(colsize(),rowsize()-i);
2841                 return vec_type(
2842                     ptr()+i*ptrdiff_t(stepj()), diagsize,diagstep,NonConj
2843                     TMV_FIRSTLAST);
2844             } else {
2845                 const ptrdiff_t diagsize = TMV_MIN(colsize()+i,rowsize());
2846                 return vec_type(
2847                     ptr()-i*ptrdiff_t(stepi()), diagsize,diagstep,NonConj
2848                     TMV_FIRSTLAST);
2849             }
2850         }
2851 
2852         inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2)
2853         {
2854             if (I == int(FortranStyle)) { TMVAssert(j1 > 0 && j1-j2<=0); --j1; }
2855             else { TMVAssert(j1>=0 && j1-j2<=0); }
2856             TMVAssert(i>=-colsize() && i<=rowsize());
2857             const ptrdiff_t diagstep = stepi() + stepj();
2858             if (i >= 0) {
2859                 TMVAssert(j2<=TMV_MIN(colsize(),rowsize()-i));
2860                 return vec_type(
2861                     ptr()+i*ptrdiff_t(stepj()) + j1*diagstep, j2-j1, diagstep, NonConj
2862                     TMV_FIRSTLAST);
2863             } else {
2864                 TMVAssert(j2<=TMV_MIN(colsize(),rowsize()-i));
2865                 return vec_type(
2866                     ptr()-i*ptrdiff_t(stepi()) + j1*diagstep, j2-j1, diagstep, NonConj
2867                     TMV_FIRSTLAST);
2868             }
2869         }
2870 
2871         //
2872         // Modifying Functions
2873         //
2874 
2875         inline type& setZero()
2876         { linearView().setZero(); return *this; }
2877 
2878         inline type& setAllTo(const T& x)
2879         { linearView().setAllTo(x); return *this; }
2880 
2881         inline type& addToAll(const T& x)
2882         { linearView().addToAll(x); return *this; }
2883 
2884         inline type& clip(RT thresh)
2885         { linearView().clip(thresh); return *this; }
2886 
2887         inline type& transposeSelf()
2888         { view().transposeSelf(); return *this; }
2889 
2890         inline type& conjugateSelf()
2891         { linearView().conjugateSelf(); return *this; }
2892 
2893         inline type& setToIdentity(const T& x=T(1))
2894         {
2895             TMVAssert(colsize() == rowsize());
2896             setZero(); diag().setAllTo(x);
2897             return *this;
2898         }
2899 
2900         inline type& swapRows(ptrdiff_t i1, ptrdiff_t i2)
2901         {
2902             if (I == int(CStyle)) {
2903                 TMVAssert(i1>=0 && i1<colsize());
2904                 TMVAssert(i2>=0 && i2<colsize());
2905             } else {
2906                 TMVAssert(i1>0 && i1<=colsize());
2907                 TMVAssert(i2>0 && i2<=colsize());
2908             }
2909             if (i1!=i2) Swap(row(i1),row(i2));
2910             return *this;
2911         }
2912 
2913         inline type& swapCols(ptrdiff_t j1, ptrdiff_t j2)
2914         {
2915             if (I == int(CStyle)) {
2916                 TMVAssert(j1>=0 && j1<rowsize());
2917                 TMVAssert(j2>=0 && j2<rowsize());
2918             } else {
2919                 TMVAssert(j1>0 && j1<=rowsize());
2920                 TMVAssert(j2>0 && j2<=rowsize());
2921             }
2922             if (j1!=j2) Swap(col(j1),col(j2));
2923             return *this;
2924         }
2925 
2926         inline type& permuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2)
2927         { view().permuteRows(p,i1,i2); return *this; }
2928 
2929         inline type& permuteRows(const ptrdiff_t* p)
2930         { view().permuteRows(p); return *this; }
2931 
2932         inline type& permuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
2933         { view().permuteCols(p,j1,j2); return *this; }
2934 
2935         inline type& permuteCols(const ptrdiff_t* p)
2936         { view().permuteCols(p); return *this; }
2937 
2938         inline type& reversePermuteRows(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2)
2939         { view().reversePermuteRows(p,i1,i2); return *this; }
2940 
2941         inline type& reversePermuteRows(const ptrdiff_t* p)
2942         { view().reversePermuteRows(p); return *this; }
2943 
2944         inline type& reversePermuteCols(const ptrdiff_t* p, ptrdiff_t j1, ptrdiff_t j2)
2945         { view().reversePermuteCols(p,j1,j2); return *this; }
2946 
2947         inline type& reversePermuteCols(const ptrdiff_t* p)
2948         { view().reversePermuteCols(p); return *this; }
2949 
2950         //
2951         // subMatrix
2952         //
2953 
2954         inline const_view_type cSubMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
2955         {
2956             return const_view_type(
2957                 itsm.get()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
2958                 i2-i1,j2-j1,stepi(),stepj(),NonConj);
2959         }
2960 
2961         inline const_view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const
2962         {
2963             TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1));
2964             if (I == int(FortranStyle)) { --i1; --j1; }
2965             return cSubMatrix(i1,i2,j1,j2);
2966         }
2967 
2968         inline const_view_type cSubMatrix(
2969             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
2970         {
2971             return const_view_type(
2972                 itsm.get()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
2973                 (i2-i1)/istep,(j2-j1)/jstep,
2974                 istep*stepi(),jstep*stepj(),NonConj);
2975         }
2976 
2977         inline const_view_type subMatrix(
2978             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const
2979         {
2980             TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep));
2981             if (I == int(FortranStyle)) {
2982                 --i1; --j1;
2983                 i2 += istep-1; j2 += jstep-1;
2984             }
2985             return cSubMatrix(i1,i2,j1,j2,istep,jstep);
2986         }
2987 
2988         inline const_vec_type cSubVector(
2989             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
2990         {
2991             return const_vec_type(
2992                 itsm.get()+i*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),s,
2993                 istep*stepi()+jstep*stepj(),NonConj);
2994         }
2995 
2996         inline const_vec_type subVector(
2997             ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s) const
2998         {
2999             TMVAssert(view().hasSubVector(i,j,istep,jstep,s));
3000             if (I==int(FortranStyle)) { --i; --j; }
3001             return cSubVector(i,j,istep,jstep,s);
3002         }
3003 
3004         inline const_uppertri_type unitUpperTri() const
3005         {
3006             TMVAssert(rowsize() <= colsize());
3007             return const_uppertri_type(
3008                 cptr(),rowsize(), stepi(),stepj(),UnitDiag,ct());
3009         }
3010 
3011         inline const_uppertri_type upperTri(DiagType dt=NonUnitDiag) const
3012         {
3013             TMVAssert(rowsize() <= colsize());
3014             return const_uppertri_type(
3015                 cptr(),rowsize(), stepi(),stepj(),dt,ct());
3016         }
3017 
3018         inline const_lowertri_type unitLowerTri() const
3019         {
3020             TMVAssert(colsize() <= rowsize());
3021             return const_lowertri_type(
3022                 cptr(),colsize(), stepi(),stepj(),UnitDiag,ct());
3023         }
3024 
3025         inline const_lowertri_type lowerTri(DiagType dt=NonUnitDiag) const
3026         {
3027             TMVAssert(colsize() <= rowsize());
3028             return const_lowertri_type(
3029                 cptr(),colsize(), stepi(),stepj(),dt,ct());
3030         }
3031 
3032         inline const_view_type cColPair(ptrdiff_t j1, ptrdiff_t j2) const
3033         {
3034             return const_view_type(
3035                 itsm.get()+j1*ptrdiff_t(stepj()),colsize(),2,
3036                 stepi(),(j2-j1)*stepj(),NonConj);
3037         }
3038 
3039         inline const_view_type colPair(ptrdiff_t j1, ptrdiff_t j2) const
3040         {
3041             if (I == int(CStyle)) {
3042                 TMVAssert(j1>=0 && j1<rowsize() &&
3043                           j2>=0 && j2<rowsize());
3044             } else  {
3045                 TMVAssert(j1>0 && j1<=rowsize() &&
3046                           j2>0 && j2<=rowsize());
3047                 --j1; --j2;
3048             }
3049             return cColPair(j1,j2);
3050         }
3051 
3052         inline const_view_type cRowPair(ptrdiff_t i1, ptrdiff_t i2) const
3053         {
3054             return const_view_type(
3055                 itsm.get()+i1*ptrdiff_t(stepi()),2,rowsize(),
3056                 (i2-i1)*stepi(),stepj(),NonConj);
3057         }
3058 
3059         inline const_view_type rowPair(ptrdiff_t i1, ptrdiff_t i2) const
3060         {
3061             if (I == int(CStyle))  {
3062                 TMVAssert(i1>=0 && i1<colsize() &&
3063                           i2>=0 && i2<colsize());
3064             } else  {
3065                 TMVAssert(i1>0 && i1<=colsize() &&
3066                           i2>0 && i2<=colsize());
3067                 --i1; --i2;
3068             }
3069             return cRowPair(i1,i2);
3070         }
3071 
3072         inline const_view_type cColRange(ptrdiff_t j1, ptrdiff_t j2) const
3073         {
3074             return const_view_type(
3075                 itsm.get()+j1*ptrdiff_t(stepj()),colsize(),j2-j1,
3076                 stepi(),stepj(),NonConj,iscm()?-1:0);
3077         }
3078 
3079         inline const_view_type colRange(ptrdiff_t j1, ptrdiff_t j2) const
3080         {
3081             if (I==int(FortranStyle)) {
3082                 TMVAssert(j1>0 && j1-j2<=0 && j2<=rowsize());
3083                 --j1;
3084             } else {
3085                 TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
3086             }
3087             return cColRange(j1,j2);
3088         }
3089 
3090         inline const_view_type cRowRange(ptrdiff_t i1, ptrdiff_t i2) const
3091         {
3092             return const_view_type(
3093                 itsm.get()+i1*ptrdiff_t(stepi()),i2-i1,rowsize(),
3094                 stepi(),stepj(),NonConj,isrm()?-1:0);
3095         }
3096 
3097         inline const_view_type rowRange(ptrdiff_t i1, ptrdiff_t i2) const
3098         {
3099             if (I==int(FortranStyle)) {
3100                 TMVAssert(i1>0 && i1-i2<=0 && i2<=colsize());
3101                 --i1;
3102             } else {
3103                 TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
3104             }
3105             return cRowRange(i1,i2);
3106         }
3107 
3108         inline const_realpart_type realPart() const
3109         {
3110             return const_realpart_type(
3111                 reinterpret_cast<const RT*>(itsm.get()),
3112                 colsize(),rowsize(),
3113                 isReal(T()) ? stepi() : 2*stepi(),
3114                 isReal(T()) ? stepj() : 2*stepj(),NonConj);
3115         }
3116 
3117         inline const_realpart_type imagPart() const
3118         {
3119             TMVAssert(isComplex(T()));
3120             return const_realpart_type(
3121                 reinterpret_cast<const RT*>(itsm.get())+1,
3122                 colsize(),rowsize(),2*stepi(),2*stepj(),NonConj);
3123         }
3124 
3125         inline view_type cSubMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2)
3126         {
3127             return view_type(
3128                 ptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
3129                 i2-i1,j2-j1,stepi(),stepj(),NonConj
3130                 TMV_FIRSTLAST);
3131         }
3132 
3133         inline view_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2)
3134         {
3135             TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1));
3136             if (I==int(FortranStyle)) { --i1; --j1; }
3137             return cSubMatrix(i1,i2,j1,j2);
3138         }
3139 
3140         inline view_type cSubMatrix(
3141             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep)
3142         {
3143             return view_type(
3144                 ptr()+i1*ptrdiff_t(stepi())+j1*ptrdiff_t(stepj()),
3145                 (i2-i1)/istep,(j2-j1)/jstep,
3146                 istep*stepi(),jstep*stepj(), NonConj TMV_FIRSTLAST);
3147         }
3148 
3149         inline view_type subMatrix(
3150             ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep)
3151         {
3152             TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep));
3153             if (I == int(FortranStyle)) {
3154                 --i1; --j1;
3155                 i2 += istep-1; j2 += jstep-1;
3156             }
3157             return cSubMatrix(i1,i2,j1,j2,istep,jstep);
3158         }
3159 
3160         inline vec_type cSubVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s)
3161         {
3162             return vec_type(
3163                 ptr()+i*ptrdiff_t(stepi())+j*ptrdiff_t(stepj()),s,
3164                 istep*stepi()+jstep*stepj(),NonConj
3165                 TMV_FIRSTLAST);
3166         }
3167 
3168         inline vec_type subVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t s)
3169         {
3170             TMVAssert(view().hasSubVector(i,j,istep,jstep,s));
3171             if (I == int(FortranStyle)) { --i; --j; }
3172             return cSubVector(i,j,istep,jstep,s);
3173         }
3174 
3175         inline uppertri_type unitUpperTri()
3176         {
3177             TMVAssert(rowsize() <= colsize());
3178             return uppertri_type(
3179                 ptr(),rowsize(), stepi(),stepj(),UnitDiag,ct()
3180                 TMV_FIRSTLAST);
3181         }
3182 
3183         inline uppertri_type upperTri(DiagType dt=NonUnitDiag)
3184         {
3185             TMVAssert(rowsize() <= colsize());
3186             return uppertri_type(
3187                 ptr(),rowsize(), stepi(),stepj(),dt,ct()
3188                 TMV_FIRSTLAST);
3189         }
3190 
3191         inline lowertri_type unitLowerTri()
3192         {
3193             TMVAssert(colsize() <= rowsize());
3194             return lowertri_type(
3195                 ptr(),colsize(), stepi(),stepj(),UnitDiag,ct()
3196                 TMV_FIRSTLAST);
3197         }
3198 
3199         inline lowertri_type lowerTri(DiagType dt=NonUnitDiag)
3200         {
3201             TMVAssert(colsize() <= rowsize());
3202             return lowertri_type(
3203                 ptr(),colsize(), stepi(),stepj(),dt,ct()
3204                 TMV_FIRSTLAST);
3205         }
3206 
3207         inline view_type cColPair(ptrdiff_t j1, ptrdiff_t j2)
3208         {
3209             return view_type(
3210                 ptr()+j1*ptrdiff_t(stepj()),colsize(),2,stepi(),(j2-j1)*stepj(),NonConj
3211                 TMV_FIRSTLAST);
3212         }
3213 
3214         inline view_type colPair(ptrdiff_t j1, ptrdiff_t j2)
3215         {
3216             if (I == int(CStyle))
3217                 TMVAssert(j1>=0 && j1<rowsize() &&
3218                           j2>=0 && j2<rowsize());
3219             else {
3220                 TMVAssert(j1>0 && j1<=rowsize() &&
3221                           j2>0 && j2<=rowsize());
3222                 --j1; --j2;
3223             }
3224             return cColPair(j1,j2);
3225         }
3226 
3227         inline view_type cRowPair(ptrdiff_t i1, ptrdiff_t i2)
3228         {
3229             return view_type(
3230                 ptr()+i1*ptrdiff_t(stepi()),2,rowsize(),(i2-i1)*stepi(),stepj(),NonConj
3231                 TMV_FIRSTLAST);
3232         }
3233 
3234         inline view_type rowPair(ptrdiff_t i1, ptrdiff_t i2)
3235         {
3236             if (I == int(CStyle))
3237                 TMVAssert(i1>=0 && i1<colsize() &&
3238                           i2>=0 && i2<colsize());
3239             else {
3240                 TMVAssert(i1>0 && i1<=colsize() &&
3241                           i2>0 && i2<=colsize());
3242                 --i1; --i2;
3243             }
3244             return cRowPair(i1,i2);
3245         }
3246 
3247         inline view_type cColRange(ptrdiff_t j1, ptrdiff_t j2)
3248         {
3249             return view_type(
3250                 ptr()+j1*ptrdiff_t(stepj()),colsize(),j2-j1,
3251                 stepi(),stepj(),NonConj,iscm()?-1:0 TMV_FIRSTLAST);
3252         }
3253 
3254         inline view_type colRange(ptrdiff_t j1, ptrdiff_t j2)
3255         {
3256             if (I==int(FortranStyle)) {
3257                 TMVAssert(j1>0 && j1-j2<=0 && j2<=rowsize());
3258                 --j1;
3259             } else {
3260                 TMVAssert(j1>=0 && j1-j2<=0 && j2<=rowsize());
3261             }
3262             return cColRange(j1,j2);
3263         }
3264 
3265         inline view_type cRowRange(ptrdiff_t i1, ptrdiff_t i2)
3266         {
3267             return view_type(
3268                 ptr()+i1*ptrdiff_t(stepi()),i2-i1,rowsize(),
3269                 stepi(),stepj(),NonConj,isrm()?-1:0 TMV_FIRSTLAST);
3270         }
3271 
3272         inline view_type rowRange(ptrdiff_t i1, ptrdiff_t i2)
3273         {
3274             if (I==int(FortranStyle)) {
3275                 TMVAssert(i1>0 && i1-i2<=0 && i2<=colsize());
3276                 --i1;
3277             } else {
3278                 TMVAssert(i1>=0 && i1-i2<=0 && i2<=colsize());
3279             }
3280             return cRowRange(i1,i2);
3281         }
3282 
3283         inline realpart_type realPart()
3284         {
3285             return realpart_type(
3286                 reinterpret_cast<RT*>(ptr()),
3287                 colsize(),rowsize(),
3288                 isReal(T()) ? stepi() : 2*stepi(),
3289                 isReal(T()) ? stepj() : 2*stepj(), NonConj
3290 #ifdef TMVFLDEBUG
3291                 ,reinterpret_cast<const RT*>(_first)+1
3292                 ,reinterpret_cast<const RT*>(_last)+1
3293 #endif
3294             );
3295         }
3296 
3297         inline realpart_type imagPart()
3298         {
3299             TMVAssert(isComplex(T()));
3300             return realpart_type(
3301                 reinterpret_cast<RT*>(ptr())+1,
3302                 colsize(),rowsize(),2*stepi(),2*stepj(),NonConj
3303 #ifdef TMVFLDEBUG
3304                 ,reinterpret_cast<const RT*>(_first)+1
3305                 ,reinterpret_cast<const RT*>(_last)+1
3306 #endif
3307             );
3308         }
3309 
3310         //
3311         // Views
3312         //
3313 
3314         inline const_view_type view() const
3315         {
3316             return const_view_type(
3317                 itsm.get(),colsize(),rowsize(),
3318                 stepi(),stepj(),NonConj,linsize);
3319         }
3320 
3321         inline const_view_type transpose() const
3322         {
3323             return const_view_type(
3324                 itsm.get(),rowsize(),colsize(),
3325                 stepj(),stepi(),NonConj,linsize);
3326         }
3327 
3328         inline const_view_type conjugate() const
3329         {
3330             return const_view_type(
3331                 itsm.get(),colsize(),rowsize(),
3332                 stepi(),stepj(),TMV_ConjOf(T,NonConj),linsize);
3333         }
3334 
3335         inline const_view_type adjoint() const
3336         {
3337             return const_view_type(
3338                 itsm.get(),rowsize(),colsize(),
3339                 stepj(),stepi(),TMV_ConjOf(T,NonConj),linsize);
3340         }
3341 
3342         inline const_vec_type constLinearView() const
3343         {
3344             TMVAssert(linsize == colsize()*rowsize());
3345             return const_vec_type(itsm.get(),linsize,1,NonConj);
3346         }
3347 
3348         inline view_type view()
3349         {
3350             return view_type(
3351                 ptr(),colsize(),rowsize(), stepi(),stepj(),NonConj,linsize
3352                 TMV_FIRSTLAST);
3353         }
3354 
3355         inline view_type transpose()
3356         {
3357             return view_type(
3358                 ptr(),rowsize(),colsize(), stepj(),stepi(),NonConj,linsize
3359                 TMV_FIRSTLAST);
3360         }
3361 
3362         inline view_type conjugate()
3363         {
3364             return view_type(
3365                 ptr(),colsize(),rowsize(),
3366                 stepi(),stepj(),TMV_ConjOf(T,NonConj),linsize TMV_FIRSTLAST);
3367         }
3368 
3369         inline view_type adjoint()
3370         {
3371             return view_type(
3372                 ptr(),rowsize(),colsize(),
3373                 stepj(),stepi(),TMV_ConjOf(T,NonConj),linsize TMV_FIRSTLAST);
3374         }
3375 
3376         inline vec_type linearView()
3377         {
3378             TMVAssert(linsize == colsize()*rowsize());
3379             return vec_type(ptr(),linsize,1,NonConj TMV_FIRSTLAST);
3380         }
3381 
3382         //
3383         // I/O
3384         //
3385 
3386         void read(const TMV_Reader& reader);
3387 
3388         virtual inline ptrdiff_t ls() const { return linsize; }
3389         virtual inline ptrdiff_t colsize() const { return itscs; }
3390         virtual inline ptrdiff_t rowsize() const { return itsrs; }
3391         virtual inline const T* cptr() const { return itsm.get(); }
3392         inline T* ptr() { return itsm.get(); }
3393         virtual inline ptrdiff_t stepi() const
3394         { return S == int(RowMajor) ? itsrs : 1; }
3395         virtual inline ptrdiff_t stepj() const
3396         { return S == int(RowMajor) ? 1 : itscs; }
3397         inline bool isrm() const { return S==int(RowMajor); }
3398         inline bool iscm() const { return S==int(ColMajor); }
3399         inline bool isconj() const { return false; }
3400         virtual inline ConjType ct() const { return NonConj; }
3401 
3402         virtual inline bool canLinearize() const { return true; }
3403 
3404         virtual inline T cref(ptrdiff_t i, ptrdiff_t j) const
3405         { return itsm.get()[S==int(RowMajor) ? i*ptrdiff_t(stepi())+j : i+j*ptrdiff_t(stepj())]; }
3406 
3407         inline T& ref(ptrdiff_t i, ptrdiff_t j)
3408         { return itsm.get()[S==int(RowMajor) ? i*ptrdiff_t(stepi())+j : i+j*ptrdiff_t(stepj())]; }
3409 
3410         inline void resize(ptrdiff_t cs, ptrdiff_t rs)
3411         {
3412             TMVAssert(cs >= 0 && rs >= 0);
3413             linsize = cs*rs;
3414             itsm.resize(linsize);
3415             itscs = cs;
3416             itsrs = rs;
3417             DivHelper<T>::resetDivType();
3418 #ifdef TMVFLDEBUG
3419             _first = itsm.get();
3420             _last = _first + linsize;
3421 #endif
3422 #ifdef TMV_EXTRA_DEBUG
3423             setAllTo(T(888));
3424 #endif
3425         }
3426 
3427         inline rowmajor_iterator rowmajor_begin()
3428         { return MatrixIterHelper<S,type>::rowmajor_begin(this); }
3429         inline rowmajor_iterator rowmajor_end()
3430         { return MatrixIterHelper<S,type>::rowmajor_end(this); }
3431 
3432         inline const_rowmajor_iterator rowmajor_begin() const
3433         { return MatrixIterHelper<S,type>::rowmajor_begin(this); }
3434         inline const_rowmajor_iterator rowmajor_end() const
3435         { return MatrixIterHelper<S,type>::rowmajor_end(this); }
3436 
3437         inline colmajor_iterator colmajor_begin()
3438         { return MatrixIterHelper<S,type>::colmajor_begin(this); }
3439         inline colmajor_iterator colmajor_end()
3440         { return MatrixIterHelper<S,type>::colmajor_end(this); }
3441 
3442         inline const_colmajor_iterator colmajor_begin() const
3443         { return MatrixIterHelper<S,type>::colmajor_begin(this); }
3444         inline const_colmajor_iterator colmajor_end() const
3445         { return MatrixIterHelper<S,type>::colmajor_end(this); }
3446 
3447 
3448     protected :
3449 
3450         ptrdiff_t linsize;
3451         AlignedArray<T> itsm;
3452         ptrdiff_t itscs;
3453         ptrdiff_t itsrs;
3454 
3455 #ifdef TMVFLDEBUG
3456     public:
3457         const T* _first;
3458         const T* _last;
3459     protected:
3460 #endif
3461 
3462         // If two matrices are the same size and storage, then
3463         // swap can be much faster by copying the pointers to the data.
3464         friend void Swap(Matrix<T,A>& m1, Matrix<T,A>& m2)
3465         {
3466             TMVAssert(m1.colsize() == m2.colsize());
3467             TMVAssert(m1.rowsize() == m2.rowsize());
3468             m1.itsm.swapWith(m2.itsm);
3469 #ifdef TMVFLDEBUG
3470             TMV_SWAP(m1._first,m2._first);
3471             TMV_SWAP(m1._last,m2._last);
3472 #endif
3473         }
3474 
3475     }; // Matrix
3476 
3477     //-------------------------------------------------------------------------
3478 
3479     //
3480     // Special Creators:
3481     //   RowVectorViewOf(v) = 1xn Matrix with v in only row - Same Storage
3482     //   ColVectorViewOf(v) = nx1 Matrix with v in only col - Same Storage
3483     //   MatrixViewOf(m,colsize,rowsize,storage) = MatrixView of m
3484     //   MatrixViewOf(m,colsize,rowsize,stepi,stepj) = MatrixView of m
3485     //
3486 
3487     template <typename T>
3488     inline ConstMatrixView<T> RowVectorViewOf(const GenVector<T>& v)
3489     {
3490         return ConstMatrixView<T>(
3491             v.cptr(),1,v.size(),v.size(),v.step(),
3492             v.ct(),v.step()==1?v.size():0);
3493     }
3494 
3495     template <typename T, int A>
3496     inline ConstMatrixView<T,A> RowVectorViewOf(const ConstVectorView<T,A>& v)
3497     {
3498         return ConstMatrixView<T,A>(
3499             v.cptr(),1,v.size(),v.size(),v.step(),
3500             v.ct(),v.step()==1?v.size():0);
3501     }
3502 
3503     template <typename T, int A>
3504     inline ConstMatrixView<T,A> RowVectorViewOf(const Vector<T,A>& v)
3505     {
3506         return ConstMatrixView<T,A>(
3507             v.cptr(),1,v.size(),v.size(),1,v.ct(),v.size());
3508     }
3509 
3510     template <typename T, int A>
3511     inline MatrixView<T,A> RowVectorViewOf(VectorView<T,A> v)
3512     {
3513         return MatrixView<T,A>(
3514             v.ptr(),1,v.size(),v.size(),v.step(),
3515             v.ct(),v.step()==1?v.size():0
3516             TMV_FIRSTLAST1(v.ptr(),v.ptr()+v.size()) );
3517     }
3518 
3519     template <typename T, int A>
3520     inline MatrixView<T,A> RowVectorViewOf(Vector<T,A>& v)
3521     {
3522         return MatrixView<T,A>(
3523             v.ptr(),1,v.size(),v.size(),1,v.ct(),v.size()
3524             TMV_FIRSTLAST1(v.ptr(),v.ptr()+v.size()) );
3525     }
3526 
3527     template <typename T>
3528     inline ConstMatrixView<T> ColVectorViewOf(const GenVector<T>& v)
3529     {
3530         return ConstMatrixView<T>(
3531             v.cptr(),v.size(),1,v.step(),v.size(),
3532             v.ct(),v.step()==1?v.size():0);
3533     }
3534 
3535     template <typename T, int A>
3536     inline ConstMatrixView<T,A> ColVectorViewOf(const ConstVectorView<T,A>& v)
3537     {
3538         return ConstMatrixView<T,A>(
3539             v.cptr(),v.size(),1,v.step(),v.size(),
3540             v.ct(),v.step()==1?v.size():0);
3541     }
3542 
3543     template <typename T, int A>
3544     inline ConstMatrixView<T,A> ColVectorViewOf(const Vector<T,A>& v)
3545     {
3546         return ConstMatrixView<T,A>(
3547             v.cptr(),v.size(),1,1,v.size(),v.ct(),v.size());
3548     }
3549 
3550     template <typename T, int A>
3551     inline MatrixView<T,A> ColVectorViewOf(VectorView<T,A> v)
3552     {
3553         return MatrixView<T,A>(
3554             v.ptr(),v.size(),1,v.step(),v.size(),
3555             v.ct(),v.step()==1?v.size():0
3556             TMV_FIRSTLAST1(v.ptr(),v.ptr()+v.size()) );
3557     }
3558 
3559     template <typename T, int A>
3560     inline MatrixView<T,A> ColVectorViewOf(Vector<T,A>& v)
3561     {
3562         return MatrixView<T,A>(
3563             v.ptr(),v.size(),1,1,v.size(),v.ct(),v.size()
3564             TMV_FIRSTLAST1(v.ptr(),v.ptr()+v.size()) );
3565     }
3566 
3567     template <typename T>
3568     inline MatrixView<T> MatrixViewOf(
3569         T* m, ptrdiff_t colsize, ptrdiff_t rowsize, StorageType stor)
3570     {
3571         TMVAssert(colsize >= 0 && rowsize >= 0);
3572         TMVAssert(stor == RowMajor || stor == ColMajor);
3573         const ptrdiff_t linsize = colsize * rowsize;
3574         const ptrdiff_t stepi = stor == RowMajor ? rowsize : 1;
3575         const ptrdiff_t stepj = stor == RowMajor ? 1 : colsize;
3576         return MatrixView<T>(
3577             m,colsize,rowsize,stepi,stepj,NonConj,linsize
3578             TMV_FIRSTLAST1(m,m+linsize));
3579     }
3580 
3581     template <typename T>
3582     inline ConstMatrixView<T> MatrixViewOf(
3583         const T* m, ptrdiff_t colsize, ptrdiff_t rowsize, StorageType stor)
3584     {
3585         TMVAssert(colsize >= 0 && rowsize >= 0);
3586         TMVAssert(stor == RowMajor || stor == ColMajor);
3587         const ptrdiff_t linsize = colsize*rowsize;
3588         const ptrdiff_t stepi = stor == RowMajor ? rowsize : 1;
3589         const ptrdiff_t stepj = stor == RowMajor ? 1 : colsize;
3590         return ConstMatrixView<T>(
3591             m,colsize,rowsize,stepi,stepj,NonConj,linsize);
3592     }
3593 
3594     template <typename T>
3595     inline MatrixView<T> MatrixViewOf(
3596         T* m, ptrdiff_t colsize, ptrdiff_t rowsize, ptrdiff_t stepi, ptrdiff_t stepj)
3597     {
3598         TMVAssert(colsize >= 0 && rowsize >= 0);
3599         const ptrdiff_t linsize = (
3600             (stepi==1 && stepj==colsize) ? colsize * rowsize :
3601             (stepj==1 && stepi==rowsize) ? colsize * rowsize :
3602             0 );
3603         return MatrixView<T>(
3604             m,colsize,rowsize,stepi,stepj,NonConj,linsize
3605             TMV_FIRSTLAST1(m,m+stepi*(colsize-1)+stepj*(rowsize-1)+1));
3606     }
3607 
3608     template <typename T>
3609     inline ConstMatrixView<T> MatrixViewOf(
3610         const T* m, ptrdiff_t colsize, ptrdiff_t rowsize, ptrdiff_t stepi, ptrdiff_t stepj)
3611     {
3612         TMVAssert(colsize >= 0 && rowsize >= 0);
3613         const ptrdiff_t linsize = (
3614             (stepi==1 && stepj==colsize) ? colsize * rowsize :
3615             (stepj==1 && stepi==rowsize) ? colsize * rowsize :
3616             0 );
3617         return ConstMatrixView<T>(
3618             m,colsize,rowsize,stepi,stepj,NonConj,linsize);
3619     }
3620 
3621 
3622 
3623     //
3624     // Copy Matrices
3625     //
3626 
3627     template <typename T>
3628     void DoCopySameType(const GenMatrix<T>& m1, MatrixView<T> m2);
3629 
3630     template <typename T>
3631     inline void DoCopy(const GenMatrix<T>& m1, MatrixView<T> m2)
3632     { DoCopySameType(m1,m2); }
3633 
3634     template <typename T, typename T1>
3635     inline void DoCopyDiffType(const GenMatrix<T1>& m1, MatrixView<T> m2)
3636     {
3637         TMVAssert(m2.rowsize() == m1.rowsize());
3638         TMVAssert(m2.colsize() == m1.colsize());
3639         TMVAssert(m2.rowsize() > 0);
3640         TMVAssert(m2.colsize() > 0);
3641         TMVAssert(m1.ct()==NonConj);
3642         TMVAssert(m2.ct()==NonConj);
3643         TMVAssert(!m2.isSameAs(m1));
3644         TMVAssert(isComplex(T()) || isReal(T1()));
3645 
3646         if (m1.iscm() && m2.iscm() && m1.colsize() > 1)  {
3647             for(ptrdiff_t j=0;j<m2.rowsize();++j)
3648                 DoCopyDiffType(m1.col(j),m2.col(j));
3649         } else if (m2.colsize() < m2.rowsize()) {
3650             if (shouldReverse(m1.stepj(),m2.stepj())) {
3651                 for(ptrdiff_t i=0;i<m2.colsize();++i)
3652                     DoCopyDiffType(m1.row(i).reverse(),m2.row(i).reverse());
3653             } else {
3654                 for(ptrdiff_t i=0;i<m2.colsize();++i)
3655                     DoCopyDiffType(m1.row(i),m2.row(i));
3656             }
3657         } else {
3658             if (shouldReverse(m1.stepi(),m2.stepi())) {
3659                 for(ptrdiff_t j=0;j<m2.rowsize();++j)
3660                     DoCopyDiffType(m1.col(j).reverse(),m2.col(j).reverse());
3661             } else {
3662                 for(ptrdiff_t j=0;j<m2.rowsize();++j)
3663                     DoCopyDiffType(m1.col(j),m2.col(j));
3664             }
3665         }
3666     }
3667 
3668     template <typename T, typename T1>
3669     inline void DoCopy(const GenMatrix<T1>& m1, MatrixView<T> m2)
3670     { DoCopyDiffType(m1,m2); }
3671 
3672     template <typename T>
3673     inline void DoCopy(const GenMatrix<std::complex<T> >&, MatrixView<T>)
3674     { TMVAssert(TMV_FALSE); }
3675 
3676     template <typename T1, typename T2>
3677     inline void nonconjCopy(const GenMatrix<T1>& m1, MatrixView<T2> m2)
3678     {
3679         TMVAssert(isComplex(T2()) || isReal(T1()));
3680         TMVAssert(m2.rowsize() == m1.rowsize());
3681         TMVAssert(m2.colsize() == m1.colsize());
3682         TMVAssert(m1.ct() == NonConj);
3683         TMVAssert(m2.ct() == NonConj);
3684 
3685         if (!m2.iscm() && (m2.isrm() || m1.isrm()))
3686             DoCopy(m1.transpose(),m2.transpose());
3687         else
3688             DoCopy(m1,m2);
3689     }
3690 
3691     template <typename T1, typename T2>
3692     inline void Copy(const GenMatrix<T1>& m1, MatrixView<T2> m2)
3693     {
3694         TMVAssert(isComplex(T2()) || isReal(T1()));
3695         TMVAssert(m2.rowsize() == m1.rowsize());
3696         TMVAssert(m2.colsize() == m1.colsize());
3697         if (m2.rowsize() > 0 && m2.colsize() > 0) {
3698             if (SameStorage(m1,m2)) {
3699                 if (m2.isSameAs(m1)) {
3700                     // Do Nothing
3701                 } else if (m2.transpose().isSameAs(m1)) {
3702                     m2.transposeSelf();
3703                 } else if (m1.isrm()) {
3704                     Matrix<T1,RowMajor> m1x = m1;
3705                     m2 = m1x;
3706                 } else {
3707                     Matrix<T1,ColMajor> m1x = m1;
3708                     m2 = m1x;
3709                 }
3710             } else if (m1.canLinearize() && m2.canLinearize() &&
3711                        m1.stepi() == m2.stepi() && m1.stepj() == m2.stepj()) {
3712                 TMVAssert(m1.constLinearView().size()==m2.linearView().size());
3713                 TMVAssert((m1.stepi()==m2.stepi() && m1.stepj()==m2.stepj()));
3714                 m2.linearView() = m1.constLinearView();
3715             } else {
3716                 if (m1.isconj()) {
3717                     if (m2.isconj()) {
3718                         nonconjCopy(m1.conjugate(),m2.conjugate());
3719                     } else {
3720                         nonconjCopy(m1.conjugate(),m2);
3721                         m2.conjugateSelf();
3722                     }
3723                 } else {
3724                     if (m2.isconj()) {
3725                         nonconjCopy(m1,m2.conjugate());
3726                         m2.conjugateSelf();
3727                     } else  {
3728                         nonconjCopy(m1,m2);
3729                     }
3730                 }
3731             }
3732         }
3733     }
3734 
3735     //
3736     // Swap Matrices
3737     //
3738 
3739     template <typename T>
3740     void Swap(MatrixView<T> m1, MatrixView<T> m2);
3741 
3742     template <typename T, int A>
3743     inline void Swap(MatrixView<T> m1, Matrix<T,A>& m2)
3744     { Swap(m1,m2.view()); }
3745 
3746     template <typename T, int A>
3747     inline void Swap(Matrix<T,A>& m1, MatrixView<T> m2)
3748     { Swap(m1.view(),m2); }
3749 
3750     template <typename T, int A1, int A2>
3751     inline void Swap(Matrix<T,A1>& m1, Matrix<T,A2>& m2)
3752     { Swap(m1.view(),m2.view()); }
3753 
3754 
3755     //
3756     // Views of a Matrix:
3757     //
3758 
3759     template <typename T>
3760     inline ConstMatrixView<T> Transpose(const GenMatrix<T>& m)
3761     { return m.transpose(); }
3762 
3763     template <typename T, int A>
3764     inline ConstMatrixView<T,A> Transpose(const ConstMatrixView<T,A>& m)
3765     { return m.transpose(); }
3766 
3767     template <typename T, int A>
3768     inline ConstMatrixView<T,A&FortranStyle> Transpose(const Matrix<T,A>& m)
3769     { return m.transpose(); }
3770 
3771     template <typename T, int A>
3772     inline MatrixView<T,A> Transpose(MatrixView<T,A> m)
3773     { return m.transpose(); }
3774 
3775     template <typename T, int A>
3776     inline MatrixView<T,A&FortranStyle> Transpose(Matrix<T,A>& m)
3777     { return m.transpose(); }
3778 
3779     template <typename T>
3780     inline ConstMatrixView<T> Conjugate(const GenMatrix<T>& m)
3781     { return m.conjugate(); }
3782 
3783     template <typename T, int A>
3784     inline ConstMatrixView<T,A> Conjugate(const ConstMatrixView<T,A>& m)
3785     { return m.conjugate(); }
3786 
3787     template <typename T, int A>
3788     inline ConstMatrixView<T,A&FortranStyle> Conjugate(const Matrix<T,A>& m)
3789     { return m.conjugate(); }
3790 
3791     template <typename T, int A>
3792     inline MatrixView<T,A> Conjugate(MatrixView<T,A> m)
3793     { return m.conjugate(); }
3794 
3795     template <typename T, int A>
3796     inline MatrixView<T,A&FortranStyle> Conjugate(Matrix<T,A>& m)
3797     { return m.conjugate(); }
3798 
3799     template <typename T>
3800     inline ConstMatrixView<T> Adjoint(const GenMatrix<T>& m)
3801     { return m.adjoint(); }
3802 
3803     template <typename T, int A>
3804     inline ConstMatrixView<T,A> Adjoint(const ConstMatrixView<T,A>& m)
3805     { return m.adjoint(); }
3806 
3807     template <typename T, int A>
3808     inline ConstMatrixView<T,A&FortranStyle> Adjoint(const Matrix<T,A>& m)
3809     { return m.adjoint(); }
3810 
3811     template <typename T, int A>
3812     inline MatrixView<T,A> Adjoint(MatrixView<T,A> m)
3813     { return m.adjoint(); }
3814 
3815     template <typename T, int A>
3816     inline MatrixView<T,A&FortranStyle> Adjoint(Matrix<T,A>& m)
3817     { return m.adjoint(); }
3818 
3819     template <typename T>
3820     inline QuotXM<T,T> Inverse(const GenMatrix<T>& m)
3821     { return m.inverse(); }
3822 
3823 
3824     //
3825     // Matrix ==, != Matrix
3826     //
3827 
3828     template <typename T1, typename T2>
3829     bool operator==(
3830         const GenMatrix<T1>& m1, const GenMatrix<T2>& m2);
3831     template <typename T1, typename T2>
3832     inline bool operator!=(
3833         const GenMatrix<T1>& m1, const GenMatrix<T2>& m2)
3834     { return !(m1 == m2); }
3835 
3836 
3837     //
3838     // I/O
3839     //
3840 
3841     template <typename T>
3842     inline std::istream& operator>>(
3843         const TMV_Reader& reader, MatrixView<T> m)
3844     { m.read(reader); return reader.getis(); }
3845 
3846     template <typename T, int A>
3847     inline std::istream& operator>>(const TMV_Reader& reader, Matrix<T,A>& m)
3848     { m.read(reader); return reader.getis(); }
3849 
3850     template <typename T>
3851     inline std::istream& operator>>(std::istream& is, MatrixView<T> m)
3852     { return is >> IOStyle() >> m; }
3853 
3854     template <typename T, int A>
3855     inline std::istream& operator>>(std::istream& is, Matrix<T,A>& m)
3856     { return is >> IOStyle() >> m; }
3857 
3858 } // namespace tmv
3859 
3860 #endif
3861