Extreme Optimization >
Mathematics Library for .NET >
User's Guide >
Current Page >
Accessing Rows and Columns
Extreme Optimization Mathematics Library for .NET
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.
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);
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)
|
| C# | VB.NET | |
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:
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);
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)
|
| C# | VB.NET | |
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.
double SumOfAbsoluteValues(Matrix a)
{
double sum = 0;
foreach(Vector column in a.Columns)
sum += column.OneNorm();
return sum;
}
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
|
| C# | VB.NET | |
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:
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)];
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))
|
| C# | VB.NET | |
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:
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;
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
|
| C# | VB.NET | |
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:
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);
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)
|
| C# | VB.NET | |
Notice how in the last sample, the transpose of the submatrix was returned. You
can still assign to submatrices using the
CopyTo method:
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));
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))
|
| C# | VB.NET | |
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