Advertisement
Guest User

MatrixMath.cs

a guest
Jan 26th, 2020
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.39 KB | None | 0 0
  1. // Encog Neural Network and Bot Library for DotNet v0.5
  2. // http://www.heatonresearch.com/encog/
  3. // http://code.google.com/p/encog-cs/
  4. //
  5. // Copyright 2008, Heaton Research Inc., and individual contributors.
  6. // See the copyright.txt in the distribution for a full listing of
  7. // individual contributors.
  8. //
  9. // This is free software; you can redistribute it and/or modify it
  10. // under the terms of the GNU Lesser General Public License as
  11. // published by the Free Software Foundation; either version 2.1 of
  12. // the License, or (at your option) any later version.
  13. //
  14. // This software is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. // Lesser General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU Lesser General Public
  20. // License along with this software; if not, write to the Free
  21. // Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  22. // 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  23.  
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Linq;
  27. using System.Text;
  28.  
  29. namespace Encog.Matrix
  30. {
  31.  
  32.     /// <summary>
  33.     /// MatrixMath: This class can perform many different mathematical
  34.     /// operations on matrixes.
  35.     /// </summary>
  36.     public class MatrixMath
  37.     {
  38.         /// <summary>
  39.         /// Add two matrixes together, producing a third.
  40.         /// </summary>
  41.         /// <param name="a">The first matrix to add.</param>
  42.         /// <param name="b">The second matrix to add.</param>
  43.         /// <returns>The two matrixes added together.</returns>
  44.         public static Matrix Add(Matrix a, Matrix b)
  45.         {
  46.             if (a.Rows != b.Rows)
  47.             {
  48.                 throw new MatrixError(
  49.                         "To add the matrixes they must have the same number of rows and columns.  Matrix a has "
  50.                                 + a.Rows
  51.                                 + " rows and matrix b has "
  52.                                 + b.Rows + " rows.");
  53.             }
  54.  
  55.             if (a.Cols != b.Cols)
  56.             {
  57.                 throw new MatrixError(
  58.                         "To add the matrixes they must have the same number of rows and columns.  Matrix a has "
  59.                                 + a.Cols
  60.                                 + " cols and matrix b has "
  61.                                 + b.Cols + " cols.");
  62.             }
  63.  
  64.             double[,] result = new double[a.Rows, a.Cols];
  65.  
  66.             for (int resultRow = 0; resultRow < a.Rows; resultRow++)
  67.             {
  68.                 for (int resultCol = 0; resultCol < a.Cols; resultCol++)
  69.                 {
  70.                     result[resultRow, resultCol] = a[resultRow, resultCol]
  71.                             + b[resultRow, resultCol];
  72.                 }
  73.             }
  74.  
  75.             return new Matrix(result);
  76.         }
  77.  
  78.         /// <summary>
  79.         /// Copy the source matrix to the target matrix.  Both matrixes must have the same dimensions.
  80.         /// </summary>
  81.         /// <param name="source">The source matrix.</param>
  82.         /// <param name="target">The target matrix.</param>
  83.         public static void Copy(Matrix source, Matrix target)
  84.         {
  85.             for (int row = 0; row < source.Rows; row++)
  86.             {
  87.                 for (int col = 0; col < source.Cols; col++)
  88.                 {
  89.                     target[row, col] = source[row, col];
  90.                 }
  91.             }
  92.  
  93.         }
  94.  
  95.         /// <summary>
  96.         /// Delete a single column from a matrix.  A new matrix, with the delete is returned.
  97.         /// </summary>
  98.         /// <param name="matrix">The matrix to delete from.</param>
  99.         /// <param name="deleted">The column to delete.</param>
  100.         /// <returns>The matrix, with the delete.</returns>
  101.         public static Matrix DeleteCol(Matrix matrix, int deleted)
  102.         {
  103.             if (deleted >= matrix.Cols)
  104.             {
  105.                 throw new MatrixError("Can't delete column " + deleted
  106.                         + " from matrix, it only has " + matrix.Cols
  107.                         + " columns.");
  108.             }
  109.             double[,] newMatrix = new double[matrix.Rows, matrix
  110.                     .Cols - 1];
  111.  
  112.             for (int row = 0; row < matrix.Rows; row++)
  113.             {
  114.                 int targetCol = 0;
  115.  
  116.                 for (int col = 0; col < matrix.Cols; col++)
  117.                 {
  118.                     if (col != deleted)
  119.                     {
  120.                         newMatrix[row, targetCol] = matrix[row, col];
  121.                         targetCol++;
  122.                     }
  123.  
  124.                 }
  125.  
  126.             }
  127.             return new Matrix(newMatrix);
  128.         }
  129.  
  130.         /// <summary>
  131.         /// Delete a row from a matrix.  A new matrix, with the row deleted, is returned.
  132.         /// </summary>
  133.         /// <param name="matrix">The matrix to delete from.</param>
  134.         /// <param name="deleted">The row to delete.</param>
  135.         /// <returns>The matrix, with the row deleted.</returns>
  136.         public static Matrix DeleteRow(Matrix matrix, int deleted)
  137.         {
  138.             if (deleted >= matrix.Rows)
  139.             {
  140.                 throw new MatrixError("Can't delete row " + deleted
  141.                         + " from matrix, it only has " + matrix.Rows
  142.                         + " rows.");
  143.             }
  144.             double[,] newMatrix = new double[matrix.Rows - 1, matrix
  145.                     .Cols];
  146.             int targetRow = 0;
  147.             for (int row = 0; row < matrix.Rows; row++)
  148.             {
  149.                 if (row != deleted)
  150.                 {
  151.                     for (int col = 0; col < matrix.Cols; col++)
  152.                     {
  153.                         newMatrix[targetRow, col] = matrix[row, col];
  154.                     }
  155.                     targetRow++;
  156.                 }
  157.             }
  158.             return new Matrix(newMatrix);
  159.         }
  160.  
  161.         /// <summary>
  162.         /// Divide every cell in the matrix by the specified number.
  163.         /// </summary>
  164.         /// <param name="a">The matrix to divide.</param>
  165.         /// <param name="b">The number to divide by.</param>
  166.         /// <returns>The divided matrix.</returns>
  167.         public static Matrix Divide(Matrix a, double b)
  168.         {
  169.             double[,] result = new double[a.Rows, a.Cols];
  170.             for (int row = 0; row < a.Rows; row++)
  171.             {
  172.                 for (int col = 0; col < a.Cols; col++)
  173.                 {
  174.                     result[row, col] = a[row, col] / b;
  175.                 }
  176.             }
  177.             return new Matrix(result);
  178.         }
  179.  
  180.         /// <summary>
  181.         /// Compute the dot product for two matrixes.  Note: both matrixes must be vectors.
  182.         /// </summary>
  183.         /// <param name="a">The first matrix, must be a vector.</param>
  184.         /// <param name="b">The second matrix, must be a vector.</param>
  185.         /// <returns>The dot product of the two matrixes.</returns>
  186.         public static double DotProduct(Matrix a, Matrix b)
  187.         {
  188.             if (!a.isVector() || !b.isVector())
  189.             {
  190.                 throw new MatrixError(
  191.                         "To take the dot product, both matrixes must be vectors.");
  192.             }
  193.  
  194.             Double[] aArray = a.ToPackedArray();
  195.             Double[] bArray = b.ToPackedArray();
  196.  
  197.             if (aArray.Length != bArray.Length)
  198.             {
  199.                 throw new MatrixError(
  200.                         "To take the dot product, both matrixes must be of the same length.");
  201.             }
  202.  
  203.             double result = 0;
  204.             int length = aArray.Length;
  205.  
  206.             for (int i = 0; i < length; i++)
  207.             {
  208.                 result += aArray[i] * bArray[i];
  209.             }
  210.  
  211.             return result;
  212.         }
  213.  
  214.         /// <summary>
  215.         /// Create an identiry matrix, of the specified size.  An identity matrix is always square.
  216.         /// </summary>
  217.         /// <param name="size"></param>
  218.         /// <returns></returns>
  219.         public static Matrix Identity(int size)
  220.         {
  221.             if (size < 1)
  222.             {
  223.                 throw new MatrixError("Identity matrix must be at least of size 1.");
  224.             }
  225.  
  226.             Matrix result = new Matrix(size, size);
  227.  
  228.             for (int i = 0; i < size; i++)
  229.             {
  230.                 result[i, i] = 1;
  231.             }
  232.  
  233.             return result;
  234.         }
  235.  
  236.         /// <summary>
  237.         /// Multiply every cell in the matrix by the specified value.
  238.         /// </summary>
  239.         /// <param name="a">Multiply every cell in a matrix by the specified value.</param>
  240.         /// <param name="b">The value to multiply by.</param>
  241.         /// <returns>The new multiplied matrix.</returns>
  242.         public static Matrix Multiply(Matrix a, double b)
  243.         {
  244.             double[,] result = new double[a.Rows, a.Cols];
  245.             for (int row = 0; row < a.Rows; row++)
  246.             {
  247.                 for (int col = 0; col < a.Cols; col++)
  248.                 {
  249.                     result[row, col] = a[row, col] * b;
  250.                 }
  251.             }
  252.             return new Matrix(result);
  253.         }
  254.  
  255.         /// <summary>
  256.         /// Multiply two matrixes.
  257.         /// </summary>
  258.         /// <param name="a">The first matrix.</param>
  259.         /// <param name="b">The second matrix.</param>
  260.         /// <returns>The resulting matrix.</returns>
  261.         public static Matrix Multiply(Matrix a, Matrix b)
  262.         {
  263.             if (a.Cols != b.Rows)
  264.             {
  265.                 throw new MatrixError(
  266.                         "To use ordinary matrix multiplication the number of columns on the first matrix must mat the number of rows on the second.");
  267.             }
  268.  
  269.             double[,] result = new double[a.Rows, b.Cols];
  270.  
  271.             for (int resultRow = 0; resultRow < a.Rows; resultRow++)
  272.             {
  273.                 for (int resultCol = 0; resultCol < b.Cols; resultCol++)
  274.                 {
  275.                     double value = 0;
  276.  
  277.                     for (int i = 0; i < a.Cols; i++)
  278.                     {
  279.  
  280.                         value += a[resultRow, i] * b[i, resultCol];
  281.                     }
  282.                     result[resultRow, resultCol] = value;
  283.                 }
  284.             }
  285.  
  286.             return new Matrix(result);
  287.         }
  288.  
  289.         /// <summary>
  290.         /// Subtract one matrix from another.  The two matrixes must have the same number of rows and columns.
  291.         /// </summary>
  292.         /// <param name="a">The first matrix.</param>
  293.         /// <param name="b">The second matrix.</param>
  294.         /// <returns>The subtracted matrix.</returns>
  295.         public static Matrix Subtract(Matrix a, Matrix b)
  296.         {
  297.             if (a.Rows != b.Rows)
  298.             {
  299.                 throw new MatrixError(
  300.                         "To subtract the matrixes they must have the same number of rows and columns.  Matrix a has "
  301.                                 + a.Rows
  302.                                 + " rows and matrix b has "
  303.                                 + b.Rows + " rows.");
  304.             }
  305.  
  306.             if (a.Cols != b.Cols)
  307.             {
  308.                 throw new MatrixError(
  309.                         "To subtract the matrixes they must have the same number of rows and columns.  Matrix a has "
  310.                                 + a.Cols
  311.                                 + " cols and matrix b has "
  312.                                 + b.Cols + " cols.");
  313.             }
  314.  
  315.             double[,] result = new double[a.Rows, a.Cols];
  316.  
  317.             for (int resultRow = 0; resultRow < a.Rows; resultRow++)
  318.             {
  319.                 for (int resultCol = 0; resultCol < a.Cols; resultCol++)
  320.                 {
  321.                     result[resultRow, resultCol] = a[resultRow, resultCol]
  322.                             - b[resultRow, resultCol];
  323.                 }
  324.             }
  325.  
  326.             return new Matrix(result);
  327.         }
  328.  
  329.         /// <summary>
  330.         /// Transpose the specified matrix.
  331.         /// </summary>
  332.         /// <param name="input">The matrix to transpose.</param>
  333.         /// <returns>The transposed matrix.</returns>
  334.         public static Matrix Transpose(Matrix input)
  335.         {
  336.             double[,] inverseMatrix = new double[input.Cols, input
  337.                     .Rows];
  338.  
  339.             for (int r = 0; r < input.Rows; r++)
  340.             {
  341.                 for (int c = 0; c < input.Cols; c++)
  342.                 {
  343.                     inverseMatrix[c, r] = input[r, c];
  344.                 }
  345.             }
  346.  
  347.             return new Matrix(inverseMatrix);
  348.         }
  349.  
  350.         /// <summary>
  351.         /// Calculate the vector length of the matrix.
  352.         /// </summary>
  353.         /// <param name="input">The vector to calculate for.</param>
  354.         /// <returns>The vector length.</returns>
  355.         public static double vectorLength(Matrix input)
  356.         {
  357.             if (!input.isVector())
  358.             {
  359.                 throw new MatrixError(
  360.                         "Can only take the vector length of a vector.");
  361.             }
  362.             Double[] v = input.ToPackedArray();
  363.             double rtn = 0.0;
  364.             for (int i = 0; i < v.Length; i++)
  365.             {
  366.                 rtn += Math.Pow(v[i], 2);
  367.             }
  368.             return Math.Sqrt(rtn);
  369.         }
  370.  
  371.         /// <summary>
  372.         /// Private constructor.  All methods are static.
  373.         /// </summary>
  374.         private MatrixMath()
  375.         {
  376.         }
  377.  
  378.     }
  379.  
  380. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement