Sequential matrices¶
The Matrix<T>
class is the building of the library:
its purpose is to provide convenient mechanisms for performing basic matrix
manipulations, such as setting and querying individual matrix entries,
without giving up compatibility with interfaces such as BLAS and LAPACK,
which assume column-major storage.
An example of generating an \(m \times n\) matrix of real double-precision numbers where the \((i,j)\) entry is equal to \(i-j\) would be:
#include "El.hpp" using namespace El; ... Matrix<double> A( m, n ); for( Int j=0; j<n; ++j ) for( Int i=0; i<m; ++i ) A.Set( i, j, double(i-j) );
whereas the complex double-precision equivalent could use Complex<double>
, which is currently a typedef for std::complex<double>
.
The underlying data storage for Matrix<T>
is simply a contiguous
buffer that stores entries in a column-major fashion with a leading
dimension which is only required to be at least as large as the height of the
matrix (so that entry \((i,j)\) is located at position i+j*ldim
).
For modifiable instances of the Matrix<T>
class, the routine
Matrix<T>::Buffer()
returns a pointer to the underlying
buffer, while Matrix<T>::LDim()
returns the leading
dimension; these two routines could be used to directly perform the equivalent
of the first code sample as follows:
#include "El.hpp" using namespace El; ... Matrix<double> A( m, n ); double* buffer = A.Buffer(); const Int ldim = A.LDim(); for( Int j=0; j<n; ++j ) for( Int i=0; i<m; ++i ) buffer[i+j*ldim] = double(i-j);
For immutable instances of the Matrix<T>
class, a const
pointer to the underlying data can similarly be returned with a call to
Matrix<T>::LockedBuffer()
.
In addition, a (const
) pointer to the place in the
(const
) buffer where entry \((i,j)\) resides can be easily retrieved
with a call to Matrix<T>::Buffer()
or
Matrix<T>::LockedBuffer()
.
It is also important to be able to create matrices which are simply views of existing (sub)matrices. In general, to view the submatrix with row indices \([\text{iBeg},\text{iEnd}]\) and column indices \([\text{jBeg},\text{jEnd}]\), one can use a statement of the form
#include "El.hpp" ... auto ASub = A( IR(iBeg,iEnd), IR(jBeg,jEnd) );
- template<>
-
class
Matrix
<T>¶ The goal is for the Matrix class to support any datatype T which supports both addition and multiplication and has the associated identities (that is, when the datatype T is a ring). While there are several barriers to reaching this goal, it is important to keep in mind that, in addition to T being allowed to be a real or complex (single- or double-precision) floating-point type, signed integers are also supported.
Constructors and destructors
Note
Many of the following constructors have the default parameter
bool fixed=false
, which can be changed totrue
in order to produce a Matrix whose entries can be modified, but the matrix’s dimensions cannot. This is useful for theDistMatrix<T>
class, which contains a localMatrix<T>
whose entries can be locally modified in cases where it would not make sense to change the local matrix size (which should instead result from changing the size of the full distributed matrix).-
Matrix
(bool fixed = false)¶ This simply creates a default \(0 \times 0\) matrix with a leading dimension of one (BLAS and LAPACK require positive leading dimensions).
-
Matrix
(Int height, Int width, bool fixed = false)¶ A height \(\times\) width matrix is created with an unspecified leading dimension (though it is currently implemented as \(\max(height,1)\)).
-
Matrix
(Int height, Int width, Int ldim, bool fixed = false)¶ A height \(\times\) width matrix is created with a leading dimension equal to ldim (which must be greater than or equal \(\max(height,1)\)).
-
Matrix
(Int height, Int width, T *buffer, Int ldim, bool fixed = false)¶ A matrix is built around a column-major (immutable) buffer with the specified dimensions. The memory pointed to by buffer should not be freed until after the
Matrix<T>
object is destructed.
-
Matrix
(Matrix<T> &&A) noexcept¶ A C++11 move constructor which creates a new matrix by moving the metadata from the specified matrix over to the new matrix, which cheaply gives the new matrix control over the resources originally assigned to the input matrix.
-
~Matrix
()¶ Frees all resources owned by the matrix upon destruction.
Assignment and reconfiguration
-
Matrix<T> &
operator=
(Matrix<T> &&A)¶ A C++11 move assignment which swaps the metadata of two matrices so that the resources owned by the two objects will have been cheaply switched.
-
void
Empty
()¶ Sets the matrix to \(0 \times 0\) and frees any owned resources.
-
void
Resize
(Int height, Int width, Int ldim)¶ Reconfigures the matrix to be height \(\times\) width, but with leading dimension equal to ldim (which must be greater than or equal to \(\max(height,1)\)).
-
void
LockedAttach
(Int height, Int width, const T *buffer, Int ldim)¶ Reconfigure the matrix around the specified (unmodifiable) buffer.
-
void
Control
(Int height, Int width, T *buffer, Int ldim)¶ Reconfigure the matrix around a specified buffer and give ownership of the resource to the matrix.
Basic queries
-
Int
MemorySize
() const¶ Return the number of entries of type T that this
Matrix<T>
instance has allocated space for.
-
Int
DiagonalLength
(Int offset = 0) const¶ Return the length of the specified diagonal of the matrix: an offset of \(0\) refers to the main diagonal, an offset of \(1\) refers to the superdiagonal, an offset of \(-1\) refers to the subdiagonal, etc.
-
T *
Buffer
()¶
-
const T *
LockedBuffer
() const¶ Return a pointer to the (immutable) underlying buffer.
-
const T *
LockedBuffer
(Int i, Int j) const¶ Return a pointer to the (immutable) portion of the buffer that holds entry \((i,j)\).
-
bool
Viewing
() const¶ Returns true if the underlying buffer is merely a pointer into an externally-owned buffer.
-
bool
FixedSize
() const¶ Returns true if the dimensions of the matrix cannot be changed.
-
bool
Locked
() const¶ Returns true if the entries of the matrix cannot be changed.
Single-entry manipulation
-
void
SetImagPart
(Int i, Int j, Base<T> alpha)¶ Set entry \((i,j)\) (or its real or imaginary part) to \(\alpha\).
-
void
UpdateImagPart
(Int i, Int j, Base<T> alpha)¶ Add \(\alpha\) to entry \((i,j)\) (or its real or imaginary part).
Diagonal manipulation
-
void
GetImagPartOfDiagonal
(Matrix<Base<T>> &d, Int offset = 0) const¶ Modify \(d\) into a column-vector containing the entries (or their real or imaginary parts) lying on the offset diagonal of our matrix (for instance, the main diagonal has offset \(0\), the subdiagonal has offset \(-1\), and the superdiagonal has offset \(+1\)).
-
Matrix<Base<T>>
GetRealPartOfDiagonal
(Int offset = 0) const¶ Efficiently construct and return the particular diagonal (or its real or imaginary part) via C++11 move semantics.
-
void
SetImagPartOfDiagonal
(const Matrix<Base<T>> &d, Int offset = 0)¶ Set the entries (or their real or imaginary parts) in the offset diagonal entries from the contents of the column-vector \(d\).
-
void
UpdateImagPartOfDiagonal
(Base<T> alpha, const Matrix<Base<T>> &d, Int offset = 0)¶ Add the contents of \(\alpha d\) onto the entries (or the real or imaginary parts) in the offset diagonal.
-
void
ConjugateDiagonal
(nt offset = 0)¶ Conjugate the specified diagonal of the matrix.
Arbitrary-submatrix manipulation
-
void
GetRealPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, Matrix<Base<T>> &ASub) const¶
-
void
GetImagPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, Matrix<Base<T>> &ASub) const¶ Return the submatrix (or its real or imaginary part) with the specified row and column indices via ASub.
-
Matrix<Base<T>>
GetImagPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J) const¶ Return the submatrix (or its real or imaginary part) with the specified row and column indices via C++11 move semantics.
-
void
SetRealPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, const Matrix<Base<T>> &ASub)¶
-
void
SetImagPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, const Matrix<Base<T>> &ASub)¶ Set the submatrix (or its real or imaginary part) with the specified row and column indices equal to the matrix ASub.
-
void
UpdateSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, T alpha, const Matrix<T> &ASub)¶
-
void
UpdateRealPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, Base<T> alpha, const Matrix<Base<T>> &ASub)¶
-
void
UpdateImagPartOfSubmatrix
(const std::vector<Int> &I, const std::vector<Int> &J, Base<T> alpha, const Matrix<Base<T>> &ASub)¶ Update the submatrix (or its real or imaginary part) with the specified row and column indices with alpha times ASub.
-
Special cases used in Elemental¶
This list of special cases is here to help clarify the notation used throughout
Elemental’s source (as well as this documentation). These are all special
cases of Matrix<T>
.
- template<>
-
class
Matrix
<Real>¶ Used to denote that the underlying datatype Real is real.
- template<>
-
class
Matrix
<Complex<Real>>¶ Used to denote that the underlying datatype
Complex<Real>
is complex with base type Real.
- template<>
-
class
Matrix
<F>¶ Used to denote that the underlying datatype F is a field.