Extreme Optimization >
User's Guide >
Vector and Matrix Library >
Matrices >
Accessing Matrix Components
Extreme Optimization User's Guide
User's Guide
Up: Matrices Next: Mathematical Properties Previous: General Matrices Contents
Accessing Matrix Components
Matrices are two-dimensional tables. The Extreme
Optimization Mathematics Library for .NET includes classes
that allow you to work with the rows and columms of a matrix as
vectors. In addition, these classes allow you to easily navigate
through a matrix.
Accessing individual components
The Matrix class has an
indexer property. The first index is the zero-based row
index. The second index is the zero-based column index. In
languages that don't support indexers, you can use the indexed Item
property. If the index is greater than or equal to the number of
rows or columns, an exception of type
IndexOutOfRangeException is thrown.
Accessing rows and columns
Often it is necessary to work with the rows or columns of a
matrix as vectors. The Extreme Optimization Mathematics Library
for .NET includes three options for doing this.
The row and column vectors returned by these mechanisms are
derived vectors. Any change to a component of the vector will
change the corresponding component of the matrix. Conversely,
any change to a component of the matrix will change the
corresponding component in the row or column vector. To make the
row or column vector stand-alone, call its CloneData
method.
In every case, the most efficient vector type is returned. For
example, the rows and columns of a GeneralMatrix are
of type GeneralVector.
The rows and columns of a TriangularMatrix
are of type BandVector.
Indexed range access
The indexer property is overloaded to allow for direct indexed
access to complete or partial rows or columns. In the overloads,
the row or column index is replaced with a Range
structure. The return value is a Vector that points to
the specified range in the specified row or column. The special
range Range.All
lets you access an entire row or column without having to specify
any details about the range.
| C# | Copy Code |
Matrix m = new GeneralMatrix(2, 3,new double[] {1, 2, 3, 4, 5, 6});
Vector row1 = m[1, Range.All];
// This prints "[2, 4, 6]":
Console.WriteLine("row1 = {0}", row1);
Vector column1 = m[Range.All, 0];
// This prints "[1, 2]":
Console.WriteLine("column1 = {0}", column1);
Vector row2 = m[0, new Range(1, 2)];
// This prints "[3, 5]":
Console.WriteLine("row2 = {0}", row2);
// We can assign to rows and columns, too:
m[Range.All, 0] = row2;
// This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine("m = {0}", m); |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(2, 3,New Double() {1, 2, 3, 4, 5, 6})
Dim row1 As Vector = m.Item(1, Range.All)
' This prints "[2, 4, 6]":
Console.WriteLine("row1 = {0}", row1)
Dim column1 As Vector = m.Item(Range.All, 0)
' This prints "[1, 2]":
Console.WriteLine("column1 = {0}", column1)
Dim row2 As Vector = m.Item(0, New Range(1, 2))
' This prints "[3, 5]":
Console.WriteLine("row2 = {0}", row2);
' We can assign to rows and columns, too:
m.Item(Range.All, 0) = row2
' This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine("m = {0}", m) |
Keep in mind that matrices are stored in column major order by
default. The components passed to the constructor should be read
column by column.
The first example above retrieves the entire second row of
the matrix m. The second example retrieves the entire
first column. The third example retrieves only the last two
elements of the first row.
When setting this property, the components in the range
specified by the index are set to the components of the right-hand
side. This is illustrated in the final example above.
The GetRow and GetColumn methods
The GetRow
and GetColumn
methods provide the same functionality as indexed range access with
slightly less overhead. Both methods are overloaded.
GetRow always takes the row index as its first
parameter. If no further parameters are supplied, the entire row is
returned. A partial row can be returned by providing the column
index of the first and last index in the new vector, and optionally
a stride. You can also pass a Range
structure as the only second parameter. GetColumn has
similar overloads. The first parameter is always the column
index. The remaining parameters, if present, specify the range of
row indexes. The following code sample performs the same operations
as the indexed range sample above, but uses GetRow and
GetColumn:
| C# | Copy Code |
Matrix m = new GeneralMatrix(2, 3,new double[] {1, 2, 3, 4, 5, 6});
Vector row1 = m.GetRow(1);
// This prints "[2, 4, 6]":
Console.WriteLine("row1 = {0}", row1);
Vector column1 = m.GetColumn(0);
// This prints "[1, 2]":
Console.WriteLine("column1 = {0}", column1);
Vector row2 = m.GetRow(0, 1, 2);
// This prints "[3, 5]":
Console.WriteLine("row2 = {0}", row2);
// We can assign to rows and columns using the CopyTo method:
row2.CopyTo(m.GetColumn(0));
// This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine("m = {0}", m); |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(2, 3,New Double() {1, 2, 3, 4, 5, 6})
Dim row1 As Vector = m.GetRow(1)
' This prints "[2, 4, 6]":
Console.WriteLine("row1 = {0}", row1)
Dim column1 As Vector = m.GetColumn(0)
' This prints "[1, 2]":
Console.WriteLine("column1 = {0}", column1)
Dim row2 As Vector = m.GetRow(0, 1, 2)
' This prints "[3, 5]":
Console.WriteLine("row2 = {0}", row2);
' We can assign to rows and columns using the CopyTo method:
row2.CopyTo(m.GetColumn(Range.All, 0))
' This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine("m = {0}", m) |
The biggest difference with indexed range access is that the
methods' return values cannot be assigned to. The same result can
be accomplished by using the CopyTo
method of the left-hand side of the assignment.
Enumeration
Matrix operations often involve performing some action on each
of the rows or columns of a matrix. The Rows
and Columns
properties return a RowCollection and a ColumnCollection,
respectively. These collections implement the IEnumerable interface
and therefore allow you to iterate through the rows or columns of a
matrix. The following example shows a method that calculates
the sum of the absolute values of a matrix.
| C# | Copy Code |
double SumOfAbsoluteValues(Matrix a)
{
double sum = 0;
foreach(Vector column in a.Columns)
sum += column.OneNorm();
return sum;
} |
| Visual Basic | Copy Code |
Function SumOfAbsoluteValues(a As Matrix) As Double
Dim sum As Double = 0;
ForEach Vector column In a.Columns
sum = sum + column.OneNorm()
Next sum
Return sum
End Function |
The one-norm of a vector equals the sum of the absolute values
of its components. All we have to do to obtain the sum of the
absolute values of a matrix, then, is to sum the one-norms of all
the rows or columns. Since most algorithms are optimized for
matrices stored in column major order, it is recommended to
iterate over the columns rather than the rows.
Accessing diagonals
The GetDiagonal method
returns a vector whose components are the diagonal of a matrix. The
method has an optional parameter that specifies the index of the
diagonal. A value of zero indicates the main diagonal. A value
greater than zero indicates a superdiagonal. A value less than zero
indicates a subdiagonal. The default is to return the main
diagonal.
This property returns a vector view of the diagonal. Changing
the elements of this vector will also change the corresponding
elements of the underlying matrix, and vice versa. To make
the diagonal vector stand-alone, call its CloneData
method.
Accessing submatrices
Sometimes it may be useful to treat part of a matrix as if it
were a matrix in its own right. There are two ways of achieving
this. In each case, the resulting matrix is never stand-alone.
Changing one of its components changes the corresponding component
in the original matrix, and vice versa.
Indexed range access
A fourth overload of the indexer property lets you extract a
part of a matrix. Both parameters of the indexer are
Range
structures. The first specifies the range of rows to include. The
second parameter specifies the range of columns. Both parameters
may have the special value Range.All,
which indicates that the entire column or row should be included.
Some examples:
| C# | Copy Code |
Matrix m = new GeneralMatrix(10, 10);
// Extract the 2nd to the 5th row of m:
Matrix m1 = m[new Range(1, 4), Range.All];
// Extract the odd columns:
Matrix m2 = m[Range.All, new Range(1, 10, 2)];
// Extract the 4x4 leading submatrix of m:
Matrix m3 = m[new Range(0, 3), new Range(0, 3)]; |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(10, 10)
' Extract the 2nd to the 5th row of m:
Dim m1 As Matrix = m.Item(New Range(1, 4), Range.All)
' Extract the odd columns:
Dim m2 As Matrix = m.Item(Range.All, New Range(1, 10, 2))
' Extract the 4x4 leading submatrix of m:
Dim m3 As Matrix = m.Item(New Range(0, 3), New Range(0, 3)) |
You can also assign to ranges. The following example sets the
upper right and lower left blocks of a 10x10 matrix to the identity
matrix:
| C# | Copy Code |
Matrix m = new GeneralMatrix(10, 10);
Matrix identity5 = GeneralMatrix.GetIdentity(5);
m[new Range(0, 4), new Range(5, 9)] = identity5;
m[new Range(5, 9), new Range(0, 4)] = identity5; |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(10, 10)
Dim identity5 As Matrix = GeneralMatrix.GetIdentity(5)
m.Item(New Range(0, 4), New Range(5, 9)) = identity5
m.Item(New Range(5, 9), New Range(0, 4)) = identity5 |
We first create a 5x5 identity matrix by calling the
GeneralMatrix.GetIdentity
method. We then assign this matrix to the selected blocks of
m.
Submatrix access
The same results can be achieved with the GetSubmatrix
method, which is somewhat more flexible: you can get the transpose
of a submatrix.
The ranges can be specified using either Range
structures or explicit start and end indices. An optional parameter
lets you specify the transpose operation to apply, if any. The
earlier examples can be expressed using the
GetSubmatrix method as follows:
| C# | Copy Code |
Matrix m = new GeneralMatrix(10, 10);
// Extract the 2nd to the 5th row of m.
// Start and end columns are supplied manually.
Matrix m1 = m.GetSubmatrix(1, 4, 0, 9);
// Extract the odd columns:
// Here we need to supply the transpose parameter.
Matrix m2 = m.GetSubmatrix(0, 9, 1, 1, 10, 2,
TransposeOperation.None);
// Extract the 4x4 leading submatrix of m.
// And let's get its transpose, just because we can:
Matrix m3 = m.GetSubmatrix(0, 3, 1, 0, 3, 1,
TransposeOperation.Transpose); |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(10, 10)
' Extract the 2nd to the 5th row of m.
' Start and end columns are supplied manually.
Dim m1 As Matrix = m.GetSubmatrix(1, 4, 0, 9)
' Extract the odd columns:
' Here we need to supply the transpose parameter.
Dim m2 As Matrix = m.GetSubmatrix(0, 9, 1, 1, 10, 2,
TransposeOperation.None)
' Extract the 4x4 leading submatrix of m.
' And let's get its transpose, just because we can:
Dim m3 As Matrix = m.GetSubmatrix(0, 3, 1, 0, 3, 1,
TransposeOperation.Transpose) |
Notice how in the last sample, the transpose of the submatrix
was returned. You can still assign to submatrices using the
CopyTo
method:
| C# | Copy Code |
Matrix m = new GeneralMatrix(10, 10);
Matrix identity5 = GeneralMatrix.GetIdentity(5);
identity5.CopyTo(m.GetSubmatrix(0, 4, 5, 9));
identity5.CopyTo(m.GetSubmatrix(5, 9, 0, 4)); |
| Visual Basic | Copy Code |
Dim m As Matrix = New GeneralMatrix(10, 10)
Dim identity5 As Matrix = GeneralMatrix.GetIdentity(5)
identity5.CopyTo(m.GetSubmatrix(0, 4, 5, 9))
identity5.CopyTo(m.GetSubmatrix(5, 9, 0, 4)) |
Up: Matrices Next: Mathematical Properties Previous: General Matrices Contents
Copyright 2004-2008,
Extreme Optimization. All rights reserved.
Extreme Optimization, Complexity made simple, M#, and M
Sharp are trademarks of ExoAnalytics Inc.
Microsoft, Visual C#, Visual Basic, Visual Studio, Visual
Studio.NET, and the Visual Studio Logo are registered trademarks of Microsoft Corporation