Matrix-Vector Operations in C# QuickStart Sample

Illustrates how to perform operations that involve both matrices and vectors in C#.

View this sample in: Visual Basic F# IronPython

using System;
// The Vector and DenseMatrix classes reside in the 
// Extreme.Mathematics.LinearAlgebra namespace.
using Extreme.Mathematics;
using Extreme.Mathematics.LinearAlgebra;

namespace Extreme.Numerics.QuickStart.CSharp
{
    /// <summary>
    /// Illustrates operations on DenseMatrix objects and combined
    /// operations on var and DenseMatrix objects from the
    /// Extreme.Mathematics.LinearAlgebra namespace of Extreme Numerics.NET.
    /// </summary>
    class MatrixVectorOperations
    {
        static void Main(string[] args)
        {
            // The license is verified at runtime. We're using
            // a demo license here. For more information, see
            // https://numerics.net/trial-key
            Extreme.License.Verify("Demo license");
            // For details on the basic workings of var 
            // objects, including constructing, copying and
            // cloning vectors, see the BasicVectors QuickStart
            // Sample.
            //
            // For details on the basic workings of DenseMatrix
            // objects, including constructing, copying and
            // cloning vectors, see the BasicVectors QuickStart
            // Sample.
            //
            // Let's create some vectors to work with.
            var v1 = Vector.Create(new double[] { 1, 2, 3, 4, 5 });
            var v2 = Vector.Create(new double[] { 1, -2, 3, -4, 5 });
            Console.WriteLine("v1 = {0:F4}", v1);
            Console.WriteLine("v2 = {0:F4}", v2);
            // These will hold results.
            Vector<double> v;

            // Also, here are a couple of matrices.
            // We start out with a 5x5 identity matrix:
            var m1 = DenseMatrix<double>.GetIdentity(5);
            // Now we use the GetDiagonal method and combine it
            // with the SetValue method of the Vector<T> class to
            // set some of the off-diagonal elements:
            m1.GetDiagonal(1).SetValue(2);
            m1.GetDiagonal(2).SetValue(3);
            m1.GetDiagonal(-1).SetValue(4);
            Console.WriteLine("m1 = {0:F4}", m1);
            // We define our second matrix by hand:
            var m2 = Matrix.Create(5, 5, new double[]
                {
                    1, 2, 3, 4, 5, 
                    1, 3, 5, 7, 9, 
                    1, 4, 9, 16, 25,
                    1, 8, 27, 64, 125,
                    1, -1, 1, -1, 1
                }, MatrixElementOrder.ColumnMajor);
            Console.WriteLine("m2 = {0:F4}", m2);
            Console.WriteLine();
            // This one holds the results:
            Matrix<double> m;
            
            //
            // Matrix arithmetic
            //

            // The Matrix class defines operator overloads for
            // addition, subtraction, and multiplication of
            // matrices.

            // Addition:
            Console.WriteLine("Matrix arithmetic:");
            m = m1 + m2;
            Console.WriteLine("m1 + m2 = {0:F4}", m);
            // Subtraction:
            m = m1 - m2;
            Console.WriteLine("m1 - m2 = {0:F4}", m);
            // Multiplication is the true matrix product:
            m = m1 * m2;
            Console.WriteLine("m1 * m2 = {0:F4}", m);
            Console.WriteLine();

            //
            // Matrix-var products
            //

            // The DenseMatrix class defines overloaded addition, 
            // subtraction, and multiplication operators 
            // for vectors and matrices:
            Console.WriteLine("Matrix-vector products:");
            v = m1 * v1;
            Console.WriteLine("m1 v1 = {0:F4}", v);
            // You can also multiply a vector by a matrix on the right.
            // This is equivalent to multiplying on the left by the 
            // transpose of the matrix:
            v = v1 * m1;
            Console.WriteLine("v1 m1 = {0:F4}", v);
            
            // Now for some methods of the Vector<T> class that
            // involve matrices:
            // Add a product of a matrix and a vector:
            v.AddProductInPlace(m1, v1);
            Console.WriteLine("v + m1 v1 = {0:F4}", v);
            // Or add a scaled product:
            v.AddScaledProductInPlace(-2, m1, v2);
            Console.WriteLine("v - 2 m1 v2 = {0:F4}", v);
            // You can also use static Subtract methods:
            v.SubtractProductInPlace(m1, v1);
            Console.WriteLine("v - m1 v1 = {0:F4}", v);
            Console.WriteLine();

            //
            // Matrix norms
            //
            Console.WriteLine("Matrix norms");
            // Matrix norms are not as easily defined as
            // vector norms. Three matrix norms are available.
            // 1. The one-norm through the OneNorm property:
            double a = m2.OneNorm();
            Console.WriteLine("OneNorm of m2 = {0:F4}", a);
            // 2. The infinity norm through the 
            //    InfinityNorm property:
            a = m2.InfinityNorm();
            Console.WriteLine("InfinityNorm of m2 = {0:F4}", a);
            // 3. The Frobenius norm is often used because it
            //    is easy to calculate.
            a = m2.FrobeniusNorm();
            Console.WriteLine("FrobeniusNorm of m2 = {0:F4}", a);
            Console.WriteLine();

            // The trace of a matrix is the sum of its diagonal
            // elements. It is returned by the Trace property:
            a = m2.Trace();
            Console.WriteLine("Trace(m2) = {0:F4}", a);

            // The Transpose method returns the transpose of a 
            // matrix. This transposed matrix shares element storage
            // with the original matrix. Use the CloneData method
            // to give the transpose its own data storage.
            m = m2.Transpose();
            Console.WriteLine("Transpose(m2) = {0:F4}", m);

            Console.Write("Press Enter key to exit...");
            Console.ReadLine();
        }
    }
}