Content |
Symmetric and Hermitian Matrices with Full Storage
Concepts of TrMatrix shown on the previous page can be transfered to symmetric and hermitian matrices. Classes SyMatrix and HeMatrix represent symmertric and hermitian matrix classes with full storage respectively. Either the lower or upper triangular part of the full storage schemes is used to represent the symmetric or hermitian matrix.
Using views the same full storage scheme can be used for a GeMatrix, TrMatrix, SyMatrix or HeMatrix type:
-
GeMatrix views can be created form TrMatrix, SyMatrix or HeMatrix types using the general() method.
-
TrMatrix views can be created from
-
GeMatrix using the upper(), upperUnit(), lower() or lowerUnit() methods.
-
SyMatrix or HeMatrix using the triangular() method.
-
-
SyMatrix views can be created from a TrMatrix using the symmetric() method.
-
HeMatrix views can be created from a TrMatrix using the hermitian() method.
Chaining methods allows any combination of view creation.
Matrix Types SyMatrix and HeMatrix
Symmetric and hermitian matrices are always square. The types SyMatrix and HeMatrix use a full storage scheme for their data:
-
Matrices of type SyMatrix specify that the underlying full storage scheme should be assumed to represent a symmetric matrix.
-
Matrices of type HeMatrix specify that the underlying full storage scheme should be assumed to represent a hermitian matrix.
In most cases you first allocate a GeMatrix and then create a symmetric or hermitian view from some triangular part. But you also can go the way around, i.e. allocate a symmetric/hermitian matrix and create triangular or general matrix views referencing the underlying full storage scheme.
Common Interface of SyMatrix and HeMatrix
SyMatrix(IndexType dim, StorageUpLo upLo);
|
Allocates a memory for dim x dim elements. The triangular part specified by upLo (Lower or Upper) is used to represent a symmetric or hermitian matrix. |
HeMatrix(IndexType dim, StorageUpLo upLo);
|
|
IndexType
dim() const; |
Returns the matrix dimension. |
StorageUpLo
upLo() const; |
Returns Lower if the matrix is represented by lower triangular part. Otherwise Upper. In non-const context the method returns a reference of the attribute. So you can change it. |
StorageUpLo &
upLo(); |
|
const ElementType &
operator()(IndexType i, IndexType j) const; |
Return a reference to element in row \(i\) and column \(j\). Only accessing elements from the triangular part specified by upLo() is allowed. Otherwise a runtime assertion gets triggered. Note: The operator returns a reference to value actually stored in memory. If you have a hermitian matrix and you access a diagonal element it is your responsibility to ignore the imaginary part and assume it to be zero. |
ElementType &
operator()(IndexType i, IndexType j); |
|
const ElementType * data() const; |
Pointer to the first element of the matrix. So this is the address of A(1,1) |
ElementType * data(); |
|
StorageOrder
order() const; |
Returns RowMajor, ColMajor or Grid. An storage order Grid occurs if you have e.g. a matrix view that references every second row and every third column of a matrix. |
IndexType
strideRow() const; |
Stride in memory between elements in the same column. So A.data() + A.strideRow() is the address of A(2,1). If your matrix is ColMajor this is 1. |
IndexType
strideCol() const; |
Stride in memory between elements in the same row. So A.data() + A.strideCol() is the address of A(2,1). If your matrix is RowMajor this is 1. |
IndexType
leadingDimension() const; |
|
Creating Matrix Views from GeMatrix
From a GeMatrix you only can create TrMatrix views directly. Other matrix views like symmetric or hermitian views can be created by chaining view creation.
The following list of GeMatrix methods was already listed on the previous page:
const ConstTriangularView
upper() const; |
Return a triangular or trapezoidal matrix view represented by the upper triangular part. |
TriangularView
upper(); |
|
const ConstTriangularView
upperUnit() const; |
Return a triangular or trapezoidal matrix view represented by the upper triangular part. Elements on the diagonal must be assumed to be one. |
TriangularView
upperUnit(); |
|
const ConstTriangularView
lower() const; |
Return a triangular or trapezoidal matrix view represented by the lower triangular part. |
TriangularView
lower(); |
|
const ConstTriangularView
lowerUnit() const; |
Return a triangular or trapezoidal matrix view represented by the lower triangular part. Elements on the diagonal must be assumed to be one. |
TriangularView
lowerUnit(); |
Example
#include <iostream>
using namespace flens;
using namespace std;
int
main()
{
GeMatrix<FullStorage<double> > A(3,4);
A = 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12;
cout << "A = " << A << endl;
cout << "A.upper() = " << A.upper() << endl;
cout << "A.upperUnit() = " << A.upperUnit() << endl;
cout << "A.lower() = " << A.lower() << endl;
cout << "A.lowerUnit() = " << A.lowerUnit() << endl;
}
Compile and Run
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. matrixviews_from_gematrix.cc $shell> ./a.out A = 1 2 3 4 5 6 7 8 9 10 11 12 A.upper() = 1 2 3 4 0 6 7 8 0 0 11 12 A.upperUnit() = 1 2 3 4 0 1 7 8 0 0 1 12 A.lower() = 1 0 0 0 5 6 0 0 9 10 11 0 A.lowerUnit() = 1 0 0 0 5 1 0 0 9 10 1 0
Creating Matrix Views from TrMatrix
From a TrMatrix you can create GeMatrix, SyMatrix and HeMatrix views directly:
const ConstGeneralView general() const; |
Return a general matrix view referencing the complete underlying full storage scheme. Through this view any element can be accessed. |
GeneralView general(); |
|
const ConstHermitianView hermitian() const; |
If the TrMatrix is triangular (and not trapezoidal returns a hermitian matrix view. The hermitian matrix is represented by the given triangular part. If the TrMatrix is trapezoidal this causes an assertion failure at runtime. |
HermitianView hermitian(); |
|
const ConstSymmetricView symmetric() const; |
If the TrMatrix is triangular (and not trapezoidal returns a symmetric matrix view. The symmetric matrix is represented by the given triangular part. If the TrMatrix is trapezoidal this causes an assertion failure at runtime. |
SymmetricView symmetric(); |
Example
#include <complex>
#include <iostream>
using namespace flens;
using namespace std;
int
main()
{
typedef std::complex<double> zcomplex;
GeMatrix<FullStorage<zcomplex> > A(3,3);
A = zcomplex(1,1), zcomplex(1,2), zcomplex(1,3),
zcomplex(2,1), zcomplex(2,2), zcomplex(2,3),
zcomplex(3,1), zcomplex(3,2), zcomplex(3,3);
auto U = A.upper();
cout << "U = " << U << endl;
cout << "U.general() = " << U.general() << endl;
cout << "U.hermitian() = " << U.hermitian() << endl;
cout << "U.symmetric() = " << U.symmetric() << endl;
}
Compile and Run
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. matrixviews_from_trmatrix.cc $shell> ./a.out U = (1,1) (1,2) (1,3) (0,0) (2,2) (2,3) (0,0) (0,0) (3,3) U.general() = (1,1) (1,2) (1,3) (2,1) (2,2) (2,3) (3,1) (3,2) (3,3) U.hermitian() = (1,0) (1,2) (1,3) (1,-2) (2,0) (2,3) (1,-3) (2,-3) (3,0) U.symmetric() = (1,1) (1,2) (1,3) (1,2) (2,2) (2,3) (1,3) (2,3) (3,3)
Creating Matrix Views from SyMatrix
const ConstGeneralView general() const; |
Return a general matrix view referencing the complete underlying full storage scheme. Through this view any element can be accessed. |
GeneralView general(); |
|
const ConstHermitianView hermitian() const; |
Returns a hermitian matrix view. The hermitian matrix is represented by the same triangular part that represents the SyMatrix. |
HermitianView hermitian(); |
|
const ConstTriangularView triangular() const; |
Returns a triangular matrix view. The triangular matrix is represented by the same triangular part that represents the SyMatrix. |
TriangularView triangular(); |
Example
#include <complex>
#include <iostream>
using namespace flens;
using namespace std;
int
main()
{
typedef std::complex<double> zcomplex;
GeMatrix<FullStorage<zcomplex> > A(3,3);
A = zcomplex(1,1), zcomplex(1,2), zcomplex(1,3),
zcomplex(2,1), zcomplex(2,2), zcomplex(2,3),
zcomplex(3,1), zcomplex(3,2), zcomplex(3,3);
auto S = A.upper().symmetric();
cout << "S = " << S << endl;
cout << "S.triangular() = " << S.triangular() << endl;
cout << "S.general() = " << S.general() << endl;
cout << "S.hermitian() = " << S.hermitian() << endl;
}
Compile and Run
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. matrixviews_from_symatrix.cc $shell> ./a.out S = (1,1) (1,2) (1,3) (1,2) (2,2) (2,3) (1,3) (2,3) (3,3) S.triangular() = (1,1) (1,2) (1,3) (0,0) (2,2) (2,3) (0,0) (0,0) (3,3) S.general() = (1,1) (1,2) (1,3) (2,1) (2,2) (2,3) (3,1) (3,2) (3,3) S.hermitian() = (1,0) (1,2) (1,3) (1,-2) (2,0) (2,3) (1,-3) (2,-3) (3,0)
Creating Matrix Views from HeMatrix
const ConstGeneralView general() const; |
Return a general matrix view referencing the complete underlying full storage scheme. Through this view any element can be accessed. |
GeneralView general(); |
|
const ConstSymmetricView symmetric() const; |
Returns a symmetric matrix view. The symmetric matrix is represented by the same triangular part that represents the HeMatrix. |
SymmetricView symmetric(); |
|
const ConstTriangularView triangular() const; |
Returns a triangular matrix view. The triangular matrix is represented by the same triangular part that represents the HeMatrix. |
TriangularView triangular(); |
Example
#include <complex>
#include <iostream>
using namespace flens;
using namespace std;
int
main()
{
typedef std::complex<double> zcomplex;
GeMatrix<FullStorage<zcomplex> > A(3,3);
A = zcomplex(1,1), zcomplex(1,2), zcomplex(1,3),
zcomplex(2,1), zcomplex(2,2), zcomplex(2,3),
zcomplex(3,1), zcomplex(3,2), zcomplex(3,3);
auto H = A.upper().hermitian();
cout << "H = " << H << endl;
cout << "H.triangular() = " << H.triangular() << endl;
cout << "H.general() = " << H.general() << endl;
cout << "H.symmetric() = " << H.symmetric() << endl;
}
Compile and Run
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. matrixviews_from_hematrix.cc $shell> ./a.out H = (1,0) (1,2) (1,3) (1,-2) (2,0) (2,3) (1,-3) (2,-3) (3,0) H.triangular() = (1,1) (1,2) (1,3) (0,0) (2,2) (2,3) (0,0) (0,0) (3,3) H.general() = (1,1) (1,2) (1,3) (2,1) (2,2) (2,3) (3,1) (3,2) (3,3) H.symmetric() = (1,1) (1,2) (1,3) (1,2) (2,2) (2,3) (1,3) (2,3) (3,3)
Matrix Views from Rectangular Parts
The same concepts introduced for TrMatrix apply to SyMatrix and HeMatrix: You can create a general matrix view from a SyMatrix or HeMatrix. From there you can select any block and create a GeMatrix view:
auto A = S.general();
A12 = A(_(1,4),_(5,8));
// ...
As this is a frequently needed task we offer a more direct support. The return type of the following methods is always a GeMatrix view (even if you select a block on the diagonal that logically would be symmetric or hermitian):
const ConstGeneralView
operator()(const Range<IndexType> &rows, const Range<IndexType> &cols) const; |
Select a rectangualr area of the form (fromRow:toRow, fromCol:toCol) or (fromRow:stepRow:toRow, fromCol:stepRow:toCol) |
GeneralView
operator()(const Range<IndexType> &rows, const Range<IndexType> &cols); |
|
const ConstGeneralView
operator()(const Underscore<IndexType> &, const Range<IndexType> &cols) const; |
All rows are selected. So the range has the form (all, from:to). |
GeneralView
operator()(const Underscore<IndexType> &, const Range<IndexType> &cols); |
|
const ConstGeneralView
operator()(const Range<IndexType> &rows, const Underscore<IndexType> &) const; |
All columns are selected. So the range has the form (from:to, all). |
GeneralView
operator()(const Range<IndexType> &rows, const Underscore<IndexType> &); |
Vector Views
The return type is always a DenseVector view:
const ConstVectorView
operator()(IndexType row, const Underscore<IndexType> &) const; |
Select (row, all), i.e. the row with index row. |
VectorView
operator()(IndexType row, const Underscore<IndexType> &); |
|
const ConstVectorView
operator()(IndexType row, const Range<IndexType> &cols) const; |
Select (row, from:to), i.e. from the row with index row the elements in the column in range from:to. |
VectorView
operator()(IndexType row, const Range<IndexType> &cols); |
|
const ConstVectorView
operator()(const Underscore<IndexType> &, IndexType col) const; |
Select (all, col), i.e. the column with index col. |
VectorView
operator()(const Underscore<IndexType> &, IndexType col); |
|
const ConstVectorView
operator()(const Range<IndexType> &rows, IndexType col) const; |
Select (from:to, col), i.e. from the column with index col the elements in the row range from:to. |
VectorView
operator()(const Range<IndexType> &rows, IndexType col); |