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