コード例 #1
0
        public static Span <T> MultiplyMatrices(IMatrix <T> Left, IMatrix <T> Right, TwoElementOperation <T> Multiplier, TwoElementOperation <T> Adder)
        {
            // to multiply two matrices we calc the dot product of the first row of the left with the first column of the right
            // we can either tranpose the whole matrix or use referenced mapped indices

            // try ref mapping
            T[] FinalMatrixArray = new T[Left.Rows * Right.Columns];

            Span <T> FinalMatrixSpan = new(FinalMatrixArray);

            // transpose the matrix to avoid using slow indice mapping
            IMatrix <T> Transposed = Left.Transpose();

            // once the matrix is transposed we can avoid math to mapp rows to columns
            // store the shapes of the matrxes to avoid slowness from using properties that have null checks
            (int Rows, int Columns)LeftShape  = (Transposed.Rows, Transposed.Columns);
            (int Rows, int Columns)RightShape = (Right.Rows, Right.Columns);
            for (int RowIndex = 0; RowIndex < LeftShape.Rows; RowIndex++)
            {
                // store both rows directly in contigous memory
                Span <T> LeftSpan  = new(Transposed[RowIndex]);
                Span <T> RightSpan = new(Right[RowIndex]);

                int index = 0;
                for (int LeftColumn = 0; LeftColumn < LeftShape.Columns; LeftColumn++)
                {
                    for (int RightColumn = 0; RightColumn < RightShape.Columns; RightColumn++)
                    {
                        // multiply the two values and store them in a tmp var
                        T Multiplied = Multiplier(ref LeftSpan[LeftColumn], ref RightSpan[RightColumn]);

                        // add the value to the final array
                        Adder(ref FinalMatrixSpan[index++], ref Multiplied);
                    }
                }
            }

            return(FinalMatrixSpan);
        }
コード例 #2
0
        public static IMatrix <T> PerformTwoSidedNonMutableOperation(IMatrix <T> Left, IMatrix <T> Right, TwoElementOperation <T> Operation)
        {
            // duplicate the matrix to verify that we are not mutating the original matrix
            IMatrix <T> Dupe = Left.Duplicate();

            // perform the possible mytating operation on all items int he matrix
            PerformTwoSidedMutableOperation(Dupe, Right, Operation);

            // return the duplicated matrix and not the original
            return(Dupe);
        }
コード例 #3
0
 public static IMatrix <T> PerformTwoSidedMutableOperation(IMatrix <T> Left, IMatrix <T> Right, TwoElementOperation <T> Operation)
 {
     // this function should only be used when the two matrices are the same shape(same row and column count)
     for (int row = 0; row < Left.Rows; row++)
     {
         Span <T> LeftRow  = new(Left[row]);
         Span <T> RightRow = new(Right[row]);
         for (int column = 0; column < Left.Columns; column++)
         {
             Operation(ref LeftRow[column], ref RightRow[column]);
         }
     }
     return(Left);
 }