// SPDX-License-Identifier: Apache-2.0 // // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // // 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. // ------------------------------------------------------------------------ //! \addtogroup auxlib //! @{ //! low-level interface functions for accessing LAPACK class auxlib { public: // // inv template inline static bool inv(Mat& A); template inline static bool inv(Mat& out, const Mat& X); template inline static bool inv_rcond(Mat& A, typename get_pod_type::result& out_rcond); template inline static bool inv_tr(Mat& A, const uword layout); template inline static bool inv_tr_rcond(Mat& A, typename get_pod_type::result& out_rcond, const uword layout); template inline static bool inv_sympd(Mat& A, bool& out_sympd_state); template inline static bool inv_sympd(Mat& out, const Mat& X); template inline static bool inv_sympd_rcond(Mat& A, bool& out_sympd_state, eT& out_rcond); template inline static bool inv_sympd_rcond(Mat< std::complex >& A, bool& out_sympd_state, T& out_rcond); // // det and log_det template inline static bool det(eT& out_val, Mat& A); template inline static bool log_det(eT& out_val, typename get_pod_type::result& out_sign, Mat& A); template inline static bool log_det_sympd(typename get_pod_type::result& out_val, Mat& A); // // lu template inline static bool lu(Mat& L, Mat& U, podarray& ipiv, const Base& X); template inline static bool lu(Mat& L, Mat& U, Mat& P, const Base& X); template inline static bool lu(Mat& L, Mat& U, const Base& X); // // eig_gen template inline static bool eig_gen(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base& expr); template inline static bool eig_gen(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base< std::complex, T1 >& expr); // // eig_gen_balance template inline static bool eig_gen_balance(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base& expr); template inline static bool eig_gen_balance(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base< std::complex, T1 >& expr); // // eig_gen_twosided template inline static bool eig_gen_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& expr); template inline static bool eig_gen_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& expr); // // eig_gen_twosided_balance template inline static bool eig_gen_twosided_balance(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& expr); template inline static bool eig_gen_twosided_balance(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& expr); // // eig_pair template inline static bool eig_pair(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base& A_expr, const Base& B_expr); template inline static bool eig_pair(Mat< std::complex >& vals, Mat< std::complex >& vecs, const bool vecs_on, const Base< std::complex, T1 >& A_expr, const Base< std::complex, T2 >& B_expr); // // eig_pair_twosided template inline static bool eig_pair_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& A_expr, const Base& B_expr); template inline static bool eig_pair_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& A_expr, const Base< std::complex, T2 >& B_expr); // // eig_sym template inline static bool eig_sym(Col& eigval, Mat& A); template inline static bool eig_sym(Col& eigval, Mat< std::complex >& A); template inline static bool eig_sym(Col& eigval, Mat& eigvec, const Mat& X); template inline static bool eig_sym(Col& eigval, Mat< std::complex >& eigvec, const Mat< std::complex >& X); template inline static bool eig_sym_dc(Col& eigval, Mat& eigvec, const Mat& X); template inline static bool eig_sym_dc(Col& eigval, Mat< std::complex >& eigvec, const Mat< std::complex >& X); // // chol template inline static bool chol_simple(Mat& X); template inline static bool chol(Mat& X, const uword layout); template inline static bool chol_band(Mat& X, const uword KD, const uword layout); template inline static bool chol_band(Mat< std::complex >& X, const uword KD, const uword layout); template inline static bool chol_band_common(Mat& X, const uword KD, const uword layout); template inline static bool chol_pivot(Mat& X, Mat& P, const uword layout); // // hessenberg decomposition template inline static bool hess(Mat& H, const Base& X, Col& tao); // // qr template inline static bool qr(Mat& Q, Mat& R, const Base& X); template inline static bool qr_econ(Mat& Q, Mat& R, const Base& X); template inline static bool qr_pivot(Mat& Q, Mat& R, Mat& P, const Base& X); template inline static bool qr_pivot(Mat< std::complex >& Q, Mat< std::complex >& R, Mat& P, const Base,T1>& X); // // svd template inline static bool svd(Col& S, Mat& A); template inline static bool svd(Col& S, Mat< std::complex >& A); template inline static bool svd(Mat& U, Col& S, Mat& V, Mat& A); template inline static bool svd(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); template inline static bool svd_econ(Mat& U, Col& S, Mat& V, Mat& A, const char mode); template inline static bool svd_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A, const char mode); template inline static bool svd_dc(Col& S, Mat& A); template inline static bool svd_dc(Col& S, Mat< std::complex >& A); template inline static bool svd_dc(Mat& U, Col& S, Mat& V, Mat& A); template inline static bool svd_dc(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); template inline static bool svd_dc_econ(Mat& U, Col& S, Mat& V, Mat& A); template inline static bool svd_dc_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); // // solve template inline static bool solve_square_fast(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_square_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); template inline static bool solve_square_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate); template inline static bool solve_square_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate); // template inline static bool solve_sympd_fast(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_sympd_fast_common(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_sympd_rcond(Mat& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); template inline static bool solve_sympd_rcond(Mat< std::complex >& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr); template inline static bool solve_sympd_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate); template inline static bool solve_sympd_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate); // template inline static bool solve_rect_fast(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_rect_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); // template inline static bool solve_approx_svd(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_approx_svd(Mat< std::complex >& out, Mat< std::complex >& A, const Base,T1>& B_expr); // template inline static bool solve_trimat_fast(Mat& out, const Mat& A, const Base& B_expr, const uword layout); template inline static bool solve_trimat_rcond(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const Base& B_expr, const uword layout); // template inline static bool solve_band_fast(Mat& out, Mat& A, const uword KL, const uword KU, const Base& B_expr); template inline static bool solve_band_fast(Mat< std::complex >& out, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr); template inline static bool solve_band_fast_common(Mat& out, const Mat& A, const uword KL, const uword KU, const Base& B_expr); template inline static bool solve_band_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr); template inline static bool solve_band_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr); template inline static bool solve_band_rcond_common(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const uword KL, const uword KU, const Base& B_expr); template inline static bool solve_band_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool equilibrate); template inline static bool solve_band_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base,T1>& B_expr, const bool equilibrate); // template inline static bool solve_tridiag_fast(Mat& out, Mat& A, const Base& B_expr); template inline static bool solve_tridiag_fast(Mat< std::complex >& out, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr); template inline static bool solve_tridiag_fast_common(Mat& out, const Mat& A, const Base& B_expr); // // Schur decomposition template inline static bool schur(Mat& U, Mat& S, const Base& X, const bool calc_U = true); template inline static bool schur(Mat< std::complex >& U, Mat< std::complex >& S, const Base,T1>& X, const bool calc_U = true); template inline static bool schur(Mat< std::complex >& U, Mat< std::complex >& S, const bool calc_U = true); // // solve the Sylvester equation AX + XB = C template inline static bool syl(Mat& X, const Mat& A, const Mat& B, const Mat& C); // // QZ decomposition template inline static bool qz(Mat& A, Mat& B, Mat& vsl, Mat& vsr, const Base& X_expr, const Base& Y_expr, const char mode); template inline static bool qz(Mat< std::complex >& A, Mat< std::complex >& B, Mat< std::complex >& vsl, Mat< std::complex >& vsr, const Base< std::complex, T1 >& X_expr, const Base< std::complex, T2 >& Y_expr, const char mode); // // rcond template inline static eT rcond(Mat& A); template inline static T rcond(Mat< std::complex >& A); template inline static eT rcond_sympd(Mat& A, bool& calc_ok); template inline static T rcond_sympd(Mat< std::complex >& A, bool& calc_ok); template inline static eT rcond_trimat(const Mat& A, const uword layout); template inline static T rcond_trimat(const Mat< std::complex >& A, const uword layout); // // lu_rcond (rcond from pre-computed LU decomposition) template inline static eT lu_rcond(const Mat& A, const eT norm_val); template inline static T lu_rcond(const Mat< std::complex >& A, const T norm_val); template inline static eT lu_rcond_sympd(const Mat& A, const eT norm_val); template inline static T lu_rcond_sympd(const Mat< std::complex >& A, const T norm_val); template inline static eT lu_rcond_band(const Mat& AB, const uword KL, const uword KU, const podarray& ipiv, const eT norm_val); template inline static T lu_rcond_band(const Mat< std::complex >& AB, const uword KL, const uword KU, const podarray& ipiv, const T norm_val); // // misc template inline static bool crippled_lapack(const Base&); template inline static bool rudimentary_sym_check(const Mat& X); template inline static bool rudimentary_sym_check(const Mat< std::complex >& X); template inline static typename get_pod_type::result norm1_gen(const Mat& A); template inline static typename get_pod_type::result norm1_sym(const Mat& A); template inline static typename get_pod_type::result norm1_band(const Mat& A, const uword KL, const uword KU); }; namespace qz_helper { template inline blas_int select_lhp(const T* x_ptr, const T* y_ptr, const T* z_ptr); template inline blas_int select_rhp(const T* x_ptr, const T* y_ptr, const T* z_ptr); template inline blas_int select_iuc(const T* x_ptr, const T* y_ptr, const T* z_ptr); template inline blas_int select_ouc(const T* x_ptr, const T* y_ptr, const T* z_ptr); template inline blas_int cx_select_lhp(const std::complex* x_ptr, const std::complex* y_ptr); template inline blas_int cx_select_rhp(const std::complex* x_ptr, const std::complex* y_ptr); template inline blas_int cx_select_iuc(const std::complex* x_ptr, const std::complex* y_ptr); template inline blas_int cx_select_ouc(const std::complex* x_ptr, const std::complex* y_ptr); template inline void_ptr ptr_cast(blas_int (*function)(const T*, const T*, const T*)); template inline void_ptr ptr_cast(blas_int (*function)(const std::complex*, const std::complex*)); } //! @}