Calculating the exponent of a square matrix

I am trying to write a method that calculates the exponent of a square matrix. In this case, the matrix is ​​a square array of the value:

[ten]

[0 10]

and the method should return a value:

[e 0]

[0 e ^ 10]

However, when I run my code, I get a range of values ​​depending on which bits I changed, not particularly close to the expected value.

The way the method works is to use power series for the matrix, therefore, mainly for matrix A, n steps and unit matrix I:

exp (A) = i + A + 1/2! * AA + 1/3! * AAA + ... + 1 / n! * AAA ..

Below is the code. The method I'm having a problem with is the exponential method (Matrix A, int nSteps). Methods to apply are provided, and Matrix objects take arguments (int m, int n) to create an array of size double [m] [n].

    public static Matrix multiply(Matrix m1, Matrix m2){

    if(m1.getN()!=m2.getM()) return null;

    Matrix res = new Matrix(m1.getM(), m2.getN());

    for(int i = 0; i < m1.getM(); i++){
        for(int j = 0; j < m2.getN(); j++){
            res.getArray()[i][j] = 0;
            for(int k = 0; k < m1.getN(); k++){
                res.getArray()[i][j] = res.getArray()[i][j] + m1.getArray()[i][k]*m2.getArray()[k][j];
            }
        }
    }   
    return res;
}


public static Matrix identityMatrix(int M){

    Matrix id = new Matrix(M, M);

    for(int i = 0; i < id.getM(); i++){
        for(int j = 0; j < id.getN(); j++){
            if(i==j) id.getArray()[i][j] = 1;
            else id.getArray()[i][j] = 0;
        }
    }
    return id;
}


public static Matrix addMatrix(Matrix m1, Matrix m2){
    Matrix m3 = new Matrix(m1.getM(), m2.getN());

    for(int i = 0; i < m3.getM(); i++){
        for(int j = 0; j < m3.getN(); j++){
            m3.getArray()[i][j] = m1.getArray()[i][j] + m2.getArray()[i][j];
        }
    }       
    return m3;
}


public static Matrix scaleMatrix(Matrix m, double scale){
    Matrix res = new Matrix(m.getM(), m.getN());
    for(int i = 0; i < res.getM(); i++){
        for(int j = 0; j < res.getN(); j++){
            res.getArray()[i][j] = m.getArray()[i][j]*scale;
        }
    }
    return res;
}


public static Matrix exponential(Matrix A, int nSteps){

    Matrix runtot = identityMatrix(A.getM());
    Matrix sum = identityMatrix(A.getM());

    double factorial = 1.0;

    for(int i = 1; i <= nSteps; i++){

        sum = Matrix.multiply(Matrix.scaleMatrix(sum, factorial), A);
        runtot = Matrix.addMatrix(runtot, sum);
        factorial /= (double)i;

    }
    return runtot;
}

      

So my question is, how do I modify my code so that I can enter a matrix and the number of timestamps to calculate the exponent of the specified matrix after the specified timestamps?

+3


source to share


1 answer


My way is to keep two accumulators:

  • sum which is your approximation of exp (A)
  • n-th member of the series M_n, that is, A ^ n / n!

Note that there is a good recursive relationship with M_n: M_ {n + 1} = M_n * A / (n + 1)



What gives:

public static Matrix exponential(Matrix A, int nSteps){

    Matrix seriesTerm = identityMatrix(A.getM());
    Matrix sum = identityMatrix(A.getM());

    for(int i = 1; i <= nSteps; i++){
        seriesTerm = Matrix.scaleMatrix(Matrix.multiply(seriesTerm,A),1.0/i);
        sum = Matrix.addMatrix(seriesTerm, sum);
    }
    return sum;
}

      

I fully understand what type of thrill gives you the ability to implement such algorithms. But if it's not a hobby project, I agree that you should use a library for this kind of thing. Making such calculations accurate and efficient is really not a trivial question, but a huge wheel to invent.

+2


source







All Articles