/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.math3.linear;

import java.util.Random;

import org.apache.commons.math3.exception.MathIllegalArgumentException;
import org.apache.commons.math3.util.Precision;

import org.junit.Test;
import org.junit.Assert;

public class EigenSolverTest {

    private double[][] bigSingular = {
        { 1.0, 2.0,   3.0,    4.0 },
        { 2.0, 5.0,   3.0,    4.0 },
        { 7.0, 3.0, 256.0, 1930.0 },
        { 3.0, 7.0,   6.0,    8.0 }
    }; // 4th row = 1st + 2nd

    /** test non invertible matrix */
    @Test
    public void testNonInvertible() {
        Random r = new Random(9994100315209l);
        RealMatrix m =
            EigenDecompositionTest.createTestMatrix(r, new double[] { 1.0, 0.0, -1.0, -2.0, -3.0 });
        DecompositionSolver es = new EigenDecomposition(m).getSolver();
        Assert.assertFalse(es.isNonSingular());
        try {
            es.getInverse();
            Assert.fail("an exception should have been thrown");
        } catch (SingularMatrixException ime) {
            // expected behavior
        }
    }

    /** test invertible matrix */
    @Test
    public void testInvertible() {
        Random r = new Random(9994100315209l);
        RealMatrix m =
            EigenDecompositionTest.createTestMatrix(r, new double[] { 1.0, 0.5, -1.0, -2.0, -3.0 });
        DecompositionSolver es = new EigenDecomposition(m).getSolver();
        Assert.assertTrue(es.isNonSingular());
        RealMatrix inverse = es.getInverse();
        RealMatrix error =
            m.multiply(inverse).subtract(MatrixUtils.createRealIdentityMatrix(m.getRowDimension()));
        Assert.assertEquals(0, error.getNorm(), 4.0e-15);
    }

    /**
     * Verifies operation on very small values.
     * Matrix with eigenvalues {8e-100, -1e-100, -1e-100}
     */
    @Test
    public void testInvertibleTinyValues() {
        final double tiny = 1e-100;
        RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
                {3,  2,  4},
                {2,  0,  2},
                {4,  2,  3}
        });
        m = m.scalarMultiply(tiny);

        final EigenDecomposition ed = new EigenDecomposition(m);
        RealMatrix inv = ed.getSolver().getInverse();

        final RealMatrix id = m.multiply(inv);
        for (int i = 0; i < m.getRowDimension(); i++) {
            for (int j = 0; j < m.getColumnDimension(); j++) {
                if (i == j) {
                    Assert.assertTrue(Precision.equals(1, id.getEntry(i, j), 1e-15));
                } else {
                    Assert.assertTrue(Precision.equals(0, id.getEntry(i, j), 1e-15));
                }
            }
        }
    }

    @Test(expected=SingularMatrixException.class)
    public void testNonInvertibleMath1045() {
        EigenDecomposition eigen =
            new EigenDecomposition(MatrixUtils.createRealMatrix(bigSingular));
        eigen.getSolver().getInverse();
    }

    @Test(expected=SingularMatrixException.class)
    public void testZeroMatrix() {
        EigenDecomposition eigen =
            new EigenDecomposition(MatrixUtils.createRealMatrix(new double[][] {{0}}));
        eigen.getSolver().getInverse();
    }

    @Test
    public void testIsNonSingularTinyOutOfOrderEigenvalue() {
        final EigenDecomposition eigen
            = new EigenDecomposition(MatrixUtils.createRealMatrix(new double[][] {
                        { 1e-13, 0 },
                        { 1,     1 },
                    }));
        Assert.assertFalse("Singular matrix not detected",
                           eigen.getSolver().isNonSingular());
    }

    /** test solve dimension errors */
    @Test
    public void testSolveDimensionErrors() {
        final double[] refValues = new double[] {
            2.003, 2.002, 2.001, 1.001, 1.000, 0.001
        };
        final RealMatrix matrix = EigenDecompositionTest.createTestMatrix(new Random(35992629946426l), refValues);

        DecompositionSolver es = new EigenDecomposition(matrix).getSolver();
        RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]);
        try {
            es.solve(b);
            Assert.fail("an exception should have been thrown");
        } catch (MathIllegalArgumentException iae) {
            // expected behavior
        }
        try {
            es.solve(b.getColumnVector(0));
            Assert.fail("an exception should have been thrown");
        } catch (MathIllegalArgumentException iae) {
            // expected behavior
        }
        try {
            es.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0)));
            Assert.fail("an exception should have been thrown");
        } catch (MathIllegalArgumentException iae) {
            // expected behavior
        }
    }

    /** test solve */
    @Test
    public void testSolve() {
        RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
                { 91,  5, 29, 32, 40, 14 },
                {  5, 34, -1,  0,  2, -1 },
                { 29, -1, 12,  9, 21,  8 },
                { 32,  0,  9, 14,  9,  0 },
                { 40,  2, 21,  9, 51, 19 },
                { 14, -1,  8,  0, 19, 14 }
        });
        DecompositionSolver es = new EigenDecomposition(m).getSolver();
        RealMatrix b = MatrixUtils.createRealMatrix(new double[][] {
                { 1561, 269, 188 },
                {   69, -21,  70 },
                {  739, 108,  63 },
                {  324,  86,  59 },
                { 1624, 194, 107 },
                {  796,  69,  36 }
        });
        RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] {
                { 1,   2, 1 },
                { 2,  -1, 2 },
                { 4,   2, 3 },
                { 8,  -1, 0 },
                { 16,  2, 0 },
                { 32, -1, 0 }
        });

        // using RealMatrix
        RealMatrix solution=es.solve(b);
        Assert.assertEquals(0, solution.subtract(xRef).getNorm(), 2.5e-12);

        // using RealVector
        for (int i = 0; i < b.getColumnDimension(); ++i) {
            Assert.assertEquals(0,
                         es.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(),
                         2.0e-11);
        }

        // using RealVector with an alternate implementation
        for (int i = 0; i < b.getColumnDimension(); ++i) {
            ArrayRealVectorTest.RealVectorTestImpl v =
                new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i));
            Assert.assertEquals(0,
                         es.solve(v).subtract(xRef.getColumnVector(i)).getNorm(),
                         2.0e-11);
        }
    }
}
