internal void MultiplyRecursiveBox(List <Task> tasks, SubMatrix <T> op, SubMatrix <T> result, int rows, int cols)
 {
     if (Rows > rows)
     {
         var half = Rows / 2;
         Sub(fromRow, half, fromCol, Cols).MultiplyRecursiveBox(tasks, op, result.Sub(result.fromRow, half, result.fromCol, result.Cols), rows, cols);
         Sub(fromRow + half, Rows - half, fromCol, Cols).MultiplyRecursiveBox(tasks, op, result.Sub(result.fromRow + half, result.Rows - half, result.fromCol, result.Cols), rows, cols);
     }
     else if (op.Cols > cols)
     {
         var half = op.Cols / 2;
         MultiplyRecursiveBox(tasks, op.Sub(op.fromRow, op.Rows, op.fromCol, half), result.Sub(result.fromRow, result.Rows, result.fromCol, half), rows, cols);
         MultiplyRecursiveBox(tasks, op.Sub(op.fromRow, op.Rows, op.fromCol + half, op.Cols - half), result.Sub(result.fromRow, result.Rows, result.fromCol + half, result.Cols - half), rows, cols);
     }
     else
     {
         tasks.Add(Task.Factory.StartNew(() => {
             for (int row = 0; row < Rows; row++)
             {
                 for (int col = 0; col < op.Cols; col++)
                 {
                     result[row, col] = matrix.Zero;
                     for (int col2 = 0; col2 < Cols; col2++)
                     {
                         result[row, col] = matrix.adder(result[row, col], matrix.multiplier(this[row, col2], op[col2, col])); //result[row, col] += this[row, col2] * op[col2, col];
                     }
                 }
             }
         }));
     }
 }
 internal void MultiplyRecursiveVector(List <Task> tasks, SubMatrix <T> op, SubMatrix <T> result)
 {
     if (Rows > 1)
     {
         var half = Rows / 2;
         Sub(fromRow, half, fromCol, Cols).MultiplyRecursiveVector(tasks, op, result.Sub(result.fromRow, half, result.fromCol, result.Cols));
         Sub(fromRow + half, Rows - half, fromCol, Cols).MultiplyRecursiveVector(tasks, op, result.Sub(result.fromRow + half, result.Rows - half, result.fromCol, result.Cols));
     }
     else if (op.Cols > 1)
     {
         var half = op.Cols / 2;
         MultiplyRecursiveVector(tasks, op.Sub(op.fromRow, op.Rows, op.fromCol, half), result.Sub(result.fromRow, result.Rows, result.fromCol, half));
         MultiplyRecursiveVector(tasks, op.Sub(op.fromRow, op.Rows, op.fromCol + half, op.Cols - half), result.Sub(result.fromRow, result.Rows, result.fromCol + half, result.Cols - half));
     }
     else
     {
         tasks.Add(Task.Factory.StartNew(() => {
             T t = matrix.Zero;
             for (int i = 0; i < Cols; i++)
             {
                 t = matrix.adder(t, matrix.multiplier(this[0, i], op[i, 0])); //t += this[0, i] * op[i, 0];
             }
             result[0, 0] = t;
         }));
     }
 }