This time, I created only a program that calculates the matrix required for deep learning. The book I referred to was "Make from scratch Deep Learning (O'Reilly)". I recommend this book because it is very easy to understand and I think it is a good book. It's not a manga, but it doesn't stop ... I was so interested. I've only read about half of it yet, so there are many things I don't understand, but this time I made a matrix calculation program in C #.
This book also explains the theory, so I wanted to make it ** from scratch ** in C # without relying on the Python library. I'll try to implement it in F # and Haskell later.
I recently started studying functional languages such as F # and Haskell, and I still can't understand the meaning of using functional languages. "By the way, functional languages have come closer to mathematical ideas." Then, deep learning! (The motive was that I didn't know how to use a functional language.) For the time being, I did it in C #.
Matrix.cs
namespace Matrix
{
    class Mat
    {
        private int r = 0;
        public int R
        {
            get { return r; }
        }
        private int c = 0;
        public int C
        {
            get { return c; }
        }
        private bool err = false;
        public bool Err
        {
            get { return err; }
        }
        private double[][] matrix_data;
        public double[][] Matrix_data
        {
            get {
                double[][] a = new double[2][];
                a[0] = new double[] { 0, 0 };
                a[1] = new double[] { 0, 0 };
                if (err) return a;
                else return matrix_data;
            }
            set
            {
                matrix_data = value;
            }
        }
        public Mat(params double[][] vs)
        {
            int len = vs[0].Length;
            for (int i = 0; i < vs.Length; i++)
            {
                if (i != 0 && len != vs[i].Length)
                {
                    err = true;
                }
            }
            if (!err)
            {
                r = vs.Length;
                c = vs[0].Length;
                matrix_data = vs;
            }
        }
        public static double[][] operator +(Mat p1, Mat p2)
        {
            double[][] d = new double[p1.R][];
            if (p1.C == p2.C && p1.R == p2.R)
            {
                for (int i = 0; i < p1.R; i++)
                {
                    d[i] = new double[p1.C];
                    for (int j = 0; j < p1.C; j++)
                    {
                        d[i][j] = p1.Matrix_data[i][j] + p2.Matrix_data[i][j];
                    }
                }
            }
            else
            {
                for (int k = 0; k < p1.R; k++)
                {
                    d[k] = new double[2] { 0, 0 };
                }
            }
            return d;
        }
        public static double[][] operator +(double p1, Mat p2)
        {
            double[][] d = new double[p2.R][];
            for (int i = 0; i < p2.R; i++)
            {
                d[i] = new double[p2.C];
                for (int j = 0; j < p2.C; j++)
                {
                    d[i][j] = p2.Matrix_data[i][j] + p1;
                }
            }
            return d;
        }
        public static double[][] operator +(Mat p1, double p2)
        {
            double[][] d = new double[p1.R][];
            for (int i = 0; i < p1.R; i++)
            {
                d[i] = new double[p1.C];
                for (int j = 0; j < p1.C; j++)
                {
                    d[i][j] = p1.Matrix_data[i][j] + p2;
                }
            }
            return d;
        }
        public static double[][] operator -(Mat p1, Mat p2)
        {
            double[][] d = new double[p1.R][];
            if (p1.C == p2.C && p1.R == p2.R)
            {
                for (int i = 0; i < p1.R; i++)
                {
                    d[i] = new double[p1.C];
                    for (int j = 0; j < p1.C; j++)
                    {
                        d[i][j] = p1.Matrix_data[i][j] - p2.Matrix_data[i][j];
                    }
                }
            }
            else
            {
                for (int k = 0; k < p1.R; k++)
                {
                    d[k] = new double[2] { 0, 0 };
                }
            }
            return d;
        }
        public static double[][] operator -(double p1, Mat p2)
        {
            double[][] d = new double[p2.R][];
            for (int i = 0; i < p2.R; i++)
            {
                d[i] = new double[p2.C];
                for (int j = 0; j < p2.C; j++)
                {
                    d[i][j] = p1 - p2.Matrix_data[i][j];
                }
            }
            return d;
        }
        public static double[][] operator -(Mat p1, double p2)
        {
            double[][] d = new double[p1.R][];
            for (int i = 0; i < p1.R; i++)
            {
                d[i] = new double[p1.C];
                for (int j = 0; j < p1.C; j++)
                {
                    d[i][j] = p1.Matrix_data[i][j] - p2;
                }
            }
            return d;
        }
        public static double[][] dot(Mat p1, Mat p2)
        {
            double[][] d = new double[p1.R][];
            double temp = 0;
            if (p1.C == p2.R)
            {
                for (int i = 0; i < p1.R; i++)
                {
                    d[i] = new double[p2.C];
                    for (int j = 0; j < p2.C; j++)
                    {
                        for(int a = 0; a < p1.C; a++)
                        {
                            temp = temp + p1.Matrix_data[i][a] * p2.Matrix_data[a][j];
                        }
                        d[i][j] = temp;
                        temp = 0.0;
                    }
                }
            }
            else
            {
                for (int k = 0; k < p1.R; k++)
                {
                    d[k] = new double[2] { 0, 0 };
                }
            }
            return d;
        }
    }
}
Class Mat is a class that calculates a matrix.
The usage example is as follows.
Program.cs
namespace Matrix
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat A = new Mat(
                new double[] { 1, 2, 3 },
                new double[] { 2, 3, 4 }) ,
                B = new Mat(
                new double[] { 1, 2 },
                new double[] { 2, 3 },
                new double[] { 3, 4 });
            double[][] ans = Mat.dot(A, B);
            _ = 1;    //Tammy program to set breakpoints
        }
    }
}
It was a hassle to output to this sole, so I put a breakpoint on the line _ = 1; and checked the contents of the array ʻans`.

It is calculated properly.
This time, the dot product is calculated with Mat, but you can also add and subtract.
Recommended Posts