Exemplo n.º 1
0
        public static double[] Power(double[] aStore, int dimension, int power)
        {
            // We take powers via the exponentiation-by-squaring algorithm.
            // This is not strictly optimal, but it is very simple, is optimal in most cases (e.g. all n<15),
            // and is nearly optimal (e.g. 6 multiplies instead of 5 for n=15) even when it is not perfectly optimal.

            if (power == 1)
            {
                return(aStore);
                // Returning the given storage for A^1 instead of copying it saves space and time and works fine when this point is reached via recursion,
                // since that storage will just be read for a multiply, not returned to the calling user. But it would be bad to do so when the user requests
                // A^1, since the returned matrix would not be independent of the original. So don't call this method to compute A^1 for the user.
            }
            else
            {
                if (power % 2 == 0)
                {
                    // return (A * A)^{n/2}
                    double[] bStore = MatrixAlgorithms.Multiply(aStore, dimension, dimension, aStore, dimension, dimension);
                    double[] cStore = Power(bStore, dimension, power / 2);
                    return(cStore);
                }
                else
                {
                    // return A * (A * A)^{(n-1)/2}
                    double[] bStore = MatrixAlgorithms.Multiply(aStore, dimension, dimension, aStore, dimension, dimension);
                    double[] cStore = Power(bStore, dimension, (power - 1) / 2);
                    double[] dStore = MatrixAlgorithms.Multiply(aStore, dimension, dimension, cStore, dimension, dimension);
                    return(dStore);
                }
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Negates a real, rectangular matrix.
 /// </summary>
 /// <param name="A">The matrix.</param>
 /// <returns>The matrix -A.</returns>
 public static RectangularMatrix operator -(RectangularMatrix A)
 {
     if (A == null)
     {
         throw new ArgumentNullException(nameof(A));
     }
     double[] store = MatrixAlgorithms.Multiply(-1.0, A.store, A.offset, A.rowStride, A.colStride, A.rows, A.cols);
     return(new RectangularMatrix(store, A.rows, A.cols));
 }
Exemplo n.º 3
0
 /// <summary>
 /// Divides a real, rectangular matrix by a real constant.
 /// </summary>
 /// <param name="A">The matrix.</param>
 /// <param name="alpha">The constant.</param>
 /// <returns>The quotient A/a.</returns>
 public static RectangularMatrix operator *(RectangularMatrix A, double alpha)
 {
     if (A == null)
     {
         throw new ArgumentNullException("A");
     }
     double[] store = MatrixAlgorithms.Multiply(1.0 / alpha, A.store, A.rows, A.cols);
     return(new RectangularMatrix(store, A.rows, A.cols));
 }
Exemplo n.º 4
0
 /// <summary>
 /// Negates a real, square matrix.
 /// </summary>
 /// <param name="A">The matrix.</param>
 /// <returns>The matrix -A.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="A"/> is <see langword="null"/>.</exception>
 public static SquareMatrix operator -(SquareMatrix A)
 {
     if (A == null)
     {
         throw new ArgumentNullException(nameof(A));
     }
     double[] store = MatrixAlgorithms.Multiply(-1.0, A.store, A.offset, A.rowStride, A.colStride, A.dimension, A.dimension);
     return(new SquareMatrix(store, A.dimension));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Divides a real, square matrix by a real constant.
 /// </summary>
 /// <param name="A">The matrix.</param>
 /// <param name="alpha">The constant.</param>
 /// <returns>The quotient A/a.</returns>
 public static SquareMatrix operator *(SquareMatrix A, double alpha)
 {
     if (A == null)
     {
         throw new ArgumentNullException("A");
     }
     double[] store = MatrixAlgorithms.Multiply(1.0 / alpha, A.store, A.dimension, A.dimension);
     return(new SquareMatrix(store, A.dimension));
 }
Exemplo n.º 6
0
 /// <summary>
 /// Multiplies two real, rectangular matrices.
 /// </summary>
 /// <param name="A">The first matrix.</param>
 /// <param name="B">The second matrix.</param>
 /// <returns>The product matrix AB.</returns>
 public static RectangularMatrix operator *(RectangularMatrix A, RectangularMatrix B)
 {
     // this is faster than the base operator, because it knows about the underlying structure
     if (A == null)
     {
         throw new ArgumentNullException("A");
     }
     if (B == null)
     {
         throw new ArgumentNullException("B");
     }
     if (A.cols != B.rows)
     {
         throw new DimensionMismatchException();
     }
     double[] abStore = MatrixAlgorithms.Multiply(A.store, A.rows, A.cols, B.store, B.rows, B.cols);
     return(new RectangularMatrix(abStore, A.rows, B.cols));
 }
Exemplo n.º 7
0
 /// <summary>
 /// Computes the product of two square matrices.
 /// </summary>
 /// <param name="A">The first matrix.</param>
 /// <param name="B">The second matrix.</param>
 /// <returns>The product <paramref name="A"/> * <paramref name="B"/>.</returns>
 /// <remarks>
 /// <para>Note that matrix multiplication is not commutative, i.e. M1*M2 is generally not the same as M2*M1.</para>
 /// <para>Matrix multiplication is an O(N<sup>3</sup>) process.</para>
 /// </remarks>
 /// <exception cref="ArgumentNullException"><paramref name="A"/> or <paramref name="B"/> is null.</exception>
 /// <exception cref="DimensionMismatchException">The dimension of <paramref name="A"/> is not the same as the dimension of <paramref name="B"/>.</exception>
 public static SquareMatrix operator *(SquareMatrix A, SquareMatrix B)
 {
     // this is faster than the base operator, because it knows about the underlying structure
     if (A == null)
     {
         throw new ArgumentNullException("A");
     }
     if (B == null)
     {
         throw new ArgumentNullException("B");
     }
     if (A.dimension != B.dimension)
     {
         throw new DimensionMismatchException();
     }
     double[] abStore = MatrixAlgorithms.Multiply(A.store, A.dimension, A.dimension, B.store, B.dimension, B.dimension);
     return(new SquareMatrix(abStore, A.dimension));
 }
Exemplo n.º 8
0
        /// <summary>
        /// Solve the system of equations Ax=b, where A is the original matrix.
        /// </summary>
        /// <param name="rhs">The right-hand-side vector b.</param>
        /// <returns>The solution vector x.</returns>
        /// <remarks>
        /// <para>The components of <paramref name="rhs"/> are not modified.</para>
        /// </remarks>
        public ColumnVector Solve(IList <double> rhs)
        {
            if (rhs == null)
            {
                throw new ArgumentNullException(nameof(rhs));
            }
            if (rhs.Count != dimension)
            {
                throw new DimensionMismatchException();
            }

            double[] y = new double[rhs.Count];
            rhs.CopyTo(y, 0);

            y = MatrixAlgorithms.Multiply(qtStore, dimension, dimension, y, dimension, 1);
            SquareMatrixAlgorithms.SolveUpperRightTriangular(rStore, y, 0, dimension);

            return(new ColumnVector(y, dimension));
        }