Merge branch 'master' into RVV_Chip

This commit is contained in:
Chip Kerchner 2025-10-17 15:30:14 +00:00
commit 54d8399bf3
53 changed files with 2917 additions and 718 deletions

View File

@ -1,42 +1,37 @@
<!--
Please read this!
Thank you for submitting an issue!
Before opening a new issue, make sure to search for keywords in the issues
filtered by "bug::confirmed" or "bug::unconfirmed" and "bugzilla" label:
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aconfirmed
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aunconfirmed
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bugzilla
and verify the issue you're about to submit isn't a duplicate. -->
Before opening a new issue, please search for keywords in the existing [list of issues](https://gitlab.com/libeigen/eigen/-/issues?state=opened) to verify it isn't a duplicate.
-->
### Summary
<!-- Summarize the bug encountered concisely. -->
### Environment
<!-- Please provide your development environment here -->
<!-- Please provide your development environment. -->
- **Operating System** : Windows/Linux
- **Architecture** : x64/Arm64/PowerPC ...
- **Eigen Version** : 3.3.9
- **Compiler Version** : Gcc7.0
- **Eigen Version** : 5.0.0
- **Compiler Version** : gcc-12.0
- **Compile Flags** : -O3 -march=native
- **Vector Extension** : SSE/AVX/NEON ...
### Minimal Example
<!-- If possible, please create a minimal example here that exhibits the problematic behavior.
You can also link to [godbolt](https://godbolt.org). But please note that you need to click
the "Share" button in the top right-hand corner of the godbolt page where you reproduce the sample
code to get the share link instead of in your browser address bar.
<!--
Please create a minimal reproducing example here that exhibits the problematic behavior.
The example should be complete, in that it can fully build and run. See the [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example) for how to create a good minimal example.
You can read [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example)
on how to create a good minimal example. -->
You can also link to [godbolt](https://godbolt.org). Note that you need to click
the "Share" button in the top right-hand corner of the godbolt page to get the share link
instead of the URL in your browser address bar.
-->
```cpp
//show your code here
// Insert your code here.
```
### Steps to reproduce
<!-- Describe how one can reproduce the issue - this is very important. Please use an ordered list. -->
### Steps to reproduce the issue
<!-- Describe the necessary steps to reproduce the issue. -->
1. first step
2. second step
@ -49,21 +44,16 @@ on how to create a good minimal example. -->
<!-- Describe what you should see instead. -->
### Relevant logs
<!-- Add relevant code snippets or program output within blocks marked by " ``` " -->
<!-- Add relevant build logs or program output within blocks marked by " ``` " -->
<!-- OPTIONAL: remove this section if you are not reporting a compilation warning issue.-->
### Warning Messages
<!-- Show us the warning messages you got! -->
<!-- OPTIONAL: remove this section if you are not reporting a performance issue. -->
### Benchmark scripts and results
### [Optional] Benchmark scripts and results
<!-- Please share any benchmark scripts - either standalone, or using [Google Benchmark](https://github.com/google/benchmark). -->
### Anything else that might help
<!-- It will be better to provide us more information to help narrow down the cause.
<!--
It will be better to provide us more information to help narrow down the cause.
Including but not limited to the following:
- lines of code that might help us diagnose the problem.
- potential ways to address the issue.
- last known working/first broken version (release number or commit hash). -->
- [ ] Have a plan to fix this issue.
- last known working/first broken version (release number or commit hash).
-->

View File

@ -1,6 +1,13 @@
<!--
Thank you for submitting a Feature Request!
If you want to run ideas by the maintainers and the Eigen community first,
you can chat about them on the [Eigen Discord server](https://discord.gg/2SkEJGqZjR).
-->
### Describe the feature you would like to be implemented.
### Would such a feature be useful for other users? Why?
### Why Would such a feature be useful for other users?
### Any hints on how to implement the requested feature?

View File

@ -1,26 +0,0 @@
<!--
Thanks for contributing a merge request! Please name and fully describe your MR as you would for a commit message.
If the MR fixes an issue, please include "Fixes #issue" in the commit message and the MR description.
In addition, we recommend that first-time contributors read our [contribution guidelines](https://eigen.tuxfamily.org/index.php?title=Contributing_to_Eigen) and [git page](https://eigen.tuxfamily.org/index.php?title=Git), which will help you submit a more standardized MR.
Before submitting the MR, you also need to complete the following checks:
- Make one PR per feature/bugfix (don't mix multiple changes into one PR). Avoid committing unrelated changes.
- Rebase before committing
- For code changes, run the test suite (at least the tests that are likely affected by the change).
See our [test guidelines](https://eigen.tuxfamily.org/index.php?title=Tests).
- If possible, add a test (both for bug-fixes as well as new features)
- Make sure new features are documented
Note that we are a team of volunteers; we appreciate your patience during the review process.
Again, thanks for contributing! -->
### Reference issue
<!-- You can link to a specific issue using the gitlab syntax #<issue number> -->
### What does this implement/fix?
<!--Please explain your changes.-->
### Additional information
<!--Any additional information you think is important.-->

View File

@ -0,0 +1,30 @@
<!--
Thanks for contributing a merge request!
We recommend that first-time contributors read our [contribution guidelines](https://eigen.tuxfamily.org/index.php?title=Contributing_to_Eigen).
Before submitting the MR, please complete the following checks:
- Create one PR per feature or bugfix,
- Run the test suite to verify your changes.
See our [test guidelines](https://eigen.tuxfamily.org/index.php?title=Tests).
- Add tests to cover the bug addressed or any new feature.
- Document new features. If it is a substantial change, add it to the [Changelog](https://gitlab.com/libeigen/eigen/-/blob/master/CHANGELOG.md).
- Leave the following box checked when submitting: `Allow commits from members who can merge to the target branch`.
This allows us to rebase and merge your change.
Note that we are a team of volunteers; we appreciate your patience during the review process.
-->
### Description
<!--Please explain your changes.-->
%{first_multiline_commit}
### Reference issue
<!--
You can link to a specific issue using the gitlab syntax #<issue number>.
If the MR fixes an issue, write "Fixes #<issue number>" to have the issue automatically closed on merge.
-->
### Additional information
<!--Any additional information you think is important.-->

View File

@ -63,13 +63,8 @@ option(EIGEN_LEAVE_TEST_IN_ALL_TARGET "Leaves tests in the all target, needed by
option(EIGEN_BUILD_BLAS "Toggles the building of the Eigen Blas library" ${PROJECT_IS_TOP_LEVEL})
option(EIGEN_BUILD_LAPACK "Toggles the building of the included Eigen LAPACK library" ${PROJECT_IS_TOP_LEVEL})
if (EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK)
# BLAS and LAPACK currently need a fortran compiler.
include(CMakeDetermineFortranCompiler)
if (NOT CMAKE_Fortran_COMPILER)
set(EIGEN_BUILD_BLAS OFF)
set(EIGEN_BUILD_LAPACK OFF)
else()
# Determine if we should build shared libraries for BLAS/LAPACK on this platform.
# Determine if we should build shared libraries for BLAS/LAPACK on this platform.
if (NOT EIGEN_BUILD_SHARED_LIBS)
get_cmake_property(EIGEN_BUILD_SHARED_LIBS TARGET_SUPPORTS_SHARED_LIBS)
endif()
endif()

View File

@ -106,6 +106,11 @@
#include <thread>
#endif
// for __cpp_lib feature test macros
#if defined(__has_include) && __has_include(<version>)
#include <version>
#endif
// for std::bit_cast()
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
#include <bit>

View File

@ -32,8 +32,6 @@
* \endcode
*/
#include "src/misc/RealSvd2x2.h"
// IWYU pragma: begin_exports
#include "src/Eigenvalues/Tridiagonalization.h"
#include "src/Eigenvalues/RealSchur.h"
@ -44,6 +42,7 @@
#include "src/Eigenvalues/ComplexSchur.h"
#include "src/Eigenvalues/ComplexEigenSolver.h"
#include "src/Eigenvalues/RealQZ.h"
#include "src/Eigenvalues/ComplexQZ.h"
#include "src/Eigenvalues/GeneralizedEigenSolver.h"
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
#ifdef EIGEN_USE_LAPACKE

View File

@ -33,7 +33,6 @@
*/
// IWYU pragma: begin_exports
#include "src/misc/RealSvd2x2.h"
#include "src/SVD/UpperBidiagonalization.h"
#include "src/SVD/SVDBase.h"
#include "src/SVD/JacobiSVD.h"

View File

@ -65,7 +65,8 @@ struct plain_array {
template <typename T, int Size, int MatrixOrArrayOptions>
struct plain_array<T, Size, MatrixOrArrayOptions, 0> {
T array[Size];
// on some 32-bit platforms, stack-allocated arrays are aligned to 4 bytes, not the preferred alignment of T
EIGEN_ALIGN_TO_BOUNDARY(alignof(T)) T array[Size];
#if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default;
#else
@ -73,12 +74,6 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 0> {
#endif
};
template <typename T, int MatrixOrArrayOptions, int Alignment>
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment> {
T array[1];
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default;
};
template <typename T, int Size, int Options, int Alignment>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap_plain_array(plain_array<T, Size, Options, Alignment>& a,
plain_array<T, Size, Options, Alignment>& b,

View File

@ -1004,8 +1004,7 @@ struct madd_impl {
}
};
// Use FMA if there is a single CPU instruction.
#ifdef EIGEN_VECTORIZE_FMA
#if EIGEN_SCALAR_MADD_USE_FMA
template <typename Scalar>
struct madd_impl<Scalar, std::enable_if_t<has_fma<Scalar>::value>> {
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run(const Scalar& x, const Scalar& y, const Scalar& z) {
@ -1927,7 +1926,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar arithmetic_shift_right(const Scalar
return bit_cast<Scalar, SignedScalar>(bit_cast<SignedScalar, Scalar>(a) >> n);
}
// Otherwise, rely on template implementation.
template <typename Scalar>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar fma(const Scalar& x, const Scalar& y, const Scalar& z) {
return internal::fma_impl<Scalar>::run(x, y, z);

View File

@ -240,8 +240,8 @@ EIGEN_STRONG_INLINE Packet4d pcast<Packet4l, Packet4d>(const Packet4l& a) {
#if defined(EIGEN_VECTORIZE_AVX512DQ) && defined(EIGEN_VECTORIZE_AVS512VL)
return _mm256_cvtepi64_pd(a);
#else
EIGEN_ALIGN16 int64_t aux[4];
pstore(aux, a);
int64_t aux[4];
pstoreu(aux, a);
return _mm256_set_pd(static_cast<double>(aux[3]), static_cast<double>(aux[2]), static_cast<double>(aux[1]),
static_cast<double>(aux[0]));
#endif

View File

@ -17,6 +17,9 @@
EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const { \
return padd(c, this->pmul(x, y)); \
} \
EIGEN_STRONG_INLINE PACKET_CPLX pmsub(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const { \
return psub(this->pmul(x, y), c); \
} \
EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const { \
return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x, y.v)); \
} \
@ -27,6 +30,9 @@
EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const { \
return padd(c, this->pmul(x, y)); \
} \
EIGEN_STRONG_INLINE PACKET_CPLX pmsub(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const { \
return psub(this->pmul(x, y), c); \
} \
EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const { \
return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x.v, y)); \
} \
@ -76,6 +82,11 @@ struct conj_helper {
return this->pmul(x, y) + c;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmsub(const LhsType& x, const RhsType& y,
const ResultType& c) const {
return this->pmul(x, y) - c;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmul(const LhsType& x, const RhsType& y) const {
return conj_if<ConjLhs>()(x) * conj_if<ConjRhs>()(y);
}
@ -104,6 +115,10 @@ struct conj_helper<Packet, Packet, ConjLhs, ConjRhs> {
return Eigen::internal::pmadd(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y), c);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmsub(const Packet& x, const Packet& y, const Packet& c) const {
return Eigen::internal::pmsub(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y), c);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmul(const Packet& x, const Packet& y) const {
return Eigen::internal::pmul(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y));
}
@ -116,6 +131,9 @@ struct conj_helper<Packet, Packet, true, true> {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmadd(const Packet& x, const Packet& y, const Packet& c) const {
return Eigen::internal::pmadd(pconj(x), pconj(y), c);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmsub(const Packet& x, const Packet& y, const Packet& c) const {
return Eigen::internal::pmsub(pconj(x), pconj(y), c);
}
// We save a conjuation by using the identity conj(a)*conj(b) = conj(a*b).
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmul(const Packet& x, const Packet& y) const {
return pconj(Eigen::internal::pmul(x, y));

View File

@ -1679,9 +1679,9 @@ EIGEN_STRONG_INLINE Packet16b pgather<bool, Packet16b>(const bool* from, Index s
template <>
EIGEN_STRONG_INLINE void pscatter<float, Packet4f>(float* to, const Packet4f& from, Index stride) {
to[stride * 0] = pfirst(from);
to[stride * 1] = pfirst(_mm_shuffle_ps(from, from, 1));
to[stride * 2] = pfirst(_mm_shuffle_ps(from, from, 2));
to[stride * 3] = pfirst(_mm_shuffle_ps(from, from, 3));
to[stride * 1] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 1)));
to[stride * 2] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 2)));
to[stride * 3] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 3)));
}
template <>
EIGEN_STRONG_INLINE void pscatter<double, Packet2d>(double* to, const Packet2d& from, Index stride) {

View File

@ -52,6 +52,26 @@
#define EIGEN_STACK_ALLOCATION_LIMIT 131072
#endif
/* Specify whether to use std::fma for scalar multiply-add instructions.
*
* On machines that have FMA as a single instruction, this will generally
* improve precision without significant performance implications.
*
* Without a single instruction, performance has been found to be reduced 2-3x
* on Intel CPUs, and up to 30x for WASM.
*
* If unspecified, defaults to using FMA if hardware support is available.
* The default should be used in most cases to ensure consistency between
* vectorized and non-vectorized paths.
*/
#ifndef EIGEN_SCALAR_MADD_USE_FMA
#ifdef EIGEN_VECTORIZE_FMA
#define EIGEN_SCALAR_MADD_USE_FMA 1
#else
#define EIGEN_SCALAR_MADD_USE_FMA 0
#endif
#endif
//------------------------------------------------------------------------------------------
// Compiler identification, EIGEN_COMP_*
//------------------------------------------------------------------------------------------

View File

@ -1345,10 +1345,10 @@ EIGEN_DEVICE_FUNC void destroy_at(T* p) {
#ifndef EIGEN_ASSUME_ALIGNED
#if defined(__cpp_lib_assume_aligned) && (__cpp_lib_assume_aligned >= 201811L)
#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) \
{ PTR = std::assume_aligned<8 * (ALIGN_BYTES)>(PTR); }
{ PTR = std::assume_aligned<ALIGN_BYTES>(PTR); }
#elif EIGEN_HAS_BUILTIN(__builtin_assume_aligned)
#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) \
{ PTR = static_cast<decltype(PTR)>(__builtin_assume_aligned(PTR, (ALIGN_BYTES))); }
{ PTR = static_cast<decltype(PTR)>(__builtin_assume_aligned(PTR, ALIGN_BYTES)); }
#else
#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) /* do nothing */
#endif

View File

@ -0,0 +1,656 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 Alexey Korepanov
// Copyright (C) 2025 Ludwig Striet <ludwig.striet@mathematik.uni-freiburg.de>
//
// 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
// https://mozilla.org/MPL/2.0/.
//
// Derived from: Eigen/src/Eigenvalues/RealQZ.h
#include "Eigen/Core"
#include "Eigen/Jacobi"
#ifndef EIGEN_COMPLEX_QZ_H_
#define EIGEN_COMPLEX_QZ_H_
#include "../../SparseQR"
// IWYU pragma: private
#include "./InternalHeaderCheck.h"
/** \eigenvalues_module \ingroup Eigenvalues_Module
*
*
* \class ComplexQZ
*
* \brief Performs a QZ decomposition of a pair of matrices A, B
*
* \tparam MatrixType_ the type input type of the matrix.
*
* Given to complex square matrices A and B, this class computes the QZ decomposition
* \f$ A = Q S Z \f$, \f$ B = Q T Z\f$ where Q and Z are unitary matrices and
* S and T a re upper-triangular matrices. More precisely, Q and Z fulfill
* \f$ Q Q* = Id\f$ and \f$ Z Z* = Id\f$. The generalized Eigenvalues are then
* obtained as ratios of corresponding diagonal entries, lambda(i) = S(i,i) / T(i, i).
*
* The QZ algorithm was introduced in the seminal work "An Algorithm for
* Generalized Matrix Eigenvalue Problems" by Moler & Stewart in 1973. The matrix
* pair S = A, T = B is first transformed to Hessenberg-Triangular form where S is an
* upper Hessenberg matrix and T is an upper Triangular matrix.
*
* This pair is subsequently reduced to the desired form using implicit QZ shifts as
* described in the original paper. The algorithms to find small entries on the
* diagonals and subdiagonals are based on the variants in the implementation
* for Real matrices in the RealQZ class.
*
* \sa class RealQZ
*/
namespace Eigen {
template <typename MatrixType_>
class ComplexQZ {
public:
using MatrixType = MatrixType_;
using Scalar = typename MatrixType_::Scalar;
using RealScalar = typename MatrixType_::RealScalar;
enum {
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
Options = internal::traits<MatrixType>::Options,
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
};
using Vec = Matrix<Scalar, Dynamic, 1>;
using Vec2 = Matrix<Scalar, 2, 1>;
using Vec3 = Matrix<Scalar, 3, 1>;
using Row2 = Matrix<Scalar, 1, 2>;
using Mat2 = Matrix<Scalar, 2, 2>;
/** \brief Returns matrix Q in the QZ decomposition.
*
* \returns A const reference to the matrix Q.
*/
const MatrixType& matrixQ() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
return m_Q;
}
/** \brief Returns matrix Z in the QZ decomposition.
*
* \returns A const reference to the matrix Z.
*/
const MatrixType& matrixZ() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
return m_Z;
}
/** \brief Returns matrix S in the QZ decomposition.
*
* \returns A const reference to the matrix S.
*/
const MatrixType& matrixS() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
return m_S;
}
/** \brief Returns matrix S in the QZ decomposition.
*
* \returns A const reference to the matrix S.
*/
const MatrixType& matrixT() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
return m_T;
}
/** \brief Constructor
*
* \param[in] n size of the matrices whose QZ decomposition we compute
*
* This constructor is used when we use the compute(...) method later,
* especially when we aim to compute the decomposition of two sparse
* matrices.
*/
ComplexQZ(Index n, bool computeQZ = true, unsigned int maxIters = 400)
: m_n(n),
m_S(n, n),
m_T(n, n),
m_Q(computeQZ ? n : (MatrixType::RowsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::RowsAtCompileTime),
computeQZ ? n : (MatrixType::ColsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::ColsAtCompileTime)),
m_Z(computeQZ ? n : (MatrixType::RowsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::RowsAtCompileTime),
computeQZ ? n : (MatrixType::ColsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::ColsAtCompileTime)),
m_ws(2 * n),
m_computeQZ(computeQZ),
m_maxIters(maxIters){
};
/** \brief Constructor. computes the QZ decomposition of given matrices
* upon creation
*
* \param[in] A input matrix A
* \param[in] B input matrix B
* \param[in] computeQZ If false, the matrices Q and Z are not computed
*
* This constructor calls the compute() method to compute the QZ decomposition.
* If input matrices are sparse, call the constructor that uses only the
* size as input the computeSparse(...) method.
*/
ComplexQZ(const MatrixType& A, const MatrixType& B, bool computeQZ = true, unsigned int maxIters = 400)
: m_n(A.rows()),
m_maxIters(maxIters),
m_computeQZ(computeQZ),
m_S(A.rows(), A.cols()),
m_T(A.rows(), A.cols()),
m_Q(computeQZ ? m_n : (MatrixType::RowsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::RowsAtCompileTime),
computeQZ ? m_n : (MatrixType::ColsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::ColsAtCompileTime)),
m_Z(computeQZ ? m_n : (MatrixType::RowsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::RowsAtCompileTime),
computeQZ ? m_n : (MatrixType::ColsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::ColsAtCompileTime)),
m_ws(2 * m_n) {
compute(A, B, computeQZ);
}
/** \brief Compute the QZ decomposition of complex input matrices
*
* \param[in] A Matrix A.
* \param[in] B Matrix B.
* \param[in] computeQZ If false, the matrices Q and Z are not computed.
*/
void compute(const MatrixType& A, const MatrixType& B, bool computeQZ = true);
/** \brief Compute the decomposition of sparse complex input matrices.
* Main difference to the compute(...) method is that it computes a
* SparseQR decomposition of B
*
* \param[in] A Matrix A.
* \param[in] B Matrix B.
* \param[in] computeQZ If false, the matrices Q and Z are not computed.
*/
template <typename SparseMatrixType_>
void computeSparse(const SparseMatrixType_& A, const SparseMatrixType_& B, bool computeQZ = true);
/** \brief Reports whether the last computation was successfull.
*
* \returns \c Success if computation was successfull, \c NoConvergence otherwise.
*/
ComputationInfo info() const { return m_info; };
/** \brief number of performed QZ steps
*/
unsigned int iterations() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
return m_global_iter;
};
private:
Index m_n;
const unsigned int m_maxIters;
unsigned int m_global_iter;
bool m_isInitialized;
bool m_computeQZ;
ComputationInfo m_info;
MatrixType m_S, m_T, m_Q, m_Z;
RealScalar m_normOfT, m_normOfS;
Vec m_ws;
// Test if a Scalar is 0 up to a certain tolerance
static bool is_negligible(const Scalar x, const RealScalar tol = NumTraits<RealScalar>::epsilon()) {
return numext::abs(x) <= tol;
}
void do_QZ_step(Index p, Index q);
inline Mat2 computeZk2(const Row2& b);
// This is basically taken from from Eigen3::RealQZ
void hessenbergTriangular(const MatrixType& A, const MatrixType& B);
// This function can be called when m_Q and m_Z are initialized and m_S, m_T
// are in hessenberg-triangular form
void reduceHessenbergTriangular();
// Sparse variant of the above method.
template <typename SparseMatrixType_>
void hessenbergTriangularSparse(const SparseMatrixType_& A, const SparseMatrixType_& B);
void computeNorms();
Index findSmallSubdiagEntry(Index l);
Index findSmallDiagEntry(Index f, Index l);
void push_down_zero_ST(Index k, Index l);
void reduceDiagonal2x2block(Index i);
};
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::compute(const MatrixType& A, const MatrixType& B, bool computeQZ) {
m_computeQZ = computeQZ;
m_n = A.rows();
eigen_assert(m_n == A.cols() && "A is not a square matrix");
eigen_assert(m_n == B.rows() && m_n == B.cols() && "B is not a square matrix or B is not of the same size as A");
m_isInitialized = true;
m_global_iter = 0;
// This will initialize m_Q and m_Z and bring m_S, m_T to hessenberg-triangular form
hessenbergTriangular(A, B);
// We assume that we already have that S is upper-Hessenberg and T is
// upper-triangular. This is what the hessenbergTriangular(...) method does
reduceHessenbergTriangular();
}
// This is basically taken from from Eigen3::RealQZ
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::hessenbergTriangular(const MatrixType& A, const MatrixType& B) {
// Copy A and B, these will be the matrices on which we operate later
m_S = A;
m_T = B;
// Perform QR decomposition of the matrix Q
HouseholderQR<MatrixType> qr(m_T);
m_T = qr.matrixQR();
m_T.template triangularView<StrictlyLower>().setZero();
if (m_computeQZ) m_Q = qr.householderQ();
// overwrite S with Q* x S
m_S.applyOnTheLeft(qr.householderQ().adjoint());
if (m_computeQZ) m_Z = MatrixType::Identity(m_n, m_n);
// reduce S to upper Hessenberg with Givens rotations
for (Index j = 0; j <= m_n - 3; j++) {
for (Index i = m_n - 1; i >= j + 2; i--) {
JacobiRotation<Scalar> G;
// delete S(i,j)
if (!numext::is_exactly_zero(m_S.coeff(i, j))) {
G.makeGivens(m_S.coeff(i - 1, j), m_S.coeff(i, j), &m_S.coeffRef(i - 1, j));
m_S.coeffRef(i, j) = Scalar(0);
m_T.rightCols(m_n - i + 1).applyOnTheLeft(i - 1, i, G.adjoint());
m_S.rightCols(m_n - j - 1).applyOnTheLeft(i - 1, i, G.adjoint());
// This is what we want to achieve
if (!is_negligible(m_S(i, j)))
m_info = ComputationInfo::NumericalIssue;
else
m_S(i, j) = Scalar(0);
// update Q
if (m_computeQZ) m_Q.applyOnTheRight(i - 1, i, G);
}
if (!numext::is_exactly_zero(m_T.coeff(i, i - 1))) {
// Compute rotation and update matrix T
G.makeGivens(m_T.coeff(i, i), m_T.coeff(i, i - 1), &m_T.coeffRef(i, i));
m_T.topRows(i).applyOnTheRight(i - 1, i, G.adjoint());
m_T.coeffRef(i, i - 1) = Scalar(0);
// Update matrix S
m_S.applyOnTheRight(i - 1, i, G.adjoint());
// update Z
if (m_computeQZ) m_Z.applyOnTheLeft(i - 1, i, G);
}
}
}
}
template <typename MatrixType>
template <typename SparseMatrixType_>
void ComplexQZ<MatrixType>::hessenbergTriangularSparse(const SparseMatrixType_& A, const SparseMatrixType_& B) {
m_S = A.toDense();
SparseQR<SparseMatrix<Scalar, ColMajor>, NaturalOrdering<Index>> sparseQR;
eigen_assert(B.isCompressed() &&
"SparseQR requires a sparse matrix in compressed mode."
"Call .makeCompressed() before passing it to SparseQR");
// Computing QR decomposition of T...
sparseQR.setPivotThreshold(RealScalar(0)); // This prevends algorithm from doing pivoting
sparseQR.compute(B);
// perform QR decomposition of T, overwrite T with R, save Q
// HouseholderQR<Mat> qrT(m_T);
m_T = sparseQR.matrixR();
m_T.template triangularView<StrictlyLower>().setZero();
if (m_computeQZ) m_Q = sparseQR.matrixQ();
// overwrite S with Q* S
m_S = sparseQR.matrixQ().adjoint() * m_S;
if (m_computeQZ) m_Z = MatrixType::Identity(m_n, m_n);
// reduce S to upper Hessenberg with Givens rotations
for (Index j = 0; j <= m_n - 3; j++) {
for (Index i = m_n - 1; i >= j + 2; i--) {
JacobiRotation<Scalar> G;
// kill S(i,j)
// if(!numext::is_exactly_zero(_S.coeff(i, j)))
if (m_S.coeff(i, j) != Scalar(0)) {
// This is the adapted code
G.makeGivens(m_S.coeff(i - 1, j), m_S.coeff(i, j), &m_S.coeffRef(i - 1, j));
m_S.coeffRef(i, j) = Scalar(0);
m_T.rightCols(m_n - i + 1).applyOnTheLeft(i - 1, i, G.adjoint());
m_S.rightCols(m_n - j - 1).applyOnTheLeft(i - 1, i, G.adjoint());
// This is what we want to achieve
if (!is_negligible(m_S(i, j))) {
m_info = ComputationInfo::NumericalIssue;
}
m_S(i, j) = Scalar(0);
// update Q
if (m_computeQZ) m_Q.applyOnTheRight(i - 1, i, G);
}
if (!numext::is_exactly_zero(m_T.coeff(i, i - 1))) {
// Compute rotation and update matrix T
G.makeGivens(m_T.coeff(i, i), m_T.coeff(i, i - 1), &m_T.coeffRef(i, i));
m_T.topRows(i).applyOnTheRight(i - 1, i, G.adjoint());
m_T.coeffRef(i, i - 1) = Scalar(0);
// Update matrix S
m_S.applyOnTheRight(i - 1, i, G.adjoint());
// update Z
if (m_computeQZ) m_Z.applyOnTheLeft(i - 1, i, G);
}
}
}
}
template <typename MatrixType>
template <typename SparseMatrixType_>
void ComplexQZ<MatrixType>::computeSparse(const SparseMatrixType_& A, const SparseMatrixType_& B, bool computeQZ) {
m_computeQZ = computeQZ;
m_n = A.rows();
eigen_assert(m_n == A.cols() && "A is not a square matrix");
eigen_assert(m_n == B.rows() && m_n == B.cols() && "B is not a square matrix or B is not of the same size as A");
m_isInitialized = true;
m_global_iter = 0;
hessenbergTriangularSparse(A, B);
// We assume that we already have that A is upper-Hessenberg and B is
// upper-triangular. This is what the hessenbergTriangular(...) method does
reduceHessenbergTriangular();
}
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::reduceHessenbergTriangular() {
Index l = m_n - 1, f;
unsigned int local_iter = 0;
computeNorms();
while (l > 0 && local_iter < m_maxIters) {
f = findSmallSubdiagEntry(l);
// Subdiag entry is small -> can be safely set to 0
if (f > 0) {
m_S.coeffRef(f, f - 1) = Scalar(0);
}
if (f == l) { // One root found
l--;
local_iter = 0;
} else if (f == l - 1) { // Two roots found
// We found an undesired non-zero at (f+1,f) in S and eliminate it immediately
reduceDiagonal2x2block(f);
l -= 2;
local_iter = 0;
} else {
Index z = findSmallDiagEntry(f, l);
if (z >= f) {
push_down_zero_ST(z, l);
} else {
do_QZ_step(f, m_n - l - 1);
local_iter++;
m_global_iter++;
}
}
}
m_info = (local_iter < m_maxIters) ? Success : NoConvergence;
}
template <typename MatrixType_>
inline typename ComplexQZ<MatrixType_>::Mat2 ComplexQZ<MatrixType_>::computeZk2(const Row2& b) {
Mat2 S;
S << Scalar(0), Scalar(1), Scalar(1), Scalar(0);
Vec2 bprime = S * b.adjoint();
JacobiRotation<Scalar> J;
J.makeGivens(bprime(0), bprime(1));
Mat2 Z = S;
Z.applyOnTheLeft(0, 1, J);
Z = S * Z;
return Z;
}
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::do_QZ_step(Index p, Index q) {
// This is certainly not the most efficient way of doing this,
// but a readable one.
const auto a = [p, this](Index i, Index j) { return m_S(p + i - 1, p + j - 1); };
const auto b = [p, this](Index i, Index j) { return m_T(p + i - 1, p + j - 1); };
const Index m = m_n - p - q; // Size of the inner block
Scalar x, y, z;
// We could introduce doing exceptional shifts from time to time.
Scalar W1 = a(m - 1, m - 1) / b(m - 1, m - 1) - a(1, 1) / b(1, 1), W2 = a(m, m) / b(m, m) - a(1, 1) / b(1, 1),
W3 = a(m, m - 1) / b(m - 1, m - 1);
x = (W1 * W2 - a(m - 1, m) / b(m, m) * W3 + W3 * b(m - 1, m) / b(m, m) * a(1, 1) / b(1, 1)) * b(1, 1) / a(2, 1) +
a(1, 2) / b(2, 2) - a(1, 1) / b(1, 1) * b(1, 2) / b(2, 2);
y = (a(2, 2) / b(2, 2) - a(1, 1) / b(1, 1)) - a(2, 1) / b(1, 1) * b(1, 2) / b(2, 2) - W1 - W2 +
W3 * (b(m - 1, m) / b(m, m));
z = a(3, 2) / b(2, 2);
Vec3 X;
const PermutationMatrix<3, 3, int> S3(Vector3i(2, 0, 1));
for (Index k = p; k < p + m - 2; k++) {
X << x, y, z;
Vec2 ess;
Scalar tau;
RealScalar beta;
X.makeHouseholder(ess, tau, beta);
// The permutations are needed because the makeHouseHolder-method computes
// the householder transformation in a way that the vector is reflected to
// (1 0 ... 0) instead of (0 ... 0 1)
m_S.template middleRows<3>(k)
.rightCols((std::min)(m_n, m_n - k + 1))
.applyHouseholderOnTheLeft(ess, tau, m_ws.data());
m_T.template middleRows<3>(k).rightCols(m_n - k).applyHouseholderOnTheLeft(ess, tau, m_ws.data());
if (m_computeQZ) m_Q.template middleCols<3>(k).applyHouseholderOnTheRight(ess, std::conj(tau), m_ws.data());
// Compute Matrix Zk1 s.t. (b(k+2,k) ... b(k+2, k+2)) Zk1 = (0,0,*)
Vec3 bprime = (m_T.template block<1, 3>(k + 2, k) * S3).adjoint();
bprime.makeHouseholder(ess, tau, beta);
m_S.template middleCols<3>(k).topRows((std::min)(k + 4, m_n)).applyOnTheRight(S3);
m_S.template middleCols<3>(k)
.topRows((std::min)(k + 4, m_n))
.applyHouseholderOnTheRight(ess, std::conj(tau), m_ws.data());
m_S.template middleCols<3>(k).topRows((std::min)(k + 4, m_n)).applyOnTheRight(S3.transpose());
m_T.template middleCols<3>(k).topRows((std::min)(k + 3, m_n)).applyOnTheRight(S3);
m_T.template middleCols<3>(k)
.topRows((std::min)(k + 3, m_n))
.applyHouseholderOnTheRight(ess, std::conj(tau), m_ws.data());
m_T.template middleCols<3>(k).topRows((std::min)(k + 3, m_n)).applyOnTheRight(S3.transpose());
if (m_computeQZ) {
m_Z.template middleRows<3>(k).applyOnTheLeft(S3.transpose());
m_Z.template middleRows<3>(k).applyHouseholderOnTheLeft(ess, tau, m_ws.data());
m_Z.template middleRows<3>(k).applyOnTheLeft(S3);
}
Mat2 Zk2 = computeZk2(m_T.template block<1, 2>(k + 1, k));
m_S.template middleCols<2>(k).topRows((std::min)(k + 4, m_n)).applyOnTheRight(Zk2);
m_T.template middleCols<2>(k).topRows((std::min)(k + 3, m_n)).applyOnTheRight(Zk2);
if (m_computeQZ) m_Z.template middleRows<2>(k).applyOnTheLeft(Zk2.adjoint());
x = m_S(k + 1, k);
y = m_S(k + 2, k);
if (k < p + m - 3) {
z = m_S(k + 3, k);
}
};
// Find a Householdermartirx Qn1 s.t. Qn1 (x y)^T = (* 0)
JacobiRotation<Scalar> J;
J.makeGivens(x, y);
m_S.template middleRows<2>(p + m - 2).applyOnTheLeft(0, 1, J.adjoint());
m_T.template middleRows<2>(p + m - 2).applyOnTheLeft(0, 1, J.adjoint());
if (m_computeQZ) m_Q.template middleCols<2>(p + m - 2).applyOnTheRight(0, 1, J);
// Find a Householdermatrix Zn1 s.t. (b(n,n-1) b(n,n)) * Zn1 = (0 *)
Mat2 Zn1 = computeZk2(m_T.template block<1, 2>(p + m - 1, p + m - 2));
m_S.template middleCols<2>(p + m - 2).applyOnTheRight(Zn1);
m_T.template middleCols<2>(p + m - 2).applyOnTheRight(Zn1);
if (m_computeQZ) m_Z.template middleRows<2>(p + m - 2).applyOnTheLeft(Zn1.adjoint());
}
/** \internal we found an undesired non-zero at (i+1,i) on the subdiagonal of S and reduce the block */
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::reduceDiagonal2x2block(Index i) {
// We have found a non-zero on the subdiagonal and want to eliminate it
Mat2 Si = m_S.template block<2, 2>(i, i), Ti = m_T.template block<2, 2>(i, i);
if (is_negligible(Ti(0, 0)) && !is_negligible(Ti(1, 1))) {
Eigen::JacobiRotation<Scalar> G;
G.makeGivens(m_S(i, i), m_S(i + 1, i));
m_S.applyOnTheLeft(i, i + 1, G.adjoint());
m_T.applyOnTheLeft(i, i + 1, G.adjoint());
if (m_computeQZ) m_Q.applyOnTheRight(i, i + 1, G);
} else if (!is_negligible(Ti(0, 0)) && is_negligible(Ti(1, 1))) {
Eigen::JacobiRotation<Scalar> G;
G.makeGivens(m_S(i + 1, i + 1), m_S(i + 1, i));
m_S.applyOnTheRight(i, i + 1, G.adjoint());
m_T.applyOnTheRight(i, i + 1, G.adjoint());
if (m_computeQZ) m_Z.applyOnTheLeft(i, i + 1, G);
} else if (!is_negligible(Ti(0, 0)) && !is_negligible((Ti(1, 1)))) {
Scalar mu = Si(0, 0) / Ti(0, 0);
Scalar a12_bar = Si(0, 1) - mu * Ti(0, 1);
Scalar a22_bar = Si(1, 1) - mu * Ti(1, 1);
Scalar p = Scalar(0.5) * (a22_bar / Ti(1, 1) - Ti(0, 1) * Si(1, 0) / (Ti(0, 0) * Ti(1, 1)));
RealScalar sgn_p = p.real() >= RealScalar(0) ? RealScalar(1) : RealScalar(-1);
Scalar q = Si(1, 0) * a12_bar / (Ti(0, 0) * Ti(1, 1));
Scalar r = p * p + q;
Scalar lambda = mu + p + sgn_p * numext::sqrt(r);
Mat2 E = Si - lambda * Ti;
Index l;
E.rowwise().norm().maxCoeff(&l);
JacobiRotation<Scalar> G;
G.makeGivens(E(l, 1), E(l, 0));
m_S.applyOnTheRight(i, i + 1, G.adjoint());
m_T.applyOnTheRight(i, i + 1, G.adjoint());
if (m_computeQZ) m_Z.applyOnTheLeft(i, i + 1, G);
Mat2 tildeSi = m_S.template block<2, 2>(i, i), tildeTi = m_T.template block<2, 2>(i, i);
Mat2 C = tildeSi.norm() < (lambda * tildeTi).norm() ? tildeSi : lambda * tildeTi;
G.makeGivens(C(0, 0), C(1, 0));
m_S.applyOnTheLeft(i, i + 1, G.adjoint());
m_T.applyOnTheLeft(i, i + 1, G.adjoint());
if (m_computeQZ) m_Q.applyOnTheRight(i, i + 1, G);
}
if (!is_negligible(m_S(i + 1, i), m_normOfS * NumTraits<RealScalar>::epsilon())) {
m_info = ComputationInfo::NumericalIssue;
} else {
m_S(i + 1, i) = Scalar(0);
}
}
/** \internal We found a zero at T(k,k) and want to "push it down" to T(l,l) */
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::push_down_zero_ST(Index k, Index l) {
// Test Preconditions
JacobiRotation<Scalar> J;
for (Index j = k + 1; j <= l; j++) {
// Create a 0 at _T(j, j)
J.makeGivens(m_T(j - 1, j), m_T(j, j), &m_T.coeffRef(j - 1, j));
m_T.rightCols(m_n - j - 1).applyOnTheLeft(j - 1, j, J.adjoint());
m_T.coeffRef(j, j) = Scalar(0);
m_S.applyOnTheLeft(j - 1, j, J.adjoint());
if (m_computeQZ) m_Q.applyOnTheRight(j - 1, j, J);
// Delete the non-desired non-zero at _S(j, j-2)
if (j > 1) {
J.makeGivens(std::conj(m_S(j, j - 1)), std::conj(m_S(j, j - 2)));
m_S.applyOnTheRight(j - 1, j - 2, J);
m_S(j, j - 2) = Scalar(0);
m_T.applyOnTheRight(j - 1, j - 2, J);
if (m_computeQZ) m_Z.applyOnTheLeft(j - 1, j - 2, J.adjoint());
}
}
// Assume we have the desired structure now, up to the non-zero entry at
// _S(l, l-1) which we will delete through a last right-jacobi-rotation
J.makeGivens(std::conj(m_S(l, l)), std::conj(m_S(l, l - 1)));
m_S.topRows(l + 1).applyOnTheRight(l, l - 1, J);
if (!is_negligible(m_S(l, l - 1), m_normOfS * NumTraits<Scalar>::epsilon())) {
m_info = ComputationInfo::NumericalIssue;
} else {
m_S(l, l - 1) = Scalar(0);
}
m_T.topRows(l + 1).applyOnTheRight(l, l - 1, J);
if (m_computeQZ) m_Z.applyOnTheLeft(l, l - 1, J.adjoint());
// Ensure postconditions
if (!is_negligible(m_T(l, l)) || !is_negligible(m_S(l, l - 1))) {
m_info = ComputationInfo::NumericalIssue;
} else {
m_T(l, l) = Scalar(0);
m_S(l, l - 1) = Scalar(0);
}
}
/** \internal Computes vector L1 norms of S and T when in Hessenberg-Triangular form already */
template <typename MatrixType_>
void ComplexQZ<MatrixType_>::computeNorms() {
const Index size = m_S.cols();
m_normOfS = RealScalar(0);
m_normOfT = RealScalar(0);
for (Index j = 0; j < size; ++j) {
m_normOfS += m_S.col(j).segment(0, (std::min)(size, j + 2)).cwiseAbs().sum();
m_normOfT += m_T.row(j).segment(j, size - j).cwiseAbs().sum();
}
}
/** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0). Copied from Eigen3 RealQZ
* implementation */
template <typename MatrixType_>
inline Index ComplexQZ<MatrixType_>::findSmallSubdiagEntry(Index iu) {
Index res = iu;
while (res > 0) {
RealScalar s = numext::abs(m_S.coeff(res - 1, res - 1)) + numext::abs(m_S.coeff(res, res));
if (s == Scalar(0)) s = m_normOfS;
if (numext::abs(m_S.coeff(res, res - 1)) < NumTraits<RealScalar>::epsilon() * s) break;
res--;
}
return res;
}
//
/** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1).
* Copied from Eigen3 RealQZ implementation. */
template <typename MatrixType_>
inline Index ComplexQZ<MatrixType_>::findSmallDiagEntry(Index f, Index l) {
Index res = l;
while (res >= f) {
if (numext::abs(m_T.coeff(res, res)) <= NumTraits<RealScalar>::epsilon() * m_normOfT) break;
res--;
}
return res;
}
} // namespace Eigen
#endif // _COMPLEX_QZ_H_

View File

@ -348,8 +348,8 @@ struct apply_rotation_in_the_plane_selector<Scalar, OtherScalar, SizeAtCompileTi
for (Index i = alignedStart; i < alignedEnd; i += PacketSize) {
Packet xi = pload<Packet>(px);
Packet yi = pload<Packet>(py);
pstore(px, padd(pm.pmul(pc, xi), pcj.pmul(ps, yi)));
pstore(py, psub(pcj.pmul(pc, yi), pm.pmul(ps, xi)));
pstore(px, pm.pmadd(pc, xi, pcj.pmul(ps, yi)));
pstore(py, pcj.pmsub(pc, yi, pm.pmul(ps, xi)));
px += PacketSize;
py += PacketSize;
}
@ -360,18 +360,18 @@ struct apply_rotation_in_the_plane_selector<Scalar, OtherScalar, SizeAtCompileTi
Packet xi1 = ploadu<Packet>(px + PacketSize);
Packet yi = pload<Packet>(py);
Packet yi1 = pload<Packet>(py + PacketSize);
pstoreu(px, padd(pm.pmul(pc, xi), pcj.pmul(ps, yi)));
pstoreu(px + PacketSize, padd(pm.pmul(pc, xi1), pcj.pmul(ps, yi1)));
pstore(py, psub(pcj.pmul(pc, yi), pm.pmul(ps, xi)));
pstore(py + PacketSize, psub(pcj.pmul(pc, yi1), pm.pmul(ps, xi1)));
pstoreu(px, pm.pmadd(pc, xi, pcj.pmul(ps, yi)));
pstoreu(px + PacketSize, pm.pmadd(pc, xi1, pcj.pmul(ps, yi1)));
pstore(py, pcj.pmsub(pc, yi, pm.pmul(ps, xi)));
pstore(py + PacketSize, pcj.pmsub(pc, yi1, pm.pmul(ps, xi1)));
px += Peeling * PacketSize;
py += Peeling * PacketSize;
}
if (alignedEnd != peelingEnd) {
Packet xi = ploadu<Packet>(x + peelingEnd);
Packet yi = pload<Packet>(y + peelingEnd);
pstoreu(x + peelingEnd, padd(pm.pmul(pc, xi), pcj.pmul(ps, yi)));
pstore(y + peelingEnd, psub(pcj.pmul(pc, yi), pm.pmul(ps, xi)));
pstoreu(x + peelingEnd, pm.pmadd(pc, xi, pcj.pmul(ps, yi)));
pstore(y + peelingEnd, pcj.pmsub(pc, yi, pm.pmul(ps, xi)));
}
}
@ -394,8 +394,8 @@ struct apply_rotation_in_the_plane_selector<Scalar, OtherScalar, SizeAtCompileTi
for (Index i = 0; i < size; i += PacketSize) {
Packet xi = pload<Packet>(px);
Packet yi = pload<Packet>(py);
pstore(px, padd(pm.pmul(pc, xi), pcj.pmul(ps, yi)));
pstore(py, psub(pcj.pmul(pc, yi), pm.pmul(ps, xi)));
pstore(px, pm.pmadd(pc, xi, pcj.pmul(ps, yi)));
pstore(py, pcj.pmsub(pc, yi, pm.pmul(ps, xi)));
px += PacketSize;
py += PacketSize;
}
@ -433,6 +433,34 @@ EIGEN_DEVICE_FUNC void inline apply_rotation_in_the_plane(DenseBase<VectorX>& xp
x, incrx, y, incry, size, c, s);
}
template <typename MatrixType, typename RealScalar, typename Index>
void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, JacobiRotation<RealScalar>* j_left,
JacobiRotation<RealScalar>* j_right) {
using std::abs;
using std::sqrt;
Matrix<RealScalar, 2, 2> m;
m << numext::real(matrix.coeff(p, p)), numext::real(matrix.coeff(p, q)), numext::real(matrix.coeff(q, p)),
numext::real(matrix.coeff(q, q));
JacobiRotation<RealScalar> rot1;
RealScalar t = m.coeff(0, 0) + m.coeff(1, 1);
RealScalar d = m.coeff(1, 0) - m.coeff(0, 1);
if (abs(d) < (std::numeric_limits<RealScalar>::min)()) {
rot1.s() = RealScalar(0);
rot1.c() = RealScalar(1);
} else {
// If d!=0, then t/d cannot overflow because the magnitude of the
// entries forming d are not too small compared to the ones forming t.
RealScalar u = t / d;
RealScalar tmp = sqrt(RealScalar(1) + numext::abs2(u));
rot1.s() = RealScalar(1) / tmp;
rot1.c() = u / tmp;
}
m.applyOnTheLeft(0, 1, rot1);
j_right->makeJacobi(m, 0, 1);
*j_left = rot1 * j_right->transpose();
}
} // end namespace internal
} // end namespace Eigen

View File

@ -182,7 +182,7 @@ class KLU : public SparseSolverBase<KLU<MatrixType_> > {
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the pattern anylysis has been performed.
* The given matrix must have the same sparsity than the matrix on which the pattern anylysis has been performed.
*
* \sa analyzePattern(), compute()
*/

View File

@ -157,7 +157,8 @@ class PardisoImpl : public SparseSolverBase<Derived> {
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/

View File

@ -571,6 +571,11 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
compute_impl(matrix, internal::get_computation_options(Options));
}
template <typename Derived>
explicit JacobiSVD(const TriangularBase<Derived>& matrix) {
compute_impl(matrix, internal::get_computation_options(Options));
}
/** \brief Constructor performing the decomposition of given matrix using specified options
* for computing unitaries.
*
@ -601,6 +606,11 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
return compute_impl(matrix, m_computationOptions);
}
template <typename Derived>
JacobiSVD& compute(const TriangularBase<Derived>& matrix) {
return compute_impl(matrix, m_computationOptions);
}
/** \brief Method performing the decomposition of given matrix, as specified by
* the `computationOptions` parameter.
*
@ -638,6 +648,8 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
}
private:
template <typename Derived>
JacobiSVD& compute_impl(const TriangularBase<Derived>& matrix, unsigned int computationOptions);
template <typename Derived>
JacobiSVD& compute_impl(const MatrixBase<Derived>& matrix, unsigned int computationOptions);
@ -676,6 +688,13 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
WorkMatrixType m_workMatrix;
};
template <typename MatrixType, int Options>
template <typename Derived>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const TriangularBase<Derived>& matrix,
unsigned int computationOptions) {
return compute_impl(matrix.toDenseMatrix(), computationOptions);
}
template <typename MatrixType, int Options>
template <typename Derived>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const MatrixBase<Derived>& matrix,

View File

@ -416,7 +416,8 @@ class SimplicialLLT : public SimplicialCholeskyBase<SimplicialLLT<MatrixType_, U
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/
@ -504,7 +505,8 @@ class SimplicialLDLT : public SimplicialCholeskyBase<SimplicialLDLT<MatrixType_,
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/
@ -585,7 +587,8 @@ class SimplicialNonHermitianLLT
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/
@ -674,7 +677,8 @@ class SimplicialNonHermitianLDLT
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/
@ -757,7 +761,8 @@ class SimplicialCholesky : public SimplicialCholeskyBase<SimplicialCholesky<Matr
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/

View File

@ -487,7 +487,8 @@ class SuperLU : public SuperLUBase<MatrixType_, SuperLU<MatrixType_> > {
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/
@ -791,7 +792,8 @@ class SuperILU : public SuperLUBase<MatrixType_, SuperILU<MatrixType_> > {
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed.
* The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been
* performed.
*
* \sa analyzePattern()
*/

View File

@ -425,7 +425,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<MatrixType_> > {
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparsity than the matrix on which the pattern anylysis has been performed.
* The given matrix must have the same sparsity than the matrix on which the pattern anylysis has been performed.
*
* \sa analyzePattern(), compute()
*/

View File

@ -1,53 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2013-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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/.
#ifndef EIGEN_REALSVD2X2_H
#define EIGEN_REALSVD2X2_H
// IWYU pragma: private
#include "./InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
template <typename MatrixType, typename RealScalar, typename Index>
void real_2x2_jacobi_svd(const MatrixType &matrix, Index p, Index q, JacobiRotation<RealScalar> *j_left,
JacobiRotation<RealScalar> *j_right) {
using std::abs;
using std::sqrt;
Matrix<RealScalar, 2, 2> m;
m << numext::real(matrix.coeff(p, p)), numext::real(matrix.coeff(p, q)), numext::real(matrix.coeff(q, p)),
numext::real(matrix.coeff(q, q));
JacobiRotation<RealScalar> rot1;
RealScalar t = m.coeff(0, 0) + m.coeff(1, 1);
RealScalar d = m.coeff(1, 0) - m.coeff(0, 1);
if (abs(d) < (std::numeric_limits<RealScalar>::min)()) {
rot1.s() = RealScalar(0);
rot1.c() = RealScalar(1);
} else {
// If d!=0, then t/d cannot overflow because the magnitude of the
// entries forming d are not too small compared to the ones forming t.
RealScalar u = t / d;
RealScalar tmp = sqrt(RealScalar(1) + numext::abs2(u));
rot1.s() = RealScalar(1) / tmp;
rot1.c() = u / tmp;
}
m.applyOnTheLeft(0, 1, rot1);
j_right->makeJacobi(m, 0, 1);
*j_left = rot1 * j_right->transpose();
}
} // end namespace internal
} // end namespace Eigen
#endif // EIGEN_REALSVD2X2_H

View File

@ -19,7 +19,9 @@ add_library(eigen_blas_static STATIC ${EigenBlas_SRCS})
list(APPEND EIGEN_BLAS_TARGETS eigen_blas_static)
if (EIGEN_BUILD_SHARED_LIBS)
add_library(eigen_blas SHARED ${EigenBlas_SRCS})
add_library(eigen_blas SHARED ${EigenBlas_SRCS} "eigen_blas.def")
target_compile_definitions(eigen_blas PUBLIC "EIGEN_BLAS_BUILD_DLL")
set_target_properties(eigen_blas PROPERTIES CXX_VISIBILITY_PRESET hidden)
list(APPEND EIGEN_BLAS_TARGETS eigen_blas)
endif()

View File

@ -1,6 +1,20 @@
#ifndef BLAS_H
#define BLAS_H
#if defined(_WIN32)
#if defined(EIGEN_BLAS_BUILD_DLL)
#define EIGEN_BLAS_API __declspec(dllexport)
#elif defined(EIGEN_BLAS_LINK_DLL)
#define EIGEN_BLAS_API __declspec(dllimport)
#else
#define EIGEN_BLAS_API
#endif
#elif ((defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)) && defined(EIGEN_BLAS_BUILD_DLL)
#define EIGEN_BLAS_API __attribute__((visibility("default")))
#else
#define EIGEN_BLAS_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -15,467 +29,514 @@ typedef long BLASLONG;
typedef unsigned long BLASULONG;
#endif
void BLASFUNC(xerbla)(const char *, int *info);
EIGEN_BLAS_API int BLASFUNC(lsame)(const char *, const char *);
EIGEN_BLAS_API void BLASFUNC(xerbla)(const char *, int *info);
float BLASFUNC(sdot)(int *, float *, int *, float *, int *);
float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *);
EIGEN_BLAS_API float BLASFUNC(sdot)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *);
double BLASFUNC(dsdot)(int *, float *, int *, float *, int *);
double BLASFUNC(ddot)(int *, double *, int *, double *, int *);
double BLASFUNC(qdot)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(dsdot)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(ddot)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qdot)(int *, double *, int *, double *, int *);
void BLASFUNC(cdotuw)(int *, float *, int *, float *, int *, float *);
void BLASFUNC(cdotcw)(int *, float *, int *, float *, int *, float *);
void BLASFUNC(zdotuw)(int *, double *, int *, double *, int *, double *);
void BLASFUNC(zdotcw)(int *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(cdotu)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(cdotc)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zdotu)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(zdotc)(int *, double *, int *, double *, int *);
void BLASFUNC(saxpy)(const int *, const float *, const float *, const int *, float *, const int *);
void BLASFUNC(daxpy)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(qaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(caxpy)(const int *, const float *, const float *, const int *, float *, const int *);
void BLASFUNC(zaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(xaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(caxpyc)(const int *, const float *, const float *, const int *, float *, const int *);
void BLASFUNC(zaxpyc)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(xaxpyc)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(cdotuw)(int *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(cdotcw)(int *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(zdotuw)(int *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(zdotcw)(int *, double *, int *, double *, int *, double *);
void BLASFUNC(scopy)(int *, float *, int *, float *, int *);
void BLASFUNC(dcopy)(int *, double *, int *, double *, int *);
void BLASFUNC(qcopy)(int *, double *, int *, double *, int *);
void BLASFUNC(ccopy)(int *, float *, int *, float *, int *);
void BLASFUNC(zcopy)(int *, double *, int *, double *, int *);
void BLASFUNC(xcopy)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(saxpy)(const int *, const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(daxpy)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(caxpy)(const int *, const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xaxpy)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(caxpyc)(const int *, const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zaxpyc)(const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xaxpyc)(const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(sswap)(int *, float *, int *, float *, int *);
void BLASFUNC(dswap)(int *, double *, int *, double *, int *);
void BLASFUNC(qswap)(int *, double *, int *, double *, int *);
void BLASFUNC(cswap)(int *, float *, int *, float *, int *);
void BLASFUNC(zswap)(int *, double *, int *, double *, int *);
void BLASFUNC(xswap)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(scopy)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dcopy)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qcopy)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ccopy)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zcopy)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xcopy)(int *, double *, int *, double *, int *);
float BLASFUNC(sasum)(int *, float *, int *);
float BLASFUNC(scasum)(int *, float *, int *);
double BLASFUNC(dasum)(int *, double *, int *);
double BLASFUNC(qasum)(int *, double *, int *);
double BLASFUNC(dzasum)(int *, double *, int *);
double BLASFUNC(qxasum)(int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(sswap)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dswap)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qswap)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cswap)(int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zswap)(int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xswap)(int *, double *, int *, double *, int *);
int BLASFUNC(isamax)(int *, float *, int *);
int BLASFUNC(idamax)(int *, double *, int *);
int BLASFUNC(iqamax)(int *, double *, int *);
int BLASFUNC(icamax)(int *, float *, int *);
int BLASFUNC(izamax)(int *, double *, int *);
int BLASFUNC(ixamax)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(sasum)(int *, float *, int *);
EIGEN_BLAS_API float BLASFUNC(scasum)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dasum)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qasum)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(dzasum)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxasum)(int *, double *, int *);
int BLASFUNC(ismax)(int *, float *, int *);
int BLASFUNC(idmax)(int *, double *, int *);
int BLASFUNC(iqmax)(int *, double *, int *);
int BLASFUNC(icmax)(int *, float *, int *);
int BLASFUNC(izmax)(int *, double *, int *);
int BLASFUNC(ixmax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(isamax)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(idamax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(iqamax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(icamax)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(izamax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ixamax)(int *, double *, int *);
int BLASFUNC(isamin)(int *, float *, int *);
int BLASFUNC(idamin)(int *, double *, int *);
int BLASFUNC(iqamin)(int *, double *, int *);
int BLASFUNC(icamin)(int *, float *, int *);
int BLASFUNC(izamin)(int *, double *, int *);
int BLASFUNC(ixamin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ismax)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(idmax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(iqmax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(icmax)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(izmax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ixmax)(int *, double *, int *);
int BLASFUNC(ismin)(int *, float *, int *);
int BLASFUNC(idmin)(int *, double *, int *);
int BLASFUNC(iqmin)(int *, double *, int *);
int BLASFUNC(icmin)(int *, float *, int *);
int BLASFUNC(izmin)(int *, double *, int *);
int BLASFUNC(ixmin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(isamin)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(idamin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(iqamin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(icamin)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(izamin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ixamin)(int *, double *, int *);
float BLASFUNC(samax)(int *, float *, int *);
double BLASFUNC(damax)(int *, double *, int *);
double BLASFUNC(qamax)(int *, double *, int *);
float BLASFUNC(scamax)(int *, float *, int *);
double BLASFUNC(dzamax)(int *, double *, int *);
double BLASFUNC(qxamax)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ismin)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(idmin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(iqmin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(icmin)(int *, float *, int *);
EIGEN_BLAS_API int BLASFUNC(izmin)(int *, double *, int *);
EIGEN_BLAS_API int BLASFUNC(ixmin)(int *, double *, int *);
float BLASFUNC(samin)(int *, float *, int *);
double BLASFUNC(damin)(int *, double *, int *);
double BLASFUNC(qamin)(int *, double *, int *);
float BLASFUNC(scamin)(int *, float *, int *);
double BLASFUNC(dzamin)(int *, double *, int *);
double BLASFUNC(qxamin)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(samax)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(damax)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qamax)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(scamax)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dzamax)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxamax)(int *, double *, int *);
float BLASFUNC(smax)(int *, float *, int *);
double BLASFUNC(dmax)(int *, double *, int *);
double BLASFUNC(qmax)(int *, double *, int *);
float BLASFUNC(scmax)(int *, float *, int *);
double BLASFUNC(dzmax)(int *, double *, int *);
double BLASFUNC(qxmax)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(samin)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(damin)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qamin)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(scamin)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dzamin)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxamin)(int *, double *, int *);
float BLASFUNC(smin)(int *, float *, int *);
double BLASFUNC(dmin)(int *, double *, int *);
double BLASFUNC(qmin)(int *, double *, int *);
float BLASFUNC(scmin)(int *, float *, int *);
double BLASFUNC(dzmin)(int *, double *, int *);
double BLASFUNC(qxmin)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(smax)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dmax)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qmax)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(scmax)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dzmax)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxmax)(int *, double *, int *);
void BLASFUNC(sscal)(int *, float *, float *, int *);
void BLASFUNC(dscal)(int *, double *, double *, int *);
void BLASFUNC(qscal)(int *, double *, double *, int *);
void BLASFUNC(cscal)(int *, float *, float *, int *);
void BLASFUNC(zscal)(int *, double *, double *, int *);
void BLASFUNC(xscal)(int *, double *, double *, int *);
void BLASFUNC(csscal)(int *, float *, float *, int *);
void BLASFUNC(zdscal)(int *, double *, double *, int *);
void BLASFUNC(xqscal)(int *, double *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(smin)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dmin)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qmin)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(scmin)(int *, float *, int *);
EIGEN_BLAS_API double BLASFUNC(dzmin)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxmin)(int *, double *, int *);
float BLASFUNC(snrm2)(int *, float *, int *);
float BLASFUNC(scnrm2)(int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(sscal)(int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dscal)(int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qscal)(int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cscal)(int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zscal)(int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xscal)(int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(csscal)(int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zdscal)(int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xqscal)(int *, double *, double *, int *);
double BLASFUNC(dnrm2)(int *, double *, int *);
double BLASFUNC(qnrm2)(int *, double *, int *);
double BLASFUNC(dznrm2)(int *, double *, int *);
double BLASFUNC(qxnrm2)(int *, double *, int *);
EIGEN_BLAS_API float BLASFUNC(snrm2)(int *, float *, int *);
EIGEN_BLAS_API float BLASFUNC(scnrm2)(int *, float *, int *);
void BLASFUNC(srot)(int *, float *, int *, float *, int *, float *, float *);
void BLASFUNC(drot)(int *, double *, int *, double *, int *, double *, double *);
void BLASFUNC(qrot)(int *, double *, int *, double *, int *, double *, double *);
void BLASFUNC(csrot)(int *, float *, int *, float *, int *, float *, float *);
void BLASFUNC(zdrot)(int *, double *, int *, double *, int *, double *, double *);
void BLASFUNC(xqrot)(int *, double *, int *, double *, int *, double *, double *);
EIGEN_BLAS_API double BLASFUNC(dnrm2)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qnrm2)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(dznrm2)(int *, double *, int *);
EIGEN_BLAS_API double BLASFUNC(qxnrm2)(int *, double *, int *);
void BLASFUNC(srotg)(float *, float *, float *, float *);
void BLASFUNC(drotg)(double *, double *, double *, double *);
void BLASFUNC(qrotg)(double *, double *, double *, double *);
void BLASFUNC(crotg)(float *, float *, float *, float *);
void BLASFUNC(zrotg)(double *, double *, double *, double *);
void BLASFUNC(xrotg)(double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(srot)(int *, float *, int *, float *, int *, float *, float *);
EIGEN_BLAS_API void BLASFUNC(drot)(int *, double *, int *, double *, int *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(qrot)(int *, double *, int *, double *, int *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(csrot)(int *, float *, int *, float *, int *, float *, float *);
EIGEN_BLAS_API void BLASFUNC(zdrot)(int *, double *, int *, double *, int *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(xqrot)(int *, double *, int *, double *, int *, double *, double *);
void BLASFUNC(srotmg)(float *, float *, float *, float *, float *);
void BLASFUNC(drotmg)(double *, double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(srotg)(float *, float *, float *, float *);
EIGEN_BLAS_API void BLASFUNC(drotg)(double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(qrotg)(double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(crotg)(float *, float *, float *, float *);
EIGEN_BLAS_API void BLASFUNC(zrotg)(double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(xrotg)(double *, double *, double *, double *);
void BLASFUNC(srotm)(int *, float *, int *, float *, int *, float *);
void BLASFUNC(drotm)(int *, double *, int *, double *, int *, double *);
void BLASFUNC(qrotm)(int *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(srotmg)(float *, float *, float *, float *, float *);
EIGEN_BLAS_API void BLASFUNC(drotmg)(double *, double *, double *, double *, double *);
EIGEN_BLAS_API void BLASFUNC(srotm)(int *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(drotm)(int *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(qrotm)(int *, double *, int *, double *, int *, double *);
/* Level 2 routines */
void BLASFUNC(sger)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
void BLASFUNC(dger)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(qger)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(cgeru)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
void BLASFUNC(cgerc)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
void BLASFUNC(zgeru)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(zgerc)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(xgeru)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(xgerc)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(sger)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dger)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qger)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cgeru)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(cgerc)(int *, int *, float *, float *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zgeru)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(zgerc)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xgeru)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xgerc)(int *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(sgemv)(const char *, const int *, const int *, const float *, const float *, const int *, const float *,
const int *, const float *, float *, const int *);
void BLASFUNC(dgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(qgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cgemv)(const char *, const int *, const int *, const float *, const float *, const int *, const float *,
const int *, const float *, float *, const int *);
void BLASFUNC(zgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(sgemv)(const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(cgemv)(const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xgemv)(const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(strsv)(const char *, const char *, const char *, const int *, const float *, const int *, float *,
const int *);
void BLASFUNC(dtrsv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(qtrsv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(ctrsv)(const char *, const char *, const char *, const int *, const float *, const int *, float *,
const int *);
void BLASFUNC(ztrsv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(xtrsv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(strsv)(const char *, const char *, const char *, const int *, const float *, const int *,
float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dtrsv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qtrsv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ctrsv)(const char *, const char *, const char *, const int *, const float *, const int *,
float *, const int *);
EIGEN_BLAS_API void BLASFUNC(ztrsv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xtrsv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
void BLASFUNC(stpsv)(char *, char *, char *, int *, float *, float *, int *);
void BLASFUNC(dtpsv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(qtpsv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(ctpsv)(char *, char *, char *, int *, float *, float *, int *);
void BLASFUNC(ztpsv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(xtpsv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(stpsv)(char *, char *, char *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dtpsv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qtpsv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ctpsv)(char *, char *, char *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(ztpsv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xtpsv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(strmv)(const char *, const char *, const char *, const int *, const float *, const int *, float *,
const int *);
void BLASFUNC(dtrmv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(qtrmv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(ctrmv)(const char *, const char *, const char *, const int *, const float *, const int *, float *,
const int *);
void BLASFUNC(ztrmv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
void BLASFUNC(xtrmv)(const char *, const char *, const char *, const int *, const double *, const int *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(strmv)(const char *, const char *, const char *, const int *, const float *, const int *,
float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dtrmv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qtrmv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ctrmv)(const char *, const char *, const char *, const int *, const float *, const int *,
float *, const int *);
EIGEN_BLAS_API void BLASFUNC(ztrmv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xtrmv)(const char *, const char *, const char *, const int *, const double *, const int *,
double *, const int *);
void BLASFUNC(stpmv)(char *, char *, char *, int *, float *, float *, int *);
void BLASFUNC(dtpmv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(qtpmv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(ctpmv)(char *, char *, char *, int *, float *, float *, int *);
void BLASFUNC(ztpmv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(xtpmv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(stpmv)(char *, char *, char *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dtpmv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qtpmv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ctpmv)(char *, char *, char *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(ztpmv)(char *, char *, char *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xtpmv)(char *, char *, char *, int *, double *, double *, int *);
void BLASFUNC(stbmv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
void BLASFUNC(dtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(qtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(ctbmv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
void BLASFUNC(ztbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(xtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(stbmv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ctbmv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(ztbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xtbmv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(stbsv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
void BLASFUNC(dtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(qtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(ctbsv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
void BLASFUNC(ztbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(xtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(stbsv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ctbsv)(char *, char *, char *, int *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(ztbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xtbsv)(char *, char *, char *, int *, int *, double *, int *, double *, int *);
void BLASFUNC(ssymv)(const char *, const int *, const float *, const float *, const int *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(dsymv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
void BLASFUNC(qsymv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssymv)(const char *, const int *, const float *, const float *, const int *, const float *,
const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dsymv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qsymv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(sspmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
void BLASFUNC(dspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(qspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(sspmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(ssyr)(const char *, const int *, const float *, const float *, const int *, float *, const int *);
void BLASFUNC(dsyr)(const char *, const int *, const double *, const double *, const int *, double *, const int *);
void BLASFUNC(qsyr)(const char *, const int *, const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssyr)(const char *, const int *, const float *, const float *, const int *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(dsyr)(const char *, const int *, const double *, const double *, const int *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(qsyr)(const char *, const int *, const double *, const double *, const int *, double *,
const int *);
void BLASFUNC(ssyr2)(const char *, const int *, const float *, const float *, const int *, const float *, const int *,
float *, const int *);
void BLASFUNC(dsyr2)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, double *, const int *);
void BLASFUNC(qsyr2)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, double *, const int *);
void BLASFUNC(csyr2)(const char *, const int *, const float *, const float *, const int *, const float *, const int *,
float *, const int *);
void BLASFUNC(zsyr2)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, double *, const int *);
void BLASFUNC(xsyr2)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssyr2)(const char *, const int *, const float *, const float *, const int *, const float *,
const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dsyr2)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qsyr2)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(csyr2)(const char *, const int *, const float *, const float *, const int *, const float *,
const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zsyr2)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xsyr2)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, double *, const int *);
void BLASFUNC(sspr)(char *, int *, float *, float *, int *, float *);
void BLASFUNC(dspr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(qspr)(char *, int *, double *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(sspr)(char *, int *, float *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(dspr)(char *, int *, double *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(qspr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(sspr2)(char *, int *, float *, float *, int *, float *, int *, float *);
void BLASFUNC(dspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(qspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(cspr2)(char *, int *, float *, float *, int *, float *, int *, float *);
void BLASFUNC(zspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(xspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(sspr2)(char *, int *, float *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(dspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(qspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(cspr2)(char *, int *, float *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(zspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(xspr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(cher)(char *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(zher)(char *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(xher)(char *, int *, double *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cher)(char *, int *, float *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zher)(char *, int *, double *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xher)(char *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(chpr)(char *, int *, float *, float *, int *, float *);
void BLASFUNC(zhpr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(xhpr)(char *, int *, double *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(chpr)(char *, int *, float *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(zhpr)(char *, int *, double *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(xhpr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(cher2)(char *, int *, float *, float *, int *, float *, int *, float *, int *);
void BLASFUNC(zher2)(char *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(xher2)(char *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cher2)(char *, int *, float *, float *, int *, float *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zher2)(char *, int *, double *, double *, int *, double *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xher2)(char *, int *, double *, double *, int *, double *, int *, double *, int *);
void BLASFUNC(chpr2)(char *, int *, float *, float *, int *, float *, int *, float *);
void BLASFUNC(zhpr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(xhpr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(chpr2)(char *, int *, float *, float *, int *, float *, int *, float *);
EIGEN_BLAS_API void BLASFUNC(zhpr2)(char *, int *, double *, double *, int *, double *, int *, double *);
EIGEN_BLAS_API void BLASFUNC(xhpr2)(char *, int *, double *, double *, int *, double *, int *, double *);
void BLASFUNC(chemv)(const char *, const int *, const float *, const float *, const int *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(zhemv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
void BLASFUNC(xhemv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(chemv)(const char *, const int *, const float *, const float *, const int *, const float *,
const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zhemv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xhemv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(chpmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
void BLASFUNC(zhpmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(xhpmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(chpmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zhpmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xhpmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(snorm)(char *, int *, int *, float *, int *);
void BLASFUNC(dnorm)(char *, int *, int *, double *, int *);
void BLASFUNC(cnorm)(char *, int *, int *, float *, int *);
void BLASFUNC(znorm)(char *, int *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(snorm)(char *, int *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dnorm)(char *, int *, int *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cnorm)(char *, int *, int *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(znorm)(char *, int *, int *, double *, int *);
void BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
void BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
void BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
void BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
void BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
void BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
EIGEN_BLAS_API void BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, float *, int *,
float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, float *, int *,
float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
void BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *);
void BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
void BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
void BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *);
void BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
void BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
EIGEN_BLAS_API void BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
EIGEN_BLAS_API void BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
void BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *);
void BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
void BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
EIGEN_BLAS_API void BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
/* Level 3 routines */
void BLASFUNC(sgemm)(const char *, const char *, const int *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
void BLASFUNC(dgemm)(const char *, const char *, const int *, const int *, const int *, const double *, const double *,
const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(qgemm)(const char *, const char *, const int *, const int *, const int *, const double *, const double *,
const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cgemm)(const char *, const char *, const int *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zgemm)(const char *, const char *, const int *, const int *, const int *, const double *, const double *,
const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xgemm)(const char *, const char *, const int *, const int *, const int *, const double *, const double *,
const int *, const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(sgemm)(const char *, const char *, const int *, const int *, const int *, const float *,
const float *, const int *, const float *, const int *, const float *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(dgemm)(const char *, const char *, const int *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(qgemm)(const char *, const char *, const int *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(cgemm)(const char *, const char *, const int *, const int *, const int *, const float *,
const float *, const int *, const float *, const int *, const float *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(zgemm)(const char *, const char *, const int *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xgemm)(const char *, const char *, const int *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
void BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
void BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
void BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *, float *, int *, float *, int *,
float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
void BLASFUNC(sge2mm)(char *, char *, char *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
void BLASFUNC(dge2mm)(char *, char *, char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
void BLASFUNC(cge2mm)(char *, char *, char *, int *, int *, float *, float *, int *, float *, int *, float *, float *,
int *);
void BLASFUNC(zge2mm)(char *, char *, char *, int *, int *, double *, double *, int *, double *, int *, double *,
double *, int *);
EIGEN_BLAS_API void BLASFUNC(sge2mm)(char *, char *, char *, int *, int *, float *, float *, int *, float *, int *,
float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(dge2mm)(char *, char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(cge2mm)(char *, char *, char *, int *, int *, float *, float *, int *, float *, int *,
float *, float *, int *);
EIGEN_BLAS_API void BLASFUNC(zge2mm)(char *, char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
void BLASFUNC(strsm)(const char *, const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, float *, const int *);
void BLASFUNC(dtrsm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(qtrsm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(ctrsm)(const char *, const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, float *, const int *);
void BLASFUNC(ztrsm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(xtrsm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(strsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dtrsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qtrsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ctrsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(ztrsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xtrsm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
void BLASFUNC(strmm)(const char *, const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, float *, const int *);
void BLASFUNC(dtrmm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(qtrmm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(ctrmm)(const char *, const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, float *, const int *);
void BLASFUNC(ztrmm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
void BLASFUNC(xtrmm)(const char *, const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(strmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dtrmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qtrmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ctrmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const float *, const float *, const int *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(ztrmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xtrmm)(const char *, const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, double *, const int *);
void BLASFUNC(ssymm)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(dsymm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(qsymm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(csymm)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zsymm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xsymm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssymm)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dsymm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(qsymm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(csymm)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zsymm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xsymm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
void BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *);
void BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
void BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
EIGEN_BLAS_API void BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *, float *, int *, float *,
float *, int *);
EIGEN_BLAS_API void BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
void BLASFUNC(ssyrk)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(dsyrk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
void BLASFUNC(qsyrk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
void BLASFUNC(csyrk)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(zsyrk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
void BLASFUNC(xsyrk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssyrk)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dsyrk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qsyrk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(csyrk)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zsyrk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xsyrk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(ssyr2k)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(dsyr2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(qsyr2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(csyr2k)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zsyr2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xsyr2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(ssyr2k)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(dsyr2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(qsyr2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(csyr2k)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zsyr2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xsyr2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
void BLASFUNC(chemm)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zhemm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xhemm)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(chemm)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zhemm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xhemm)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
void BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *);
void BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
void BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *, double *, double *,
int *);
EIGEN_BLAS_API void BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *, float *, int *, float *,
float *, int *);
EIGEN_BLAS_API void BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
EIGEN_BLAS_API void BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *, double *, int *,
double *, double *, int *);
void BLASFUNC(cherk)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(zherk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
void BLASFUNC(xherk)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(cherk)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zherk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xherk)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cher2k)(const char *, const char *, const int *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zher2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xher2k)(const char *, const char *, const int *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cher2m)(const char *, const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zher2m)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xher2m)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(cher2k)(const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
EIGEN_BLAS_API void BLASFUNC(zher2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xher2k)(const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(cher2m)(const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, const float *, const int *, const float *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(zher2m)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
EIGEN_BLAS_API void BLASFUNC(xher2m)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *,
const int *);
void BLASFUNC(sgemmtr)(const char *, const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
void BLASFUNC(dgemmtr)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(qgemmtr)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cgemmtr)(const char *, const char *, const char *, const int *, const int *, const float *, const float *,
const int *, const float *, const int *, const float *, float *, const int *);
void BLASFUNC(zgemmtr)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
void BLASFUNC(xgemmtr)(const char *, const char *, const char *, const int *, const int *, const double *,
const double *, const int *, const double *, const int *, const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(sgemmtr)(const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, const float *, const int *, const float *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(dgemmtr)(const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, const double *, const int *,
const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(qgemmtr)(const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, const double *, const int *,
const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(cgemmtr)(const char *, const char *, const char *, const int *, const int *, const float *,
const float *, const int *, const float *, const int *, const float *, float *,
const int *);
EIGEN_BLAS_API void BLASFUNC(zgemmtr)(const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, const double *, const int *,
const double *, double *, const int *);
EIGEN_BLAS_API void BLASFUNC(xgemmtr)(const char *, const char *, const char *, const int *, const int *,
const double *, const double *, const int *, const double *, const int *,
const double *, double *, const int *);
#ifdef __cplusplus
}

222
blas/eigen_blas.def Normal file
View File

@ -0,0 +1,222 @@
; Definition file for eigen_blas.dll.
LIBRARY eigen_blas
EXPORTS
; Utilities
lsame_
xerbla_
; Level 1
saxpy_
daxpy_
caxpy_
zaxpy_
; caxpyc_
; zaxpyc_
scopy_
dcopy_
ccopy_
zcopy_
sdot_
sdsdot_
dsdot_
ddot_
cdotc_
zdotc_
cdotu_
zdotu_
cdotcw_
zdotcw_
cdotuw_
zdotuw_
snrm2_
dnrm2_
scnrm2_
dznrm2_
srot_
drot_
csrot_
zdrot_
srotg_
drotg_
crotg_
zrotg_
srotm_
drotm_
srotmg_
drotmg_
sscal_
dscal_
cscal_
zscal_
csscal_
zdscal_
sswap_
dswap_
cswap_
zswap_
sasum_
scasum_
dasum_
dzasum_
; ismax_
; idmax_
; icmax_
; izmax_
isamax_
idamax_
icamax_
izamax_
isamin_
idamin_
icamin_
izamin_
; ismin_
; idmin_
; icmin_
; izmin_
; samax_
; damax_
; scamax_
; dzamax_
; samin_
; damin_
; scamin_
; dzamin_
; smax_
; dmax_
; cmax_
; zmax_
; smin_
; dmin_
; cmin_
; zmin_
; Level 2
sgemv_
dgemv_
cgemv_
zgemv_
sger_
dger_
cgerc_
zgerc_
cgeru_
zgeru_
ssymv_
dsymv_
ssyr_
dsyr_
ssyr2_
dsyr2_
; csyr2_
; zsyr2_
strmv_
dtrmv_
ctrmv_
ztrmv_
strsv_
dtrsv_
ctrsv_
ztrsv_
stpsv_
dtpsv_
ctpsv_
ztpsv_
stpmv_
dtpmv_
ctpmv_
ztpmv_
stbmv_
dtbmv_
ctbmv_
ztbmv_
stbsv_
dtbsv_
ctbsv_
ztbsv_
sspmv_
dspmv_
sspr_
dspr_
; cspr_
; zspr_
sspr2_
dspr2_
; cspr2_
; zspr2_
cher_
zher_
chpr_
zhpr_
cher2_
zher2_
chpr2_
zhpr2_
chemv_
zhemv_
chpmv_
zhpmv_
; snorm_
; dnorm_
; cnorm_
; znorm_
sgbmv_
dgbmv_
cgbmv_
zgbmv_
ssbmv_
dsbmv_
; csbmv_
; zsbmv_
chbmv_
zhbmv_
; Level 3 BLAS
sgemm_
dgemm_
cgemm_
zgemm_
; cgemm3m_
; zgemm3m_
; sge2mm_
; dge2mm_
; cge2mm_
; zge2mm_
ssymm_
dsymm_
csymm_
zsymm_
; csymm3m_
; zsymm3m_
ssyrk_
dsyrk_
csyrk_
zsyrk_
ssyr2k_
dsyr2k_
csyr2k_
zsyr2k_
strmm_
dtrmm_
ctrmm_
ztrmm_
strsm_
dtrsm_
ctrsm_
ztrsm_
chemm_
zhemm_
; chemm3m_
; zhemm3m_
cherk_
zherk_
cher2k_
zher2k_
; cher2m_
; zher2m_
sgemmtr_
dgemmtr_
cgemmtr_
zgemmtr_

View File

@ -1,6 +1,8 @@
#include <stdio.h>
#include "blas.h"
#if (defined __GNUC__) && (!defined __MINGW32__) && (!defined __CYGWIN__)
#define EIGEN_WEAK_LINKING __attribute__((weak))
#else

View File

@ -176,6 +176,8 @@ build:linux:rocm-latest:gcc-10:
EIGEN_CI_CXX_COMPILER: g++-10
EIGEN_CI_BUILD_TARGET: buildtests_gpu
EIGEN_CI_ADDITIONAL_ARGS: -DEIGEN_TEST_HIP=on
cache: {} # Disable cache for ROCm, since it fails whenever the image updates.
######## Arm ###################################################################

View File

@ -31,23 +31,20 @@
build:windows:x86:msvc-14.29:default:
extends: .build:windows
variables:
EIGEN_CI_MSVC_VER: "14.29"
EIGEN_CI_MSVC_ARCH: "x86"
EIGEN_CI_MSVC_ARCH: "x64_x86"
# MSVC 14.29 (VS 2019) 64 bit
build:windows:x86-64:msvc-14.29:default:
extends: .build:windows
variables:
EIGEN_CI_MSVC_VER: "14.29"
build:windows:x86-64:msvc-14.29:avx2:
extends: build:windows:x86-64:msvc-14.29:default
extends: .build:windows
variables:
EIGEN_CI_ADDITIONAL_ARGS: "-DEIGEN_TEST_AVX2=on"
build:windows:x86-64:msvc-14.29:avx512dq:
extends: build:windows:x86-64:msvc-14.29:default
extends: .build:windows
variables:
EIGEN_CI_ADDITIONAL_ARGS: "-DEIGEN_TEST_AVX512DQ=on"
@ -73,5 +70,4 @@ build:windows:x86-64:msvc-14.29:avx512dq:
build:windows:x86-64:cuda-11.4:msvc-14.29:
extends: .build:windows:cuda
variables:
EIGEN_CI_MSVC_VER: "14.29"
EIGEN_CI_BEFORE_SCRIPT: $$env:CUDA_PATH=$$env:CUDA_PATH_V11_4

View File

@ -19,35 +19,29 @@
# MSVC 14.29 (VS 2019) 64 bit
.test:windows:x86-64:msvc-14.29:default:
test:windows:x86-64:msvc-14.29:default:official:
extends: .test:windows
needs: [ build:windows:x86-64:msvc-14.29:default ]
test:windows:x86-64:msvc-14.29:default:official:
extends: .test:windows:x86-64:msvc-14.29:default
variables:
EIGEN_CI_CTEST_LABEL: Official
test:windows:x86-64:msvc-14.29:default:unsupported:
extends: .test:windows:x86-64:msvc-14.29:default
extends: test:windows:x86-64:msvc-14.29:default:official
variables:
EIGEN_CI_CTEST_LABEL: Unsupported
.test:windows:x86-64:msvc-14.29:avx2:
test:windows:x86-64:msvc-14.29:avx2:official:
extends: .test:windows
needs: [ build:windows:x86-64:msvc-14.29:avx2 ]
test:windows:x86-64:msvc-14.29:avx2:official:
extends: .test:windows:x86-64:msvc-14.29:avx2
variables:
EIGEN_CI_CTEST_LABEL: Official
test:windows:x86-64:msvc-14.29:avx2:unsupported:
extends: .test:windows:x86-64:msvc-14.29:avx2
extends: test:windows:x86-64:msvc-14.29:avx2:official
variables:
EIGEN_CI_CTEST_LABEL: Unsupported
.test:windows:x86-64:msvc-14.29:avx512dq:
test:windows:x86-64:msvc-14.29:avx512dq:official:
extends: .test:windows
needs: [ build:windows:x86-64:msvc-14.29:avx512dq ]
tags:
@ -55,14 +49,11 @@ test:windows:x86-64:msvc-14.29:avx2:unsupported:
- windows
- x86-64
- avx512
test:windows:x86-64:msvc-14.29:avx512dq:official:
extends: .test:windows:x86-64:msvc-14.29:avx512dq
variables:
EIGEN_CI_CTEST_LABEL: Official
test:windows:x86-64:msvc-14.29:avx512dq:unsupported:
extends: .test:windows:x86-64:msvc-14.29:avx512dq
extends: test:windows:x86-64:msvc-14.29:avx512dq:official
variables:
EIGEN_CI_CTEST_LABEL: Unsupported

View File

@ -18,9 +18,6 @@ one option, and other parts (or libraries that you use) are compiled with anothe
fail to link or exhibit subtle bugs. Nevertheless, these options can be useful for people who know what they
are doing.
- \b EIGEN2_SUPPORT and \b EIGEN2_SUPPORT_STAGEnn_xxx are disabled starting from the 3.3 release.
Defining one of these will raise a compile-error. If you need to compile Eigen2 code,
<a href="http://eigen.tuxfamily.org/index.php?title=Eigen2">check this site</a>.
- \b EIGEN_DEFAULT_DENSE_INDEX_TYPE - the type for column and row indices in matrices, vectors and array
(DenseBase::Index). Set to \c std::ptrdiff_t by default.
- \b EIGEN_DEFAULT_IO_FORMAT - the IOFormat to use when printing a matrix if no %IOFormat is specified.
@ -44,7 +41,7 @@ are doing.
preferable. Not defined by default.
\warning See the documentation of \c EIGEN_INITIALIZE_MATRICES_BY_ZERO for a discussion on a limitations
of these macros when applied to \c 1x1, \c 1x2, and \c 2x1 fixed-size matrices.
- \b EIGEN_NO_AUTOMATIC_RESIZING - if defined, the matrices (or arrays) on both sides of an assignment
- \b EIGEN_NO_AUTOMATIC_RESIZING - if defined, the matrices (or arrays) on both sides of an assignment
<tt>a = b</tt> have to be of the same size; otherwise, %Eigen automatically resizes \c a so that it is of
the correct size. Not defined by default.
@ -72,8 +69,8 @@ The %Eigen library contains many assertions to guard against programming errors,
run time. However, these assertions do cost time and can thus be turned off.
- \b EIGEN_NO_DEBUG - disables %Eigen's assertions if defined. Not defined by default, unless the
\c NDEBUG macro is defined (this is a standard C++ macro which disables all asserts).
- \b EIGEN_NO_STATIC_ASSERT - if defined, compile-time static assertions are replaced by runtime assertions;
\c NDEBUG macro is defined (this is a standard C++ macro which disables all asserts).
- \b EIGEN_NO_STATIC_ASSERT - if defined, compile-time static assertions are replaced by runtime assertions;
this saves compilation time. Not defined by default.
- \b eigen_assert - macro with one argument that is used inside %Eigen for assertions. By default, it is
basically defined to be \c assert, which aborts the program if the assertion is violated. Redefine this
@ -90,7 +87,7 @@ run time. However, these assertions do cost time and can thus be turned off.
Let us emphasize that \c EIGEN_MAX_*_ALIGN_BYTES define only a desirable upper bound. In practice data is aligned to largest power-of-two common divisor of \c EIGEN_MAX_STATIC_ALIGN_BYTES and the size of the data, such that memory is not wasted.
- \b \c EIGEN_DONT_PARALLELIZE - if defined, this disables multi-threading. This is only relevant if you enabled OpenMP.
See \ref TopicMultiThreading for details.
- \b \c EIGEN_DONT_VECTORIZE - disables explicit vectorization when defined. Not defined by default, unless
- \b \c EIGEN_DONT_VECTORIZE - disables explicit vectorization when defined. Not defined by default, unless
alignment is disabled by %Eigen's platform test or the user defining \c EIGEN_DONT_ALIGN.
- \b \c EIGEN_UNALIGNED_VECTORIZE - disables/enables vectorization with unaligned stores. Default is 1 (enabled).
If set to 0 (disabled), then expression for which the destination cannot be aligned are not vectorized (e.g., unaligned

View File

@ -22,9 +22,11 @@ add_custom_target(lapack)
include_directories(../blas)
set(EigenLapack_SRCS
dsecnd_INT_CPU_TIME.cpp second_INT_CPU_TIME.cpp single.cpp double.cpp complex_single.cpp complex_double.cpp ../blas/xerbla.cpp
dsecnd_INT_CPU_TIME.cpp second_INT_CPU_TIME.cpp single.cpp double.cpp complex_single.cpp complex_double.cpp
)
set(EIGEN_LAPACK_DEF "eigen_lapack_cpp.def")
if(EIGEN_Fortran_COMPILER_WORKS)
set(EigenLapack_SRCS ${EigenLapack_SRCS}
@ -40,6 +42,8 @@ set(EigenLapack_SRCS ${EigenLapack_SRCS}
slamch.f dlamch.f
)
set(EIGEN_LAPACK_DEF "eigen_lapack.def")
option(EIGEN_ENABLE_LAPACK_TESTS OFF "Enable the Lapack unit tests")
if(EIGEN_ENABLE_LAPACK_TESTS)
@ -98,12 +102,16 @@ endif()
set(EIGEN_LAPACK_TARGETS "")
add_library(eigen_lapack_static STATIC ${EigenLapack_SRCS} ${ReferenceLapack_SRCS})
target_link_libraries(eigen_lapack_static eigen_blas_static)
list(APPEND EIGEN_LAPACK_TARGETS eigen_lapack_static)
if (EIGEN_BUILD_SHARED_LIBS)
add_library(eigen_lapack SHARED ${EigenLapack_SRCS})
list(APPEND EIGEN_LAPACK_TARGETS eigen_lapack)
add_library(eigen_lapack SHARED ${EigenLapack_SRCS} ${EIGEN_LAPACK_DEF})
# Build LAPACK but link BLAS.
target_compile_definitions(eigen_lapack PUBLIC "EIGEN_BLAS_LINK_DLL" "EIGEN_LAPACK_BUILD_DLL")
target_link_libraries(eigen_lapack eigen_blas)
set_target_properties(eigen_lapack PROPERTIES CXX_VISIBILITY_PRESET hidden)
list(APPEND EIGEN_LAPACK_TARGETS eigen_lapack)
endif()
foreach(target IN LISTS EIGEN_LAPACK_TARGETS)

View File

@ -11,7 +11,7 @@
#include <Eigen/Cholesky>
// POTRF computes the Cholesky factorization of a real symmetric positive definite matrix A.
EIGEN_LAPACK_FUNC(potrf)(char *uplo, int *n, RealScalar *pa, int *lda, int *info) {
EIGEN_LAPACK_FUNC(potrf)(const char *uplo, int *n, RealScalar *pa, int *lda, int *info) {
*info = 0;
if (UPLO(*uplo) == INVALID)
*info = -1;
@ -38,7 +38,8 @@ EIGEN_LAPACK_FUNC(potrf)(char *uplo, int *n, RealScalar *pa, int *lda, int *info
// POTRS solves a system of linear equations A*X = B with a symmetric
// positive definite matrix A using the Cholesky factorization
// A = U**T*U or A = L*L**T computed by DPOTRF.
EIGEN_LAPACK_FUNC(potrs)(char *uplo, int *n, int *nrhs, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, int *info) {
EIGEN_LAPACK_FUNC(potrs)
(const char *uplo, int *n, int *nrhs, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, int *info) {
*info = 0;
if (UPLO(*uplo) == INVALID)
*info = -1;

View File

@ -15,6 +15,8 @@
#include <ctime>
#endif
#include "lapack.h"
extern "C" {
double dsecnd_();
}

143
lapack/eigen_lapack.def Normal file
View File

@ -0,0 +1,143 @@
; Definition file for eigen_lapack.dll.
LIBRARY eigen_lapack
EXPORTS
; Eigen C/C++ implementations
; Utilities
xerbla_
; Eigenvalues
ssyev_
dsyev_
; LU
sgetrf_
sgetrs_
dgetrf_
dgetrs_
cgetrf_
cgetrs_
zgetrf_
zgetrs_
; QR
spotrf_
spotrs_
dpotrf_
dpotrs_
cpotrf_
cpotrs_
zpotrf_
zpotrs_
; SVD
sgesdd_
sgesvd_
dgesdd_
dgesvd_
cgesdd_
cgesvd_
zgesdd_
zgesvd_
; Time
second_
dsecnd_
; Fortran implementations
clacgv_
zlacgv_
sladiv_
dladiv_
cladiv_
zladiv_
slamch_
dlamch_
slamc3_
dlamc3_
slapy2_
dlapy2_
slapy3_
dlapy3_
slarf_
dlarf_
clarf_
zlarf_
slarfb_
dlarfb_
clarfb_
zlarfb_
slarfg_
dlarfg_
clarfg_
zlarfg_
slarft_
dlarft_
clarft_
zlarft_
ilaclc_
ilaclr_
iladlc_
iladlr_
ilaslc_
ilaslr_
ilazlc_
ilazlr_
; Missing
; csymv_
; zsymv_
; cspmv_
; zspmv_
; csyr_
; zsyr_
; cspr_
; zspr_
; sgemt_
; dgemt_
; cgemt_
; zgemt_
; sgema_
; dgema_
; cgema_
; zgema_
; sgems_
; dgems_
; cgems_
; zgems_
; sgetf2_
; dgetf2_
; cgetf2_
; zgetf2_
; slaswp_
; dlaswp_
; claswp_
; zlaswp_
; sgesv_
; dgesv_
; cgesv_
; zgesv_
; spotf2_
; dpotf2_
; cpotf2_
; zpotf2_
; slauu2_
; dlauu2_
; clauu2_
; zlauu2_
; slauum_
; dlauum_
; clauum_
; zlauum_
; strti2_
; dtrti2_
; ctrti2_
; ztrti2_
; strtri_
; dtrtri_
; ctrtri_
; ztrtri_
; spotri_
; dpotri_
; cpotri_
; zpotri_

143
lapack/eigen_lapack_cpp.def Normal file
View File

@ -0,0 +1,143 @@
; Definition file for eigen_lapack.dll, containing only the C++ implementations.
LIBRARY eigen_lapack
EXPORTS
; Eigen C/C++ implementations
; Utilities
xerbla_
; Eigenvalues
ssyev_
dsyev_
; LU
sgetrf_
sgetrs_
dgetrf_
dgetrs_
cgetrf_
cgetrs_
zgetrf_
zgetrs_
; QR
spotrf_
spotrs_
dpotrf_
dpotrs_
cpotrf_
cpotrs_
zpotrf_
zpotrs_
; SVD
sgesdd_
sgesvd_
dgesdd_
dgesvd_
cgesdd_
cgesvd_
zgesdd_
zgesvd_
; Time
second_
dsecnd_
; Fortran implementations
; clacgv_
; zlacgv_
; sladiv_
; dladiv_
; cladiv_
; zladiv_
; slamch_
; dlamch_
; slamc3_
; dlamc3_
; slapy2_
; dlapy2_
; slapy3_
; dlapy3_
; slarf_
; dlarf_
; clarf_
; zlarf_
; slarfb_
; dlarfb_
; clarfb_
; zlarfb_
; slarfg_
; dlarfg_
; clarfg_
; zlarfg_
; slarft_
; dlarft_
; clarft_
; zlarft_
; ilaclc_
; ilaclr_
; iladlc_
; iladlr_
; ilaslc_
; ilaslr_
; ilazlc_
; ilazlr_
; Missing
; csymv_
; zsymv_
; cspmv_
; zspmv_
; csyr_
; zsyr_
; cspr_
; zspr_
; sgemt_
; dgemt_
; cgemt_
; zgemt_
; sgema_
; dgema_
; cgema_
; zgema_
; sgems_
; dgems_
; cgems_
; zgems_
; sgetf2_
; dgetf2_
; cgetf2_
; zgetf2_
; slaswp_
; dlaswp_
; claswp_
; zlaswp_
; sgesv_
; dgesv_
; cgesv_
; zgesv_
; spotf2_
; dpotf2_
; cpotf2_
; zpotf2_
; slauu2_
; dlauu2_
; clauu2_
; zlauu2_
; slauum_
; dlauum_
; clauum_
; zlauum_
; strti2_
; dtrti2_
; ctrti2_
; ztrti2_
; strtri_
; dtrtri_
; ctrtri_
; ztrtri_
; spotri_
; dpotri_
; cpotri_
; zpotri_

View File

@ -12,7 +12,8 @@
// computes eigen values and vectors of a general N-by-N matrix A
EIGEN_LAPACK_FUNC(syev)
(char* jobz, char* uplo, int* n, Scalar* a, int* lda, Scalar* w, Scalar* /*work*/, int* lwork, int* info) {
(const char* jobz, const char* uplo, int* n, RealScalar* ra, int* lda, RealScalar* rw, RealScalar* /*work*/, int* lwork,
int* info) {
// TODO exploit the work buffer
bool query_size = *lwork == -1;
@ -40,6 +41,9 @@ EIGEN_LAPACK_FUNC(syev)
if (*n == 0) return;
Scalar* a = reinterpret_cast<Scalar*>(ra);
Scalar* w = reinterpret_cast<Scalar*>(rw);
PlainMatrixType mat(*n, *n);
if (UPLO(*uplo) == UP)
mat = matrix(a, *n, *n, *lda).adjoint();

View File

@ -3,131 +3,192 @@
#include "../blas/blas.h"
#if defined(_WIN32)
#if defined(EIGEN_LAPACK_BUILD_DLL)
#define EIGEN_LAPACK_API __declspec(dllexport)
#elif defined(EIGEN_LAPACK_LINK_DLL)
#define EIGEN_LAPACK_API __declspec(dllimport)
#else
#define EIGEN_LAPACK_API
#endif
#elif ((defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)) && defined(EIGEN_LAPACK_BUILD_DLL)
#define EIGEN_LAPACK_API __attribute__((visibility("default")))
#else
#define EIGEN_LAPACK_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
void BLASFUNC(csymv)(const char *, const int *, const float *, const float *, const int *, const float *, const int *,
const float *, float *, const int *);
void BLASFUNC(zsymv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
void BLASFUNC(xsymv)(const char *, const int *, const double *, const double *, const int *, const double *,
const int *, const double *, double *, const int *);
EIGEN_LAPACK_API void BLASFUNC(csymv)(const char *, const int *, const float *, const float *, const int *,
const float *, const int *, const float *, float *, const int *);
EIGEN_LAPACK_API void BLASFUNC(zsymv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
EIGEN_LAPACK_API void BLASFUNC(xsymv)(const char *, const int *, const double *, const double *, const int *,
const double *, const int *, const double *, double *, const int *);
void BLASFUNC(cspmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
void BLASFUNC(zspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(xspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(cspmv)(char *, int *, float *, float *, float *, int *, float *, float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(xspmv)(char *, int *, double *, double *, double *, int *, double *, double *, int *);
void BLASFUNC(csyr)(char *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(zsyr)(char *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(xsyr)(char *, int *, double *, double *, int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(csyr)(char *, int *, float *, float *, int *, float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zsyr)(char *, int *, double *, double *, int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(xsyr)(char *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(cspr)(char *, int *, float *, float *, int *, float *);
void BLASFUNC(zspr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(xspr)(char *, int *, double *, double *, int *, double *);
EIGEN_LAPACK_API void BLASFUNC(cspr)(char *, int *, float *, float *, int *, float *);
EIGEN_LAPACK_API void BLASFUNC(zspr)(char *, int *, double *, double *, int *, double *);
EIGEN_LAPACK_API void BLASFUNC(xspr)(char *, int *, double *, double *, int *, double *);
void BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *, float *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *, float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *, double *, int *);
void BLASFUNC(sgema)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(dgema)(char *, char *, int *, int *, double *, double *, int *, double *, double *, int *, double *,
int *);
void BLASFUNC(cgema)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(zgema)(char *, char *, int *, int *, double *, double *, int *, double *, double *, int *, double *,
int *);
EIGEN_LAPACK_API void BLASFUNC(sgema)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *,
float *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgema)(char *, char *, int *, int *, double *, double *, int *, double *, double *,
int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgema)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *,
float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgema)(char *, char *, int *, int *, double *, double *, int *, double *, double *,
int *, double *, int *);
void BLASFUNC(sgems)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(dgems)(char *, char *, int *, int *, double *, double *, int *, double *, double *, int *, double *,
int *);
void BLASFUNC(cgems)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *, float *, int *);
void BLASFUNC(zgems)(char *, char *, int *, int *, double *, double *, int *, double *, double *, int *, double *,
int *);
EIGEN_LAPACK_API void BLASFUNC(sgems)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *,
float *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgems)(char *, char *, int *, int *, double *, double *, int *, double *, double *,
int *, double *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgems)(char *, char *, int *, int *, float *, float *, int *, float *, float *, int *,
float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgems)(char *, char *, int *, int *, double *, double *, int *, double *, double *,
int *, double *, int *);
void BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *);
void BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *);
void BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *);
void BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *);
void BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *);
void BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *);
void BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *);
void BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *);
void BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *);
void BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *);
void BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *);
void BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);
void BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);
void BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
void BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
void BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double *, int *, int *);
void BLASFUNC(spotf2)(char *, int *, float *, int *, int *);
void BLASFUNC(dpotf2)(char *, int *, double *, int *, int *);
void BLASFUNC(qpotf2)(char *, int *, double *, int *, int *);
void BLASFUNC(cpotf2)(char *, int *, float *, int *, int *);
void BLASFUNC(zpotf2)(char *, int *, double *, int *, int *);
void BLASFUNC(xpotf2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(spotf2)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dpotf2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qpotf2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cpotf2)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zpotf2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xpotf2)(char *, int *, double *, int *, int *);
void BLASFUNC(spotrf)(char *, int *, float *, int *, int *);
void BLASFUNC(dpotrf)(char *, int *, double *, int *, int *);
void BLASFUNC(qpotrf)(char *, int *, double *, int *, int *);
void BLASFUNC(cpotrf)(char *, int *, float *, int *, int *);
void BLASFUNC(zpotrf)(char *, int *, double *, int *, int *);
void BLASFUNC(xpotrf)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qpotrf)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xpotrf)(char *, int *, double *, int *, int *);
void BLASFUNC(slauu2)(char *, int *, float *, int *, int *);
void BLASFUNC(dlauu2)(char *, int *, double *, int *, int *);
void BLASFUNC(qlauu2)(char *, int *, double *, int *, int *);
void BLASFUNC(clauu2)(char *, int *, float *, int *, int *);
void BLASFUNC(zlauu2)(char *, int *, double *, int *, int *);
void BLASFUNC(xlauu2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(slauu2)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dlauu2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qlauu2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(clauu2)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zlauu2)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xlauu2)(char *, int *, double *, int *, int *);
void BLASFUNC(slauum)(char *, int *, float *, int *, int *);
void BLASFUNC(dlauum)(char *, int *, double *, int *, int *);
void BLASFUNC(qlauum)(char *, int *, double *, int *, int *);
void BLASFUNC(clauum)(char *, int *, float *, int *, int *);
void BLASFUNC(zlauum)(char *, int *, double *, int *, int *);
void BLASFUNC(xlauum)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(slauum)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dlauum)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qlauum)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(clauum)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zlauum)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xlauum)(char *, int *, double *, int *, int *);
void BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *);
void BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *);
void BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *);
void BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *);
void BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *);
void BLASFUNC(spotri)(char *, int *, float *, int *, int *);
void BLASFUNC(dpotri)(char *, int *, double *, int *, int *);
void BLASFUNC(qpotri)(char *, int *, double *, int *, int *);
void BLASFUNC(cpotri)(char *, int *, float *, int *, int *);
void BLASFUNC(zpotri)(char *, int *, double *, int *, int *);
void BLASFUNC(xpotri)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(spotri)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dpotri)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(qpotri)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cpotri)(char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zpotri)(char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(xpotri)(char *, int *, double *, int *, int *);
//-----------------------------------------------------------------------------
// Eigen C++ implementations.
//-----------------------------------------------------------------------------
// Cholesky.
EIGEN_LAPACK_API void BLASFUNC(spotrf)(const char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dpotrf)(const char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cpotrf)(const char *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zpotrf)(const char *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(spotrs)(const char *, int *, int *, float *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dpotrs)(const char *, int *, int *, double *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cpotrs)(const char *, int *, int *, float *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zpotrs)(const char *, int *, int *, double *, int *, double *, int *, int *);
// Eigenvalues.
EIGEN_LAPACK_API void BLASFUNC(ssyev)(const char *, const char *, int *, float *, int *, float *, float *, int *,
int *);
EIGEN_LAPACK_API void BLASFUNC(dsyev)(const char *, const char *, int *, double *, int *, double *, double *, int *,
int *);
// LU.
EIGEN_LAPACK_API void BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(sgetrs)(const char *, int *, int *, float *, int *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgetrs)(const char *, int *, int *, double *, int *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgetrs)(const char *, int *, int *, float *, int *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgetrs)(const char *, int *, int *, double *, int *, int *, double *, int *, int *);
// SVD.
EIGEN_LAPACK_API void BLASFUNC(sgesdd)(const char *, int *, int *, float *, int *, float *, float *, int *, float *,
int *, float *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgesdd)(const char *, int *, int *, double *, int *, double *, double *, int *, double *,
int *, double *, int *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgesdd)(const char *, int *, int *, float *, int *, float *, float *, int *, float *,
int *, float *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgesdd)(const char *, int *, int *, double *, int *, double *, double *, int *, double *,
int *, double *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(sgesvd)(const char *, const char *, int *, int *, float *, int *, float *, float *,
int *, float *, int *, float *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(dgesvd)(const char *, const char *, int *, int *, double *, int *, double *, double *,
int *, double *, int *, double *, int *, int *);
EIGEN_LAPACK_API void BLASFUNC(cgesvd)(const char *, const char *, int *, int *, float *, int *, float *, float *,
int *, float *, int *, float *, int *, float *, int *);
EIGEN_LAPACK_API void BLASFUNC(zgesvd)(const char *, const char *, int *, int *, double *, int *, double *, double *,
int *, double *, int *, double *, int *, double *, int *);
// Time.
EIGEN_LAPACK_API float BLASFUNC(second)();
EIGEN_LAPACK_API double BLASFUNC(dsecnd)();
#ifdef __cplusplus
}

View File

@ -40,7 +40,7 @@ EIGEN_LAPACK_FUNC(getrf)(int *m, int *n, RealScalar *pa, int *lda, int *ipiv, in
// A * X = B or A' * X = B
// with a general N-by-N matrix A using the LU factorization computed by GETRF
EIGEN_LAPACK_FUNC(getrs)
(char *trans, int *n, int *nrhs, RealScalar *pa, int *lda, int *ipiv, RealScalar *pb, int *ldb, int *info) {
(const char *trans, int *n, int *nrhs, RealScalar *pa, int *lda, int *ipiv, RealScalar *pb, int *ldb, int *info) {
*info = 0;
if (OP(*trans) == INVALID)
*info = -1;

View File

@ -15,6 +15,8 @@
#include <ctime>
#endif
#include "lapack.h"
extern "C" {
float second_();
}

View File

@ -18,8 +18,9 @@
// computes the singular values/vectors a general M-by-N matrix A using divide-and-conquer
EIGEN_LAPACK_FUNC(gesdd)
(char *jobz, int *m, int *n, Scalar *a, int *lda, RealScalar *s, Scalar *u, int *ldu, Scalar *vt, int *ldvt,
Scalar * /*work*/, int *lwork, EIGEN_LAPACK_ARG_IF_COMPLEX(RealScalar * /*rwork*/) int * /*iwork*/, int *info) {
(const char *jobz, int *m, int *n, RealScalar *ra, int *lda, RealScalar *s, RealScalar *ru, int *ldu, RealScalar *rvt,
int *ldvt, RealScalar * /*work*/, int *lwork, EIGEN_LAPACK_ARG_IF_COMPLEX(RealScalar * /*rwork*/) int * /*iwork*/,
int *info) {
// TODO exploit the work buffer
bool query_size = *lwork == -1;
int diag_size = (std::min)(*m, *n);
@ -53,37 +54,44 @@ EIGEN_LAPACK_FUNC(gesdd)
if (*n == 0 || *m == 0) return;
Scalar *a = reinterpret_cast<Scalar *>(ra);
Scalar *u = reinterpret_cast<Scalar *>(ru);
Scalar *vt = reinterpret_cast<Scalar *>(rvt);
PlainMatrixType mat(*m, *n);
mat = matrix(a, *m, *n, *lda);
int option = *jobz == 'A' ? Eigen::ComputeFullU | Eigen::ComputeFullV
: *jobz == 'S' ? Eigen::ComputeThinU | Eigen::ComputeThinV
: *jobz == 'O' ? Eigen::ComputeThinU | Eigen::ComputeThinV
: 0;
Eigen::BDCSVD<PlainMatrixType> svd(mat, option);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
if (*jobz == 'A') {
Eigen::BDCSVD<PlainMatrixType, Eigen::ComputeFullU | Eigen::ComputeFullV> svd(mat);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
matrix(u, *m, *m, *ldu) = svd.matrixU();
matrix(vt, *n, *n, *ldvt) = svd.matrixV().adjoint();
} else if (*jobz == 'S') {
Eigen::BDCSVD<PlainMatrixType, Eigen::ComputeThinU | Eigen::ComputeThinV> svd(mat);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
matrix(u, *m, diag_size, *ldu) = svd.matrixU();
matrix(vt, diag_size, *n, *ldvt) = svd.matrixV().adjoint();
} else if (*jobz == 'O' && *m >= *n) {
Eigen::BDCSVD<PlainMatrixType, Eigen::ComputeThinU | Eigen::ComputeThinV> svd(mat);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
matrix(a, *m, *n, *lda) = svd.matrixU();
matrix(vt, *n, *n, *ldvt) = svd.matrixV().adjoint();
} else if (*jobz == 'O') {
Eigen::BDCSVD<PlainMatrixType, Eigen::ComputeThinU | Eigen::ComputeThinV> svd(mat);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
matrix(u, *m, *m, *ldu) = svd.matrixU();
matrix(a, diag_size, *n, *lda) = svd.matrixV().adjoint();
} else {
Eigen::BDCSVD<PlainMatrixType> svd(mat);
make_vector(s, diag_size) = svd.singularValues().head(diag_size);
}
}
// computes the singular values/vectors a general M-by-N matrix A using two sided jacobi algorithm
EIGEN_LAPACK_FUNC(gesvd)
(char *jobu, char *jobv, int *m, int *n, Scalar *a, int *lda, RealScalar *s, Scalar *u, int *ldu, Scalar *vt, int *ldvt,
Scalar * /*work*/, int *lwork, EIGEN_LAPACK_ARG_IF_COMPLEX(RealScalar * /*rwork*/) int *info) {
(const char *jobu, const char *jobv, int *m, int *n, RealScalar *ra, int *lda, RealScalar *s, RealScalar *ru, int *ldu,
RealScalar *rvt, int *ldvt, RealScalar * /*work*/, int *lwork,
EIGEN_LAPACK_ARG_IF_COMPLEX(RealScalar * /*rwork*/) int *info) {
// TODO exploit the work buffer
bool query_size = *lwork == -1;
int diag_size = (std::min)(*m, *n);
@ -116,6 +124,10 @@ EIGEN_LAPACK_FUNC(gesvd)
if (*n == 0 || *m == 0) return;
Scalar *a = reinterpret_cast<Scalar *>(ra);
Scalar *u = reinterpret_cast<Scalar *>(ru);
Scalar *vt = reinterpret_cast<Scalar *>(rvt);
PlainMatrixType mat(*m, *n);
mat = matrix(a, *m, *n, *lda);

View File

@ -0,0 +1,128 @@
"""Search for MRs and issues related to a list of commits."""
import argparse
import json
import sys
import subprocess
import re
def find_cherry_pick_source(commit_hash: str):
"""
For a given commit hash, find the original commit it was cherry-picked from.
Args:
commit_hash: The commit hash to inspect.
Returns:
The full hash of the original commit if found, otherwise None.
"""
try:
# Use 'git show' to get the full commit message for the given hash.
# The '-s' flag suppresses the diff output.
# The '--format=%B' flag prints only the raw commit body/message.
commit_message = subprocess.check_output(
["git", "show", "-s", "--format=%B", commit_hash.strip()],
text=True,
stderr=subprocess.PIPE,
).strip()
# This regex looks for the specific line Git adds during a cherry-pick.
# It captures the full 40-character SHA-1 hash.
cherry_pick_pattern = re.compile(
r"\(cherry picked from commit ([a-f0-9]{40})\)"
)
# Search the entire commit message for the pattern.
match = cherry_pick_pattern.search(commit_message)
if match:
# If a match is found, return the captured group (the original commit hash).
return match.group(1)
else:
return None
except subprocess.CalledProcessError as e:
# This error occurs if the git command fails, e.g., for an invalid hash.
print(
f"Error processing commit '{commit_hash.strip()}': {e.stderr.strip()}",
file=sys.stderr,
)
return None
except FileNotFoundError:
# This error occurs if the 'git' command itself isn't found.
print(
"Error: 'git' command not found. Please ensure Git is installed and in your PATH.",
file=sys.stderr,
)
sys.exit(1)
def main():
"""
Main function to read commit hashes from stdin and process them.
"""
parser = argparse.ArgumentParser(
description="A script to download all MRs from GitLab matching specified criteria."
)
parser.add_argument(
"--merge_requests_file",
type=str,
required=True,
help="JSON file containing all the merge request information extracted via the GitLab API.",
)
# E.g. git log --pretty=%H 3e819d83bf52abda16bb53565f6801df40d071f1..3.4.1
parser.add_argument(
"--commits",
required=True,
help="List of commits, '-' for stdin.",
)
args = parser.parse_args()
mrs = []
with open(args.merge_requests_file, "r") as file:
mrs = json.load(file)
mrs_by_commit = {}
if args.commits == "-":
commit_hashes = sys.stdin.readlines()
else:
with open(args.commits, "r") as file:
commit_hashes = file.readlines()
# Arrange commits by SHA.
for mr in mrs:
for key in ["sha", "merge_commit_sha", "squash_commit_sha"]:
sha = mr[key]
if sha:
mrs_by_commit[sha] = mr
# Find the MRs and issues related to each commit.
info = {}
for sha in commit_hashes:
sha = sha.strip()
if not sha:
continue
# If a cherry-pick, extract the original hash.
sha = find_cherry_pick_source(sha) or sha
mr = mrs_by_commit.get(sha)
commit_info = {}
if mr:
commit_info["merge_request"] = mr["iid"]
commit_info["related_issues"] = [
issue["iid"] for issue in mr["related_issues"]
]
commit_info["closes_issues"] = [
issue["iid"] for issue in mr["closes_issues"]
]
info[sha] = commit_info
print(json.dumps(info, indent=2))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,136 @@
"""Helper script to download source archives and upload them to the Eigen GitLab generic package registry."""
import os
import requests
import hashlib
import argparse
import sys
import tempfile
EIGEN_PROJECT_ID = 15462818 # Taken from the gitlab project page.
def calculate_sha256(filepath: str):
"""Calculates the SHA256 checksum of a file."""
sha256_hash = hashlib.sha256()
with open(filepath, "rb") as f:
# Read and update hash in chunks of 4K
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def upload_to_generic_registry(
gitlab_private_token: str, package_name: str, package_version: str, filepath: str
):
"""Uploads a file to the GitLab generic package registry."""
headers = {"PRIVATE-TOKEN": gitlab_private_token}
filename = os.path.basename(filepath)
upload_url = f"https://gitlab.com/api/v4/projects/{EIGEN_PROJECT_ID}/packages/generic/{package_name}/{package_version}/{filename}"
print(f"Uploading {filename} to {upload_url}...")
try:
with open(filepath, "rb") as f:
response = requests.put(upload_url, headers=headers, data=f)
response.raise_for_status()
print(f"Successfully uploaded {filename}.")
return True
except requests.exceptions.RequestException as e:
print(f"Error uploading {filename}: {e}")
if e.response is not None:
print(f"Response content: {e.response.text}")
return False
def main():
"""Main function to download archives and upload them to the registry."""
parser = argparse.ArgumentParser(
description="Download GitLab release archives for Eigen and upload them to the generic package registry."
)
parser.add_argument(
"--gitlab_private_token",
type=str,
help="GitLab private API token. Defaults to the GITLAB_PRIVATE_TOKEN environment variable if set.",
)
parser.add_argument(
"--version",
required=True,
help="Specify a single version (tag name) to process.",
)
parser.add_argument(
"--download-dir", help=f"Directory to store temporary downloads (optional)."
)
args = parser.parse_args()
if not args.gitlab_private_token:
args.gitlab_private_token = os.getenv("GITLAB_PRIVATE_TOKEN")
if not args.gitlab_private_token:
print("Could not determine GITLAB_PRIVATE_TOKEN.", file=sys.stderr)
parser.print_usage()
sys.exit(1)
# Create download directory if it doesn't exist.
cleanup_download_dir = False
if args.download_dir:
if not os.path.exists(args.download_dir):
cleanup_download_dir = True
os.makedirs(args.download_dir)
else:
args.download_dir = tempfile.mkdtemp()
cleanup_download_dir = True
for ext in ["tar.gz", "tar.bz2", "tar", "zip"]:
archive_filename = f"eigen-{args.version}.{ext}"
archive_url = f"https://gitlab.com/libeigen/eigen/-/archive/{args.version}/{archive_filename}"
archive_filepath = os.path.join(args.download_dir, archive_filename)
# Download the archive
print(f"Downloading {archive_url}...")
try:
response = requests.get(archive_url, stream=True)
response.raise_for_status()
with open(archive_filepath, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Downloaded to {archive_filepath}")
except requests.exceptions.RequestException as e:
print(f"Error downloading {archive_url}: {e}. Skipping.")
continue
# Calculate SHA256 sum
sha256_sum = calculate_sha256(archive_filepath)
print(f"SHA256 sum: {sha256_sum}")
# Create SHA256 sum file
sha_filename = f"{archive_filename}.sha256"
sha_filepath = os.path.join(args.download_dir, sha_filename)
with open(sha_filepath, "w") as f:
f.write(f"{sha256_sum} {archive_filename}\n")
print(f"Created SHA256 file: {sha_filepath}")
# Upload archive to generic registry
if not upload_to_generic_registry(
args.gitlab_private_token, "eigen", args.version, archive_filepath
):
# If upload fails, clean up and move to the next release
os.remove(archive_filepath)
os.remove(sha_filepath)
continue
# Upload SHA256 sum file to generic registry
upload_to_generic_registry(
args.gitlab_private_token, "eigen", args.version, sha_filepath
)
# Clean up downloaded files
print("Cleaning up local files...")
os.remove(archive_filepath)
os.remove(sha_filepath)
# Clean up the download directory if it's empty
if cleanup_download_dir and not os.listdir(args.download_dir):
os.rmdir(args.download_dir)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,174 @@
"""Downloads all issues from GitLab matching specified criteria."""
import argparse
import datetime
import json
import os
import requests
import sys
EIGEN_PROJECT_ID = 15462818 # Taken from the gitlab project page.
def date(date_string: str):
"""Convert a date YY-MM-DD string to a datetime object."""
try:
return datetime.strptime(date_string, "%Y-%m-%d")
except ValueError:
msg = f"Not a valid date: '{date_string}'. Expected format is YYYY-MM-DD."
raise argparse.ArgumentTypeError(msg)
def _get_api_query(
gitlab_private_token: str, url: str, params: dict[str, str] | None = None
):
next_page = "1"
if not params:
params = dict()
params["per_page"] = "100"
headers = {"PRIVATE-TOKEN": gitlab_private_token}
out = []
while next_page:
params["page"] = next_page
try:
resp = requests.head(url=url, params=params, headers=headers)
if resp.status_code != 200:
print("Request failed: ", resp, file=sys.stderr)
break
next_next_page = resp.headers["x-next-page"]
resp = requests.get(url=url, params=params, headers=headers)
if resp.status_code != 200:
# Try again.
continue
out.extend(resp.json())
# Advance at the end, in case an exception occurs above so we can retry
next_page = next_next_page
except:
# Keep same next_page
continue
return out
def get_issues(
gitlab_private_token: str,
author_username: str | None = None,
state: str | None = None,
created_before: datetime.datetime | None = None,
created_after: datetime.datetime | None = None,
updated_after: datetime.datetime | None = None,
updated_before: datetime.datetime | None = None,
):
"""Return list of merge requests.
Args:
gitlab_token: GitLab API token.
author_username: issue author username.
state: issue state (opened, closed).
created_after: datetime start of period.
created_before: datetime end of period.
updated_after: datetime start of period.
updated_before: datetime end of period.
Returns:
List of merge requests.
"""
url = f"https://gitlab.com/api/v4/projects/{str(EIGEN_PROJECT_ID)}/issues"
params = dict()
if author_username:
params["author_username"] = author_username
if state:
params["state"] = state
if created_before:
params["created_before"] = created_before.isoformat()
if created_after:
params["created_after"] = created_after.isoformat()
if updated_before:
params["updated_before"] = updated_before.isoformat()
if updated_after:
params["updated_after"] = updated_after.isoformat()
params["order_by"] = "created_at"
params["sort"] = "asc"
issues = _get_api_query(gitlab_private_token, url, params)
for issue in issues:
if int(issue["merge_requests_count"]) > 0:
issue_iid = issue["iid"]
issue["related_merge_requests"] = _get_api_query(
gitlab_private_token, f"{url}/{issue_iid}/related_merge_requests"
)
issue["closed_by_merge_requests"] = _get_api_query(
gitlab_private_token, f"{url}/{issue_iid}/closed_by"
)
return issues
def main(_):
parser = argparse.ArgumentParser(
description="A script to download all issues from GitLab matching specified criteria."
)
parser.add_argument(
"--gitlab_private_token",
type=str,
help="GitLab private API token. Defaults to the GITLAB_PRIVATE_TOKEN environment variable if set.",
)
parser.add_argument("--author", type=str, help="The name of the author.")
parser.add_argument(
"--state",
type=str,
choices=["opened", "closed"],
help="The state of the issue.",
)
parser.add_argument(
"--created_before",
type=date,
help="The created-before date in YYYY-MM-DD format.",
)
parser.add_argument(
"--created_after",
type=date,
help="The created-after date in YYYY-MM-DD format.",
)
parser.add_argument(
"--updated_before",
type=date,
help="The updated-before date in YYYY-MM-DD format.",
)
parser.add_argument(
"--updated_after",
type=date,
help="The updated-after date in YYYY-MM-DD format.",
)
args = parser.parse_args()
if not args.gitlab_private_token:
args.gitlab_private_token = os.getenv("GITLAB_PRIVATE_TOKEN")
if not args.gitlab_private_token:
print("Could not determine GITLAB_PRIVATE_TOKEN.", file=sys.stderr)
parser.print_usage()
sys.exit(1)
# Parse the arguments from the command line
issues = get_issues(
gitlab_private_token=args.gitlab_private_token,
author_username=args.author,
state=args.state,
created_before=args.created_before,
created_after=args.created_after,
updated_before=args.updated_before,
updated_after=args.updated_after,
)
issue_str = json.dumps(issues, indent=2)
print(issue_str)
if __name__ == "__main__":
main(sys.argv)

View File

@ -0,0 +1,122 @@
"""Adds a label to a GitLab merge requests or issues."""
import os
import sys
import argparse
import requests
EIGEN_PROJECT_ID = 15462818 # Taken from the gitlab project page.
def add_label_to_mr(private_token: str, mr_iid: int, label: str):
"""
Adds a label to a specific merge request in a GitLab project.
Args:
private_token: The user's private GitLab API token.
mr_iid: The internal ID (IID) of the merge request.
label: The label to add.
"""
api_url = (
f"https://gitlab.com/api/v4/projects/{EIGEN_PROJECT_ID}/merge_requests/{mr_iid}"
)
headers = {"PRIVATE-TOKEN": private_token}
# Using 'add_labels' ensures we don't overwrite existing labels.
payload = {"add_labels": label}
try:
response = requests.put(api_url, headers=headers, json=payload)
response.raise_for_status() # Raises an HTTPError for bad responses (4xx or 5xx)
print(f"✅ Successfully added label '{label}' to Merge Request !{mr_iid}.")
except requests.exceptions.RequestException as e:
print(f"❌ Error updating Merge Request !{mr_iid}: {e}", file=sys.stderr)
if hasattr(e, "response") and e.response is not None:
print(f" Response: {e.response.text}", file=sys.stderr)
def add_label_to_issue(private_token: str, issue_iid: int, label: str):
"""
Adds a label to a specific issue in a GitLab project.
Args:
private_token: The user's private GitLab API token.
issue_iid: The internal ID (IID) of the issue.
label: The label to add.
"""
api_url = (
f"https://gitlab.com/api/v4/projects/{EIGEN_PROJECT_ID}/issues/{issue_iid}"
)
headers = {"PRIVATE-TOKEN": private_token}
payload = {"add_labels": label}
try:
response = requests.put(api_url, headers=headers, json=payload)
response.raise_for_status()
print(f"✅ Successfully added label '{label}' to Issue #{issue_iid}.")
except requests.exceptions.RequestException as e:
print(f"❌ Error updating Issue #{issue_iid}: {e}", file=sys.stderr)
if hasattr(e, "response") and e.response is not None:
print(f" Response: {e.response.text}", file=sys.stderr)
def main():
"""
Main function to parse arguments and trigger the labelling process.
"""
parser = argparse.ArgumentParser(
description="Add a label to GitLab merge requests and issues.",
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument("label", help="The label to add.")
parser.add_argument(
"--mrs",
nargs="+",
type=int,
help="A space-separated list of Merge Request IIDs.",
)
parser.add_argument(
"--issues", nargs="+", type=int, help="A space-separated list of Issue IIDs."
)
parser.add_argument(
"--gitlab_private_token",
help="Your GitLab private access token. \n(Best practice is to use the GITLAB_PRIVATE_TOKEN environment variable instead.)",
)
args = parser.parse_args()
# Prefer environment variable for the token for better security.
gitlab_private_token = args.gitlab_private_token or os.environ.get(
"GITLAB_PRIVATE_TOKEN"
)
if not gitlab_private_token:
print("Error: GitLab private token not found.", file=sys.stderr)
print(
"Please provide it using the --token argument or by setting the GITLAB_PRIVATE_TOKEN environment variable.",
file=sys.stderr,
)
sys.exit(1)
if not args.mrs and not args.issues:
print(
"Error: You must provide at least one merge request (--mrs) or issue (--issues) ID.",
file=sys.stderr,
)
sys.exit(1)
print("-" * 30)
if args.mrs:
print(f"Processing {len(args.mrs)} merge request(s)...")
for mr_iid in args.mrs:
add_label_to_mr(gitlab_private_token, mr_iid, args.label)
if args.issues:
print(f"\nProcessing {len(args.issues)} issue(s)...")
for issue_iid in args.issues:
add_label_to_issue(gitlab_private_token, issue_iid, args.label)
print("-" * 30)
print("Script finished.")
if __name__ == "__main__":
main()

200
scripts/gitlab_api_mrs.py Normal file
View File

@ -0,0 +1,200 @@
"""Downloads all MRs from GitLab matching specified criteria."""
import argparse
import datetime
import json
import os
import requests
import sys
EIGEN_PROJECT_ID = 15462818 # Taken from the gitlab project page.
def date(date_string: str):
"""Convert a date YY-MM-DD string to a datetime object."""
try:
return datetime.strptime(date_string, "%Y-%m-%d")
except ValueError:
msg = f"Not a valid date: '{date_string}'. Expected format is YYYY-MM-DD."
raise argparse.ArgumentTypeError(msg)
def _get_api_query(
gitlab_private_token: str, url: str, params: dict[str, str] | None = None
):
next_page = "1"
if not params:
params = dict()
params["per_page"] = "100"
headers = {"PRIVATE-TOKEN": gitlab_private_token}
out = []
while next_page:
params["page"] = next_page
try:
resp = requests.head(url=url, params=params, headers=headers)
if resp.status_code != 200:
print("Request failed: ", resp, file=sys.stderr)
break
next_next_page = resp.headers["x-next-page"]
resp = requests.get(url=url, params=params, headers=headers)
if resp.status_code != 200:
# Try again.
continue
out.extend(resp.json())
# Advance at the end, in case an exception occurs above so we can retry
next_page = next_next_page
except:
# Keep same next_page
continue
return out
def get_merge_requests(
gitlab_private_token: str,
author_username: str | None = None,
state: str | None = None,
created_before: datetime.datetime | None = None,
created_after: datetime.datetime | None = None,
updated_after: datetime.datetime | None = None,
updated_before: datetime.datetime | None = None,
related_issues: bool = False,
closes_issues: bool = False,
):
"""Return list of merge requests.
Args:
gitlab_token: GitLab API token.
author_username: MR author username.
state: MR state (merged, opened, closed, locked).
created_after: datetime start of period.
created_before: datetime end of period.
updated_after: datetime start of period.
updated_before: datetime end of period.
Returns:
List of merge requests.
"""
url = (
"https://gitlab.com/api/v4/projects/"
+ str(EIGEN_PROJECT_ID)
+ "/merge_requests"
)
params = dict()
if author_username:
params["author_username"] = author_username
if state:
params["state"] = state
if created_before:
params["created_before"] = created_before.isoformat()
if created_after:
params["created_after"] = created_after.isoformat()
if updated_before:
params["updated_before"] = updated_before.isoformat()
if updated_after:
params["updated_after"] = updated_after.isoformat()
params["order_by"] = "created_at"
params["sort"] = "asc"
next_page = "1"
params["per_page"] = "100"
headers = {"PRIVATE-TOKEN": gitlab_private_token}
mrs = _get_api_query(gitlab_private_token, url, params)
if related_issues:
for mr in mrs:
mr["related_issues"] = _get_api_query(
gitlab_private_token, f"{url}/{mr['iid']}/related_issues"
)
if closes_issues:
for mr in mrs:
mr["closes_issues"] = _get_api_query(
gitlab_private_token, f"{url}/{mr['iid']}/closes_issues"
)
return mrs
def main(_):
parser = argparse.ArgumentParser(
description="A script to download all MRs from GitLab matching specified criteria."
)
parser.add_argument(
"--gitlab_private_token",
type=str,
help="GitLab private API token. Defaults to the GITLAB_PRIVATE_TOKEN environment variable if set.",
)
parser.add_argument("--author", type=str, help="The name of the author.")
parser.add_argument(
"--state",
type=str,
choices=["merged", "opened", "closed", "locked"],
help="The state of the MR.",
)
parser.add_argument(
"--created_before",
type=date,
help="The created-before date in YYYY-MM-DD format.",
)
parser.add_argument(
"--created_after",
type=date,
help="The created-after date in YYYY-MM-DD format.",
)
parser.add_argument(
"--updated_before",
type=date,
help="The updated-before date in YYYY-MM-DD format.",
)
parser.add_argument(
"--updated_after",
type=date,
help="The updated-after date in YYYY-MM-DD format.",
)
parser.add_argument(
"--related_issues", action="store_true", help="Query for related issues."
)
parser.add_argument(
"--closes_issues",
action="store_true",
help="Query for issues closed by the MR.",
)
args = parser.parse_args()
if not args.gitlab_private_token:
args.gitlab_private_token = os.getenv("GITLAB_PRIVATE_TOKEN")
if not args.gitlab_private_token:
print("Could not determine GITLAB_PRIVATE_TOKEN.", file=sys.stderr)
parser.print_usage()
sys.exit(1)
# Parse the arguments from the command line
mrs = get_merge_requests(
gitlab_private_token=args.gitlab_private_token,
author_username=args.author,
state=args.state,
created_before=args.created_before,
created_after=args.created_after,
updated_before=args.updated_before,
updated_after=args.updated_after,
related_issues=args.related_issues,
closes_issues=args.closes_issues,
)
mr_str = json.dumps(mrs, indent=2)
print(mr_str)
if __name__ == "__main__":
main(sys.argv)

View File

@ -1,9 +1,6 @@
# Powershell script to set up MSVC environment.
param ($EIGEN_CI_MSVC_ARCH, $EIGEN_CI_MSVC_VER)
Set-PSDebug -Trace 1
function Get-ScriptDirectory { Split-Path $MyInvocation.ScriptName }
# Set defaults if not already set.

View File

@ -257,6 +257,7 @@ ei_add_test(eigensolver_selfadjoint)
ei_add_test(eigensolver_generic)
ei_add_test(eigensolver_complex)
ei_add_test(real_qz)
ei_add_test(complex_qz)
ei_add_test(eigensolver_generalized_real)
ei_add_test(jacobi)
ei_add_test(jacobisvd)

86
test/complex_qz.cpp Normal file
View File

@ -0,0 +1,86 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 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/.
#define EIGEN_RUNTIME_NO_MALLOC
#include "main.h"
#include <Eigen/Eigenvalues>
/* this test covers the following files:
ComplexQZ.h
*/
template <typename MatrixType>
void generate_random_matrix_pair(const Index dim, MatrixType& A, MatrixType& B) {
A.resize(dim, dim);
B.resize(dim, dim);
A.setRandom();
B.setRandom();
// Set each row of B with a probability of 10% to 0
for (int i = 0; i < dim; i++) {
if (internal::random<int>(0, 10) == 0) B.row(i).setZero();
}
}
template <typename MatrixType>
void complex_qz(const MatrixType& A, const MatrixType& B) {
using std::abs;
const Index dim = A.rows();
ComplexQZ<MatrixType> qz(A, B);
VERIFY_IS_EQUAL(qz.info(), Success);
auto T = qz.matrixT(), S = qz.matrixS();
bool is_all_zero_T = true, is_all_zero_S = true;
using RealScalar = typename MatrixType::RealScalar;
RealScalar tol = dim * 10 * NumTraits<RealScalar>::epsilon();
for (Index j = 0; j < dim; j++) {
for (Index i = j + 1; i < dim; i++) {
if (std::abs(T(i, j)) > tol) {
std::cerr << std::abs(T(i, j)) << std::endl;
is_all_zero_T = false;
}
if (std::abs(S(i, j)) > tol) {
std::cerr << std::abs(S(i, j)) << std::endl;
is_all_zero_S = false;
}
}
}
VERIFY_IS_EQUAL(is_all_zero_T, true);
VERIFY_IS_EQUAL(is_all_zero_S, true);
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixS() * qz.matrixZ(), A);
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixT() * qz.matrixZ(), B);
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixQ().adjoint(), MatrixType::Identity(dim, dim));
VERIFY_IS_APPROX(qz.matrixZ() * qz.matrixZ().adjoint(), MatrixType::Identity(dim, dim));
}
EIGEN_DECLARE_TEST(complex_qz) {
// const Index dim1 = 15;
// const Index dim2 = 80;
for (int i = 0; i < g_repeat; i++) {
// Check for very small, fixed-sized double- and float complex matrices
Eigen::Matrix2cd A_2x2, B_2x2;
A_2x2.setRandom();
B_2x2.setRandom();
B_2x2.row(1).setZero();
Eigen::Matrix3cf A_3x3, B_3x3;
A_3x3.setRandom();
B_3x3.setRandom();
B_3x3.col(i % 3).setRandom();
// Test for small float complex matrices
Eigen::MatrixXcf A_float, B_float;
const Index dim1 = internal::random<Index>(15, 80), dim2 = internal::random<Index>(15, 80);
generate_random_matrix_pair(dim1, A_float, B_float);
// Test for a bit larger double complex matrices
Eigen::MatrixXcd A_double, B_double;
generate_random_matrix_pair(dim2, A_double, B_double);
CALL_SUBTEST_1(complex_qz(A_2x2, B_2x2));
CALL_SUBTEST_2(complex_qz(A_3x3, B_3x3));
CALL_SUBTEST_3(complex_qz(A_float, B_float));
CALL_SUBTEST_4(complex_qz(A_double, B_double));
}
}

View File

@ -126,12 +126,12 @@ void homogeneous(void) {
}
{
const Eigen::PermutationMatrix<Size> P{Eigen::Vector<int, Size>::EqualSpaced(0, 1)};
const auto right = Eigen::Vector<Scalar, Size - 1>::Random().eval().homogeneous();
const auto left = Eigen::RowVector<Scalar, Size - 1>::Random().eval().homogeneous();
PermutationMatrix<Size> P{Vector<int, Size>::EqualSpaced(0, 1).reverse()};
auto right = Vector<Scalar, Size - 1>::Random().eval().nestByValue().homogeneous();
auto left = RowVector<Scalar, Size - 1>::Random().eval().nestByValue().homogeneous();
VERIFY_IS_APPROX(P * right, P * right.eval());
VERIFY_IS_APPROX(left * P, left.eval() * P);
VERIFY_IS_APPROX(P * right, right.reverse());
VERIFY_IS_APPROX(left * P, left.reverse());
}
}

View File

@ -94,6 +94,19 @@ void jacobisvd_verify_inputs(const MatrixType& input = MatrixType()) {
(int)ColPivHouseholderQRPreconditioner));
}
template <typename MatrixType>
void svd_triangular_matrix(const MatrixType& input = MatrixType()) {
MatrixType matrix(input.rows(), input.cols());
svd_fill_random(matrix);
// Make sure that we only consider the 'Lower' part of the matrix.
MatrixType matrix_self_adj = matrix.template selfadjointView<Lower>().toDenseMatrix();
JacobiSVD<MatrixType, ComputeFullV> svd_triangular(matrix.template selfadjointView<Lower>());
JacobiSVD<MatrixType, ComputeFullV> svd_full(matrix_self_adj);
VERIFY_IS_APPROX(svd_triangular.singularValues(), svd_full.singularValues());
}
namespace Foo {
// older compiler require a default constructor for Bar
// cf: https://stackoverflow.com/questions/7411515/
@ -211,5 +224,10 @@ EIGEN_DECLARE_TEST(jacobisvd) {
CALL_SUBTEST_55(svd_underoverflow<void>());
// Check that the TriangularBase constructor works
CALL_SUBTEST_56((svd_triangular_matrix<Matrix3d>()));
CALL_SUBTEST_57((svd_triangular_matrix<Matrix4f>()));
CALL_SUBTEST_58((svd_triangular_matrix<Matrix<double, 10, 10>>()));
msvc_workaround();
}

View File

@ -352,7 +352,7 @@ void test_cref_move_ctor(const DenseBase<Derived> &expr) {
const double *data1 = cref1.data(), *obj_data1 = static_cast<CRefDerived &>(cref1).m_object.data();
VERIFY(test_is_equal(data1, obj_data1, owns_data));
CRef cref2(std::move(cref1));
VERIFY_IS_EQUAL(data1, cref1.data());
VERIFY_IS_EQUAL(std::uintptr_t(data1), std::uintptr_t(cref1.data()));
const double *data2 = cref2.data(), *obj_data2 = static_cast<CRefDerived &>(cref2).m_object.data();
VERIFY(test_is_equal(data1, data2, MatrixType::MaxSizeAtCompileTime == Dynamic || !owns_data));
VERIFY(test_is_equal(data1, obj_data2, MatrixType::MaxSizeAtCompileTime == Dynamic && owns_data));