/*
* Copyright 2011-2014, by Vladimir Kostyukov and Contributors.
*
* This file is part of la4j project (http://la4j.org)
*
* Licensed 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.
*
* Contributor(s): -
*/
package org.la4j;
import org.la4j.decomposition.CholeskyDecompositor;
import org.la4j.decomposition.EigenDecompositor;
import org.la4j.decomposition.LUDecompositor;
import org.la4j.decomposition.MatrixDecompositor;
import org.la4j.decomposition.QRDecompositor;
import org.la4j.decomposition.RawLUDecompositor;
import org.la4j.decomposition.RawQRDecompositor;
import org.la4j.decomposition.SingularValueDecompositor;
import org.la4j.inversion.NoPivotGaussInverter;
import org.la4j.inversion.GaussJordanInverter;
import org.la4j.inversion.MatrixInverter;
import org.la4j.linear.ForwardBackSubstitutionSolver;
import org.la4j.linear.GaussianSolver;
import org.la4j.linear.JacobiSolver;
import org.la4j.linear.LeastSquaresSolver;
import org.la4j.linear.LinearSystemSolver;
import org.la4j.linear.SeidelSolver;
import org.la4j.linear.SquareRootSolver;
import org.la4j.linear.SweepSolver;
import org.la4j.operation.MatrixMatrixOperation;
import org.la4j.operation.MatrixOperation;
import org.la4j.operation.MatrixVectorOperation;
import org.la4j.operation.inplace.InPlaceCopyMatrixToMatrix;
import org.la4j.operation.ooplace.OoPlaceKroneckerProduct;
import org.la4j.operation.ooplace.OoPlaceMatricesAddition;
import org.la4j.operation.ooplace.OoPlaceMatricesMultiplication;
import org.la4j.operation.ooplace.OoPlaceMatricesSubtraction;
import org.la4j.operation.ooplace.OoPlaceMatrixByItsTransposeMultiplication;
import org.la4j.operation.ooplace.OoPlaceMatrixByVectorMultiplication;
import org.la4j.operation.ooplace.OoPlaceMatrixHadamardProduct;
import org.la4j.operation.VectorMatrixOperation;
import org.la4j.operation.VectorVectorOperation;
import org.la4j.operation.ooplace.OoPlaceVectorHadamardProduct;
import org.la4j.operation.ooplace.OoPlaceInnerProduct;
import org.la4j.operation.ooplace.OoPlaceOuterProduct;
import org.la4j.operation.ooplace.OoPlaceVectorByMatrixMultiplication;
import org.la4j.operation.ooplace.OoPlaceVectorsSubtraction;
import org.la4j.operation.ooplace.OoPlaceVectorsAddition;
/**
* Tiny class for common things.
*/
public final class LinearAlgebra {
/**
* The library version.
*/
public static final String VERSION = "0.5.5";
/**
* The library name.
*/
public static final String NAME = "la4j";
/**
* The library release date.
*/
public static final String DATE = "March 2015";
/**
* The library full name.
*/
public static final String FULL_NAME = NAME + "-" + VERSION + " (" + DATE + ")";
/**
* The machine epsilon, which is calculated at runtime.
*/
public static final double EPS;
/**
* Exponent of machine epsilon
*/
public static final int ROUND_FACTOR;
/**
* References to the Gaussian solver factory.
*/
public static final SolverFactory GAUSSIAN = SolverFactory.GAUSSIAN;
/**
* References to the Jacobi solver factory.
*/
public static final SolverFactory JACOBI = SolverFactory.JACOBI;
/**
* References to the Seidel solver factory.
*/
public static final SolverFactory SEIDEL = SolverFactory.SEIDEL;
/**
* References to the Least Squares solver factory.
*/
public static final SolverFactory LEAST_SQUARES = SolverFactory.LEAST_SQUARES;
/**
* References to the Forward-Back Substitution solver factory.
*/
public static final SolverFactory FORWARD_BACK_SUBSTITUTION = SolverFactory.FORWARD_BACK_SUBSTITUTION;
/**
* References to the Square Root solver factory.
*/
public static final SolverFactory SQUARE_ROOT = SolverFactory.SQUARE_ROOT;
/**
* References to the Smart solver factory.
*/
public static final SolverFactory SOLVER = SolverFactory.SMART;
/**
* References to the Sweep solver factory.
*/
public static final SolverFactory SWEEP = SolverFactory.SWEEP;
/**
* Reference to an inverter factory solving n linear systems.
*/
public static final InverterFactory GAUSS_JORDAN = InverterFactory.GAUSS_JORDAN;
/**
* Reference to the Gauss elimination method-based inverter factory.
*
* Note: this version of the Gauss elimination method does not use a
* pivot and does not swap either columns or rows. As a result, it will fail
* if there is a zero on the diagonal.
*/
public static final InverterFactory NO_PIVOT_GAUSS = InverterFactory.NO_PIVOT_GAUSS;
/**
* Reference to the Smart inverter factory.
*/
public static final InverterFactory INVERTER = InverterFactory.SMART;
/**
* Reference to Cholesky decompositor factory.
*/
public static final DecompositorFactory CHOLESKY = DecompositorFactory.CHOLESKY;
/**
* Reference to Eigen decompositor factory.
*/
public static final DecompositorFactory EIGEN = DecompositorFactory.EIGEN;
/**
* Reference to Raw LU decompositor factory.
*/
public static final DecompositorFactory RAW_LU = DecompositorFactory.RAW_LU;
/**
* Reference to LU decompositor factory.
*/
public static final DecompositorFactory LU = DecompositorFactory.LU;
/**
* Reference to Raw QR decompositor factory.
*/
public static final DecompositorFactory RAW_QR = DecompositorFactory.RAW_QR;
/**
* Reference to QR decompositor factory.
*/
public static final DecompositorFactory QR = DecompositorFactory.QR;
/**
* Reference to SVD decompositor factory.
*/
public static final DecompositorFactory SVD = DecompositorFactory.SVD;
public final static VectorVectorOperation<Double> OO_PLACE_INNER_PRODUCT =
new OoPlaceInnerProduct();
public final static VectorVectorOperation<Vector> OO_PLACE_VECTORS_ADDITION =
new OoPlaceVectorsAddition();
public final static VectorVectorOperation<Vector> OO_PLACE_VECTOR_HADAMARD_PRODUCT =
new OoPlaceVectorHadamardProduct();
public final static VectorVectorOperation<Vector> OO_PLACE_VECTORS_SUBTRACTION =
new OoPlaceVectorsSubtraction();
public final static VectorMatrixOperation<Vector> OO_PLACE_VECTOR_BY_MATRIX_MULTIPLICATION =
new OoPlaceVectorByMatrixMultiplication();
public final static VectorVectorOperation<Matrix> OO_PLACE_OUTER_PRODUCT =
new OoPlaceOuterProduct();
public final static MatrixMatrixOperation<Matrix> IN_PLACE_COPY_MATRIX_TO_MATRIX =
new InPlaceCopyMatrixToMatrix();
public final static MatrixMatrixOperation<Matrix> OO_PLACE_MATRIX_ADDITION =
new OoPlaceMatricesAddition();
public final static MatrixVectorOperation<Vector> OO_PLACE_MATRIX_BY_VECTOR_MULTIPLICATION =
new OoPlaceMatrixByVectorMultiplication();
public final static MatrixMatrixOperation<Matrix> OO_PLACE_MATRICES_SUBTRACTION =
new OoPlaceMatricesSubtraction();
public final static MatrixMatrixOperation<Matrix> OO_PLACE_MATRIX_HADAMARD_PRODUCT =
new OoPlaceMatrixHadamardProduct();
public final static MatrixOperation<Matrix> OO_PLACE_MATRIX_BY_ITS_TRANSPOSE_MULTIPLICATION =
new OoPlaceMatrixByItsTransposeMultiplication();
public final static MatrixMatrixOperation<Matrix> OO_PLACE_KRONECKER_PRODUCT =
new OoPlaceKroneckerProduct();
public final static MatrixMatrixOperation<Matrix> OO_PLACE_MATRICES_MULTIPLICATION =
new OoPlaceMatricesMultiplication();
private LinearAlgebra() {}
// Determine the machine epsilon
// Tolerance is 10e1
static {
int roundFactor = 0;
double eps = 1.0;
while (1 + eps > 1) {
eps = eps / 2;
roundFactor++;
}
EPS = eps * 10e1;
ROUND_FACTOR = roundFactor - 1;
}
public static enum SolverFactory {
GAUSSIAN {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new GaussianSolver(matrix);
}
},
JACOBI {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new JacobiSolver(matrix);
}
},
SEIDEL {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new SeidelSolver(matrix);
}
},
FORWARD_BACK_SUBSTITUTION {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new ForwardBackSubstitutionSolver(matrix);
}
},
LEAST_SQUARES {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new LeastSquaresSolver(matrix);
}
},
SQUARE_ROOT {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new SquareRootSolver(matrix);
}
},
SWEEP {
@Override
public LinearSystemSolver create(Matrix matrix) {
return new SweepSolver(matrix);
}
},
SMART {
@Override
public LinearSystemSolver create(Matrix matrix) {
// TODO: We can do it smarter in future
if (matrix.rows() == matrix.columns()) {
return new ForwardBackSubstitutionSolver(matrix);
} else if (matrix.rows() > matrix.columns()) {
return new LeastSquaresSolver(matrix);
}
throw new IllegalArgumentException("Underdetermined system of linear equations can not be solved.");
}
};
public abstract LinearSystemSolver create(Matrix matrix);
}
public static enum InverterFactory {
GAUSS_JORDAN {
@Override
public MatrixInverter create(Matrix matrix) {
return new GaussJordanInverter(matrix);
}
},
NO_PIVOT_GAUSS {
@Override
public MatrixInverter create(Matrix matrix) {
return new NoPivotGaussInverter(matrix);
}
},
SMART {
@Override
public MatrixInverter create(Matrix matrix) {
return new GaussJordanInverter(matrix);
}
};
public abstract MatrixInverter create(Matrix matrix);
}
public static enum DecompositorFactory {
CHOLESKY {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new CholeskyDecompositor(matrix);
}
},
EIGEN {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new EigenDecompositor(matrix);
}
},
RAW_LU {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new RawLUDecompositor(matrix);
}
},
LU {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new LUDecompositor(matrix);
}
},
RAW_QR {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new RawQRDecompositor(matrix);
}
},
QR {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new QRDecompositor(matrix);
}
},
SVD {
@Override
public MatrixDecompositor create(Matrix matrix) {
return new SingularValueDecompositor(matrix);
}
};
public abstract MatrixDecompositor create(Matrix matrix);
}
}