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# CopyCode imageCopy 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 CopyCode imageCopy 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# CopyCode imageCopy 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 CopyCode imageCopy 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# CopyCode imageCopy Code
double SumOfAbsoluteValues(Matrix a)
{
    double sum = 0;
    foreach(Vector column in a.Columns)
        sum += column.OneNorm();
    return sum;
}
Visual Basic CopyCode imageCopy 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# CopyCode imageCopy 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 CopyCode imageCopy 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# CopyCode imageCopy 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 CopyCode imageCopy 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# CopyCode imageCopy 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 CopyCode imageCopy 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# CopyCode imageCopy 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 CopyCode imageCopy 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

Overview
Introduction
Features
Documentation
QuickStart Samples
Sample Applications
Downloads
Get it now!
Download trial version
How to Buy
Information
Resources
Contact Us
Search

"The Extreme Optimization Statistics Library for .NET is a major boon for those doing statistical work in .NET. I strongly recommend this product."
- Marc Brooks

"I have made it my mission to institutionalize the value of good API design.  I strongly believe that this is key to making developers more productive and happy on our platform. It is clear that you value good API design in your work, and take to heart developer productivity and synergy with the .NET framework."
- Brad Abrams,
Lead Program Manager, Microsoft.

This is a partial list of companies who are using our libraries:
ABB Robotics
Allstate
Applied Materials
Arcam
Astra Schedule
Babson College
Canadian Council on Learning
Canyon Associates
Caxton Associates
CECity
Constellation Energy
CreditSights
DeepOcean
Duke University
Dynamotive
Elecsoft
Engelhard Corporation
Epcor
Equipoise Software
Galileo International
GAM UK
Gammex
GlaxoSmithKline
Global Matrix
The Hartford
Infinera Corporation
Intel
JDS Uniphase
LaBranche & Co.
Learning & Skills Council
Jacobs Consultancy
Litman Gregory
Lucas Systems
Malvern Instruments
Medrio
Merck & Co.
Mintera.
Monitor Software
MorningStar
NanoString Technologies
Paletta Invent
Parametric Portfolio Associates
Prosanos
RATA Associates
RiskShield
Ramboll
Standard & Poor's
Strategic Analysis Corporation
Univ. of Alicante
Univ. of South Carolina
vielife
Xerox
US Army