C# Matrix Example

[TOC]

using System;

using CenterSpace.NMath.Core;

namespace CenterSpace.NMath.Core.Examples.CSharp
{
  /// <summary>
  /// A .NET example in C# showing some of the basic functionality of the matrix classes.
  /// </summary>
  class MatrixExample
  {
    static void Main( string[] args )
    {
      var A = new DoubleMatrix( "3x3 [1 2 3  4 5 6  7 8 9]" );

      // You can obtain vector "views" of the rows and columns.
      DoubleVector row1 = A.Row( 1 );

      Console.WriteLine();

      // Remember, indexing starts at 0 so row one really means the second
      // row of the matrix.
      Console.WriteLine( "Row 1 = {0}", row1.ToString() ); // [4 5 6]
      Console.WriteLine();

      DoubleVector col0 = A.Col( 0 );
      Console.WriteLine( "Column 0 = {0}", col0.ToString() ); // [1 4 7]
      Console.WriteLine();

      // Remember that these vectors are different views of the data in
      // the matrix A. Changing a value in one of these vectors will change
      // the corresponding value in the matrix.
      row1[0] = 10;
      Console.WriteLine( "Value of A[1,0] == 10 is {0}", A[1, 0] == 10 ); // True
      Console.WriteLine();

      // You can make sure that your data is not being shared with anyone
      // else by invoking the DeepenThisCopy method. This will insure that
      // you have your own private copy of the data and that it occupies
      // contiguous storage.
      A.DeepenThisCopy();
      row1[0] = 100;
      Console.WriteLine( "Value of A[1,0] == 100 is {0}", A[1, 0] == 100 ); // False
      Console.WriteLine();

      // You can also obtain vector views of the various diagonals of A.
      // Here's is one way to create the 3 by 3 matrix B
      //     |1  2 0|
      // B = |-2 1 2|
      //     |0 -2 1|
      // That is, 1's on the main diagonal, 2's in the super-diagonal, and 
      // -2's on the sub-diagonal.
      var B = new DoubleMatrix( 3, 3 ); // 3x3 matrix with all zeroes
      B.Diagonal().Set( Range.All, 1.0 );
      B.Diagonal( 1 ).Set( Range.All, 2.0 );
      B.Diagonal( -1 ).Set( Range.All, -2.0 );
      Console.WriteLine( "B..." );
      Console.WriteLine( B.ToTabDelimited() ); // B = 3x3 [1 2 0  -2 1 2  0 -2 1]
      Console.WriteLine();

      // Sum the columns of B
      DoubleVector totals = NMathFunctions.Sum( B );
      Console.WriteLine( "Column totals of B = {0}", totals.ToString() );
      Console.WriteLine();

      // There are methods to compute matrix norms with respect to the one
      // and infinity norms.
      Console.WriteLine( "The one-norm of A = {0}", A.InfinityNorm() );
      Console.WriteLine();
      Console.WriteLine( "The infinity-norm of A = {0}", A.OneNorm() );
      Console.WriteLine();

      // The Resize method changes the dimensions of a matrix. Values are
      // truncated or padded with zeros as appropriate.
      A.Resize( 5, 5 );

      // A will have it's original values in the top-left 3 by 3 corner. 
      // The last two rows and the last two columns will zeros.
      Console.WriteLine( "A resized..." );
      Console.WriteLine( A.ToTabDelimited() );
      Console.WriteLine();

      // The indexers can be used to obtain vector views of slices of the
      // rows or columns of A.
      // Construct a Range object which starts at 0, goes to the end and has
      // a stride of 2.
      var everyOtherElt = new Range( 0, Position.End, 2 );

      // Create a vector that views every other element of the last
      // last column of A.
      DoubleVector lastColEveryOther = A[everyOtherElt, A.Cols - 1];

      // Use this vector to set every other element in the last column
      // of A to 2.
      lastColEveryOther.Set( Range.All, 2.0 );
      Console.WriteLine( "lastColEveryOther = {0}", lastColEveryOther.ToString() ); // [1 1 1 1 1]
      Console.WriteLine();

      // Last column of A is [2 0 2 0 2]
      Console.WriteLine( "Last column of A = {0}", A.Col( A.Cols - 1 ).ToString() );
      Console.WriteLine();

      // Matrix/Matrix and Matrix/Vector products are computed using the appropriate
      // static methods in the NMath class.
      B = new DoubleMatrix( 5, 5, 1, 1 );
      DoubleMatrix C = NMathFunctions.Product( A, B );
      Console.WriteLine( "Inner product of A and B is..." );
      Console.WriteLine( C.ToTabDelimited() );
      Console.WriteLine();

      var v = new DoubleVector( "[5 4 3 2 1]" );
      DoubleVector u = NMathFunctions.Product( A, v );
      Console.WriteLine( "Inner product of A and v = {0}", u.ToString() );
      // If you are repeatedly computing a matrix-vector product and
      // do not need to save the results for each iteration, you can avoid
      // creating a new vector object to hold the results for each iteration
      // by using the 3 argument version of the Product function. This version
      // places the results of matrix and the first vector argument in a third
      // vector argument, which is assumed to be created with the correct size
      // (the number of rows of the matrix argument);
      NMathFunctions.Product( A, v, u );
      Console.WriteLine( "Three argument inner product of A and v = {0}", u.ToString() );
      Console.WriteLine();

      // Transpose products are available too.
      C = NMathFunctions.TransposeProduct( A, B );
      Console.WriteLine( "The inner product of the transpose of A with B..." );
      Console.WriteLine( C.ToTabDelimited() );
      Console.WriteLine();

      // For complex matrices, conjugate transpose products are available.
      var c = new DoubleComplex( 1, 1 );

      // Construct a two matrices whose values are multiples of c and 2c
      var F = new DoubleComplexMatrix( 3, 3, c, c );
      var G = new DoubleComplexMatrix( 3, 3, c, 2 * c );
      var H = NMathFunctions.ConjTransposeProduct( F, G );
      Console.WriteLine( "The inner product of the complex conjugate of F and G..." );
      Console.WriteLine( NMathFunctions.Real( H ).ToTabDelimited() );
      Console.WriteLine();

      Console.WriteLine();
      Console.WriteLine( "Press Enter Key" );
      Console.Read();

    } // Main

  }// class

}// namespace

[TOC]