// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/Algebra.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_Algebra_h #define __PCL_Algebra_h /// \file pcl/Algebra.h #include #include #include namespace pcl { // ---------------------------------------------------------------------------- /*! * \defgroup in_place_gauss_jordan In-Place Gauss-Jordan Solvers */ /*! * Solution to the linear system A*X = B * * On output, A is replaced by its inverse matrix and B is the set of solution * vectors X. * * This is an overloaded function for the Matrix type, which is a template * instantiation of GenericMatrix for double. * * \ingroup in_place_gauss_jordan */ void PCL_FUNC InPlaceGaussJordan( Matrix& A, Matrix& B ); /*! * Solution to the linear system A*X = B * * On output, A is replaced by its inverse matrix and B is the set of solution * vectors X. * * This is an overloaded function for the FMatrix type, which is a template * instantiation of GenericMatrix for float. * * \ingroup in_place_gauss_jordan */ void PCL_FUNC InPlaceGaussJordan( FMatrix& A, FMatrix& B ); /*! * \class GenericGaussJordan * \brief Generic Gauss-Jordan linear system solver. */ template class PCL_CLASS GenericGaussJordan { public: /*! * Represents a matrix involved in the solution of a linear system. */ typedef GenericMatrix matrix; /*! * Represents a matrix element. */ typedef typename matrix::element matrix_element; /*! * Inverse matrix */ matrix Ai; // Inverse matrix /*! * Solution vectors */ matrix X; // Solution vectors /*! * Solution to the linear system A*X = B * * This constructor replaces the Ai member of this object with the inverse * matrix of \a A, and the X member with the set of solution vectors. */ GenericGaussJordan( const matrix& A, const matrix& B ) { Ai = A; X = B; InPlaceGaussJordan( Ai, X ); } }; /*! * \class GaussJordan * \brief Gauss-Jordan linear system solver for Matrix objects. * * %GaussJordan is a template instantiation of GenericGaussJordan for the * double type. %GaussJordan works with Matrix objects. %Matrix is a template * instantiation of GenericMatrix for double. */ class PCL_CLASS GaussJordan : public GenericGaussJordan { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericGaussJordan algorithm_implementation; /*! * Represents a matrix involved in the solution of a linear system. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Solution to the linear system A*X = B * * This constructor replaces the Ai member of this object with the inverse * matrix of \a A, and the X member with the set of solution vectors. */ GaussJordan( const Matrix& A, const Matrix& B ) : algorithm_implementation( A, B ) { } }; /*! * \class FGaussJordan * \brief Gauss-Jordan linear system solver for FMatrix objects. * * %FGaussJordan is a template instantiation of GenericGaussJordan for the * float type. %FGaussJordan works with FMatrix objects. %FMatrix is a template * instantiation of GenericMatrix for float. */ class PCL_CLASS FGaussJordan : public GenericGaussJordan { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericGaussJordan algorithm_implementation; /*! * Represents a matrix involved in the solution of a linear system. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Solution to the linear system A*X = B * * This constructor replaces the Ai member of this object with the inverse * matrix of \a A, and the X member with the set of solution vectors. */ FGaussJordan( const FMatrix& A, const FMatrix& B ) : algorithm_implementation( A, B ) { } }; // ---------------------------------------------------------------------------- void PCL_FUNC InPlaceSVDImplementation( Matrix&, Vector&, Matrix& ); void PCL_FUNC InPlaceSVDImplementation( FMatrix&, FVector&, FMatrix& ); /*! * \class GenericInPlaceSVD * \brief Generic in-place singular value decomposition algorithm. */ template class PCL_CLASS GenericInPlaceSVD { public: /*! * Represents a vector involved in a singular value decomposition. */ typedef GenericVector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef GenericMatrix matrix; /*! * Represents a vector component. */ typedef typename vector::component vector_component; /*! * Represents a matrix element. */ typedef typename matrix::element matrix_element; /*! * The components of this vector are the m (positive) diagonal elements of * the matrix W in a singular value decomposition A=U*W*Vt. m is the number * of columns in the decomposed matrix A. */ vector W; /*! * Each column of this m x m matrix is the eigenvector for the corresponding * element of W in a singular value decomposition A=U*W*Vt. m is the number * of columns in the decomposed matrix A. */ matrix V; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor replaces the specified matrix \a A with the * matrix U that results from the SVD decomposition (indeed that's why this * is an in-place decomposition). W and V are stored in the corresponding * members of this object. */ GenericInPlaceSVD( matrix& A ) : W( A.Columns() ) , V( A.Columns(), A.Columns() ) { InPlaceSVDImplementation( A, W, V ); } /*! * Returns the column index of the largest eigenvector in matrix V. This is * the index of the largest component of vector W. */ int IndexOfLargestSingularValue() const { return W.IndexOfLargestComponent(); } /*! * Returns the column index of the smallest eigenvector in matrix V. This is * the index of the smallest nonzero component of vector W. * * Before calling this function, you should edit the components of vector W * to set to zero all singular values below a suitable tolerance. For * example, using the machine epsilon: * * \code * Matrix A; * ... * InPlaceSVD svd( A ); * for ( int i = 0; i < svd.W.Length(); ++i ) * if ( 1 + svd.W[i] == 1 ) * svd.W[i] = 0; * int i = svd.IndexOfSmallestSingularValue(); * ... * \endcode */ int IndexOfSmallestSingularValue() const { return W.IndexOfSmallestNonzeroComponent(); } }; /*! * \class InPlaceSVD * \brief In-place singular value decomposition algorithm for Matrix and Vector objects. * * %InPlaceSVD is a template instantiation of GenericInPlaceSVD for the double * type. %InPlaceSVD works with Matrix and Vector objects. %Matrix and %Vector * are template instantiations of GenericMatrix and GenericVector, * respectively, for the double type. */ class PCL_CLASS InPlaceSVD : public GenericInPlaceSVD { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericInPlaceSVD algorithm_implementation; /*! * Represents a vector involved in a singular value decomposition. */ typedef algorithm_implementation::vector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a vector component. */ typedef vector::component vector_component; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor replaces the specified matrix \a A with the * matrix U that results from the SVD decomposition (indeed that's why this * is an in-place decomposition). W and V are stored in the corresponding * members of this object. */ InPlaceSVD( matrix& A ) : algorithm_implementation( A ) { } }; /*! * \class FInPlaceSVD * \brief In-place singular value decomposition algorithm for FMatrix and FVector objects. * * %FInPlaceSVD is a template instantiation of GenericInPlaceSVD for the float * type. %FInPlaceSVD works with FMatrix and FVector objects. %FMatrix and * %FVector are template instantiations of GenericMatrix and GenericVector, * respectively, for the float type. */ class PCL_CLASS FInPlaceSVD : public GenericInPlaceSVD { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericInPlaceSVD algorithm_implementation; /*! * Represents a vector involved in a singular value decomposition. */ typedef algorithm_implementation::vector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a vector component. */ typedef vector::component vector_component; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor replaces the specified matrix \a A with the * matrix U that results from the SVD decomposition (indeed that's why this * is an in-place decomposition). W and V are stored in the corresponding * members of this object. */ FInPlaceSVD( matrix& A ) : algorithm_implementation( A ) { } }; /*! * \class GenericSVD * \brief Generic singular value decomposition algorithm. */ template class PCL_CLASS GenericSVD { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericInPlaceSVD algorithm_implementation; /*! * Represents a vector involved in a singular value decomposition. */ typedef typename algorithm_implementation::vector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef typename algorithm_implementation::matrix matrix; /*! * Represents a vector component. */ typedef typename vector::component vector_component; /*! * Represents a matrix element. */ typedef typename matrix::element matrix_element; /*! * This is the n x m matrix resulting from the singular value decomposition * A = U*W*Vt. n and m are the rows and columns of the decomposed matrix A. */ matrix U; /*! * The components of this vector are the m (positive) diagonal elements of * the matrix W in a singular value decomposition A = U*W*Vt. m is the * number of columns in the decomposed matrix A. */ vector W; /*! * Each column of this m x m matrix is the eigenvector for the corresponding * element of W in a singular value decomposition A = U*W*Vt. m is the * number of columns in the decomposed matrix A. */ matrix V; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor stores U, W and V in the corresponding * members of this object. */ GenericSVD( const matrix& A ) { U = A; algorithm_implementation svd( U ); W = svd.W; V = svd.V; } /*! * Returns the column index of the largest eigenvector in matrix V. This is * the index of the largest component of vector W. */ int IndexOfLargestSingularValue() const { return W.IndexOfLargestComponent(); } /*! * Returns the column index of the smallest eigenvector in matrix V. This is * the index of the smallest nonzero component of vector W. * * Before calling this function, you should edit the components of vector W * to set to zero all singular values below a suitable tolerance. For * example, using the machine epsilon: * * \code * Matrix A; * ... * SVD svd( A ); * for ( int i = 0; i < svd.W.Length(); ++i ) * if ( 1 + svd.W[i] == 1 ) * svd.W[i] = 0; * int i = svd.IndexOfSmallestSingularValue(); * ... * \endcode */ int IndexOfSmallestSingularValue() const { return W.IndexOfSmallestNonzeroComponent(); } }; /*! * \class SVD * \brief Singular value decomposition algorithm for Matrix and Vector objects. * * %SVD is a template instantiation of GenericSVD for the double type. %SVD * works with Matrix and Vector objects. %Matrix and %Vector are template * instantiations of GenericMatrix and GenericVector, respectively, for the * double type. */ class PCL_CLASS SVD : public GenericSVD { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericSVD algorithm_implementation; /*! * Represents a vector involved in a singular value decomposition. */ typedef algorithm_implementation::vector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a vector component. */ typedef vector::component vector_component; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor stores U, W and V in the corresponding * members of this object. */ SVD( const matrix& A ) : algorithm_implementation( A ) { } }; /*! * \class FSVD * \brief Singular value decomposition algorithm for FMatrix and FVector objects. * * %FSVD is a template instantiation of GenericSVD for the float type. %FSVD * works with FMatrix and FVector objects. %FMatrix and %FVector are template * instantiations of GenericMatrix and GenericVector, respectively, for the * float type. */ class PCL_CLASS FSVD : public GenericSVD { public: /*! * Identifies the parent template class, which implements the underlying * algorithm for this class. */ typedef GenericSVD algorithm_implementation; /*! * Represents a vector involved in a singular value decomposition. */ typedef algorithm_implementation::vector vector; /*! * Represents a matrix involved in a singular value decomposition. */ typedef algorithm_implementation::matrix matrix; /*! * Represents a vector component. */ typedef vector::component vector_component; /*! * Represents a matrix element. */ typedef matrix::element matrix_element; /*! * Singular Value Decomposition: A = U*W*Vt * * The dimensions of A are n rows and m columns. U is an n x m matrix. The m * components of W are the positive diagonal elements of W, and each column * of V (m x m) is the eigenvector for the corresponding element of W. * * On output, this constructor stores U, W and V in the corresponding * members of this object. */ FSVD( const matrix& A ) : algorithm_implementation( A ) { } }; // ---------------------------------------------------------------------------- } // pcl #endif // __PCL_Algebra_h // ---------------------------------------------------------------------------- // EOF pcl/Algebra.h - Released 2022-03-12T18:59:29Z