Accessing Matrix Elements in C# QuickStart Sample
Illustrates different ways of iterating through the rows and columns of a matrix using classes in the Numerics.NET.LinearAlgebra namespace in C#.
This sample is also available in: Visual Basic, F#, IronPython.
Overview
This QuickStart sample demonstrates the various ways to access and manipulate elements, rows, columns, and submatrices in Numerics.NET matrices.
The sample shows how to:
- Access individual matrix elements using index notation
- Extract complete or partial rows and columns using range syntax
- Use the
GetRow
andGetColumn
methods for accessing matrix components - Enumerate through matrix rows and columns
- Access matrix diagonals and superdiagonals
- Work with submatrices through both indexing and dedicated methods
- Assign values to matrix components, including rows, columns and submatrices
The sample provides practical examples of each operation, demonstrating both read and write operations on matrices. It illustrates the flexibility of Numerics.NET’s matrix access methods, from simple element access to sophisticated operations on matrix substructures.
The code
using System;
using Numerics.NET;
using Numerics.NET.LinearAlgebra;
// Avoid ambiguity.
using Range = Numerics.NET.Range;
// Illustrates accessing matrix components and iterating
// through the rows and columns of a matrix. Matrix classes
// reside in the Numerics.NET.LinearAlgebra namespace
// of Numerics.NET.
// The license is verified at runtime. We're using
// a 30 day trial key here. For more information, see
// https://numerics.net/trial-key
Numerics.NET.License.Verify("your-trial-key-here");
// We'll work with this matrix:
var m = Matrix.CreateFromArray(2, 3, new double[] { 1, 2, 3, 4, 5, 6 },
MatrixElementOrder.ColumnMajor);
//
// Individual components
//
// The Matrix class has an indexer property that takes two arguments:
// the row and column index. Both are zero based.
Console.WriteLine("m[1,1] = {0}", m[1, 1]);
//
// Rows and columns
//
// Indexed range access
// The indexer property is overloaded to allow for direct indexed access
// to complete or partial rows or columns.
var row1 = m[0, new Range(1, 2)];
// This prints "[3, 5]":
Console.WriteLine($"row1 = {row1}");
// The special range Range.All lets you access an entire row
// or column without having to specify any details about the range.
var row2 = m[1, Range.All];
// This prints "[2, 4, 6]":
Console.WriteLine($"2nd row = {row2}");
var column1 = m[Range.All, 0];
// This prints "[1, 2]":
Console.WriteLine($"column1 = {column1}");
// We can assign to rows and columns, too:
m[Range.All, 0] = row1;
// This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine($"m = {m}");
// GetRow and GetColumn provide an alternate mechanism
// for achieving the same result.
// Passing just one parameter retrieves the specified row or column:
row1 = m.GetRow(1);
// This prints "[2, 4, 6]":
Console.WriteLine($"row1 = {row1}");
column1 = m.GetColumn(0);
// This prints "[1, 2]":
Console.WriteLine($"column1 = {column1}");
// You can also pass a start and end index:
row2 = m.GetRow(0, 1, 2);
// This prints "[3, 5]":
Console.WriteLine($"row2 = {row2}");
// We can assign to rows and columns, too, using CopyTo:
row2.CopyTo(m.GetColumn(0));
// This prints "[[3, 3, 5] [5, 4, 6]]"
Console.WriteLine($"m = {m}");
// Enumeration
// The Rows and Columns methods allow you to enumerate over
// the rows and columns of a matrix.
// For example: this calculates the sum of the absolute values
// of the components of the matrix m:
double sum = 0;
foreach(Vector<double> column in m.Columns )
sum += column.OneNorm();
//
// Accessing diagonals
//
// Diagonals are retrieved using the GetDiagonal method:
var mainDiagonal = m.GetDiagonal();
// An optional parameter specifies which diagonal:
// n < 0 means subdiagonal
// n > 0 means nth superdiagonal:
var superDiagonal = m.GetDiagonal(1);
//
// Accessing submatrices
//
// Indexed range access
// A fourth overload of the indexer property lets you
// extract a part of a matrix. Both parameters are Range
// structures:
var a = Matrix.Create<double>(10, 10);
// Extract the 2nd to the 5th row of m:
var a1 = a[new Range(1, 4), Range.All];
// Extract the odd columns:
var a2 = a[Range.All, new Range(1, 9, 2)];
// Extract the 4x4 leading submatrix of m:
var a3 = a[new Range(0, 3), new Range(0, 3)];
// You can also assign to submatrices:
var identity5 = DenseMatrix<double>.GetIdentity(5);
a[new Range(0, 4), new Range(5, 9)] = identity5;
a[new Range(5, 9), new Range(0, 4)] = identity5;
// The same results can be achieved with the GetSubmatrix method.
// Extract the 2nd to the 5th row of m.
// Start and end columns are supplied manually.
var a4 = a.GetSubmatrix(1, 4, 0, 9);
// Extract the odd columns:
// Here we need to supply the transpose parameter.
var a5 = a.GetSubmatrix(0, 9, 1, 1, 9, 2,
TransposeOperation.None);
// Extract the 4x4 leading submatrix of m.
// And let's get its transpose, just because we can.
// We need to specify the row and column stride:
var a6 = a.GetSubmatrix(0, 3, 1, 0, 3, 1,
TransposeOperation.Transpose);
// You can still assign to submatrices, using the
// CopyTo method:
identity5.CopyTo(a.GetSubmatrix(0, 4, 5, 9));
identity5.CopyTo(a.GetSubmatrix(5, 9, 0, 4));
Console.WriteLine("Press Enter key to continue.");
Console.ReadLine();