Generalised Eigenvalue Problems

ojAlgo v47.3 was released 2019-08-08. The main new features are:

  • New, long overdue, functionality to help control multithreading
  • Support for (some) Generalised Eigenvalue Problems
  • A bunch of minor changes and improvements. To get a complete list of what’s changed check out the changelog.

Generalised Eigenvalue Problems

ojAlgo now has built-in direct support for (some) generalised eigenvalue problems

where both A and B are symmetric/hermitian and B is positive definite. Each of these problems can be reduced to a standard symmetric eigenvalue problem, using a Cholesky factorisation of B. ojAlgo now handles this for you.

Example Code

GeneralisedEigenvalueProblem.java
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.matrix.decomposition.Eigenvalue;
import org.ojalgo.matrix.store.MatrixStore;
import org.ojalgo.matrix.store.R064Store;
import org.ojalgo.netio.BasicLogger;

/**
 * An example that outlines how to solve Generalised Symmetric Definite Eigenproblems
 *
 * @see https://www.ojalgo.org/2019/08/generalised-eigenvalue-problems/
 */
public class GeneralisedEigenvalueProblem {

    public static void main(final String[] args) {

        BasicLogger.debug();
        BasicLogger.debug(GeneralisedEigenvalueProblem.class);
        BasicLogger.debug(OjAlgoUtils.getTitle());
        BasicLogger.debug(OjAlgoUtils.getDate());
        BasicLogger.debug();

        int dim = 5;

        /*
         * Create 2 random Symmetric Positive Definite matrices
         */
        R064Store mtrxA = R064Store.FACTORY.makeSPD(dim);
        R064Store mtrxB = R064Store.FACTORY.makeSPD(dim);

        /*
         * There are several generalisations. 3 are supported by ojAlgo, specified by the enum:
         * Eigenvalue.Generalisation This factory method returns the most common alternative.
         */
        Eigenvalue.Generalised<Double> generalisedEvD = Eigenvalue.R064.makeGeneralised(mtrxA);
        // Generalisation: [A][V] = [B][V][D]

        // Use 2-args alternative

        generalisedEvD.computeValuesOnly(mtrxA, mtrxB);
        generalisedEvD.decompose(mtrxA, mtrxB); // Use one of these methods, not both

        // Alternatively, prepare and then use the usual 1-arg methods

        generalisedEvD.prepare(mtrxB);

        generalisedEvD.computeValuesOnly(mtrxA); // either
        generalisedEvD.decompose(mtrxA); // or
        // Can be called repeatedly with each "preparation"
        // Useful if the B matrix doesn't change but A does

        MatrixStore<Double> mtrxV = generalisedEvD.getV();
        // Eigenvectors in the columns

        MatrixStore<Double> mtrxD = generalisedEvD.getD();
        // Eigenvalues on the diagonal

        /*
         * Reconstruct the left and right hand sides of the eigenproblem
         */
        MatrixStore<Double> left = mtrxA.multiply(mtrxV);
        MatrixStore<Double> right = mtrxB.multiply(mtrxV).multiply(mtrxD);

        BasicLogger.debug();
        BasicLogger.debug("Generalised Eigenproblem [A][V] = [B][V][D]");
        BasicLogger.debugMatrix("[A]", mtrxA);
        BasicLogger.debugMatrix("[B]", mtrxB);
        BasicLogger.debugMatrix("Eigenvectors - [V]", mtrxV);
        BasicLogger.debugMatrix("Eigenvalues - [D]", mtrxD);
        BasicLogger.debugMatrix("Left - [A][V]", left);
        BasicLogger.debugMatrix("Right - [B][V][D]", right);

    }

}

Console Output

class GeneralisedEigenvalueProblem
ojAlgo
2019-08-07


Generalised Eigenproblem [A][V] = [B][V][D]
[A]
 1.604074 0.006127 0.133308 0.250127 0.259224
 0.006127 1.010143 0.002238   0.0042 0.004353
 0.133308 0.002238 1.220681 0.091377   0.0947
 0.250127   0.0042 0.091377 1.414067 0.177687
 0.259224 0.004353   0.0947 0.177687 1.429126
[B]
 1.412855 0.107653 0.393856  0.33646 0.313754
 0.107653 1.260753 0.248753 0.212503 0.198162
 0.393856 0.248753 1.953979 0.777454 0.724987
  0.33646 0.212503 0.777454 1.814959 0.619337
 0.313754 0.198162 0.724987 0.619337 1.759961
Eigenvectors - [V]
 -0.666868  0.341593 -0.447915 -0.083526 -0.024999
  0.091459 -0.030955  0.045101 -0.879487  0.195642
  0.509203  0.331432 -0.346537  0.186981  0.408749
 -0.227578 -0.755407 -0.104048  0.109849  0.251976
 -0.266076  0.262438  0.717441  0.100321  0.222165
Eigenvalues - [D]
 1.263856        0        0        0        0
        0 1.075374        0        0        0
        0        0 1.052367        0        0
        0        0        0 0.863366        0
        0        0        0        0 0.452183
Left - [A][V]
 -1.127161  0.471016 -0.604457 -0.060962  0.136204
  0.087327 -0.030464  0.044724 -0.887602  0.200414
  0.486888  0.405867 -0.424187  0.234679  0.540121
 -0.488978 -0.905967 -0.163164  0.165659  0.427706
 -0.544943  0.360632  0.858094  0.155118  0.395354
Right - [B][V][D]
 -1.127161  0.471016 -0.604457 -0.060962  0.136204
  0.087327 -0.030464  0.044724 -0.887602  0.200414
  0.486888  0.405867 -0.424187  0.234679  0.540121
 -0.488978 -0.905967 -0.163164  0.165659  0.427706
 -0.544943  0.360632  0.858094  0.155118  0.395354