Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

eigency

Package Overview
Dependencies
Maintainers
3
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eigency - npm Package Compare versions

Comparing version
3.4.0.5
to
3.4.0.6
+4
.gitmodules
[submodule "eigen"]
path = eigency/eigen
url = https://gitlab.com/libeigen/eigen.git
shallow = true
Metadata-Version: 2.4
Name: eigency
Version: 3.4.0.6
Summary: Cython interface between the numpy arrays and the Matrix/Array classes of the Eigen C++ library
Author-email: Wouter Boomsma <wb@di.ku.dk>, Felipe Bordeu <felipebordeu@gmail.com>
Maintainer-email: Felipe Bordeu <felipebordeu@gmail.com>, Wouter Boomsma <wb@di.ku.dk>
License-Expression: LicenseRef-Wouter-Boomsma-1.0
Project-URL: Homepage, https://github.com/eigency-org/eigency
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: C++
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23.5
Dynamic: license-file
# Eigency
[![PyPI version](https://badge.fury.io/py/eigency.svg)](https://badge.fury.io/py/eigency)
[![PEP 517](https://github.com/eigency-org/eigency/actions/workflows/build.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/build.yml)
[![pip wheel](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml)
[![setup.py](https://github.com/eigency-org/eigency/actions/workflows/setup.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/setup.yml)
[![pre-commit](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml)
Eigency is a Cython interface between Numpy arrays and Matrix/Array
objects from the Eigen C++ library. It is intended to simplify the
process of writing C++ extensions using the Eigen library. Eigency is
designed to reuse the underlying storage of the arrays when passing
data back and forth, and will thus avoid making unnecessary copies
whenever possible. Only in cases where copies are explicitly requested
by your C++ code will they be made.
## Versioning
Eigency uses a 4-number version (`N.N.N.N`) where the first 3 parts correspond to the embedded Eigen library version.
The last part is a revision number of Eigency itself.
## Installing
Eigency is packaged as a source distribution (`sdist`) and available on PyPi.
It can be easily installed using `pip`:
```bash
python -m pip install eigency
```
**Requirement**: `pip >= 18.0`
If your `pip` is too old, then upgrade it using:
```bash
python -m pip install --upgrade pip
```
## Contributing
For instructions on building and/or packaging Eigency from source,
see the contributing guide [here](https://github.com/eigency-org/eigency/blob/master/CONTRIBUTING.md).
## Usage
Below is a description of a range of common usage scenarios. A full working
example of both setup and these different use cases is available in the
`test` directory distributed with the this package.
### Setup
To import eigency functionality, add the following to your `.pyx` file:
```
from eigency.core cimport *
```
In addition, in the `setup.py` file, the include directories must be
set up to include the eigency includes. This can be done by calling
the `get_includes` function in the `eigency` module:
```
import eigency
...
extensions = [
Extension("module-dir-name/module-name", ["module-dir-name/module-name.pyx"],
include_dirs = [".", "module-dir-name"] + eigency.get_includes()
),
]
```
Eigency includes a version of the Eigen library, and the `get_includes` function will include the path to this directory. If you
have your own version of Eigen, just set the `include_eigen` option to False, and add your own path instead:
```
include_dirs = [".", "module-dir-name", 'path-to-own-eigen'] + eigency.get_includes(include_eigen=False)
```
### From Numpy to Eigen
Assume we are writing a Cython interface to the following C++ function:
```c++
void function_w_mat_arg(const Eigen::Map<Eigen::MatrixXd> &mat) {
std::cout << mat << "\n";
}
```
Note that we use `Eigen::Map` to ensure that we can reuse the storage
of the numpy array, thus avoiding making a copy. Assuming the C++ code
is in a file called `functions.h`, the corresponding `.pyx` entry could look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
The last line contains the actual conversion. `Map` is an Eigency
type that derives from the real Eigen map, and will take care of
the conversion from the numpy array to the corresponding Eigen type.
We can now call the C++ function directly from Python:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1.1, 2.2], [3.3, 4.4]])
>>> eigency_tests.function_w_mat_arg(x)
1.1 3.3
2.2 4.4
```
(if you are wondering about why the matrix is transposed, please
see the Storage layout section below).
## Types matter
The basic idea behind eigency is to share the underlying representation of a
numpy array between Python and C++. This means that somewhere in the process,
we need to make explicit which numerical types we are dealing with. In the
function above, we specify that we expect an Eigen MatrixXd, which means
that the numpy array must also contain double (i.e. float64) values. If we instead provide
a numpy array of ints, we will get strange results.
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
4.94066e-324 1.4822e-323
9.88131e-324 1.97626e-323
```
This is because we are explicitly asking C++ to interpret out python integer
values as floats.
To avoid this type of error, you can force your cython function to
accept only numpy arrays of a specific type:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
(Note that when using this technique to select the type, you also need to specify
the dimensions of the array (this will default to 1)). Using this new definition,
users will get an error when passing arrays of the wrong type:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "eigency_tests/eigency_tests.pyx", line 87, in eigency_tests.eigency_tests.function_w_mat_arg
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long'
```
Since it avoids many surprises, it is strongly recommended to use this technique
to specify the full types of numpy arrays in your cython code whenever
possible.
### Writing Eigen Map types in Cython
Since Cython does not support nested fused types, you cannot write types like `Map[Matrix[double, 2, 2]]`. In most cases, you won't need to, since you can just use Eigens convenience typedefs, such as `Map[VectorXd]`. If you need the additional flexibility of the full specification, you can use the `FlattenedMap` type, where all type arguments can be specified at top level, for instance `FlattenedMap[Matrix, double, _2, _3]` or `FlattenedMap[Matrix, double, _2, Dynamic]`. Note that dimensions must be prefixed with an underscore.
Using full specifications of the Eigen types, the previous example would look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg" (FlattenedMap[Matrix, double, Dynamic, Dynamic] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(FlattenedMap[Matrix, double, Dynamic, Dynamic](array))
```
`FlattenedType` takes four template parameters: arraytype, scalartype,
rows and cols. Eigen supports a few other template arguments for
setting the storage layout and Map strides. Since cython does not
support default template arguments for fused types, we have instead
defined separate types for this purpose. These are called
`FlattenedMapWithOrder` and `FlattenedMapWithStride` with five and eight
template arguments, respectively. For details on their use, see the section
about storage layout below.
### From Numpy to Eigen (insisting on a copy)
Eigency will not complain if the C++ function you interface with does
not take a Eigen Map object, but instead a regular Eigen Matrix or
Array. However, in such cases, a copy will be made. Actually, the
procedure is exactly the same as above. In the `.pyx` file, you still
define everything exactly the same way as for the Map case described above.
For instance, given the following C++ function:
```c++
void function_w_vec_arg_no_map(const Eigen::VectorXd &vec);
```
The Cython definitions would still look like this:
```
cdef extern from "functions.h":
cdef void _function_w_vec_arg_no_map "function_w_vec_arg_no_map"(Map[VectorXd] &)
# This will be exposed to Python
def function_w_vec_arg_no_map(np.ndarray[np.float64_t] array):
return _function_w_vec_arg_no_map(Map[VectorXd](array))
```
Cython will not mind the fact that the argument type in the extern
declaration (a Map type) differs from the actual one in the `.h` file,
as long as one can be assigned to the other. Since Map objects can be
assigned to their corresponding Matrix/Array types this works
seemlessly. But keep in mind that this assignment will make a copy of
the underlying data.
### Eigen to Numpy
C++ functions returning a reference to an Eigen Matrix/Array can also
be transferred to numpy arrays without copying their content. Assume
we have a class with a single getter function that returns an Eigen
matrix member:
```c++
class MyClass {
public:
MyClass():
matrix(Eigen::Matrix3d::Constant(3.)) {
}
Eigen::MatrixXd &get_matrix() {
return this->matrix;
}
private:
Eigen::Matrix3d matrix;
};
```
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
_MyClass "MyClass"() except +
Matrix3d &get_matrix()
```
And the corresponding Python wrapper:
```python
cdef class MyClass:
cdef _MyClass *thisptr;
def __cinit__(self):
self.thisptr = new _MyClass()
def __dealloc__(self):
del self.thisptr
def get_matrix(self):
return ndarray(self.thisptr.get_matrix())
```
This last line contains the actual conversion. Again, eigency has its
own version of `ndarray`, that will take care of the conversion for
you.
Due to limitations in Cython, Eigency cannot deal with full
Matrix/Array template specifications as return types
(e.g. `Matrix[double, 4, 2]`). However, as a workaround, you can use
`PlainObjectBase` as a return type in such cases (or in all cases if
you prefer):
```
PlainObjectBase &get_matrix()
```
### Overriding default behavior
The `ndarray` conversion type specifier will attempt do guess whether you want a copy
or a view, depending on the return type. Most of the time, this is
probably what you want. However, there might be cases where you want
to override this behavior. For instance, functions returning const
references will result in a copy of the array, since the const-ness
cannot be enforced in Python. However, you can always override the
default behavior by using the `ndarray_copy` or `ndarray_view`
functions.
Expanding the `MyClass` example from before:
```c++
class MyClass {
public:
...
const Eigen::MatrixXd &get_const_matrix() {
return this->matrix;
}
...
};
```
With the corresponding cython interface specification
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
...
const Matrix3d &get_const_matrix()
```
The following would return a copy
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray(self.thisptr.get_const_matrix())
```
while the following would force it to return a view
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray_view(self.thisptr.get_const_matrix())
```
### Eigen to Numpy (non-reference return values)
Functions returning an Eigen object (not a reference), are specified
in a similar way. For instance, given the following C++ function:
```c++
Eigen::Matrix3d function_w_mat_retval();
```
The Cython code could be written as:
```
cdef extern from "functions.h":
cdef Matrix3d _function_w_mat_retval "function_w_mat_retval" ()
# This will be exposed to Python
def function_w_mat_retval():
return ndarray_copy(_function_w_mat_retval())
```
As mentioned above, you can replace `Matrix3d` (or any other Eigen return type) with
`PlainObjectBase`, which is especially relevant when working with
Eigen object that do not have an associated convenience typedef.
Note that we use `ndarray_copy` instead of `ndarray` to explicitly
state that a copy should be made. In c++11 compliant compilers, it
will detect the rvalue reference and automatically make a copy even if
you just use `ndarray` (see next section), but to ensure that it works
also with older compilers it is recommended to always use
`ndarray_copy` when returning newly constructed eigen values.
### Corrupt data when returning non-map types
The tendency of Eigency to avoid copies whenever possible can lead
to corrupted data when returning non-map Eigen arrays. For instance,
in the `function_w_mat_retval` from the previous section, a temporary
value will be returned from C++, and we have to take care to make
a copy of this data instead of letting the resulting numpy array
refer directly to this memory. In C++11, this situation can be
detected directly using rvalue references, and it will therefore
automatically make a copy:
```
def function_w_mat_retval():
# This works in C++11, because it detects the rvalue reference
return ndarray(_function_w_mat_retval())
```
However, to make sure it works with older compilers,
it is recommended to use the `ndarray_copy` conversion:
```
def function_w_mat_retval():
# Explicit request for copy - this always works
return ndarray_copy(_function_w_mat_retval())
```
### Storage layout - why arrays are sometimes transposed
The default storage layout used in numpy and Eigen differ. Numpy uses
a row-major layout (C-style) per default while Eigen uses a
column-major layout (Fortran style) by default. In Eigency, we prioritize to
avoid copying of data whenever possible, which can have unexpected
consequences in some cases: There is no problem when passing values
from C++ to Python - we just adjust the storage layout of the returned
numpy array to match that of Eigen. However, since the storage layout
is encoded into the _type_ of the Eigen array (or the type of the
Map), we cannot automatically change the layout in the Python to C++ direction. In
Eigency, we have therefore opted to return the transposed array/matrix
in such cases. This provides the user with the flexibility to deal
with the problem either in Python (use order="F" when constructing
your numpy array), or on the C++ side: (1) explicitly define your
argument to have the row-major storage layout, 2) manually set the Map
stride, or 3) just call `.transpose()` on the received
array/matrix).
As an example, consider the case of a C++ function that both receives
and returns a Eigen Map type, thus acting as a filter:
```c++
Eigen::Map<Eigen::ArrayXXd> function_filter(Eigen::Map<Eigen::ArrayXXd> &mat) {
return mat;
}
```
The Cython code could be:
```
cdef extern from "functions.h":
...
cdef Map[ArrayXXd] &_function_filter1 "function_filter1" (Map[ArrayXXd] &)
def function_filter1(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter1(Map[ArrayXXd](array)))
```
If we call this function from Python in the standard way, we will
see that the array is transposed on the way from Python to C++, and
remains that way when it is again returned to Python:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 5.]
[ 2. 6.]
[ 3. 7.]
[ 4. 8.]]
```
The simplest way to avoid this is to tell numpy to use a
column-major array layout instead of the default row-major
layout. This can be done using the order='F' option:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]], order='F')
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
```
The other alternative is to tell Eigen to use RowMajor layout. This
requires changing the C++ function definition:
```c++
typedef Eigen::Map<Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > RowMajorArrayMap;
RowMajorArrayMap &function_filter2(RowMajorArrayMap &mat) {
return mat;
}
```
To write the corresponding Cython definition, we need the expanded version of
`FlattenedMap` called `FlattenedMapWithOrder`, which allows us to specify
the storage order:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter2 "function_filter2" (FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor])
def function_filter2(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter2(FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor](array)))
```
Another alternative is to keep the array itself in RowMajor format,
but use different stride values for the Map type:
```c++
typedef Eigen::Map<Eigen::ArrayXXd, Eigen::Unaligned, Eigen::Stride<1, Eigen::Dynamic> > CustomStrideMap;
CustomStrideMap &function_filter3(CustomStrideMap &);
```
In this case, in Cython, we need to use the even more extended
`FlattenedMap` type called `FlattenedMapWithStride`, taking eight
arguments:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter3 "function_filter3" (FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic])
def function_filter3(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter3(FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic](array)))
```
In all three cases, the returned array will now be of the same shape
as the original.
### Long double support
Eigency provides new shorthands for Eigen `long double` and complex `long double` Matrix and Array types.
Examples:
```
Vector4ld
Matrix3ld
Vector2cld
Matrix4cld
Array3Xld
ArrayXXcld
```
These typedefs are available in the `eigency` namespace when including the `eigency` header:
```c++
#include "eigency.h"
void receive_long_double_matrix(Eigen::Map<eigency::MatrixXld> &mat) {
// use long double eigen matrix
}
```
Use Cython (.pyx) to create Python binding to your C++ function:
```python
cdef extern from "functions.h":
cdef void _receive_long_double_matrix "receive_long_double_matrix"(Map[MatrixXld] &)
def send_long_double_ndarray(np.ndarray[np.longdouble_t, ndim=2] array):
return _receive_long_double_matrix(Map[MatrixXld](array))
```
Invoke in Python:
```python
import numpy as np
import my_module
x = np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.longdouble)
my_module.send_long_double_ndarray(x)
```
.gitmodules
LICENSE
README.md
pyproject.toml
setup.cfg
setup.py
eigency/__init__.py
eigency/conversions.cpp
eigency/conversions.pxd
eigency/conversions.pyx
eigency/conversions_api.h
eigency/core.cpp
eigency/core.pxd
eigency/core.pyx
eigency/eigency.h
eigency/eigency_cpp.h
eigency.egg-info/PKG-INFO
eigency.egg-info/SOURCES.txt
eigency.egg-info/dependency_links.txt
eigency.egg-info/requires.txt
eigency.egg-info/top_level.txt
eigency/eigen/COPYING.APACHE
eigency/eigen/COPYING.BSD
eigency/eigen/COPYING.GPL
eigency/eigen/COPYING.LGPL
eigency/eigen/COPYING.MINPACK
eigency/eigen/COPYING.MPL2
eigency/eigen/COPYING.README
eigency/eigen/Eigen/Cholesky
eigency/eigen/Eigen/CholmodSupport
eigency/eigen/Eigen/Core
eigency/eigen/Eigen/Dense
eigency/eigen/Eigen/Eigen
eigency/eigen/Eigen/Eigenvalues
eigency/eigen/Eigen/Geometry
eigency/eigen/Eigen/Householder
eigency/eigen/Eigen/IterativeLinearSolvers
eigency/eigen/Eigen/Jacobi
eigency/eigen/Eigen/KLUSupport
eigency/eigen/Eigen/LU
eigency/eigen/Eigen/MetisSupport
eigency/eigen/Eigen/OrderingMethods
eigency/eigen/Eigen/PaStiXSupport
eigency/eigen/Eigen/PardisoSupport
eigency/eigen/Eigen/QR
eigency/eigen/Eigen/QtAlignedMalloc
eigency/eigen/Eigen/SPQRSupport
eigency/eigen/Eigen/SVD
eigency/eigen/Eigen/Sparse
eigency/eigen/Eigen/SparseCholesky
eigency/eigen/Eigen/SparseCore
eigency/eigen/Eigen/SparseLU
eigency/eigen/Eigen/SparseQR
eigency/eigen/Eigen/StdDeque
eigency/eigen/Eigen/StdList
eigency/eigen/Eigen/StdVector
eigency/eigen/Eigen/SuperLUSupport
eigency/eigen/Eigen/UmfPackSupport
eigency/eigen/Eigen/src/Cholesky/LDLT.h
eigency/eigen/Eigen/src/Cholesky/LLT.h
eigency/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h
eigency/eigen/Eigen/src/CholmodSupport/CholmodSupport.h
eigency/eigen/Eigen/src/Core/ArithmeticSequence.h
eigency/eigen/Eigen/src/Core/Array.h
eigency/eigen/Eigen/src/Core/ArrayBase.h
eigency/eigen/Eigen/src/Core/ArrayWrapper.h
eigency/eigen/Eigen/src/Core/Assign.h
eigency/eigen/Eigen/src/Core/AssignEvaluator.h
eigency/eigen/Eigen/src/Core/Assign_MKL.h
eigency/eigen/Eigen/src/Core/BandMatrix.h
eigency/eigen/Eigen/src/Core/Block.h
eigency/eigen/Eigen/src/Core/BooleanRedux.h
eigency/eigen/Eigen/src/Core/CommaInitializer.h
eigency/eigen/Eigen/src/Core/ConditionEstimator.h
eigency/eigen/Eigen/src/Core/CoreEvaluators.h
eigency/eigen/Eigen/src/Core/CoreIterators.h
eigency/eigen/Eigen/src/Core/CwiseBinaryOp.h
eigency/eigen/Eigen/src/Core/CwiseNullaryOp.h
eigency/eigen/Eigen/src/Core/CwiseTernaryOp.h
eigency/eigen/Eigen/src/Core/CwiseUnaryOp.h
eigency/eigen/Eigen/src/Core/CwiseUnaryView.h
eigency/eigen/Eigen/src/Core/DenseBase.h
eigency/eigen/Eigen/src/Core/DenseCoeffsBase.h
eigency/eigen/Eigen/src/Core/DenseStorage.h
eigency/eigen/Eigen/src/Core/Diagonal.h
eigency/eigen/Eigen/src/Core/DiagonalMatrix.h
eigency/eigen/Eigen/src/Core/DiagonalProduct.h
eigency/eigen/Eigen/src/Core/Dot.h
eigency/eigen/Eigen/src/Core/EigenBase.h
eigency/eigen/Eigen/src/Core/ForceAlignedAccess.h
eigency/eigen/Eigen/src/Core/Fuzzy.h
eigency/eigen/Eigen/src/Core/GeneralProduct.h
eigency/eigen/Eigen/src/Core/GenericPacketMath.h
eigency/eigen/Eigen/src/Core/GlobalFunctions.h
eigency/eigen/Eigen/src/Core/IO.h
eigency/eigen/Eigen/src/Core/IndexedView.h
eigency/eigen/Eigen/src/Core/Inverse.h
eigency/eigen/Eigen/src/Core/Map.h
eigency/eigen/Eigen/src/Core/MapBase.h
eigency/eigen/Eigen/src/Core/MathFunctions.h
eigency/eigen/Eigen/src/Core/MathFunctionsImpl.h
eigency/eigen/Eigen/src/Core/Matrix.h
eigency/eigen/Eigen/src/Core/MatrixBase.h
eigency/eigen/Eigen/src/Core/NestByValue.h
eigency/eigen/Eigen/src/Core/NoAlias.h
eigency/eigen/Eigen/src/Core/NumTraits.h
eigency/eigen/Eigen/src/Core/PartialReduxEvaluator.h
eigency/eigen/Eigen/src/Core/PermutationMatrix.h
eigency/eigen/Eigen/src/Core/PlainObjectBase.h
eigency/eigen/Eigen/src/Core/Product.h
eigency/eigen/Eigen/src/Core/ProductEvaluators.h
eigency/eigen/Eigen/src/Core/Random.h
eigency/eigen/Eigen/src/Core/Redux.h
eigency/eigen/Eigen/src/Core/Ref.h
eigency/eigen/Eigen/src/Core/Replicate.h
eigency/eigen/Eigen/src/Core/Reshaped.h
eigency/eigen/Eigen/src/Core/ReturnByValue.h
eigency/eigen/Eigen/src/Core/Reverse.h
eigency/eigen/Eigen/src/Core/Select.h
eigency/eigen/Eigen/src/Core/SelfAdjointView.h
eigency/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h
eigency/eigen/Eigen/src/Core/Solve.h
eigency/eigen/Eigen/src/Core/SolveTriangular.h
eigency/eigen/Eigen/src/Core/SolverBase.h
eigency/eigen/Eigen/src/Core/StableNorm.h
eigency/eigen/Eigen/src/Core/StlIterators.h
eigency/eigen/Eigen/src/Core/Stride.h
eigency/eigen/Eigen/src/Core/Swap.h
eigency/eigen/Eigen/src/Core/Transpose.h
eigency/eigen/Eigen/src/Core/Transpositions.h
eigency/eigen/Eigen/src/Core/TriangularMatrix.h
eigency/eigen/Eigen/src/Core/VectorBlock.h
eigency/eigen/Eigen/src/Core/VectorwiseOp.h
eigency/eigen/Eigen/src/Core/Visitor.h
eigency/eigen/Eigen/src/Core/arch/AVX/Complex.h
eigency/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/AVX512/Complex.h
eigency/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/Complex.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
eigency/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/CUDA/Complex.h
eigency/eigen/Eigen/src/Core/arch/Default/BFloat16.h
eigency/eigen/Eigen/src/Core/arch/Default/ConjHelper.h
eigency/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
eigency/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
eigency/eigen/Eigen/src/Core/arch/Default/Half.h
eigency/eigen/Eigen/src/Core/arch/Default/Settings.h
eigency/eigen/Eigen/src/Core/arch/Default/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/GPU/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/GPU/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/GPU/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h
eigency/eigen/Eigen/src/Core/arch/MSA/Complex.h
eigency/eigen/Eigen/src/Core/arch/MSA/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/MSA/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/NEON/Complex.h
eigency/eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h
eigency/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/NEON/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/SSE/Complex.h
eigency/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/SVE/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/SVE/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/SVE/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h
eigency/eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/SYCL/PacketMath.h
eigency/eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h
eigency/eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h
eigency/eigen/Eigen/src/Core/arch/ZVector/Complex.h
eigency/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h
eigency/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h
eigency/eigen/Eigen/src/Core/functors/AssignmentFunctors.h
eigency/eigen/Eigen/src/Core/functors/BinaryFunctors.h
eigency/eigen/Eigen/src/Core/functors/NullaryFunctors.h
eigency/eigen/Eigen/src/Core/functors/StlFunctors.h
eigency/eigen/Eigen/src/Core/functors/TernaryFunctors.h
eigency/eigen/Eigen/src/Core/functors/UnaryFunctors.h
eigency/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
eigency/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
eigency/eigen/Eigen/src/Core/products/Parallelizer.h
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
eigency/eigen/Eigen/src/Core/products/SelfadjointProduct.h
eigency/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h
eigency/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h
eigency/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
eigency/eigen/Eigen/src/Core/products/TriangularMatrixVector.h
eigency/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
eigency/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h
eigency/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
eigency/eigen/Eigen/src/Core/products/TriangularSolverVector.h
eigency/eigen/Eigen/src/Core/util/BlasUtil.h
eigency/eigen/Eigen/src/Core/util/ConfigureVectorization.h
eigency/eigen/Eigen/src/Core/util/Constants.h
eigency/eigen/Eigen/src/Core/util/DisableStupidWarnings.h
eigency/eigen/Eigen/src/Core/util/ForwardDeclarations.h
eigency/eigen/Eigen/src/Core/util/IndexedViewHelper.h
eigency/eigen/Eigen/src/Core/util/IntegralConstant.h
eigency/eigen/Eigen/src/Core/util/MKL_support.h
eigency/eigen/Eigen/src/Core/util/Macros.h
eigency/eigen/Eigen/src/Core/util/Memory.h
eigency/eigen/Eigen/src/Core/util/Meta.h
eigency/eigen/Eigen/src/Core/util/NonMPL2.h
eigency/eigen/Eigen/src/Core/util/ReenableStupidWarnings.h
eigency/eigen/Eigen/src/Core/util/ReshapedHelper.h
eigency/eigen/Eigen/src/Core/util/StaticAssert.h
eigency/eigen/Eigen/src/Core/util/SymbolicIndex.h
eigency/eigen/Eigen/src/Core/util/XprHelper.h
eigency/eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h
eigency/eigen/Eigen/src/Eigenvalues/ComplexSchur.h
eigency/eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h
eigency/eigen/Eigen/src/Eigenvalues/EigenSolver.h
eigency/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
eigency/eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
eigency/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h
eigency/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
eigency/eigen/Eigen/src/Eigenvalues/RealQZ.h
eigency/eigen/Eigen/src/Eigenvalues/RealSchur.h
eigency/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h
eigency/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
eigency/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
eigency/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h
eigency/eigen/Eigen/src/Geometry/AlignedBox.h
eigency/eigen/Eigen/src/Geometry/AngleAxis.h
eigency/eigen/Eigen/src/Geometry/EulerAngles.h
eigency/eigen/Eigen/src/Geometry/Homogeneous.h
eigency/eigen/Eigen/src/Geometry/Hyperplane.h
eigency/eigen/Eigen/src/Geometry/OrthoMethods.h
eigency/eigen/Eigen/src/Geometry/ParametrizedLine.h
eigency/eigen/Eigen/src/Geometry/Quaternion.h
eigency/eigen/Eigen/src/Geometry/Rotation2D.h
eigency/eigen/Eigen/src/Geometry/RotationBase.h
eigency/eigen/Eigen/src/Geometry/Scaling.h
eigency/eigen/Eigen/src/Geometry/Transform.h
eigency/eigen/Eigen/src/Geometry/Translation.h
eigency/eigen/Eigen/src/Geometry/Umeyama.h
eigency/eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h
eigency/eigen/Eigen/src/Householder/BlockHouseholder.h
eigency/eigen/Eigen/src/Householder/Householder.h
eigency/eigen/Eigen/src/Householder/HouseholderSequence.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h
eigency/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h
eigency/eigen/Eigen/src/Jacobi/Jacobi.h
eigency/eigen/Eigen/src/KLUSupport/KLUSupport.h
eigency/eigen/Eigen/src/LU/Determinant.h
eigency/eigen/Eigen/src/LU/FullPivLU.h
eigency/eigen/Eigen/src/LU/InverseImpl.h
eigency/eigen/Eigen/src/LU/PartialPivLU.h
eigency/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h
eigency/eigen/Eigen/src/LU/arch/InverseSize4.h
eigency/eigen/Eigen/src/MetisSupport/MetisSupport.h
eigency/eigen/Eigen/src/OrderingMethods/Amd.h
eigency/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h
eigency/eigen/Eigen/src/OrderingMethods/Ordering.h
eigency/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h
eigency/eigen/Eigen/src/PardisoSupport/PardisoSupport.h
eigency/eigen/Eigen/src/QR/ColPivHouseholderQR.h
eigency/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h
eigency/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h
eigency/eigen/Eigen/src/QR/FullPivHouseholderQR.h
eigency/eigen/Eigen/src/QR/HouseholderQR.h
eigency/eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h
eigency/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
eigency/eigen/Eigen/src/SVD/BDCSVD.h
eigency/eigen/Eigen/src/SVD/JacobiSVD.h
eigency/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h
eigency/eigen/Eigen/src/SVD/SVDBase.h
eigency/eigen/Eigen/src/SVD/UpperBidiagonalization.h
eigency/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h
eigency/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
eigency/eigen/Eigen/src/SparseCore/AmbiVector.h
eigency/eigen/Eigen/src/SparseCore/CompressedStorage.h
eigency/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
eigency/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h
eigency/eigen/Eigen/src/SparseCore/SparseAssign.h
eigency/eigen/Eigen/src/SparseCore/SparseBlock.h
eigency/eigen/Eigen/src/SparseCore/SparseColEtree.h
eigency/eigen/Eigen/src/SparseCore/SparseCompressedBase.h
eigency/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
eigency/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h
eigency/eigen/Eigen/src/SparseCore/SparseDenseProduct.h
eigency/eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h
eigency/eigen/Eigen/src/SparseCore/SparseDot.h
eigency/eigen/Eigen/src/SparseCore/SparseFuzzy.h
eigency/eigen/Eigen/src/SparseCore/SparseMap.h
eigency/eigen/Eigen/src/SparseCore/SparseMatrix.h
eigency/eigen/Eigen/src/SparseCore/SparseMatrixBase.h
eigency/eigen/Eigen/src/SparseCore/SparsePermutation.h
eigency/eigen/Eigen/src/SparseCore/SparseProduct.h
eigency/eigen/Eigen/src/SparseCore/SparseRedux.h
eigency/eigen/Eigen/src/SparseCore/SparseRef.h
eigency/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
eigency/eigen/Eigen/src/SparseCore/SparseSolverBase.h
eigency/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
eigency/eigen/Eigen/src/SparseCore/SparseTranspose.h
eigency/eigen/Eigen/src/SparseCore/SparseTriangularView.h
eigency/eigen/Eigen/src/SparseCore/SparseUtil.h
eigency/eigen/Eigen/src/SparseCore/SparseVector.h
eigency/eigen/Eigen/src/SparseCore/SparseView.h
eigency/eigen/Eigen/src/SparseCore/TriangularSolver.h
eigency/eigen/Eigen/src/SparseLU/SparseLU.h
eigency/eigen/Eigen/src/SparseLU/SparseLUImpl.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_Memory.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_Structs.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_Utils.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_pruneL.h
eigency/eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h
eigency/eigen/Eigen/src/SparseQR/SparseQR.h
eigency/eigen/Eigen/src/StlSupport/StdDeque.h
eigency/eigen/Eigen/src/StlSupport/StdList.h
eigency/eigen/Eigen/src/StlSupport/StdVector.h
eigency/eigen/Eigen/src/StlSupport/details.h
eigency/eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h
eigency/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
eigency/eigen/Eigen/src/misc/Image.h
eigency/eigen/Eigen/src/misc/Kernel.h
eigency/eigen/Eigen/src/misc/RealSvd2x2.h
eigency/eigen/Eigen/src/misc/blas.h
eigency/eigen/Eigen/src/misc/lapack.h
eigency/eigen/Eigen/src/misc/lapacke.h
eigency/eigen/Eigen/src/misc/lapacke_mangling.h
eigency/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h
eigency/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h
eigency/eigen/Eigen/src/plugins/BlockMethods.h
eigency/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h
eigency/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h
eigency/eigen/Eigen/src/plugins/IndexedViewMethods.h
eigency/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h
eigency/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h
eigency/eigen/Eigen/src/plugins/ReshapedMethods.h
Copyright (c) 2016 Wouter Boomsma
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Metadata-Version: 2.4
Name: eigency
Version: 3.4.0.6
Summary: Cython interface between the numpy arrays and the Matrix/Array classes of the Eigen C++ library
Author-email: Wouter Boomsma <wb@di.ku.dk>, Felipe Bordeu <felipebordeu@gmail.com>
Maintainer-email: Felipe Bordeu <felipebordeu@gmail.com>, Wouter Boomsma <wb@di.ku.dk>
License-Expression: LicenseRef-Wouter-Boomsma-1.0
Project-URL: Homepage, https://github.com/eigency-org/eigency
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: C++
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23.5
Dynamic: license-file
# Eigency
[![PyPI version](https://badge.fury.io/py/eigency.svg)](https://badge.fury.io/py/eigency)
[![PEP 517](https://github.com/eigency-org/eigency/actions/workflows/build.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/build.yml)
[![pip wheel](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml)
[![setup.py](https://github.com/eigency-org/eigency/actions/workflows/setup.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/setup.yml)
[![pre-commit](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml)
Eigency is a Cython interface between Numpy arrays and Matrix/Array
objects from the Eigen C++ library. It is intended to simplify the
process of writing C++ extensions using the Eigen library. Eigency is
designed to reuse the underlying storage of the arrays when passing
data back and forth, and will thus avoid making unnecessary copies
whenever possible. Only in cases where copies are explicitly requested
by your C++ code will they be made.
## Versioning
Eigency uses a 4-number version (`N.N.N.N`) where the first 3 parts correspond to the embedded Eigen library version.
The last part is a revision number of Eigency itself.
## Installing
Eigency is packaged as a source distribution (`sdist`) and available on PyPi.
It can be easily installed using `pip`:
```bash
python -m pip install eigency
```
**Requirement**: `pip >= 18.0`
If your `pip` is too old, then upgrade it using:
```bash
python -m pip install --upgrade pip
```
## Contributing
For instructions on building and/or packaging Eigency from source,
see the contributing guide [here](https://github.com/eigency-org/eigency/blob/master/CONTRIBUTING.md).
## Usage
Below is a description of a range of common usage scenarios. A full working
example of both setup and these different use cases is available in the
`test` directory distributed with the this package.
### Setup
To import eigency functionality, add the following to your `.pyx` file:
```
from eigency.core cimport *
```
In addition, in the `setup.py` file, the include directories must be
set up to include the eigency includes. This can be done by calling
the `get_includes` function in the `eigency` module:
```
import eigency
...
extensions = [
Extension("module-dir-name/module-name", ["module-dir-name/module-name.pyx"],
include_dirs = [".", "module-dir-name"] + eigency.get_includes()
),
]
```
Eigency includes a version of the Eigen library, and the `get_includes` function will include the path to this directory. If you
have your own version of Eigen, just set the `include_eigen` option to False, and add your own path instead:
```
include_dirs = [".", "module-dir-name", 'path-to-own-eigen'] + eigency.get_includes(include_eigen=False)
```
### From Numpy to Eigen
Assume we are writing a Cython interface to the following C++ function:
```c++
void function_w_mat_arg(const Eigen::Map<Eigen::MatrixXd> &mat) {
std::cout << mat << "\n";
}
```
Note that we use `Eigen::Map` to ensure that we can reuse the storage
of the numpy array, thus avoiding making a copy. Assuming the C++ code
is in a file called `functions.h`, the corresponding `.pyx` entry could look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
The last line contains the actual conversion. `Map` is an Eigency
type that derives from the real Eigen map, and will take care of
the conversion from the numpy array to the corresponding Eigen type.
We can now call the C++ function directly from Python:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1.1, 2.2], [3.3, 4.4]])
>>> eigency_tests.function_w_mat_arg(x)
1.1 3.3
2.2 4.4
```
(if you are wondering about why the matrix is transposed, please
see the Storage layout section below).
## Types matter
The basic idea behind eigency is to share the underlying representation of a
numpy array between Python and C++. This means that somewhere in the process,
we need to make explicit which numerical types we are dealing with. In the
function above, we specify that we expect an Eigen MatrixXd, which means
that the numpy array must also contain double (i.e. float64) values. If we instead provide
a numpy array of ints, we will get strange results.
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
4.94066e-324 1.4822e-323
9.88131e-324 1.97626e-323
```
This is because we are explicitly asking C++ to interpret out python integer
values as floats.
To avoid this type of error, you can force your cython function to
accept only numpy arrays of a specific type:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
(Note that when using this technique to select the type, you also need to specify
the dimensions of the array (this will default to 1)). Using this new definition,
users will get an error when passing arrays of the wrong type:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "eigency_tests/eigency_tests.pyx", line 87, in eigency_tests.eigency_tests.function_w_mat_arg
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long'
```
Since it avoids many surprises, it is strongly recommended to use this technique
to specify the full types of numpy arrays in your cython code whenever
possible.
### Writing Eigen Map types in Cython
Since Cython does not support nested fused types, you cannot write types like `Map[Matrix[double, 2, 2]]`. In most cases, you won't need to, since you can just use Eigens convenience typedefs, such as `Map[VectorXd]`. If you need the additional flexibility of the full specification, you can use the `FlattenedMap` type, where all type arguments can be specified at top level, for instance `FlattenedMap[Matrix, double, _2, _3]` or `FlattenedMap[Matrix, double, _2, Dynamic]`. Note that dimensions must be prefixed with an underscore.
Using full specifications of the Eigen types, the previous example would look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg" (FlattenedMap[Matrix, double, Dynamic, Dynamic] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(FlattenedMap[Matrix, double, Dynamic, Dynamic](array))
```
`FlattenedType` takes four template parameters: arraytype, scalartype,
rows and cols. Eigen supports a few other template arguments for
setting the storage layout and Map strides. Since cython does not
support default template arguments for fused types, we have instead
defined separate types for this purpose. These are called
`FlattenedMapWithOrder` and `FlattenedMapWithStride` with five and eight
template arguments, respectively. For details on their use, see the section
about storage layout below.
### From Numpy to Eigen (insisting on a copy)
Eigency will not complain if the C++ function you interface with does
not take a Eigen Map object, but instead a regular Eigen Matrix or
Array. However, in such cases, a copy will be made. Actually, the
procedure is exactly the same as above. In the `.pyx` file, you still
define everything exactly the same way as for the Map case described above.
For instance, given the following C++ function:
```c++
void function_w_vec_arg_no_map(const Eigen::VectorXd &vec);
```
The Cython definitions would still look like this:
```
cdef extern from "functions.h":
cdef void _function_w_vec_arg_no_map "function_w_vec_arg_no_map"(Map[VectorXd] &)
# This will be exposed to Python
def function_w_vec_arg_no_map(np.ndarray[np.float64_t] array):
return _function_w_vec_arg_no_map(Map[VectorXd](array))
```
Cython will not mind the fact that the argument type in the extern
declaration (a Map type) differs from the actual one in the `.h` file,
as long as one can be assigned to the other. Since Map objects can be
assigned to their corresponding Matrix/Array types this works
seemlessly. But keep in mind that this assignment will make a copy of
the underlying data.
### Eigen to Numpy
C++ functions returning a reference to an Eigen Matrix/Array can also
be transferred to numpy arrays without copying their content. Assume
we have a class with a single getter function that returns an Eigen
matrix member:
```c++
class MyClass {
public:
MyClass():
matrix(Eigen::Matrix3d::Constant(3.)) {
}
Eigen::MatrixXd &get_matrix() {
return this->matrix;
}
private:
Eigen::Matrix3d matrix;
};
```
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
_MyClass "MyClass"() except +
Matrix3d &get_matrix()
```
And the corresponding Python wrapper:
```python
cdef class MyClass:
cdef _MyClass *thisptr;
def __cinit__(self):
self.thisptr = new _MyClass()
def __dealloc__(self):
del self.thisptr
def get_matrix(self):
return ndarray(self.thisptr.get_matrix())
```
This last line contains the actual conversion. Again, eigency has its
own version of `ndarray`, that will take care of the conversion for
you.
Due to limitations in Cython, Eigency cannot deal with full
Matrix/Array template specifications as return types
(e.g. `Matrix[double, 4, 2]`). However, as a workaround, you can use
`PlainObjectBase` as a return type in such cases (or in all cases if
you prefer):
```
PlainObjectBase &get_matrix()
```
### Overriding default behavior
The `ndarray` conversion type specifier will attempt do guess whether you want a copy
or a view, depending on the return type. Most of the time, this is
probably what you want. However, there might be cases where you want
to override this behavior. For instance, functions returning const
references will result in a copy of the array, since the const-ness
cannot be enforced in Python. However, you can always override the
default behavior by using the `ndarray_copy` or `ndarray_view`
functions.
Expanding the `MyClass` example from before:
```c++
class MyClass {
public:
...
const Eigen::MatrixXd &get_const_matrix() {
return this->matrix;
}
...
};
```
With the corresponding cython interface specification
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
...
const Matrix3d &get_const_matrix()
```
The following would return a copy
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray(self.thisptr.get_const_matrix())
```
while the following would force it to return a view
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray_view(self.thisptr.get_const_matrix())
```
### Eigen to Numpy (non-reference return values)
Functions returning an Eigen object (not a reference), are specified
in a similar way. For instance, given the following C++ function:
```c++
Eigen::Matrix3d function_w_mat_retval();
```
The Cython code could be written as:
```
cdef extern from "functions.h":
cdef Matrix3d _function_w_mat_retval "function_w_mat_retval" ()
# This will be exposed to Python
def function_w_mat_retval():
return ndarray_copy(_function_w_mat_retval())
```
As mentioned above, you can replace `Matrix3d` (or any other Eigen return type) with
`PlainObjectBase`, which is especially relevant when working with
Eigen object that do not have an associated convenience typedef.
Note that we use `ndarray_copy` instead of `ndarray` to explicitly
state that a copy should be made. In c++11 compliant compilers, it
will detect the rvalue reference and automatically make a copy even if
you just use `ndarray` (see next section), but to ensure that it works
also with older compilers it is recommended to always use
`ndarray_copy` when returning newly constructed eigen values.
### Corrupt data when returning non-map types
The tendency of Eigency to avoid copies whenever possible can lead
to corrupted data when returning non-map Eigen arrays. For instance,
in the `function_w_mat_retval` from the previous section, a temporary
value will be returned from C++, and we have to take care to make
a copy of this data instead of letting the resulting numpy array
refer directly to this memory. In C++11, this situation can be
detected directly using rvalue references, and it will therefore
automatically make a copy:
```
def function_w_mat_retval():
# This works in C++11, because it detects the rvalue reference
return ndarray(_function_w_mat_retval())
```
However, to make sure it works with older compilers,
it is recommended to use the `ndarray_copy` conversion:
```
def function_w_mat_retval():
# Explicit request for copy - this always works
return ndarray_copy(_function_w_mat_retval())
```
### Storage layout - why arrays are sometimes transposed
The default storage layout used in numpy and Eigen differ. Numpy uses
a row-major layout (C-style) per default while Eigen uses a
column-major layout (Fortran style) by default. In Eigency, we prioritize to
avoid copying of data whenever possible, which can have unexpected
consequences in some cases: There is no problem when passing values
from C++ to Python - we just adjust the storage layout of the returned
numpy array to match that of Eigen. However, since the storage layout
is encoded into the _type_ of the Eigen array (or the type of the
Map), we cannot automatically change the layout in the Python to C++ direction. In
Eigency, we have therefore opted to return the transposed array/matrix
in such cases. This provides the user with the flexibility to deal
with the problem either in Python (use order="F" when constructing
your numpy array), or on the C++ side: (1) explicitly define your
argument to have the row-major storage layout, 2) manually set the Map
stride, or 3) just call `.transpose()` on the received
array/matrix).
As an example, consider the case of a C++ function that both receives
and returns a Eigen Map type, thus acting as a filter:
```c++
Eigen::Map<Eigen::ArrayXXd> function_filter(Eigen::Map<Eigen::ArrayXXd> &mat) {
return mat;
}
```
The Cython code could be:
```
cdef extern from "functions.h":
...
cdef Map[ArrayXXd] &_function_filter1 "function_filter1" (Map[ArrayXXd] &)
def function_filter1(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter1(Map[ArrayXXd](array)))
```
If we call this function from Python in the standard way, we will
see that the array is transposed on the way from Python to C++, and
remains that way when it is again returned to Python:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 5.]
[ 2. 6.]
[ 3. 7.]
[ 4. 8.]]
```
The simplest way to avoid this is to tell numpy to use a
column-major array layout instead of the default row-major
layout. This can be done using the order='F' option:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]], order='F')
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
```
The other alternative is to tell Eigen to use RowMajor layout. This
requires changing the C++ function definition:
```c++
typedef Eigen::Map<Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > RowMajorArrayMap;
RowMajorArrayMap &function_filter2(RowMajorArrayMap &mat) {
return mat;
}
```
To write the corresponding Cython definition, we need the expanded version of
`FlattenedMap` called `FlattenedMapWithOrder`, which allows us to specify
the storage order:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter2 "function_filter2" (FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor])
def function_filter2(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter2(FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor](array)))
```
Another alternative is to keep the array itself in RowMajor format,
but use different stride values for the Map type:
```c++
typedef Eigen::Map<Eigen::ArrayXXd, Eigen::Unaligned, Eigen::Stride<1, Eigen::Dynamic> > CustomStrideMap;
CustomStrideMap &function_filter3(CustomStrideMap &);
```
In this case, in Cython, we need to use the even more extended
`FlattenedMap` type called `FlattenedMapWithStride`, taking eight
arguments:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter3 "function_filter3" (FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic])
def function_filter3(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter3(FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic](array)))
```
In all three cases, the returned array will now be of the same shape
as the original.
### Long double support
Eigency provides new shorthands for Eigen `long double` and complex `long double` Matrix and Array types.
Examples:
```
Vector4ld
Matrix3ld
Vector2cld
Matrix4cld
Array3Xld
ArrayXXcld
```
These typedefs are available in the `eigency` namespace when including the `eigency` header:
```c++
#include "eigency.h"
void receive_long_double_matrix(Eigen::Map<eigency::MatrixXld> &mat) {
// use long double eigen matrix
}
```
Use Cython (.pyx) to create Python binding to your C++ function:
```python
cdef extern from "functions.h":
cdef void _receive_long_double_matrix "receive_long_double_matrix"(Map[MatrixXld] &)
def send_long_double_ndarray(np.ndarray[np.longdouble_t, ndim=2] array):
return _receive_long_double_matrix(Map[MatrixXld](array))
```
Invoke in Python:
```python
import numpy as np
import my_module
x = np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.longdouble)
my_module.send_long_double_ndarray(x)
```
[build-system]
requires = [
"setuptools>=60.0.0",
"setuptools_scm>=6.4.0",
"oldest-supported-numpy; python_version<='3.8'",
"numpy>=2.0.0; python_version>'3.8'",
"Cython>=3.0.0"
]
build-backend = "setuptools.build_meta"
[project]
name = "eigency"
dynamic = ["version"]
description = "Cython interface between the numpy arrays and the Matrix/Array classes of the Eigen C++ library"
readme = "README.md"
requires-python = ">=3.9"
license = "LicenseRef-Wouter-Boomsma-1.0"
license-files = ["LICENSE"]
dependencies = [
"numpy>=1.23.5",
]
authors = [
{name = "Wouter Boomsma", email = "wb@di.ku.dk"},
{name = "Felipe Bordeu", email = "felipebordeu@gmail.com"}
]
maintainers = [
{name = "Felipe Bordeu", email = "felipebordeu@gmail.com"},
{name = "Wouter Boomsma", email = "wb@di.ku.dk"}
]
classifiers = [
"Intended Audience :: Developers",
"Programming Language :: C++",
"Programming Language :: Cython",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
[project.urls]
Homepage = "https://github.com/eigency-org/eigency"
# Eigency
[![PyPI version](https://badge.fury.io/py/eigency.svg)](https://badge.fury.io/py/eigency)
[![PEP 517](https://github.com/eigency-org/eigency/actions/workflows/build.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/build.yml)
[![pip wheel](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml)
[![setup.py](https://github.com/eigency-org/eigency/actions/workflows/setup.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/setup.yml)
[![pre-commit](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml)
Eigency is a Cython interface between Numpy arrays and Matrix/Array
objects from the Eigen C++ library. It is intended to simplify the
process of writing C++ extensions using the Eigen library. Eigency is
designed to reuse the underlying storage of the arrays when passing
data back and forth, and will thus avoid making unnecessary copies
whenever possible. Only in cases where copies are explicitly requested
by your C++ code will they be made.
## Versioning
Eigency uses a 4-number version (`N.N.N.N`) where the first 3 parts correspond to the embedded Eigen library version.
The last part is a revision number of Eigency itself.
## Installing
Eigency is packaged as a source distribution (`sdist`) and available on PyPi.
It can be easily installed using `pip`:
```bash
python -m pip install eigency
```
**Requirement**: `pip >= 18.0`
If your `pip` is too old, then upgrade it using:
```bash
python -m pip install --upgrade pip
```
## Contributing
For instructions on building and/or packaging Eigency from source,
see the contributing guide [here](https://github.com/eigency-org/eigency/blob/master/CONTRIBUTING.md).
## Usage
Below is a description of a range of common usage scenarios. A full working
example of both setup and these different use cases is available in the
`test` directory distributed with the this package.
### Setup
To import eigency functionality, add the following to your `.pyx` file:
```
from eigency.core cimport *
```
In addition, in the `setup.py` file, the include directories must be
set up to include the eigency includes. This can be done by calling
the `get_includes` function in the `eigency` module:
```
import eigency
...
extensions = [
Extension("module-dir-name/module-name", ["module-dir-name/module-name.pyx"],
include_dirs = [".", "module-dir-name"] + eigency.get_includes()
),
]
```
Eigency includes a version of the Eigen library, and the `get_includes` function will include the path to this directory. If you
have your own version of Eigen, just set the `include_eigen` option to False, and add your own path instead:
```
include_dirs = [".", "module-dir-name", 'path-to-own-eigen'] + eigency.get_includes(include_eigen=False)
```
### From Numpy to Eigen
Assume we are writing a Cython interface to the following C++ function:
```c++
void function_w_mat_arg(const Eigen::Map<Eigen::MatrixXd> &mat) {
std::cout << mat << "\n";
}
```
Note that we use `Eigen::Map` to ensure that we can reuse the storage
of the numpy array, thus avoiding making a copy. Assuming the C++ code
is in a file called `functions.h`, the corresponding `.pyx` entry could look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
The last line contains the actual conversion. `Map` is an Eigency
type that derives from the real Eigen map, and will take care of
the conversion from the numpy array to the corresponding Eigen type.
We can now call the C++ function directly from Python:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1.1, 2.2], [3.3, 4.4]])
>>> eigency_tests.function_w_mat_arg(x)
1.1 3.3
2.2 4.4
```
(if you are wondering about why the matrix is transposed, please
see the Storage layout section below).
## Types matter
The basic idea behind eigency is to share the underlying representation of a
numpy array between Python and C++. This means that somewhere in the process,
we need to make explicit which numerical types we are dealing with. In the
function above, we specify that we expect an Eigen MatrixXd, which means
that the numpy array must also contain double (i.e. float64) values. If we instead provide
a numpy array of ints, we will get strange results.
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
4.94066e-324 1.4822e-323
9.88131e-324 1.97626e-323
```
This is because we are explicitly asking C++ to interpret out python integer
values as floats.
To avoid this type of error, you can force your cython function to
accept only numpy arrays of a specific type:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
(Note that when using this technique to select the type, you also need to specify
the dimensions of the array (this will default to 1)). Using this new definition,
users will get an error when passing arrays of the wrong type:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "eigency_tests/eigency_tests.pyx", line 87, in eigency_tests.eigency_tests.function_w_mat_arg
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long'
```
Since it avoids many surprises, it is strongly recommended to use this technique
to specify the full types of numpy arrays in your cython code whenever
possible.
### Writing Eigen Map types in Cython
Since Cython does not support nested fused types, you cannot write types like `Map[Matrix[double, 2, 2]]`. In most cases, you won't need to, since you can just use Eigens convenience typedefs, such as `Map[VectorXd]`. If you need the additional flexibility of the full specification, you can use the `FlattenedMap` type, where all type arguments can be specified at top level, for instance `FlattenedMap[Matrix, double, _2, _3]` or `FlattenedMap[Matrix, double, _2, Dynamic]`. Note that dimensions must be prefixed with an underscore.
Using full specifications of the Eigen types, the previous example would look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg" (FlattenedMap[Matrix, double, Dynamic, Dynamic] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(FlattenedMap[Matrix, double, Dynamic, Dynamic](array))
```
`FlattenedType` takes four template parameters: arraytype, scalartype,
rows and cols. Eigen supports a few other template arguments for
setting the storage layout and Map strides. Since cython does not
support default template arguments for fused types, we have instead
defined separate types for this purpose. These are called
`FlattenedMapWithOrder` and `FlattenedMapWithStride` with five and eight
template arguments, respectively. For details on their use, see the section
about storage layout below.
### From Numpy to Eigen (insisting on a copy)
Eigency will not complain if the C++ function you interface with does
not take a Eigen Map object, but instead a regular Eigen Matrix or
Array. However, in such cases, a copy will be made. Actually, the
procedure is exactly the same as above. In the `.pyx` file, you still
define everything exactly the same way as for the Map case described above.
For instance, given the following C++ function:
```c++
void function_w_vec_arg_no_map(const Eigen::VectorXd &vec);
```
The Cython definitions would still look like this:
```
cdef extern from "functions.h":
cdef void _function_w_vec_arg_no_map "function_w_vec_arg_no_map"(Map[VectorXd] &)
# This will be exposed to Python
def function_w_vec_arg_no_map(np.ndarray[np.float64_t] array):
return _function_w_vec_arg_no_map(Map[VectorXd](array))
```
Cython will not mind the fact that the argument type in the extern
declaration (a Map type) differs from the actual one in the `.h` file,
as long as one can be assigned to the other. Since Map objects can be
assigned to their corresponding Matrix/Array types this works
seemlessly. But keep in mind that this assignment will make a copy of
the underlying data.
### Eigen to Numpy
C++ functions returning a reference to an Eigen Matrix/Array can also
be transferred to numpy arrays without copying their content. Assume
we have a class with a single getter function that returns an Eigen
matrix member:
```c++
class MyClass {
public:
MyClass():
matrix(Eigen::Matrix3d::Constant(3.)) {
}
Eigen::MatrixXd &get_matrix() {
return this->matrix;
}
private:
Eigen::Matrix3d matrix;
};
```
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
_MyClass "MyClass"() except +
Matrix3d &get_matrix()
```
And the corresponding Python wrapper:
```python
cdef class MyClass:
cdef _MyClass *thisptr;
def __cinit__(self):
self.thisptr = new _MyClass()
def __dealloc__(self):
del self.thisptr
def get_matrix(self):
return ndarray(self.thisptr.get_matrix())
```
This last line contains the actual conversion. Again, eigency has its
own version of `ndarray`, that will take care of the conversion for
you.
Due to limitations in Cython, Eigency cannot deal with full
Matrix/Array template specifications as return types
(e.g. `Matrix[double, 4, 2]`). However, as a workaround, you can use
`PlainObjectBase` as a return type in such cases (or in all cases if
you prefer):
```
PlainObjectBase &get_matrix()
```
### Overriding default behavior
The `ndarray` conversion type specifier will attempt do guess whether you want a copy
or a view, depending on the return type. Most of the time, this is
probably what you want. However, there might be cases where you want
to override this behavior. For instance, functions returning const
references will result in a copy of the array, since the const-ness
cannot be enforced in Python. However, you can always override the
default behavior by using the `ndarray_copy` or `ndarray_view`
functions.
Expanding the `MyClass` example from before:
```c++
class MyClass {
public:
...
const Eigen::MatrixXd &get_const_matrix() {
return this->matrix;
}
...
};
```
With the corresponding cython interface specification
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
...
const Matrix3d &get_const_matrix()
```
The following would return a copy
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray(self.thisptr.get_const_matrix())
```
while the following would force it to return a view
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray_view(self.thisptr.get_const_matrix())
```
### Eigen to Numpy (non-reference return values)
Functions returning an Eigen object (not a reference), are specified
in a similar way. For instance, given the following C++ function:
```c++
Eigen::Matrix3d function_w_mat_retval();
```
The Cython code could be written as:
```
cdef extern from "functions.h":
cdef Matrix3d _function_w_mat_retval "function_w_mat_retval" ()
# This will be exposed to Python
def function_w_mat_retval():
return ndarray_copy(_function_w_mat_retval())
```
As mentioned above, you can replace `Matrix3d` (or any other Eigen return type) with
`PlainObjectBase`, which is especially relevant when working with
Eigen object that do not have an associated convenience typedef.
Note that we use `ndarray_copy` instead of `ndarray` to explicitly
state that a copy should be made. In c++11 compliant compilers, it
will detect the rvalue reference and automatically make a copy even if
you just use `ndarray` (see next section), but to ensure that it works
also with older compilers it is recommended to always use
`ndarray_copy` when returning newly constructed eigen values.
### Corrupt data when returning non-map types
The tendency of Eigency to avoid copies whenever possible can lead
to corrupted data when returning non-map Eigen arrays. For instance,
in the `function_w_mat_retval` from the previous section, a temporary
value will be returned from C++, and we have to take care to make
a copy of this data instead of letting the resulting numpy array
refer directly to this memory. In C++11, this situation can be
detected directly using rvalue references, and it will therefore
automatically make a copy:
```
def function_w_mat_retval():
# This works in C++11, because it detects the rvalue reference
return ndarray(_function_w_mat_retval())
```
However, to make sure it works with older compilers,
it is recommended to use the `ndarray_copy` conversion:
```
def function_w_mat_retval():
# Explicit request for copy - this always works
return ndarray_copy(_function_w_mat_retval())
```
### Storage layout - why arrays are sometimes transposed
The default storage layout used in numpy and Eigen differ. Numpy uses
a row-major layout (C-style) per default while Eigen uses a
column-major layout (Fortran style) by default. In Eigency, we prioritize to
avoid copying of data whenever possible, which can have unexpected
consequences in some cases: There is no problem when passing values
from C++ to Python - we just adjust the storage layout of the returned
numpy array to match that of Eigen. However, since the storage layout
is encoded into the _type_ of the Eigen array (or the type of the
Map), we cannot automatically change the layout in the Python to C++ direction. In
Eigency, we have therefore opted to return the transposed array/matrix
in such cases. This provides the user with the flexibility to deal
with the problem either in Python (use order="F" when constructing
your numpy array), or on the C++ side: (1) explicitly define your
argument to have the row-major storage layout, 2) manually set the Map
stride, or 3) just call `.transpose()` on the received
array/matrix).
As an example, consider the case of a C++ function that both receives
and returns a Eigen Map type, thus acting as a filter:
```c++
Eigen::Map<Eigen::ArrayXXd> function_filter(Eigen::Map<Eigen::ArrayXXd> &mat) {
return mat;
}
```
The Cython code could be:
```
cdef extern from "functions.h":
...
cdef Map[ArrayXXd] &_function_filter1 "function_filter1" (Map[ArrayXXd] &)
def function_filter1(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter1(Map[ArrayXXd](array)))
```
If we call this function from Python in the standard way, we will
see that the array is transposed on the way from Python to C++, and
remains that way when it is again returned to Python:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 5.]
[ 2. 6.]
[ 3. 7.]
[ 4. 8.]]
```
The simplest way to avoid this is to tell numpy to use a
column-major array layout instead of the default row-major
layout. This can be done using the order='F' option:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]], order='F')
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
```
The other alternative is to tell Eigen to use RowMajor layout. This
requires changing the C++ function definition:
```c++
typedef Eigen::Map<Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > RowMajorArrayMap;
RowMajorArrayMap &function_filter2(RowMajorArrayMap &mat) {
return mat;
}
```
To write the corresponding Cython definition, we need the expanded version of
`FlattenedMap` called `FlattenedMapWithOrder`, which allows us to specify
the storage order:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter2 "function_filter2" (FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor])
def function_filter2(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter2(FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor](array)))
```
Another alternative is to keep the array itself in RowMajor format,
but use different stride values for the Map type:
```c++
typedef Eigen::Map<Eigen::ArrayXXd, Eigen::Unaligned, Eigen::Stride<1, Eigen::Dynamic> > CustomStrideMap;
CustomStrideMap &function_filter3(CustomStrideMap &);
```
In this case, in Cython, we need to use the even more extended
`FlattenedMap` type called `FlattenedMapWithStride`, taking eight
arguments:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter3 "function_filter3" (FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic])
def function_filter3(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter3(FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic](array)))
```
In all three cases, the returned array will now be of the same shape
as the original.
### Long double support
Eigency provides new shorthands for Eigen `long double` and complex `long double` Matrix and Array types.
Examples:
```
Vector4ld
Matrix3ld
Vector2cld
Matrix4cld
Array3Xld
ArrayXXcld
```
These typedefs are available in the `eigency` namespace when including the `eigency` header:
```c++
#include "eigency.h"
void receive_long_double_matrix(Eigen::Map<eigency::MatrixXld> &mat) {
// use long double eigen matrix
}
```
Use Cython (.pyx) to create Python binding to your C++ function:
```python
cdef extern from "functions.h":
cdef void _receive_long_double_matrix "receive_long_double_matrix"(Map[MatrixXld] &)
def send_long_double_ndarray(np.ndarray[np.longdouble_t, ndim=2] array):
return _receive_long_double_matrix(Map[MatrixXld](array))
```
Invoke in Python:
```python
import numpy as np
import my_module
x = np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.longdouble)
my_module.send_long_double_ndarray(x)
```
[sdist]
owner = root
group = root
[egg_info]
tag_build =
tag_date = 0
import os
import sys
from os.path import basename, join
import numpy as np
from setuptools import find_namespace_packages, setup
from setuptools.extension import Extension
sys.path.append(".")
__package_name__ = "eigency"
include_dirs = [np.get_include()]
if "EIGEN_INC" in os.environ:
useSystemEigen = True
include_dirs.append(os.environ["EIGEN_INC"])
else:
useSystemEigen = False
import eigency # noqa: E402
__eigen_dir__ = eigency.get_eigency_eigen_dir()
__eigen_lib_dir__ = join(basename(__eigen_dir__), "Eigen")
include_dirs.append(__eigen_dir__)
# Not all users may have cython installed. If they only want this as a means
# to access the Eigen header files to compile their own C++ code, then they
# may not have cython already installed. Therefore, only require cython
# for cases where the user will need to build the .cpp files from the .pyx
# files (typically from a git clone) and not for other pip installations.
# cf. discussion in PR #26.
# Follow the pattern recommended here:
# http://cython.readthedocs.io/en/latest/src/reference/compilation.html#distributing-cython-modules
try:
from Cython.Build import cythonize
# Maybe make this a command line option?
USE_CYTHON = True
ext = ".pyx"
except ImportError:
USE_CYTHON = False
ext = ".cpp"
extensions = [
Extension(
"eigency.conversions",
["eigency/conversions" + ext],
include_dirs=include_dirs,
language="c++",
define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
),
Extension(
"eigency.core",
["eigency/core" + ext],
include_dirs=include_dirs,
language="c++",
define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
),
]
if USE_CYTHON:
extensions = cythonize(
extensions,
compiler_directives=dict(
language_level="3",
),
)
long_description = open("README.md").read()
eigen_data_files = []
exclude_package_data = {}
if not useSystemEigen:
for root, dirs, files in os.walk(join(__eigen_dir__, "Eigen")):
for f in files:
if f.endswith(".h"):
eigen_data_files.append(join(root, f))
eigen_data_files.append(join(__eigen_lib_dir__, "*"))
exclude_package_data = {__package_name__: [join(__eigen_lib_dir__, "CMakeLists.txt")]}
setup(
name=__package_name__,
use_scm_version=True,
ext_modules=extensions,
packages=find_namespace_packages(
include=[
"eigency",
"eigency.eigen",
"eigency.eigen.Eigen",
"eigency.eigen.Eigen.*",
],
),
include_package_data=True,
package_data={__package_name__: ["*.h", "*.pxd", "*.pyx"] + eigen_data_files},
exclude_package_data=exclude_package_data,
)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

