| // This file is part of Eigen, a lightweight C++ template library |
| // for linear algebra. |
| // |
| // Copyright (C) 2024 The Eigen Authors |
| // |
| // This Source Code Form is subject to the terms of the Mozilla |
| // Public License v. 2.0. If a copy of the MPL was not distributed |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| // SPDX-License-Identifier: MPL-2.0 |
| |
| #include "lapack_common.h" |
| |
| #if !ISCOMPLEX |
| |
| // Compute sqrt(x*x + y*y) taking care not to cause unnecessary overflow. |
| extern "C" EIGEN_LAPACK_API Scalar EIGEN_BLAS_FUNC_NAME(lapy2)(Scalar* x, Scalar* y) { |
| return Eigen::numext::hypot(*x, *y); |
| } |
| |
| // Compute sqrt(x*x + y*y + z*z) taking care not to cause unnecessary overflow. |
| extern "C" EIGEN_LAPACK_API Scalar EIGEN_BLAS_FUNC_NAME(lapy3)(Scalar* x, Scalar* y, Scalar* z) { |
| return Eigen::internal::xlapy3(*x, *y, *z); |
| } |
| |
| // Determines machine parameters according to LAPACK specification. |
| extern "C" EIGEN_LAPACK_API Scalar EIGEN_BLAS_FUNC_NAME(lamch)(const char* cmach) { |
| return Eigen::internal::xlamch<Scalar>(*cmach); |
| } |
| |
| // xLAMC3 is intended to force A and B to be stored prior to doing |
| // the addition of A and B, for use in situations where optimizers |
| // might hold one of these in a register. |
| extern "C" EIGEN_LAPACK_API Scalar EIGEN_BLAS_FUNC_NAME(lamc3)(Scalar* a, Scalar* b) { |
| volatile Scalar retval = *a + *b; |
| return retval; |
| } |
| |
| // Performs complex division in real arithmetic, avoiding unnecessary overflow. |
| // Consistent with LAPACK SLADIV / DLADIV (Smith's algorithm). |
| EIGEN_LAPACK_FUNC(ladiv)(const Scalar* a, const Scalar* b, const Scalar* c, const Scalar* d, Scalar* p, Scalar* q) { |
| const std::complex<Scalar> res = Eigen::internal::xladiv(*a, *b, *c, *d); |
| *p = Eigen::numext::real(res); |
| *q = Eigen::numext::imag(res); |
| } |
| |
| // Last non-zero column/row scanning for real matrices. |
| extern "C" EIGEN_LAPACK_API int EIGEN_CAT(ila, EIGEN_CAT(SCALAR_SUFFIX, lc_))(int* m, int* n, Scalar* a, int* lda) { |
| return Eigen::internal::ilaxlc(*m, *n, a, *lda); |
| } |
| |
| extern "C" EIGEN_LAPACK_API int EIGEN_CAT(ila, EIGEN_CAT(SCALAR_SUFFIX, lr_))(int* m, int* n, Scalar* a, int* lda) { |
| return Eigen::internal::ilaxlr(*m, *n, a, *lda); |
| } |
| |
| #else |
| |
| namespace { |
| template <typename T> |
| struct complex_return_type; |
| |
| template <> |
| struct complex_return_type<float> { |
| using type = eigen_lapack_complex_float; |
| }; |
| |
| template <> |
| struct complex_return_type<double> { |
| using type = eigen_lapack_complex_double; |
| }; |
| } // namespace |
| |
| // Conjugates entries of vector x. |
| EIGEN_LAPACK_FUNC(lacgv)(int* n, RealScalar* px, int* incx) { |
| Eigen::internal::xlacgv(*n, reinterpret_cast<Scalar*>(px), *incx); |
| } |
| |
| // Performs complex division avoiding unnecessary overflow. |
| // Consistent with LAPACK CLADIV / ZLADIV (Smith's algorithm). |
| // Note on calling convention: Returning a 2-element struct { RealScalar r, i; } |
| // by value adheres to the SysV AMD64 ABI (gfortran on Linux/x86_64), consistent |
| // with the return-by-value convention used for cdotc/zdotc in blas/complexdots.cpp. |
| // Non-SysV environments (such as MSVC or f2c) may use hidden-pointer return conventions |
| // for complex-valued Fortran functions. |
| extern "C" EIGEN_LAPACK_API typename complex_return_type<RealScalar>::type EIGEN_BLAS_FUNC_NAME(ladiv)( |
| const RealScalar* px, const RealScalar* py) { |
| const auto* x = reinterpret_cast<const Scalar*>(px); |
| const auto* y = reinterpret_cast<const Scalar*>(py); |
| const Scalar res = Eigen::internal::xladiv(*x, *y); |
| return {Eigen::numext::real(res), Eigen::numext::imag(res)}; |
| } |
| |
| // Last non-zero column/row scanning for complex matrices. |
| extern "C" EIGEN_LAPACK_API int EIGEN_CAT(ila, EIGEN_CAT(SCALAR_SUFFIX, lc_))(int* m, int* n, RealScalar* a, int* lda) { |
| return Eigen::internal::ilaxlc(*m, *n, reinterpret_cast<Scalar*>(a), *lda); |
| } |
| |
| extern "C" EIGEN_LAPACK_API int EIGEN_CAT(ila, EIGEN_CAT(SCALAR_SUFFIX, lr_))(int* m, int* n, RealScalar* a, int* lda) { |
| return Eigen::internal::ilaxlr(*m, *n, reinterpret_cast<Scalar*>(a), *lda); |
| } |
| |
| #endif |