Basic Tensors in C# QuickStart Sample

Illustrates the basic use of the Tensor class for working with tensors in C#.

View this sample in: Visual Basic F#

using System;

// Tensor classes reside in the Numerics.NET.Tensors
// namespace.
using Numerics.NET.Tensors;

namespace Numerics.NET.QuickStart.CSharp
{
    /// <summary>
    /// Illustrates the use of the Tensor class in the 
    /// Numerics.NET namespace of Numerics.NET.
    /// </summary>
    class BasicTensors
    {
        static void Main(string[] args)
        {
            // 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("64542-18980-57619-62268");

            //
            // Constructing tensors
            //

            // The simplest tensor is a scalar. It has no dimensions.
            // It is created using the CreateScalar method:
            var s = Tensor.CreateScalar(5.0);
            Console.WriteLine($"s.IsScalar = {s.IsScalar}");

            // To create tensors with 1 or more dimensions, there are many options,
            // including:

            // Option #1: Create an empty tensor.
            // The element type must be specified as a generic
            // type parameter. The dimensions are specified
            // as itnegers. The following constructs a tensor 
            // with 3 rows and 5 columns:
            var t1 = Tensor.Create<double>(3, 5);
            Console.WriteLine($"t1 = {t1}");

            // Option #2: specify an array of rank up to 4. 
            // By default, elements are taken in C# order.
            // Therefore, the following creates a tensor
            // with 4 rows and 3 columns:
            double[,] elements2D =
                {
                    {1, 2, 3},
                    {2, 3, 4},
                    {3, 4, 5},
                    {4, 5, 6}
                };
            var t2 = Tensor.CreateFromArray(elements2D);
            Console.WriteLine($"t2 = {t2}");

            // Option #3: Cast an array to a tensor.
            var t3 = (Tensor<double>)elements2D;
            Console.WriteLine($"t3 = {t3}");

            // Option #4: Specify an array of elements, and
            // a tuple with the dimensions. The elements are listed
            // in C# style order (last index changes fastest).
            // The following tensor is identical to t2:
            double[] elements = new double[]
            {
                1, 2, 3,
                2, 3, 4,
                3, 4, 5,
                4, 5, 6
            };
            var t4 = Tensor.CreateFromArray(elements, (4, 3));
            Console.WriteLine($"t4 = {t4}");

            // Option #5: same as above, but use a memory block
            // to store the elements. This can be both managed
            // or unmanaged memory. The following tensor is
            // identical to t3:
            var t5 = Tensor.CreateFromMemory(elements.AsMemory(), (4, 3), createView: true);
            Console.WriteLine($"t5 = {t5}");

            // Option #6: Create a tensor from a function.
            // Specify the dimensions and a function that
            // returns the value of each element:
            var t6 = Tensor.CreateFromFunction((10, 10), (i, j) => 1.0 / (1.0 + i + j));
            Console.WriteLine($"t6 = {t6:F5}");

            // Option #7-9: Create a range of values:
            var t7 = Tensor.CreateRange(10);
            // t7 -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
            var t8 = Tensor.CreateGeometricRange(1.0, 1000.0, 4);
            // t8 -> [ 1, 10, 100, 1000 ]
            var t9 = Tensor.CreateLogarithmicRange(0.0, 3.0, 4);
            // t9 -> [ 1, 10, 100, 1000 ]

            // Option #10-11: Create a tensor with random elements:
            var t10 = Tensor.CreateRandom((10, 10));
            var t11 = Tensor.CreateRandomNormal((5, 7, 18), new System.Random(17));


            //
            // Tensor properties
            //

            // The Rank property gives the rank or
            // number of dimensions of the tensor:
            Console.WriteLine($"t1.Rank = {t1.Rank}");

            // The Shape property gives the number of elements
            // along each dimension:
            Console.WriteLine($"t1.Shape = {t1.Shape}");
            Console.WriteLine($"t1 has {t1.Shape[0]} rows and {t1.Shape[1]} columns.");

            // The FlattenedLength property gives the total number of
            // elements in the tensor:
            Console.WriteLine($"t1.Length = {t1.FlattenedLength}");
if 


            var t1Layout = t1.Layout;

            // The Layout gives the strides between elements
            // along each axis in the tensor:
            Console.WriteLine($"t1 strides along axis 0: {t1Layout[0]}");
            Console.WriteLine($"t1 strides along axis 1: {t1Layout[1]}");

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