[TOC]
using System;
using CenterSpace.NMath.Core;
using CenterSpace.NMath.Matrix;
namespace CenterSpace.NMath.Matrix.Examples.CSharp
{
/// <summary>
/// A .NET example in C# demonstrating the features of the banded matrix classes.
/// </summary>
class BandMatrixExample
{
static void Main(string[] args)
{
// Set up the parameters that describe the shape of a banded matrix.
int upperBandwidth = 2;
int lowerBandwidth = 1;
int rows = 7;
int cols = 7;
// Set up a banded matrix B by setting all the diagonals within the matrix
// bandwidth.
DoubleBandMatrix B = new DoubleBandMatrix(rows, cols, lowerBandwidth, upperBandwidth);
for (int i = -B.LowerBandwidth; i <= B.UpperBandwidth; ++i)
{
B.Diagonal(i).Set(Slice.All, i + 2);
}
Console.WriteLine();
Console.WriteLine("B = {0}", B.ToString());
// B = 1 2 7x7 [ 2 3 4 0 0 0 0
// 1 2 3 4 0 0 0
// 0 1 2 3 4 0 0
// 0 0 1 2 3 4 0
// 0 0 0 1 2 3 4
// 0 0 0 0 1 2 3
// 0 0 0 0 0 1 2 ]
// Indexer accessor works just like it does for general matrices.
Console.WriteLine();
Console.WriteLine("B[2,2] = {0}", B[2, 2]);
Console.WriteLine("B[5,0] = {0}", B[5, 0]);
// You can set the values of elements in the bandwidth
// of a banded matrix using the indexer.
B[2, 1] = 99;
Console.WriteLine("B[2,1] = {0}", B[2, 1]);
// But setting an element outside the bandwidth of the
// matrix raises a NonModifiableElementException exception.
try
{
B[6, 0] = 21;
}
catch (NonModifiableElementException e)
{
Console.WriteLine();
Console.WriteLine("NonModifiableElementException: {0}", e.Message);
}
// Scalar multiplication and addition/subtraction are supported.
DoubleBandMatrix C = 3 * B;
DoubleBandMatrix D = C - B;
Console.WriteLine();
Console.WriteLine("D = {0}", D.ToString());
// D = 1 2 7x7 [ 4 6 8 0 0 0 0
// 2 4 6 8 0 0 0
// 0 2 4 6 8 0 0
// 0 0 2 4 6 8 0
// 0 0 0 2 4 6 8
// 0 0 0 0 2 4 6
// 0 0 0 0 0 2 4 ]
// Matrix/vector, Matrix/Matrix products too.
RandGenUniform rng = new RandGenUniform(-1, 1);
rng.Reset(0x124);
DoubleVector x = new DoubleVector(B.Cols, rng); // vector of random deviates
DoubleVector y = MatrixFunctions.Product(B, x);
Console.WriteLine();
Console.WriteLine("Bx = {0}", y.ToString());
DoubleBandMatrix BTB = MatrixFunctions.Product(B.Transpose(), B);
Console.WriteLine();
Console.WriteLine("BTB = {0}", BTB.ToString());
// You can transform the non-zero elements of a banded matrix object by using
// the Transform() method on its data vector.
DoubleBandMatrix Cpi = Math.PI * C;
Cpi.DataVector.Transform(NMathFunctions.CosFunction); // cosine of Cpi
Console.WriteLine();
Console.WriteLine("cos(Cpi) = {0}", Cpi.ToString());
// Since the inner product of two banded matrices is a banded matrix,
// matrix inner products are supported.
DoubleBandMatrix P = MatrixFunctions.Product(Cpi, C);
Console.WriteLine();
Console.WriteLine("Banded matrix product = {0}", P.ToString());
// You can also solve linear systems.
DoubleVector x2 = MatrixFunctions.Solve(B, y);
// x and x2 should be the same. Let's look at the l2 norm of
// their difference.
DoubleVector residual = x - x2;
double residualL2Norm = Math.Sqrt(NMathFunctions.Dot(residual, residual));
Console.WriteLine();
Console.WriteLine("||x - x2|| = {0}", residualL2Norm);
// You can use the Resize() method to change the bandwidths.
Cpi.Resize(Cpi.Rows, Cpi.Cols, 1, 1); // matrix is now tridiagonal.
// And construct a tridiagonal matrix from it.
DoubleTriDiagMatrix T = new DoubleTriDiagMatrix(Cpi);
Console.WriteLine();
Console.WriteLine("Press Enter Key");
Console.Read();
}
}
}
[TOC]