-20
Copyright (c) 2016 Wouter Boomsma
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Metadata-Version: 2.4
Name: eigency
Version: 3.4.0.5
Summary: Cython interface between the numpy arrays and the Matrix/Array classes of the Eigen C++ library
Author-email: Wouter Boomsma <wb@di.ku.dk>, Felipe Bordeu <felipebordeu@gmail.com>
Maintainer-email: Felipe Bordeu <felipebordeu@gmail.com>, Wouter Boomsma <wb@di.ku.dk>
License-Expression: LicenseRef-Wouter-Boomsma-1.0
Project-URL: Homepage, https://github.com/eigency-org/eigency
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: C++
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23.5
Dynamic: license-file
# Eigency
[![PyPI version](https://badge.fury.io/py/eigency.svg)](https://badge.fury.io/py/eigency)
[![PEP 517](https://github.com/eigency-org/eigency/actions/workflows/build.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/build.yml)
[![pip wheel](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/wheel.yml)
[![setup.py](https://github.com/eigency-org/eigency/actions/workflows/setup.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/setup.yml)
[![pre-commit](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/eigency-org/eigency/actions/workflows/pre-commit.yml)
Eigency is a Cython interface between Numpy arrays and Matrix/Array
objects from the Eigen C++ library. It is intended to simplify the
process of writing C++ extensions using the Eigen library. Eigency is
designed to reuse the underlying storage of the arrays when passing
data back and forth, and will thus avoid making unnecessary copies
whenever possible. Only in cases where copies are explicitly requested
by your C++ code will they be made.
## Versioning
Eigency uses a 4-number version (`N.N.N.N`) where the first 3 parts correspond to the embedded Eigen library version.
The last part is a revision number of Eigency itself.
## Installing
Eigency is packaged as a source distribution (`sdist`) and available on PyPi.
It can be easily installed using `pip`:
```bash
python -m pip install eigency
```
**Requirement**: `pip >= 18.0`
If your `pip` is too old, then upgrade it using:
```bash
python -m pip install --upgrade pip
```
## Contributing
For instructions on building and/or packaging Eigency from source,
see the contributing guide [here](https://github.com/eigency-org/eigency/blob/master/CONTRIBUTING.md).
## Usage
Below is a description of a range of common usage scenarios. A full working
example of both setup and these different use cases is available in the
`test` directory distributed with the this package.
### Setup
To import eigency functionality, add the following to your `.pyx` file:
```
from eigency.core cimport *
```
In addition, in the `setup.py` file, the include directories must be
set up to include the eigency includes. This can be done by calling
the `get_includes` function in the `eigency` module:
```
import eigency
...
extensions = [
Extension("module-dir-name/module-name", ["module-dir-name/module-name.pyx"],
include_dirs = [".", "module-dir-name"] + eigency.get_includes()
),
]
```
Eigency includes a version of the Eigen library, and the `get_includes` function will include the path to this directory. If you
have your own version of Eigen, just set the `include_eigen` option to False, and add your own path instead:
```
include_dirs = [".", "module-dir-name", 'path-to-own-eigen'] + eigency.get_includes(include_eigen=False)
```
### From Numpy to Eigen
Assume we are writing a Cython interface to the following C++ function:
```c++
void function_w_mat_arg(const Eigen::Map<Eigen::MatrixXd> &mat) {
std::cout << mat << "\n";
}
```
Note that we use `Eigen::Map` to ensure that we can reuse the storage
of the numpy array, thus avoiding making a copy. Assuming the C++ code
is in a file called `functions.h`, the corresponding `.pyx` entry could look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
The last line contains the actual conversion. `Map` is an Eigency
type that derives from the real Eigen map, and will take care of
the conversion from the numpy array to the corresponding Eigen type.
We can now call the C++ function directly from Python:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1.1, 2.2], [3.3, 4.4]])
>>> eigency_tests.function_w_mat_arg(x)
1.1 3.3
2.2 4.4
```
(if you are wondering about why the matrix is transposed, please
see the Storage layout section below).
## Types matter
The basic idea behind eigency is to share the underlying representation of a
numpy array between Python and C++. This means that somewhere in the process,
we need to make explicit which numerical types we are dealing with. In the
function above, we specify that we expect an Eigen MatrixXd, which means
that the numpy array must also contain double (i.e. float64) values. If we instead provide
a numpy array of ints, we will get strange results.
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
4.94066e-324 1.4822e-323
9.88131e-324 1.97626e-323
```
This is because we are explicitly asking C++ to interpret out python integer
values as floats.
To avoid this type of error, you can force your cython function to
accept only numpy arrays of a specific type:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg"(Map[MatrixXd] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(Map[MatrixXd](array))
```
(Note that when using this technique to select the type, you also need to specify
the dimensions of the array (this will default to 1)). Using this new definition,
users will get an error when passing arrays of the wrong type:
```python
>>> import numpy as np
>>> import eigency_tests
>>> x = np.array([[1, 2], [3, 4]])
>>> eigency_tests.function_w_mat_arg(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "eigency_tests/eigency_tests.pyx", line 87, in eigency_tests.eigency_tests.function_w_mat_arg
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long'
```
Since it avoids many surprises, it is strongly recommended to use this technique
to specify the full types of numpy arrays in your cython code whenever
possible.
### Writing Eigen Map types in Cython
Since Cython does not support nested fused types, you cannot write types like `Map[Matrix[double, 2, 2]]`. In most cases, you won't need to, since you can just use Eigens convenience typedefs, such as `Map[VectorXd]`. If you need the additional flexibility of the full specification, you can use the `FlattenedMap` type, where all type arguments can be specified at top level, for instance `FlattenedMap[Matrix, double, _2, _3]` or `FlattenedMap[Matrix, double, _2, Dynamic]`. Note that dimensions must be prefixed with an underscore.
Using full specifications of the Eigen types, the previous example would look like this:
```
cdef extern from "functions.h":
cdef void _function_w_mat_arg "function_w_mat_arg" (FlattenedMap[Matrix, double, Dynamic, Dynamic] &)
# This will be exposed to Python
def function_w_mat_arg(np.ndarray[np.float64_t, ndim=2] array):
return _function_w_mat_arg(FlattenedMap[Matrix, double, Dynamic, Dynamic](array))
```
`FlattenedType` takes four template parameters: arraytype, scalartype,
rows and cols. Eigen supports a few other template arguments for
setting the storage layout and Map strides. Since cython does not
support default template arguments for fused types, we have instead
defined separate types for this purpose. These are called
`FlattenedMapWithOrder` and `FlattenedMapWithStride` with five and eight
template arguments, respectively. For details on their use, see the section
about storage layout below.
### From Numpy to Eigen (insisting on a copy)
Eigency will not complain if the C++ function you interface with does
not take a Eigen Map object, but instead a regular Eigen Matrix or
Array. However, in such cases, a copy will be made. Actually, the
procedure is exactly the same as above. In the `.pyx` file, you still
define everything exactly the same way as for the Map case described above.
For instance, given the following C++ function:
```c++
void function_w_vec_arg_no_map(const Eigen::VectorXd &vec);
```
The Cython definitions would still look like this:
```
cdef extern from "functions.h":
cdef void _function_w_vec_arg_no_map "function_w_vec_arg_no_map"(Map[VectorXd] &)
# This will be exposed to Python
def function_w_vec_arg_no_map(np.ndarray[np.float64_t] array):
return _function_w_vec_arg_no_map(Map[VectorXd](array))
```
Cython will not mind the fact that the argument type in the extern
declaration (a Map type) differs from the actual one in the `.h` file,
as long as one can be assigned to the other. Since Map objects can be
assigned to their corresponding Matrix/Array types this works
seemlessly. But keep in mind that this assignment will make a copy of
the underlying data.
### Eigen to Numpy
C++ functions returning a reference to an Eigen Matrix/Array can also
be transferred to numpy arrays without copying their content. Assume
we have a class with a single getter function that returns an Eigen
matrix member:
```c++
class MyClass {
public:
MyClass():
matrix(Eigen::Matrix3d::Constant(3.)) {
}
Eigen::MatrixXd &get_matrix() {
return this->matrix;
}
private:
Eigen::Matrix3d matrix;
};
```
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
_MyClass "MyClass"() except +
Matrix3d &get_matrix()
```
And the corresponding Python wrapper:
```python
cdef class MyClass:
cdef _MyClass *thisptr;
def __cinit__(self):
self.thisptr = new _MyClass()
def __dealloc__(self):
del self.thisptr
def get_matrix(self):
return ndarray(self.thisptr.get_matrix())
```
This last line contains the actual conversion. Again, eigency has its
own version of `ndarray`, that will take care of the conversion for
you.
Due to limitations in Cython, Eigency cannot deal with full
Matrix/Array template specifications as return types
(e.g. `Matrix[double, 4, 2]`). However, as a workaround, you can use
`PlainObjectBase` as a return type in such cases (or in all cases if
you prefer):
```
PlainObjectBase &get_matrix()
```
### Overriding default behavior
The `ndarray` conversion type specifier will attempt do guess whether you want a copy
or a view, depending on the return type. Most of the time, this is
probably what you want. However, there might be cases where you want
to override this behavior. For instance, functions returning const
references will result in a copy of the array, since the const-ness
cannot be enforced in Python. However, you can always override the
default behavior by using the `ndarray_copy` or `ndarray_view`
functions.
Expanding the `MyClass` example from before:
```c++
class MyClass {
public:
...
const Eigen::MatrixXd &get_const_matrix() {
return this->matrix;
}
...
};
```
With the corresponding cython interface specification
The Cython C++ class interface is specified as usual:
```
cdef cppclass _MyClass "MyClass":
...
const Matrix3d &get_const_matrix()
```
The following would return a copy
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray(self.thisptr.get_const_matrix())
```
while the following would force it to return a view
```python
cdef class MyClass:
...
def get_const_matrix(self):
return ndarray_view(self.thisptr.get_const_matrix())
```
### Eigen to Numpy (non-reference return values)
Functions returning an Eigen object (not a reference), are specified
in a similar way. For instance, given the following C++ function:
```c++
Eigen::Matrix3d function_w_mat_retval();
```
The Cython code could be written as:
```
cdef extern from "functions.h":
cdef Matrix3d _function_w_mat_retval "function_w_mat_retval" ()
# This will be exposed to Python
def function_w_mat_retval():
return ndarray_copy(_function_w_mat_retval())
```
As mentioned above, you can replace `Matrix3d` (or any other Eigen return type) with
`PlainObjectBase`, which is especially relevant when working with
Eigen object that do not have an associated convenience typedef.
Note that we use `ndarray_copy` instead of `ndarray` to explicitly
state that a copy should be made. In c++11 compliant compilers, it
will detect the rvalue reference and automatically make a copy even if
you just use `ndarray` (see next section), but to ensure that it works
also with older compilers it is recommended to always use
`ndarray_copy` when returning newly constructed eigen values.
### Corrupt data when returning non-map types
The tendency of Eigency to avoid copies whenever possible can lead
to corrupted data when returning non-map Eigen arrays. For instance,
in the `function_w_mat_retval` from the previous section, a temporary
value will be returned from C++, and we have to take care to make
a copy of this data instead of letting the resulting numpy array
refer directly to this memory. In C++11, this situation can be
detected directly using rvalue references, and it will therefore
automatically make a copy:
```
def function_w_mat_retval():
# This works in C++11, because it detects the rvalue reference
return ndarray(_function_w_mat_retval())
```
However, to make sure it works with older compilers,
it is recommended to use the `ndarray_copy` conversion:
```
def function_w_mat_retval():
# Explicit request for copy - this always works
return ndarray_copy(_function_w_mat_retval())
```
### Storage layout - why arrays are sometimes transposed
The default storage layout used in numpy and Eigen differ. Numpy uses
a row-major layout (C-style) per default while Eigen uses a
column-major layout (Fortran style) by default. In Eigency, we prioritize to
avoid copying of data whenever possible, which can have unexpected
consequences in some cases: There is no problem when passing values
from C++ to Python - we just adjust the storage layout of the returned
numpy array to match that of Eigen. However, since the storage layout
is encoded into the _type_ of the Eigen array (or the type of the
Map), we cannot automatically change the layout in the Python to C++ direction. In
Eigency, we have therefore opted to return the transposed array/matrix
in such cases. This provides the user with the flexibility to deal
with the problem either in Python (use order="F" when constructing
your numpy array), or on the C++ side: (1) explicitly define your
argument to have the row-major storage layout, 2) manually set the Map
stride, or 3) just call `.transpose()` on the received
array/matrix).
As an example, consider the case of a C++ function that both receives
and returns a Eigen Map type, thus acting as a filter:
```c++
Eigen::Map<Eigen::ArrayXXd> function_filter(Eigen::Map<Eigen::ArrayXXd> &mat) {
return mat;
}
```
The Cython code could be:
```
cdef extern from "functions.h":
...
cdef Map[ArrayXXd] &_function_filter1 "function_filter1" (Map[ArrayXXd] &)
def function_filter1(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter1(Map[ArrayXXd](array)))
```
If we call this function from Python in the standard way, we will
see that the array is transposed on the way from Python to C++, and
remains that way when it is again returned to Python:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 5.]
[ 2. 6.]
[ 3. 7.]
[ 4. 8.]]
```
The simplest way to avoid this is to tell numpy to use a
column-major array layout instead of the default row-major
layout. This can be done using the order='F' option:
```python
>>> x = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]], order='F')
>>> y = function_filter1(x)
>>> print x
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
>>> print y
[[ 1. 2. 3. 4.]
[ 5. 6. 7. 8.]]
```
The other alternative is to tell Eigen to use RowMajor layout. This
requires changing the C++ function definition:
```c++
typedef Eigen::Map<Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > RowMajorArrayMap;
RowMajorArrayMap &function_filter2(RowMajorArrayMap &mat) {
return mat;
}
```
To write the corresponding Cython definition, we need the expanded version of
`FlattenedMap` called `FlattenedMapWithOrder`, which allows us to specify
the storage order:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter2 "function_filter2" (FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor])
def function_filter2(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter2(FlattenedMapWithOrder[Array, double, Dynamic, Dynamic, RowMajor](array)))
```
Another alternative is to keep the array itself in RowMajor format,
but use different stride values for the Map type:
```c++
typedef Eigen::Map<Eigen::ArrayXXd, Eigen::Unaligned, Eigen::Stride<1, Eigen::Dynamic> > CustomStrideMap;
CustomStrideMap &function_filter3(CustomStrideMap &);
```
In this case, in Cython, we need to use the even more extended
`FlattenedMap` type called `FlattenedMapWithStride`, taking eight
arguments:
```
cdef extern from "functions.h":
...
cdef PlainObjectBase _function_filter3 "function_filter3" (FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic])
def function_filter3(np.ndarray[np.float64_t, ndim=2] array):
return ndarray(_function_filter3(FlattenedMapWithStride[Array, double, Dynamic, Dynamic, ColMajor, Unaligned, _1, Dynamic](array)))
```
In all three cases, the returned array will now be of the same shape
as the original.
### Long double support
Eigency provides new shorthands for Eigen `long double` and complex `long double` Matrix and Array types.
Examples:
```
Vector4ld
Matrix3ld
Vector2cld
Matrix4cld
Array3Xld
ArrayXXcld
```
These typedefs are available in the `eigency` namespace when including the `eigency` header:
```c++
#include "eigency.h"
void receive_long_double_matrix(Eigen::Map<eigency::MatrixXld> &mat) {
// use long double eigen matrix
}
```
Use Cython (.pyx) to create Python binding to your C++ function:
```python
cdef extern from "functions.h":
cdef void _receive_long_double_matrix "receive_long_double_matrix"(Map[MatrixXld] &)
def send_long_double_ndarray(np.ndarray[np.longdouble_t, ndim=2] array):
return _receive_long_double_matrix(Map[MatrixXld](array))
```
Invoke in Python:
```python
import numpy as np
import my_module
x = np.array([[1.1, 2.2], [3.3, 4.4]], dtype=np.longdouble)
my_module.send_long_double_ndarray(x)
```
-361
eigency-3.4.0.5.dist-info/RECORD,,
eigency-3.4.0.5.dist-info/WHEEL,sha256=cMZt8yy9snWrcJ6ukBKliUyeAPJLnzk9nJajsmR7UPI,136
eigency-3.4.0.5.dist-info/top_level.txt,sha256=DBJvIgHQMhMUeEDbqHHPmrsyr-0YM1UyIC4Ho9YT264,8
eigency-3.4.0.5.dist-info/METADATA,sha256=NoGUGhdGaC8fgABnfhfmpKqAjxqAIh5ixu7O8UC1QRY,19602
eigency-3.4.0.5.dist-info/licenses/LICENSE,sha256=ON97Ls1S-bG2sTZRKI4qJzP_hh4_1ZnFh9CDmFfb2g0,1058
eigency/conversions.pxd,sha256=DS6p4JGfBsoWdTSRLk224zSv0zU_8hXIC8LKHEBK8Gc,1170
eigency/core.pxd,sha256=sPaXoQ8cg7_i3JIq3xPamdTp6vTtUOkWeUJ3XWYNfVo,22405
eigency/conversions.cpp,sha256=b-EjAddHSyCGUusLOc2uMH43tMnz-WnWL8No8GvP0nU,1818851
eigency/core.cpp,sha256=mllqks7P6Db-7-w83cFfk5GIS8m3lFOU9LoaYjs5XVU,320226
eigency/eigency_cpp.h,sha256=7NU7GNe7nDifjZ7OuN_caDu2SB4prLKnLPnDEEDolIc,19834
eigency/__init__.py,sha256=Cg7sAXYZ9kV0eEYhUdPWx4Gd366BMFWttkKrYx-1PX4,412
eigency/eigency.h,sha256=NLVNfM_nwXj2aXTrrRGAN9rqLcAXJJLzX8wvbEaKw2A,2257
eigency/conversions.cpython-310-darwin.so,sha256=zWd3iAU2JFZzHYt4oMOJvf51ZOjJPp7j2Yfn6xoZ2Ws,398928
eigency/conversions_api.h,sha256=RHGj9aEnbuYw22_X0i2pOG9eylRktjmzXV4sSQS0ioo,37356
eigency/core.pyx,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
eigency/conversions.pyx,sha256=mTXZSS-pjD4NF4keuNghgsWWFJkeZ3ePCgxjEREH4D4,1662
eigency/core.cpython-310-darwin.so,sha256=gRcV6QE87i2Cm_6ZZctI_Y9B6hhE4Qdu5H8Sz-MIa2Y,55976
eigency/eigen/COPYING.LGPL,sha256=3GJlINzVOiL3J68-5Cx3DlbJemT-OtsGN5nYqwMv5VE,26530
eigency/eigen/COPYING.BSD,sha256=UZKNzjYhPFMzujFy6EfXNdTG6bf_JyKjJsSQZxVbgus,1517
eigency/eigen/COPYING.APACHE,sha256=AzeQAaexKi7Jl6JVVCR9mFJws1PBDVuv7prI1lGYILc,11362
eigency/eigen/COPYING.MPL2,sha256=-rPda9qyJvHAhjCx3ZF-Efy07F4eAg4sFvg6ChOGPoU,16726
eigency/eigen/COPYING.GPL,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
eigency/eigen/COPYING.README,sha256=yDIwt3DxfvE4bqH9NoEnHdmKqTZGvb-1v_OhtwUP_50,779
eigency/eigen/COPYING.MINPACK,sha256=yHt_juiPYZXpF0OCDAA1SDNYOu8JG3Li1KScjijnmKA,2193
eigency/eigen/Eigen/CholmodSupport,sha256=JvDRvQZ3eFOU8fTrLN33Y0I_cDwJQbPlg3PpVbATAyc,1900
eigency/eigen/Eigen/StdVector,sha256=fosQYHV6EUApj_OQXfcO21mtEIP1BWgd8w3J3Jlj2Ks,803
eigency/eigen/Eigen/StdDeque,sha256=wYhRZ6RHglq3w1VzQiw--iPexi9bYwrDIv_mWODuUkI,797
eigency/eigen/Eigen/Core,sha256=uK5fd6MNSLyvYipW9wR7qosvt5D123Nhqh1X9CT6PB4,12799
eigency/eigen/Eigen/SparseLU,sha256=XnRux2MFSTHxbt5cWIqrK0TXVf69rymfXuTMoDRqhbY,1814
eigency/eigen/Eigen/OrderingMethods,sha256=JfrIHKwzWAF-Tcsg-Tr9D5zmXWBBN28v9dlv2dCEvXI,2451
eigency/eigen/Eigen/QtAlignedMalloc,sha256=xGYpHG59Iw6Ldrclza0e2Cwkm_AfXsO8tvP2UB7Q_5c,900
eigency/eigen/Eigen/Householder,sha256=GhjqJlnbFc6T3g9a_xNaU2r5cB2pr08CZxDlbe8jpVk,829
eigency/eigen/Eigen/PardisoSupport,sha256=UOxQA985n6v1GGIOIg9xxxf_OgOnIYuGUKl03DrQaxU,1116
eigency/eigen/Eigen/SparseCore,sha256=IyPB4xed_Gq_NIFht4wb9ezQyqj0UscMrKmhzf3Wpq4,2240
eigency/eigen/Eigen/Jacobi,sha256=rzAgyRuOktBzTBE_sVEdlqDWsFgSiRHYmOAXdiijWMg,894
eigency/eigen/Eigen/Dense,sha256=UyXJ1NaT5QTuASxSda1LELE1pwHL2HwURm0uoh6iLuU,122
eigency/eigen/Eigen/SPQRSupport,sha256=T6LXO5mMB5RoLWPf-__3lb6kGn0YZlhAscNX5m_xyJ0,1162
eigency/eigen/Eigen/QR,sha256=53rhAQ6d8dyw5ah1YEjDiAzrAjcR6NG1aeAbA58TCCA,1272
eigency/eigen/Eigen/Eigen,sha256=sEc7XXwM2TEdSpBUgWLozxYJBEdocff7dJ6WJOmz39E,35
eigency/eigen/Eigen/SparseQR,sha256=dDNFiuAILyaqw7VE8I5XGKXRIsR5qTFCUrQRzPHZuPs,1195
eigency/eigen/Eigen/SVD,sha256=EVWjLv1mTLQzM6NPqKy8vCb6M62u3-6OIO3fZ0Nq6IY,1584
eigency/eigen/Eigen/Cholesky,sha256=SMcsLXuY_bRRZ10u4DhQ7P3JfqQbzlXtdUsD2kqwm9A,1161
eigency/eigen/Eigen/UmfPackSupport,sha256=AD1B-gjN5oscRphJn6m_nIA867J650hhWFFRn0LcVqw,1382
eigency/eigen/Eigen/IterativeLinearSolvers,sha256=hP-jisHvO-AFv_UAt4tSnB4WT8UGN4Nv-GSP6hJ7dPc,2083
eigency/eigen/Eigen/LU,sha256=0A-rF2kizdSiMf8z6tWPwtshqdkwNLz3ugwqNRplS6Q,1268
eigency/eigen/Eigen/Sparse,sha256=vjUbbuZSp6IOOVPQ6uIW1NAcLCa6e2pGS_kI2zRJkHs,888
eigency/eigen/Eigen/Geometry,sha256=84oUXuUT0fp1v8_HlPvEfJ3mWjr12ftxngV6xjMCwvg,1940
eigency/eigen/Eigen/SuperLUSupport,sha256=iqYB8_oea_wDt5lma_OevELUSRel-yqqSJvq_WOQH3I,2243
eigency/eigen/Eigen/StdList,sha256=A1QOKXrpbtA-go2aQzu39aXpOqg8b1CmwnHHj5KD1mc,726
eigency/eigen/Eigen/MetisSupport,sha256=5G1R0wZZYkCKQDSA8snK1OfWH7UJweSmlSdHUSdJaaI,991
eigency/eigen/Eigen/SparseCholesky,sha256=bjZKchFd6lcGHhNqbsgEzyHF0815qkQ5_Ss1L1id6ps,1235
eigency/eigen/Eigen/Eigenvalues,sha256=8ZWKms880-H1GNhx19xgLoEBszzjUAi47o4XIIRb2gc,1777
eigency/eigen/Eigen/PaStiXSupport,sha256=9CO5Vxa4BPlSEjTfvFitGi-tmhb4S88W3wu4iu7MhUM,1751
eigency/eigen/Eigen/KLUSupport,sha256=vEYx66RCVNLRAih_AcArDKeTKRyXa1CbfDUoFX_tL2Q,1389
eigency/eigen/Eigen/src/CholmodSupport/CholmodSupport.h,sha256=_XiNvLNTzR8Oyp-m_2V2CzNY-7RF7n3v7x-nyYNKXnk,25441
eigency/eigen/Eigen/src/misc/blas.h,sha256=dOWodSZy7a3ZNjf23H_rilBCfqlPmsXR7VbcLa4PrWc,30560
eigency/eigen/Eigen/src/misc/lapacke.h,sha256=Bmc-lq9luQfIPUJJW3VDYbQr2_nvxjU9UfLnAjlsrrc,1058369
eigency/eigen/Eigen/src/misc/Kernel.h,sha256=IIiRDtPS_STfPS980xZLyEV8eCqOAFi39K3yKKHT7ro,2742
eigency/eigen/Eigen/src/misc/RealSvd2x2.h,sha256=X-B5X0XNkqCbSMAiWe90O6y76G-JDLDAclwMA_tWiGo,1748
eigency/eigen/Eigen/src/misc/Image.h,sha256=-Pn7ZkwUYgVhdflW2Td77dFQ6MRfuJo570RjtjaGxKE,2913
eigency/eigen/Eigen/src/misc/lapack.h,sha256=_9_gqkbLMiEgKp8lguOez21a1mYmzf1w9AmFlSHWg0Y,7834
eigency/eigen/Eigen/src/misc/lapacke_mangling.h,sha256=fXH97lOh4M0BVoq6LxUvLh5Pu4SehNdA47Ax6Bn7-iI,474
eigency/eigen/Eigen/src/Core/Reverse.h,sha256=lmCGSuTPyF3sQNgueaWYtx5cWPUwNL3TDHQJPFq5oVQ,7522
eigency/eigen/Eigen/src/Core/ConditionEstimator.h,sha256=uSdt-5gLRfIu3k4I7uRH9eAIR0AOZvJnlnaSIz5CTCc,6990
eigency/eigen/Eigen/src/Core/PermutationMatrix.h,sha256=xOo3Hcj9crxhDZe56OJB2XZcCNjWqT5m2FH8CVzZzmA,20748
eigency/eigen/Eigen/src/Core/Assign.h,sha256=dKQAmY90XhiXo_Kd4MHxDmrS6XJp9ylFq7JZ5mF_O2I,2738
eigency/eigen/Eigen/src/Core/MathFunctionsImpl.h,sha256=lvc1eFdCOZ_8YQmm2KQb8jknibWnE8nL-y8Il2dJEkc,7156
eigency/eigen/Eigen/src/Core/CwiseUnaryOp.h,sha256=ptT-VJWaOq0EShXxJmiLRFujF8jNj2DDpOGGMuMBXJA,3937
eigency/eigen/Eigen/src/Core/DiagonalMatrix.h,sha256=Kg1DVgs8zq-jetJsx7RKlRVF5WqH0X54uJbG0GPGRxg,14670
eigency/eigen/Eigen/src/Core/StlIterators.h,sha256=yudREy61voHxl0k2-akEGTWqipHX0AZbSDAeTPV7EMQ,21641
eigency/eigen/Eigen/src/Core/VectorBlock.h,sha256=1_VF-6FHnjOeMEB5nsGgAIskLLr7RWEAy5XnzWRYa0k,3488
eigency/eigen/Eigen/src/Core/ReturnByValue.h,sha256=ijhUmPC6DGdGb-FRr0LlU3vTxddbidQLc7wQPHcwlmU,4284
eigency/eigen/Eigen/src/Core/Solve.h,sha256=0UEeTDezRD00It_7piJacK4Yaw7ZCj8Ju-wUcn7fhvI,6837
eigency/eigen/Eigen/src/Core/ArithmeticSequence.h,sha256=8vgcI6huL7rFhH2DSPfdEPD-OYEoNNNLVERuG8pE-68,19214
eigency/eigen/Eigen/src/Core/Product.h,sha256=R5WGCVcHEtjAZsjnUp_OM0bwzHlKzNOQ91PZcD1IQs8,7336
eigency/eigen/Eigen/src/Core/MatrixBase.h,sha256=P8p3jdYQkj98CJ_m9j5gAAXxT-3BVoUVkfypmaKOWSs,23856
eigency/eigen/Eigen/src/Core/Stride.h,sha256=XvhjHxIi1JnpwnMmbsu4B3iRJosg3RHHv1foOz-3w30,4212
eigency/eigen/Eigen/src/Core/Map.h,sha256=N9PDYRqEYInLMKDXjd3EXTIphbtj-k31aA9vM8AWoHs,7256
eigency/eigen/Eigen/src/Core/ForceAlignedAccess.h,sha256=g5uk6NSZjvNzhM24_mbkq6A3rvqCTaxjsQLwFrNnAXU,4909
eigency/eigen/Eigen/src/Core/MathFunctions.h,sha256=s8bNFz1KyHnlaKxXCAQt0LsWCAXGupxV2gXIE0ZW91g,60784
eigency/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h,sha256=TQ8CFAN4yP0ouwXS8T3FDdhnvbwt3c4iP-N7gtvxerU,1697
eigency/eigen/Eigen/src/Core/BandMatrix.h,sha256=ZusMpQuT9NzcCDqiH0Md2QUsMZkRNW2QJVdvDNnGyJM,14075
eigency/eigen/Eigen/src/Core/Inverse.h,sha256=Xu8vJuEFNJiB6xQIzC62dLJkySTUW6P2v867yt_msQw,3503
eigency/eigen/Eigen/src/Core/Assign_MKL.h,sha256=dPYwhbhTcHKTPsFzuRtDcL7RUXeMZDWicqlBtnj4tJA,12488
eigency/eigen/Eigen/src/Core/Swap.h,sha256=cq3ST1UzR38ao94FITvncu7qmhPWfbgtAvdPzOUB6kA,2765
eigency/eigen/Eigen/src/Core/ProductEvaluators.h,sha256=2IY694zzCciY008Oizi7TBs3C1YipIBkIR9bOwrZHrA,53832
eigency/eigen/Eigen/src/Core/MapBase.h,sha256=7uz3jWkieES7KRTck21U22rNn6jvjQ4pqScrhJON4aA,11281
eigency/eigen/Eigen/src/Core/Matrix.h,sha256=_YTfwccLBClS0pnznwVpT4LKHxfKAT6zNnV6PPcebRE,24343
eigency/eigen/Eigen/src/Core/EigenBase.h,sha256=9nQxmKrOAik2Su84QtekyuxMZIJoES1dyIdQ0TnwJho,5841
eigency/eigen/Eigen/src/Core/StableNorm.h,sha256=SI5NEBo9ABOxkbgMGPwcQumIczthCbcEv6QMz3fT0Yc,8700
eigency/eigen/Eigen/src/Core/GenericPacketMath.h,sha256=FatABDPfUC3DlhmTRVtWPFXV-kfFqTIE0SrSp5cwr90,38812
eigency/eigen/Eigen/src/Core/CwiseBinaryOp.h,sha256=AxbMB-jrRUh65PJDJ5EWjhwTQHEgAU67P0FhP_xuMCw,7909
eigency/eigen/Eigen/src/Core/Visitor.h,sha256=0y8bT7AGWjEr8TooYc88PS_wjSvvStiwFLUAYa6IAqQ,11997
eigency/eigen/Eigen/src/Core/DenseStorage.h,sha256=I16S84EpH_dd3j9b2Djc9-TGyAuoOUBVDib37kt8DIg,25360
eigency/eigen/Eigen/src/Core/DiagonalProduct.h,sha256=_6cfNHpZFMnpNB6oK7Qr97b3uNBFS8F7xWKa3bghOMs,988
eigency/eigen/Eigen/src/Core/CwiseUnaryView.h,sha256=5ZqmH2GmdTLUproXOERwPH6Y4o17jH6c7gqp0w1rlnU,5551
eigency/eigen/Eigen/src/Core/NoAlias.h,sha256=Ip1s5MuKGSHKzWNPb-ZOaYxUB3MCSHxiICuEWnRGYY0,3620
eigency/eigen/Eigen/src/Core/DenseCoeffsBase.h,sha256=shKz8IklvEP3gDcJl28Iz0qD2t1UXVWLqRWZ6SoAllk,24484
eigency/eigen/Eigen/src/Core/PartialReduxEvaluator.h,sha256=hj7Bxbfe3LjOvaTLnDi2_HfcddIpDb_yw5p9uYzjOjg,9207
eigency/eigen/Eigen/src/Core/IndexedView.h,sha256=X6kQiPumLzTPCrTmy7q6iKNrfEsZXebS9nyW4pPzL-w,9620
eigency/eigen/Eigen/src/Core/Fuzzy.h,sha256=TaSjzj16hbMNNZd2WEFeSKTBBR7Wuh3Uxhy8jTUAJ9M,5759
eigency/eigen/Eigen/src/Core/TriangularMatrix.h,sha256=zEwgkLv57QKwo2EpgJ-yw5oy0r0u_qBdDeux6v6EgRE,38277
eigency/eigen/Eigen/src/Core/IO.h,sha256=iaTrSS9KSgqeIe_2ZmODFS0PRe-C1KGHnmEnfa-0rU8,8238
eigency/eigen/Eigen/src/Core/Array.h,sha256=39fKPydmTk45GiUd5NpStFdQf8lCUWohqz6Ln6T-jaQ,16782
eigency/eigen/Eigen/src/Core/SolverBase.h,sha256=M57lChZDARbiviOylEHsf7kLc_8r9r6KOeHHT7Phca4,6170
eigency/eigen/Eigen/src/Core/AssignEvaluator.h,sha256=E5UBHDUEfSI5Oeas89CW6DrsdhKG6aEJZ0pbdeBtZaM,41673
eigency/eigen/Eigen/src/Core/Replicate.h,sha256=b3eh2lzUvOvhy7kNUv1_wj0ZpG6LG48qgI7Q7L-b2-4,5656
eigency/eigen/Eigen/src/Core/CoreIterators.h,sha256=MLxTh9kMqEHm7IVobSElMYoZ1P2qBah_rm_6sISPdJo,4745
eigency/eigen/Eigen/src/Core/ArrayBase.h,sha256=h6XAellrUiXUmw2iWF2B0Ub38jt6DaeiDFHrW3Rq_F4,8217
eigency/eigen/Eigen/src/Core/Block.h,sha256=EJKGf-xoAEOIsLo403rWA8x8tdA03Ci2_jqC6SrYiK0,18648
eigency/eigen/Eigen/src/Core/Dot.h,sha256=SVnXKm92-UFx5WJF5zMtVVp3UdKdy-BLOq6iyEGODvU,11654
eigency/eigen/Eigen/src/Core/PlainObjectBase.h,sha256=-qVMt5_XTbX9X7PG9g_CUjmOvDUp6WB8_eIjIkQWIzU,49193
eigency/eigen/Eigen/src/Core/SelfAdjointView.h,sha256=awX8Mcrm-Ubbf89EOe-hPrIc2bGQOueRDMdKYRuV9o8,14999
eigency/eigen/Eigen/src/Core/GeneralProduct.h,sha256=u3pQ7qYb-HzruMX_JVPjZB4ed9YvVhg44SZb9CrIg6A,21679
eigency/eigen/Eigen/src/Core/SolveTriangular.h,sha256=8psntHTv5Wkru_Hxhj8N20zPA54-2gJ5b1TDOInchqE,9368
eigency/eigen/Eigen/src/Core/CoreEvaluators.h,sha256=6J0oxusVbLZZ9YqGGX_eJArEyGEaPdKRHkGipw0CejM,63841
eigency/eigen/Eigen/src/Core/CwiseNullaryOp.h,sha256=cPW5ApD9Ddx10LNh324u_0-7vZl_W4kyFArFgYAgJN8,36282
eigency/eigen/Eigen/src/Core/VectorwiseOp.h,sha256=taEMnk7xoASOi9F-UUNUseFkex1wDVkHbB-jTs8EvD0,35168
eigency/eigen/Eigen/src/Core/ArrayWrapper.h,sha256=i9CnjmTAjDy95K81Nv_m4GKhLOnHMhxDoUaXBKk3zOQ,7018
eigency/eigen/Eigen/src/Core/BooleanRedux.h,sha256=Udvh6C02Obp9MLeU4KmYLPizv5iZVWiJcNS81yPHCqU,4429
eigency/eigen/Eigen/src/Core/Transpositions.h,sha256=OQ83uchr7R8XCMX3eGtGCWZYIDcKQ3oiLaMgowx7mGc,13567
eigency/eigen/Eigen/src/Core/NestByValue.h,sha256=XpO9qFQqjr-zIdyRmbEQpTri-48sIOELbyTkN5sKJ8s,2520
eigency/eigen/Eigen/src/Core/Ref.h,sha256=9KCGVMNnveUblYknmVbCOht0eniluU60x-Q_Fq4mLrw,17821
eigency/eigen/Eigen/src/Core/Reshaped.h,sha256=UQGxKCGDdGABPnCtstVC9eYjzdZUHTYEr2KNKnjefhQ,17033
eigency/eigen/Eigen/src/Core/Transpose.h,sha256=qhBLL99zcYMdT87iOD3spTAMSYBbmaPIg-E_QLEiV1A,17606
eigency/eigen/Eigen/src/Core/Redux.h,sha256=3Ntognx_kGOvdFyaDh6Fz1PApptn09SIATSi747R8_Y,19195
eigency/eigen/Eigen/src/Core/NumTraits.h,sha256=YDlXi0wX8kTrbgsY8puAictK_71EMTZeT-iySCWRmfE,12884
eigency/eigen/Eigen/src/Core/CommaInitializer.h,sha256=qAJ2QnYid9sBFKj070CQMDVIQSHVtO35pQ1cEOEaGyA,5981
eigency/eigen/Eigen/src/Core/GlobalFunctions.h,sha256=NTFhnsI7k43_IwOaPw3Ykr5TP2PWgcfWWWZZ27CuMaI,11543
eigency/eigen/Eigen/src/Core/Random.h,sha256=_JWxS-8mkmR8CJGyWQbKyYjpUZ5fcZ2w_Z5k4PrwpsI,7756
eigency/eigen/Eigen/src/Core/Diagonal.h,sha256=DohU_IOblBq_OwllK1_sT6WnzTpErPy1J0p3c7abL_8,9870
eigency/eigen/Eigen/src/Core/DenseBase.h,sha256=ho6oVZqhHldM5zShTqVvXOUDJ0ay1z9MjHkw-JxZgic,31529
eigency/eigen/Eigen/src/Core/CwiseTernaryOp.h,sha256=l9ngPHPhoQE1LYsA7hkQE7a2rPAOkMiH3VS-pFUd574,8256
eigency/eigen/Eigen/src/Core/Select.h,sha256=C5vueNWTUBIRCHeLutIDpGPYHHG_tc1zK4WcAmBaHrU,6143
eigency/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h,sha256=GjBksbLTUh8dSwIroBAzFAZd3pNmaGzgwq9y_AezhAY,4126
eigency/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h,sha256=sYJHOdyCm91ch9TiA1eUIw9eqOMAeXfjeDmeGVYrmPM,108448
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h,sha256=lz3gcCibomI0C11GP9WWJfLxJWkfozIuaeKPWNp8KoQ,6936
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h,sha256=ec1yDwUGvK3GAOot40BaRFdTbko1vrQHgWH3X3YTT2c,5106
eigency/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h,sha256=mZtYGatUC0-bugfLV3Y81DPJy8H-pm4F2hKqQQZOdpM,6368
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h,sha256=33qhvQHkXEfnHqOM5XnYH1t5qlXe1A8haFgClGVk7CA,20104
eigency/eigen/Eigen/src/Core/products/Parallelizer.h,sha256=LFS04pfAyxh-5HrsMZ7q00Om_P2z9BTUJ1i_1o_0k40,5582
eigency/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h,sha256=tBWrOcXAPqby8_dJumI0JLnx4PfqHn33HhYPLuOReW4,15948
eigency/eigen/Eigen/src/Core/products/TriangularMatrixVector.h,sha256=pFx7Lk-jLFI3L51jXGWZoYRPkFPt2RCHdOZJcrC9yP4,14722
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h,sha256=X9VMtikMlDeHUmXltnN5f0zbbkXHkf4CR7QeCY4zEFU,9958
eigency/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h,sha256=e755tKu-x4ef6xyEwr-SuOUDm6p6e8_u6d7LOr9URVA,14678
eigency/eigen/Eigen/src/Core/products/GeneralMatrixVector.h,sha256=6ghVCEVie_PXwK0w7XBh1euVkLH7VI_T2P3pBnB7EfM,21724
eigency/eigen/Eigen/src/Core/products/SelfadjointProduct.h,sha256=DkewFi5s_R2NwxTXy8EFUpk2sDqAL1RsEibRG2o42-Y,6164
eigency/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h,sha256=SsT_NUCdiHXlevXOyArnxTe2QDTicg1AH766Tscmh0k,10571
eigency/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h,sha256=sJu-wvyIjUQml9JtYlcfGpkbShLzR3SJMPNZLVN8Odo,13867
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h,sha256=EKrXRBTWeuks1FjFJn-ExEHdLD3oJs1PkzOqBCzHaxw,5209
eigency/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h,sha256=2cKW56cfUCooBLv4pwS09ehmtZeNb5QWhcNUi6XmqEI,6707
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h,sha256=dO0QzTSlEY0DALfJHNCLv-VqyWWdGKOD640qrzoHDOw,11570
eigency/eigen/Eigen/src/Core/products/TriangularSolverVector.h,sha256=X-vXZ8N5pXDF-RiweJD3XIe_muTWsPVlRW8nWzCNEL4,5882
eigency/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h,sha256=inJs7op1I5ker51aTO8raRwxg5TWT0svVeE1iKWZ7RY,20987
eigency/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h,sha256=4gQBLDrdPARSB7Xk5-7qX4O_PanQxvfih6zqHFiksi0,21354
eigency/eigen/Eigen/src/Core/util/NonMPL2.h,sha256=RekKBVaidiOpEb9sm8gcs9_LyeyC3OKOSvf4JV6l2tc,85
eigency/eigen/Eigen/src/Core/util/ReshapedHelper.h,sha256=IiSNYQUioI1RXHJZb45ppb0PaTBUWphGxXXaVRGbNRI,1432
eigency/eigen/Eigen/src/Core/util/BlasUtil.h,sha256=R4hliGvYhqOw9uIh_5uBG-N0InTR-iYMf71SWivFVxY,23156
eigency/eigen/Eigen/src/Core/util/StaticAssert.h,sha256=FuzHTQMY4HyEd5nmdXqLTd13adbwcHehgKfe8-620b0,10676
eigency/eigen/Eigen/src/Core/util/Constants.h,sha256=ttU2oem4zBxoX3xs95Tr5wpnIJk3D-V-R19soXOSNqA,21931
eigency/eigen/Eigen/src/Core/util/XprHelper.h,sha256=91FpxKLKPlGo5qxCP_NK2Ce_cyZMy736OxGtGfjvEN4,35762
eigency/eigen/Eigen/src/Core/util/MKL_support.h,sha256=SH8MIg1AuEGIdrXH2QMtNZc3TN_3kNQCLo9O6pMs9iA,4268
eigency/eigen/Eigen/src/Core/util/Macros.h,sha256=jXMlm0ukgubb0Rsx2Ih_01DfsINnANMnk0Rrumqxrno,52909
eigency/eigen/Eigen/src/Core/util/DisableStupidWarnings.h,sha256=Ytqy175AkKqgXj0sZYGySbc2Vya7dQbNyRBVL8g4bFU,4892
eigency/eigen/Eigen/src/Core/util/SymbolicIndex.h,sha256=2x8GtyOpQZncKMYU5NkdJatRYS08G9cFYnN2_x0Mnv4,12003
eigency/eigen/Eigen/src/Core/util/ForwardDeclarations.h,sha256=ZhdE6dxa1vvWMloGjxiNVqfUxTouV3vfAtIDLoP5NUE,15555
eigency/eigen/Eigen/src/Core/util/Memory.h,sha256=4lVlqmrj5hLCa5LP5zGl35DX7fpme-W5h8KAHHCyyVw,46661
eigency/eigen/Eigen/src/Core/util/Meta.h,sha256=TuaFXI83ZpuMhkgzQsVvmtBvLfxpq_5GkSmKjSqUQgI,29336
eigency/eigen/Eigen/src/Core/util/ConfigureVectorization.h,sha256=Puw_386FDIesp7rEXOK_GJiASoReKalUjD6Y5Mgq01o,19876
eigency/eigen/Eigen/src/Core/util/IntegralConstant.h,sha256=MsGgGP33vR824xB3MDJWbzUa_ztaANXyOeJNDCgJ7mk,10949
eigency/eigen/Eigen/src/Core/util/ReenableStupidWarnings.h,sha256=4CANL3bylEgx4MEpc_qnL6uwRFu6_WXHrlFquM1nreU,1024
eigency/eigen/Eigen/src/Core/util/IndexedViewHelper.h,sha256=6I-WuqgpdRGkOQAtI7CuMARenFQ4pLmzaA5BgtbittU,6696
eigency/eigen/Eigen/src/Core/functors/UnaryFunctors.h,sha256=kFshHJT8zGBHriYmc8ZEq4KcgnXpi29LiXjHPLNJRio,40146
eigency/eigen/Eigen/src/Core/functors/TernaryFunctors.h,sha256=D8PBqipa0vHKnNvPN6YzcSzARSsQftY_akzxDWcREWg,607
eigency/eigen/Eigen/src/Core/functors/AssignmentFunctors.h,sha256=2PGxIkRB-s5e_kJx1zVGg-wWtcvo7InnxyjBP_hb8WA,6686
eigency/eigen/Eigen/src/Core/functors/BinaryFunctors.h,sha256=CwfNbUDL-WVhgk64Cq5a9xnc_hxNNJsBEQCs21eCGZc,20921
eigency/eigen/Eigen/src/Core/functors/StlFunctors.h,sha256=cYI-b8vomEe7fK7xnoN7Hu0cMkQs340QQQOIjE_-S7A,4998
eigency/eigen/Eigen/src/Core/functors/NullaryFunctors.h,sha256=GQpjDoSCvAuUODxnubXXpB88JssQiU1UWXz949c7pws,8334
eigency/eigen/Eigen/src/Core/arch/SSE/PacketMath.h,sha256=peCG6Wv3h2vZ2gxDEX9IJDXQTNy8TPnBBMFyRCmAQTA,64465
eigency/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h,sha256=cAcwShFbn0K0g-TiyoNqDsV41oqJo_kMBI3evwdGc-U,6765
eigency/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h,sha256=Uq2Z3RJeG1t7ZICopSGTROezDe9xwI_nTRQwSFaELmA,3650
eigency/eigen/Eigen/src/Core/arch/SSE/Complex.h,sha256=h6bwXhEi-IZVCphcy3kVC-CZmTUtfLzoa77tZIohV6k,14251
eigency/eigen/Eigen/src/Core/arch/GPU/PacketMath.h,sha256=2KKjUpwiDgzbxMXoRwB7Fg5Bs98NsGn9RWqgvd0LoD0,57047
eigency/eigen/Eigen/src/Core/arch/GPU/MathFunctions.h,sha256=WNBXkzPWzZx-a9VYKr_u3A2mS80eARwiY8LdflRmT1c,2695
eigency/eigen/Eigen/src/Core/arch/GPU/TypeCasting.h,sha256=HR1OOHLb9NmrIsW2dkRBgmWgpkHibWw0DUgJyqO8Lpg,2256
eigency/eigen/Eigen/src/Core/arch/MSA/PacketMath.h,sha256=PaxsMC3KR2tfvd6eWHG3-vSEc_100mAsB-dIOiy4ZM4,33615
eigency/eigen/Eigen/src/Core/arch/MSA/MathFunctions.h,sha256=8WDhQFA0s_u9LNZOh6J8DQ-vkAchObk3v263HzaYPyg,16159
eigency/eigen/Eigen/src/Core/arch/MSA/Complex.h,sha256=mD175hijPLKuPWMgJG8Tn1c5uyUzdRLMJSzeY2SHkWQ,17541
eigency/eigen/Eigen/src/Core/arch/CUDA/Complex.h,sha256=of74nv05x33Y09JHA06CnpMGnhKM--ya7wKOi5XHhu0,17317
eigency/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h,sha256=F01Hv3MIEyKand_VxS4kvVHMgyBC4YoaepnphPKiIXY,36894
eigency/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h,sha256=AL5v8pbey2Oeuyd75kVVmD6O2q98waSnkKYnszN19Es,8024
eigency/eigen/Eigen/src/Core/arch/ZVector/Complex.h,sha256=5kgD19Zhq9EwxI7PhkRBwLnA1cXD4uioUIo7h_DbLF8,16728
eigency/eigen/Eigen/src/Core/arch/Default/Half.h,sha256=vN9CBcF-3crLwXXBpdGI2ys2yeUCmzgpB20F39pAb00,35534
eigency/eigen/Eigen/src/Core/arch/Default/Settings.h,sha256=Qbh6le3EAOdUX3JzxZdCq8ld765sp82F-WLVGnqPt5A,1746
eigency/eigen/Eigen/src/Core/arch/Default/TypeCasting.h,sha256=Tv47egCZ2kG0IEAACpxLkr1I77NblQXEU7Xz0wT7T3U,3746
eigency/eigen/Eigen/src/Core/arch/Default/BFloat16.h,sha256=HD-vLoEqRj0L4cfaszaO3mr-hNNPBCwAe8Xa03Xpa9k,26903
eigency/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h,sha256=a9Lk1ShhdtC4I3COGmmc9GlMt06_VPLdtngnDbXEZxc,3770
eigency/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h,sha256=4-8jZykCpqD-85ybbFlSup7WnmoOsy8OzBMAT8ZgBS0,67696
eigency/eigen/Eigen/src/Core/arch/Default/ConjHelper.h,sha256=-tVUil_T8-S8sW_ihUnuc8Ht5fnin2yQIr1NitPqpSA,5251
eigency/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h,sha256=OUFH_dw0sH2Keii8gKXt0fpe8_ZRAbU1bOFo0H9xwx8,87891
eigency/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h,sha256=05V1fuacBbf_IQEpvX9UIHv4q2RJCaKC9RhMjDVuMkc,13344
eigency/eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h,sha256=dSDpOtpAFcs4vLQTWSNai66TbSU53_hs1K-naDF1Gjs,2134
eigency/eigen/Eigen/src/Core/arch/AVX512/Complex.h,sha256=ugr3JzEmI5-3tHJRvigqfAue6meW37D3xBG-XzsJI8Q,17160
eigency/eigen/Eigen/src/Core/arch/SVE/PacketMath.h,sha256=ExnP6wxeTf-muQEl0kGqp9aFrG6ZB1WERaEkRJxX6v8,21200
eigency/eigen/Eigen/src/Core/arch/SVE/MathFunctions.h,sha256=ArIHSTscu776ZEoith1MvV16BxFAhvV3iLYdC4zYHjI,1194
eigency/eigen/Eigen/src/Core/arch/SVE/TypeCasting.h,sha256=euzd4LBaPcZvuqE4w2WMiFyysQSYE_No9MdqGfO7vjQ,1351
eigency/eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h,sha256=TYakFU7yBjjXKrL1hexh9sCIGQjZhqK0_7RO-pf5ckY,691
eigency/eigen/Eigen/src/Core/arch/AVX/PacketMath.h,sha256=I0SozIfkw1iRU0p6x93nPgEpNeDNZWmbGO53u-aX_kA,64608
eigency/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h,sha256=c4oN-JVUz9ohpSw7pG5Hvf-eNRmceI3Y3U2bo8FZgQU,8102
eigency/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h,sha256=LKu4896ma5FgFwWLY-VC0hih7Y9Z7Dlv8hrjV0tZcmw,2564
eigency/eigen/Eigen/src/Core/arch/AVX/Complex.h,sha256=TReBJLZKy19ZFalvKel_Lr49xEIICFGZvQksN8hBbxA,15223
eigency/eigen/Eigen/src/Core/arch/SYCL/PacketMath.h,sha256=dZkkF8ku0zF__pcYkyFNCekEhg3xBi9NDPTmUDiwpLU,27786
eigency/eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h,sha256=Szum19_ng_oX-Tt_oykOHuEHsUkF88gV5OE36aMupD8,12539
eigency/eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h,sha256=IIOs2E1g5_iKaeuF-aC8ygJw6tb8KnDLzklMhkwGQ1k,21856
eigency/eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h,sha256=2G5Noo9_d_MvJobezN9exX1zevfW_lo6lf63Y1j1OTQ,7428
eigency/eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h,sha256=B_oAog8UHkDn2lOO-DhVRoAaAWT2Wt5sBHWAIKC9_7o,2626
eigency/eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h,sha256=VNMQHhSfKRhI0RcKJhalOI8skbh4p08tMWPagiB-p6c,6815
eigency/eigen/Eigen/src/Core/arch/NEON/PacketMath.h,sha256=PhMYCg3QG5ppvRfxeqhpw4xFFd8cyDBDuI9D2aExt18,189525
eigency/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h,sha256=jNj21p4bjGDqqIwPlR6rYZuOzpAzk9f5DXJqpIfagW4,3083
eigency/eigen/Eigen/src/Core/arch/NEON/TypeCasting.h,sha256=c2yYt3iTKrpZFLQY_YEKE1V6LreGtdEec2goqfPucIE,51286
eigency/eigen/Eigen/src/Core/arch/NEON/Complex.h,sha256=yyJ41YOVRLrIqws49Ddbi63_scdGqNavmXZv52Sv7fY,22503
eigency/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h,sha256=oPYdaGjd2Dt3f1b3YAbzU5W73cgIz7_aDhzQ5-IeSi8,102394
eigency/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h,sha256=GkyOC20PLKzbUW2SJhPzqSvHf41jfZjcomaAZs4N10s,2323
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h,sha256=qH4IawNh5kCC5e2EeYvbh8l1BfYlySMO4rDAqWtOqsY,119355
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h,sha256=MRJTWUfUBVYsDs189H1oIBeoYwbK90anZxJ1w_Zqk9E,24820
eigency/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h,sha256=BOcTnv97OFhluX8S-H-c40gQEoupm9BqXPOq_PoJ-04,9490
eigency/eigen/Eigen/src/Core/arch/AltiVec/Complex.h,sha256=CUSoZRzKfCXxeQfELlIb5y879_nskuYPPpAa34ADUeE,16540
eigency/eigen/Eigen/src/SparseLU/SparseLU_Utils.h,sha256=VfbLFtU8hQaZl3sijSs0KKJ1Ok4eH0kZwfSlAD1CchA,2049
eigency/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h,sha256=wsTY9YnpE064Zp-tp79vhsn31leV4rkHmVVkjQaVWCU,5723
eigency/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h,sha256=UEFzzPnZoMvp_q7hyaNJaMQaivnuKGgfU8OMcLkY9Eo,6712
eigency/eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h,sha256=E0ypMty0CtJ9jyiQAlbsBrUdgU3t1IHhLXoq_29kP6I,10217
eigency/eigen/Eigen/src/SparseLU/SparseLU.h,sha256=0jr8FVLqbXlYeSoQFJCA8z9Wp1gUZj-rM_8Zz7Dd4FM,33316
eigency/eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h,sha256=_1ukmKpCiPxqLHP_sW7wwJF0f58LNzJmb12dl1duO3c,6584
eigency/eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h,sha256=HHxwbCV4bDeDVwo6Pl77jhTnCVAinCQ10m2ozi0_xDw,9028
eigency/eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h,sha256=xmWkJ3HrCeYx_o2b7V1NtTwoskgt84Fzmg5OHO4ZJNY,2889
eigency/eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h,sha256=6H52qNW19OTAgaGACscVS30r9ZZjktHYzS4aEIxFPLk,4181
eigency/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h,sha256=E0ZMPmU59QNrxZLBFDQafZpbW30yduzwYIJux419A10,8485
eigency/eigen/Eigen/src/SparseLU/SparseLU_Structs.h,sha256=iiBKapQJWGE1_1IYQg3G4Tifza4c_gcnUP1EeKg5RhQ,4974
eigency/eigen/Eigen/src/SparseLU/SparseLU_pruneL.h,sha256=xbkTSkO6Y2EGGHWy8zHDVbEgOUJjm_bQLbHV7OOhWbw,4545
eigency/eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h,sha256=xuejAH5T973lZoxXrfTfZMrp5d_GWWOEUzeSsqRaFjk,3681
eigency/eigen/Eigen/src/SparseLU/SparseLU_Memory.h,sha256=0RtpqZwv2VeoYnL1E_2W55Zf-Q8GJBfCGWKnJVSMNKo,7602
eigency/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h,sha256=WtGmsoGD9gUhPImH2f4V3RfVeHbbyVghDsPtAhMwbFs,4979
eigency/eigen/Eigen/src/SparseLU/SparseLUImpl.h,sha256=xqFVMyyht4lOAPP36lz-OLTKDLLV4_abAlxAE358DkA,4303
eigency/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h,sha256=XEsGCbVbRuN7n3frLwrGupWG9vKhkYHBzFVmbY6Vflo,12837
eigency/eigen/Eigen/src/OrderingMethods/Ordering.h,sha256=zQaPZlp5hpbFNKmxRQx42zI6Y3E9uTa7ddt5tP_1LJM,5248
eigency/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h,sha256=aGVdr2uuSAuOnywk06Ox5iRwLxWsHoxIHuOpuiYJgOs,61681
eigency/eigen/Eigen/src/OrderingMethods/Amd.h,sha256=c7g7u_79UNDMwQhqLLF-io6d843uZM7zEBkL-BrNMZw,16105
eigency/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h,sha256=Lw8DNEdrrQmtr1uj64wlKMK2qzrkchCDLL0nY4hRP0w,21431
eigency/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h,sha256=KounaHKSxrMBzP7sUcUSdSELN0QhjCSXsYZbU3DYMlY,6089
eigency/eigen/Eigen/src/plugins/BlockMethods.h,sha256=VP5GDS9pFosNtDF1bpa0pUZ9uqpCas3CG4elB6fCaw8,59020
eigency/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h,sha256=3J685GySQ-w9ATdG_yU5K2_enofrPBBjhYzBaHXBnUk,14060
eigency/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h,sha256=kOqEkZJMkAgDl_sePzPQ4ahC9aO4C5n8UqIGUZWMaYI,6387
eigency/eigen/Eigen/src/plugins/IndexedViewMethods.h,sha256=XpWD8sYQXjvwE93Br-KgaFtKugYO9hEERuk3l1QEZUg,12283
eigency/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h,sha256=H4qb7Ef81ff1KdWVbhXaLQ0yURh5vfYT05-yL7ybRJg,4828
eigency/eigen/Eigen/src/plugins/ReshapedMethods.h,sha256=OYyO_yoZ3TL7X8GFrIW-IKzqs_1LbM0M96HJyZAVOi8,6915
eigency/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h,sha256=hBC2LK2aHti-DqelsfGCGw5zMMxqaFjIyd_DJ-Sd17M,3350
eigency/eigen/Eigen/src/Householder/HouseholderSequence.h,sha256=qJx7vJqOfwuk2bOCwT_qSA4uQRA5uDK07lhMOmJNTOg,23611
eigency/eigen/Eigen/src/Householder/Householder.h,sha256=Sm81woK9lvrX8YcXqLStZqdoHyWUxO9VlLOzE2iOiy0,5365
eigency/eigen/Eigen/src/Householder/BlockHouseholder.h,sha256=gT-lKuZc5n9FylQ3dARF5S0a7M4J93mT7oRzI87Koa4,4784
eigency/eigen/Eigen/src/PardisoSupport/PardisoSupport.h,sha256=wsVkKSSLM_PyT6okkE-68CY-i9uw5JQK-J_49b53K0w,20092
eigency/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h,sha256=pKMa9HSZVf4TDrSs3WQPHm81-yvYWN_X3QbDGXZhChs,25889
eigency/eigen/Eigen/src/SparseCore/SparseMatrix.h,sha256=Uahcnyjjk9enq1aUvlnqI1d5zBeHSv8rHDjVr8BKufs,57475
eigency/eigen/Eigen/src/SparseCore/CompressedStorage.h,sha256=KbsmaOECLX-_dCrw4l5OH8qSYthcNl51lHEUrOAElfU,8743
eigency/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h,sha256=UM8IsTqnqOIVvcVPNMI74lkGu0TC7c1-3OHD4E00U7U,25524
eigency/eigen/Eigen/src/SparseCore/SparseView.h,sha256=tt7YUvbYq4FC7o8OjMRAE5ENMAyDgBjJQw23fkFxKYI,8127
eigency/eigen/Eigen/src/SparseCore/SparseColEtree.h,sha256=hxvhX86IU5AEN0Re5JE7ugycPWrwjmMT8965y5Fuk0Q,6485
eigency/eigen/Eigen/src/SparseCore/SparseMatrixBase.h,sha256=vKuTKTtOY6UAAogaE7yVSPElvanBCqJB4og5B7kI21g,17451
eigency/eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h,sha256=ql1gDrRmdDxurRXKYKt3558VV56rwkkg39q1rmNjUZ8,5808
eigency/eigen/Eigen/src/SparseCore/SparseTriangularView.h,sha256=wLzim0CxFIHthPPnf-BETneIxDpr5os7WMmm22Ihps8,6437
eigency/eigen/Eigen/src/SparseCore/SparseAssign.h,sha256=V9_BJwEgsy433vZPaZkNcz7VHaUtxFty8DrG2y7Bby0,11368
eigency/eigen/Eigen/src/SparseCore/SparsePermutation.h,sha256=MOCjCgQY25pYtPMQhvGvkRk8koWuGO8dk0QRMqStiM8,7329
eigency/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h,sha256=Gt77DWmbFD21-2tgm3UCHDFB3vFqg07ZzPOmK1sYdU8,4757
eigency/eigen/Eigen/src/SparseCore/SparseMap.h,sha256=LENinGDgzP-0fSLxe9IC2QmTGpvw6-WmYZouy98GH6A,12589
eigency/eigen/Eigen/src/SparseCore/SparseDenseProduct.h,sha256=S-SIciqeQ8Cq0eRnjdwO0W-nJTdWrJ9cDSyUpTKDnwQ,13256
eigency/eigen/Eigen/src/SparseCore/SparseRef.h,sha256=KpWEyz-BSDQr2jkFY41qpl81k1xobd09MroJeAet90A,15600
eigency/eigen/Eigen/src/SparseCore/SparseFuzzy.h,sha256=-HvMRkGwLuoeAVRUzaTxJOZerK1LKoF7zIhUntzpE3A,1107
eigency/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h,sha256=LqSrqm_EN6KXQXTFIExr2w5AzGtZ39M70CDZwt1mDto,2191
eigency/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h,sha256=oJ95Mr8PoxBlVcuyIk83xAnA9B8BTF8SLFFr8JLzMcg,8704
eigency/eigen/Eigen/src/SparseCore/SparseSolverBase.h,sha256=_FJeIwvbZvS6TXnQI4bqcW07AeultzRTOhcfBDogpHk,4424
eigency/eigen/Eigen/src/SparseCore/SparseBlock.h,sha256=B_Rou_EU1DXsnaBNbKC5QPH9fWO2JUjH-dgTBVC0JFE,24360
eigency/eigen/Eigen/src/SparseCore/TriangularSolver.h,sha256=6crxaL_epxj6kAKDRIOV3leRsjdoPfEMrwtFPPTtMU8,9657
eigency/eigen/Eigen/src/SparseCore/SparseVector.h,sha256=FXR2BBlYjN74_Y7HGt_xK14qGY93lmZOLi7FEZNW4h8,14832
eigency/eigen/Eigen/src/SparseCore/SparseCompressedBase.h,sha256=i_QDAUmYXh_o_or8Ooc6-OHwzl88PFIjK1gK1uTxENc,13606
eigency/eigen/Eigen/src/SparseCore/SparseTranspose.h,sha256=vzGAkYMV3rfcQz-g1POI16Qgn6QweDzJ2ANzq4i_1y4,3175
eigency/eigen/Eigen/src/SparseCore/SparseProduct.h,sha256=XL278sDrscm5H1ClbMyWtp9zMF-KoM-vecd-fXEmZZ0,7593
eigency/eigen/Eigen/src/SparseCore/AmbiVector.h,sha256=5rbOU6LmuocubflDlpHJW-LV8RbLVt52PxlNwAD-24Q,10670
eigency/eigen/Eigen/src/SparseCore/SparseRedux.h,sha256=8-aCkMrV-7ug7PgoT6I4pSByEI4zaMBjL4yQgWtB3JE,1699
eigency/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h,sha256=NSTC00y1pePE2y11NaWiKkV-cZ7iQDu4D0uQdlX1aI4,13166
eigency/eigen/Eigen/src/SparseCore/SparseUtil.h,sha256=QbJdHLBXVilPHMYRlJUpu242IYXCyljuRWU6Gg0CHyE,6827
eigency/eigen/Eigen/src/SparseCore/SparseDot.h,sha256=qNMFtSwdxuZrJALftuwc1Uln8dXPHn7O-B6HYnfXh2c,3080
eigency/eigen/Eigen/src/Jacobi/Jacobi.h,sha256=eqr6CeolwC9s94yeCFlGF_MdSvztGqDr8OLnT6XDp08,16383
eigency/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h,sha256=aBRbczGluCFCW0z6zj-VPv3fPnseGS5Y_LWtCTPvugE,11826
eigency/eigen/Eigen/src/QR/FullPivHouseholderQR.h,sha256=0mO6wR2Oz4LkO-63diixti5mRpEwlK1j6JQpXTjknh4,26768
eigency/eigen/Eigen/src/QR/HouseholderQR.h,sha256=buDUUKKkR7GtuG59nGmnZOHPuPOfnWqZ-omhYq7e7t8,14641
eigency/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h,sha256=K80XQdqtt7GtaO6trSe9d-6SvwF_dmYkTK-aip00P9Y,23429
eigency/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h,sha256=Pg4g_uASg01GUvKv85HZ10mcLIb2TsBAe8TxUIUzMbs,4662
eigency/eigen/Eigen/src/QR/ColPivHouseholderQR.h,sha256=GRplSpNfH9u1hGj-UO_0ASrJsqUw1X873zHylf98Msg,25498
eigency/eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h,sha256=ioSGFFyQnCEIqvG71bRI-RwLslUwcNpeThs4Zht2qoc,2993
eigency/eigen/Eigen/src/SparseQR/SparseQR.h,sha256=b7kIX0lfsWOEXscFjviaUOKMkieFnGnPdkHNOIC07ms,29167
eigency/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h,sha256=ka623NBfDraF1xca6Y-VNZlJPWUcPuw7DI35DlnSLpo,5099
eigency/eigen/Eigen/src/SVD/SVDBase.h,sha256=7BZYx_gFqsiiYhobHmP6hKj-0hx_JOF27IYqlFViMAo,14743
eigency/eigen/Eigen/src/SVD/JacobiSVD.h,sha256=hAnEE_IZPVHqlmnC8LfSgDGdqVJlo1wyP6vGX4pAcQg,32988
eigency/eigen/Eigen/src/SVD/BDCSVD.h,sha256=_W5LHUpTg7pE48jCCqoZf6JbGTuUBQ76x4EEknP9Er8,54214
eigency/eigen/Eigen/src/SVD/UpperBidiagonalization.h,sha256=6IpmJCGMm2kzzhJeLAPQNt-cSmdDm-UceOm5QNDSH18,15957
eigency/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h,sha256=Hvw3IINOyWug30oGIqogw6gK5I2Q1gz6rV4L-cHPoEs,3974
eigency/eigen/Eigen/src/Cholesky/LDLT.h,sha256=zGNi3c3eoUA-qewcvqLKbq8cWHRjDxsTCE9Rx48znXg,24934
eigency/eigen/Eigen/src/Cholesky/LLT.h,sha256=Ni_msIDJtn0REG-CH5JvqE7SSyEg-9uioJ77CGnu8ew,18760
eigency/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h,sha256=to6gjstZ3u7FA3DBEekczSMwUP5inY9UoSRyeSP-6nY,24456
eigency/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h,sha256=YMCQ6x4_-d79glE5ruPlzad6znhQFY02gqV0ymmGdsY,6771
eigency/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h,sha256=l_qee65b_AyF54NQTEhqiQn4wpxF0EOgQfrjzKM-Z-o,15036
eigency/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h,sha256=skUBIA1GTm3pchMagwn-Q0vElsbBKyOXqVfZ6Ig9gp0,4212
eigency/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h,sha256=9N6ZL4g7dpQ1-C_AYBr2jV4R1nrToYgg1CJSstT8VIQ,14940
eigency/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h,sha256=hxTZyH0vfNtGucFrc_JnlmaBnvnbYwpV6lnJVrQZDB8,7349
eigency/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h,sha256=bAe7AXzOohoeR4hASXMS6QKHt2GIAwvEXN1zwa32EdM,8887
eigency/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h,sha256=JAMwkJDDKrvMpaK4iCZQ3vhXaqbDleMsAafEft8Aay0,6850
eigency/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h,sha256=RVUk3D9zTiShzR68o8N4qlsrbnu3xHAY-xCHP79Ixso,13379
eigency/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h,sha256=405eiTTFwaWRyj6v0acEWJjEBKlbk-6zdEZqEnjERiU,3555
eigency/eigen/Eigen/src/LU/InverseImpl.h,sha256=YcMuvxXWRaOKJJgf6YzAL6UanhW7sVAwgyyWOSahVeQ,15727
eigency/eigen/Eigen/src/LU/Determinant.h,sha256=Ej8IFYHDjgeiBM8MsooiCpbZMFH8fADI0ZuaGG_C-yc,3439
eigency/eigen/Eigen/src/LU/PartialPivLU.h,sha256=Lb6kmlOg7MA18WeAQAj0y0ZS5J-hiZ-kiIzX0fbApks,22069
eigency/eigen/Eigen/src/LU/FullPivLU.h,sha256=cC7S7j5wQlYzGYKS6YnPMIVZ5k_aFyKE2vR1UZMSpHE,32383
eigency/eigen/Eigen/src/LU/arch/InverseSize4.h,sha256=jEo1e85De1QKK5gpSB3wUciHnvmr4QgS4YThDNIgNQI,13693
eigency/eigen/Eigen/src/Geometry/AngleAxis.h,sha256=hWEB6P7KkVOjUDyiPkdVZ7v1PofDUIQFQDVguHGydCU,8403
eigency/eigen/Eigen/src/Geometry/RotationBase.h,sha256=EiowLy81k6w5UeRAjH0UBDYKAxuqA4Bhe6HdbdZFGMw,8063
eigency/eigen/Eigen/src/Geometry/EulerAngles.h,sha256=MvmHhZbH0Nf9YzZG8B8YjXvHXQsWz3W8HY-bbCXoX6k,3624
eigency/eigen/Eigen/src/Geometry/Hyperplane.h,sha256=L5qiKx7H8mhpvf3eXhPCpcudz_jw4XJ7nvaEty82qtc,11962
eigency/eigen/Eigen/src/Geometry/Homogeneous.h,sha256=GubxVxEyxSFiZiGMTfln7dmXw3ayq55IrdJ5R-oxb98,20726
eigency/eigen/Eigen/src/Geometry/AlignedBox.h,sha256=LJX63IVJ-iNtb4qjgCK635GG1jrtEqECu4Brzw9tUi4,18939
eigency/eigen/Eigen/src/Geometry/Quaternion.h,sha256=jigf4p9JcYKOeQ8zRlP8qq_jSnhTsO7OQiSmOhzPH6g,34367
eigency/eigen/Eigen/src/Geometry/Umeyama.h,sha256=8WBq8Bq-eOCwCPpCEJvCV4AdG9i--MYPuIQzekjltHA,6190
eigency/eigen/Eigen/src/Geometry/Translation.h,sha256=MQelKqMEPMYDxBx_o_Bin1j4nlL5aQrunz3_TYrcRjk,7664
eigency/eigen/Eigen/src/Geometry/Scaling.h,sha256=VP1L8yU9-kjXgRpJRDQ_Mobm4F6c47WBQu2qF75qbOw,6724
eigency/eigen/Eigen/src/Geometry/OrthoMethods.h,sha256=PUA_fyzkfUoG16Tlvi82LCsO2Lx8LARN56CfsjGVbEQ,8955
eigency/eigen/Eigen/src/Geometry/Rotation2D.h,sha256=ZJF39LieDyLVc82wCBjcv-89XUmjgiP8_FGtW4lhvOM,6862
eigency/eigen/Eigen/src/Geometry/Transform.h,sha256=_LyXBb70PoLUGeas7TkZRADBH8gHKJp01ui7RmJmesM,61930
eigency/eigen/Eigen/src/Geometry/ParametrizedLine.h,sha256=_XBm00cMu2GvSxc_Vq0Lw3CY6gPQPmLreuj3-ZhGkSE,9812
eigency/eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h,sha256=K0pUdNdQMSUnnx3iuujvVvmaxS3-zTIY__XXkCd3mno,5945
eigency/eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h,sha256=wmnrpnMFQ2KKgZJ2YZ0sGwtnORWfNB6zVx7yV_-mIzM,34324
eigency/eigen/Eigen/src/MetisSupport/MetisSupport.h,sha256=x7X2CnuvlYp6C0a_SEUYueSdVryY74llxUM718ZPJk8,4588
eigency/eigen/Eigen/src/StlSupport/StdList.h,sha256=_PoP9JjpMxFHyRt2ierD07kKYw5YCaQ-m2uff_9bv9A,4155
eigency/eigen/Eigen/src/StlSupport/StdDeque.h,sha256=nwcLxBznnCK-XXIVzLj6m3TE9vNf6hCB5rEwVglEMtA,4730
eigency/eigen/Eigen/src/StlSupport/details.h,sha256=N4XAZ1MVBkj5Wqqf0purzw8BN2oBMqkenPyCC7ZUF4E,2809
eigency/eigen/Eigen/src/StlSupport/StdVector.h,sha256=ZMFTM2irx-ZrmNDMIYCyoRRWvfNdab18XXVN7WYgh4g,5338
eigency/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h,sha256=dFdpa-FOJlaOirwy9MZadsnMjesv7vwHpXWVky5bSPM,5830
eigency/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h,sha256=oJz3HAOgW9nflw7znky97aP_SJz7S9vwhOhelWfXe_A,24216
eigency/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h,sha256=gjhXg_YIsizsBpnfbljjuOn7zmtAkz0levvRZRzXT4c,17176
eigency/eigen/Eigen/src/Eigenvalues/EigenSolver.h,sha256=dk5LGEjuFvvUJFChALix6WXx-S9Buki-srtgELoLhEA,22970
eigency/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h,sha256=MKr7VFn4KX1oUapqi2USdVZdn6pFEzLQSvUHE8BDVis,3650
eigency/eigen/Eigen/src/Eigenvalues/RealSchur.h,sha256=YIcKltQsAZXPrfkWnM44lWAviB4EDQ8x_1ZKlaPqZy8,21078
eigency/eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h,sha256=_WVTQ369kknRbjGuKu7XPJg8r6PKuDXMmCk0PlzO-k8,4178
eigency/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h,sha256=mnlGNd83WlBplAPiJBD2ptx8z-yFtqasH7oEygEFEEc,22764
eigency/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h,sha256=O5VrdbpZMSheCsU_bUsr7VH_sJUo5Gh8Rg-D0nEt6Vs,14349
eigency/eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h,sha256=slDfS5K-VOr0aXn4M4QT2IfQEcHoH-W3HcqYqFqKY1c,12559
eigency/eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h,sha256=4_rDPfwSRhuobLvKWLsS2dR1C_1O6ofWPX81JKXTsIQ,9716
eigency/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h,sha256=WVrgd6o4MYqGf6ZUP-qftealRVMvJ9Z2lYzB-ubvb6Q,4104
eigency/eigen/Eigen/src/Eigenvalues/ComplexSchur.h,sha256=ZxIzjl0HXd09pS0vKLopsZLqR5IRwJcWGETc0Bgup5o,17274
eigency/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h,sha256=C9q8ME35ACSMx57vfhud9XprJYazudk9QhNEuAbCbuY,35182
eigency/eigen/Eigen/src/Eigenvalues/RealQZ.h,sha256=872Nd9lFrTCQwhtLWCyAtnZeG1mnaGWi1Q60IqVWGYo,23640
eigency/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h,sha256=uxKK8knBdzSTGVJCn8qt07J_SqGDtNfT7e2z4wq1Jeg,5575
eigency/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h,sha256=guI9MhWY5GTjrYXHWWRI6mXbUfaB23ooNEgTM35fLvA,22249
eigency/eigen/Eigen/src/KLUSupport/KLUSupport.h,sha256=txjmMFEbp2X2xCmPMDheZGtR-wA_AnQWSCSnn7sAVRQ,11555
eigency
Wheel-Version: 1.0
Generator: setuptools (82.0.0)
Root-Is-Purelib: false
Tag: cp310-cp310-macosx_11_0_arm64
Generator: delocate 0.13.0

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display