001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 * image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause).
006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved.
007 * Visit https://imagingbook.com for additional details.
008 ******************************************************************************/
009package imagingbook.common.math.eigen;
010
011import org.apache.commons.math3.linear.MatrixUtils;
012import org.apache.commons.math3.linear.RealMatrix;
013import org.apache.commons.math3.linear.RealVector;
014
015/**
016 * Common interface for eigendecompositions capable of delivering solutions when all eigenvalues are real.
017 *
018 * @author WB
019 * @version 2022/07/08
020 */
021public interface RealEigenDecomposition {       // TODO: add 'ComplexEigenDecomposition' interface and implementations
022        
023        /**
024     * Returns whether the calculated eigenvalues are complex or real.
025     *
026     * @return {@code true} if any of the eigenvalues is complex, {@code false} otherwise
027     */
028        public boolean hasComplexEigenvalues();
029        
030        /**
031         * Returns the real part of the k-th eigenvalue
032         * 
033         * @param k index of the eigenvalue @param k index of the eigenvector (0-based)
034         * @return real part of the k-th eigenvalue
035         */
036        public double getRealEigenvalue(int k);
037        
038//      /**
039//       * Returns the imaginary part of the k-th eigenvalue
040//       * @return imaginary part of the k-th eigenvalue
041//       */
042//      public default double getImagEigenvalue(int k) {
043//              throw new UnsupportedOperationException();
044//      }
045        
046        /**
047         * Returns a vector holding the real parts of the eigenvalues
048         * @return real(diag(D))
049         */
050        public double[] getRealEigenvalues();
051        
052//      /**
053//       * Returns a vector holding the imaginary parts of the eigenvalues
054//       * @return imag(diag(D))
055//       */
056//      public default double[] getImagEigenvalues() {
057//              throw new UnsupportedOperationException();
058//      }
059
060        /**
061         * Returns the k-th eigenvector, i.e., the k-th column vector of the matrix returned by {@link #getV()}.
062         *
063         * @param k index of the eigenvector (0-based)
064         * @return the k-th eigenvector (instance of {@link RealVector})
065         */
066        public RealVector getEigenvector(int k);
067        
068        /**
069         * Return the matrix of eigenvectors, which are its column vectors.
070         * 
071         * @return the matrix of eigenvectors
072         */
073        public RealMatrix getV();
074
075
076        /**
077         * Gets the block diagonal matrix D of the decomposition. Real eigenvalues are on the diagonal while complex values
078         * are on 2x2 blocks {{real_pos imaginary}, {neg_imaginary, real}}.
079         *
080         * @return matrix D
081         */
082        public default RealMatrix getD() {
083                return MatrixUtils.createRealDiagonalMatrix(getRealEigenvalues());
084        }
085        
086
087}