Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
0a9916c
begin to code minres
Lucas-Haubert Mar 10, 2025
8f712d7
updated llt and ldlt
Lucas-Haubert Mar 10, 2025
681bdcb
minres and qr decomps to debug and test
Lucas-Haubert Mar 10, 2025
f32859f
update
Lucas-Haubert Mar 11, 2025
4e7092f
working on minres
Lucas-Haubert Mar 12, 2025
6a0ce33
upgraded unit tests
Lucas-Haubert Mar 17, 2025
43b6112
added decomps
Lucas-Haubert Mar 19, 2025
65761ed
pre-commit: update
jcarpent Mar 19, 2025
98c85ab
pre-commit: run on all files pre-commit run --all-files
jcarpent Mar 19, 2025
ea7f65f
git: ignore pre-commit previous commit
jcarpent Mar 19, 2025
dfabafc
cmake: fix project URL
jcarpent Mar 19, 2025
32db75d
cmake: modernize the packaging
jcarpent Mar 19, 2025
a122ac3
[cmake] nanobind is a find_package(), because we are not supposed to …
ManifoldFR Mar 19, 2025
42724f3
Add 'tests' subdir to gersemi defs
ManifoldFR Mar 19, 2025
1480a16
[cmake] add all headers to the nanoeigenpy_HEADERS var
ManifoldFR Mar 19, 2025
ce673b1
Nanobind requires Eigen 3.3.1 minimum
ManifoldFR Mar 19, 2025
ad62e4f
Remove redundant include
ManifoldFR Mar 19, 2025
20ea064
Add static_assert in SparseSolverBaseVisitor
ManifoldFR Mar 19, 2025
0ac788e
Add static_assert in SimplicialCholeskyVisitor
ManifoldFR Mar 19, 2025
807901b
Do not use EigenBaseVisitor in SimplicialCholeskyVisitor -- simplicia…
ManifoldFR Mar 19, 2025
a2c7fb2
Re-expose quaternion and angle-axis
ManifoldFR Mar 20, 2025
e62d5b5
Move 'decompositions/base.hpp' to 'nanoeigenpy/eigen-base.hpp'
ManifoldFR Mar 20, 2025
2feea2c
Rework fwd.hpp - introduce macro to check for CXX20
ManifoldFR Mar 20, 2025
cc29d11
src/module.cpp : fix exposing Simplicial sparse solvers
ManifoldFR Mar 20, 2025
1cb6e59
SimplicialCholesky.hpp : return decltype(auto) (hence, reference) fro…
ManifoldFR Mar 20, 2025
1fdb180
[cmake] Add CONFIGURE_DEPENDS
ManifoldFR Mar 20, 2025
4207912
Change typedef
ManifoldFR Mar 20, 2025
21cba24
Fix angle-axis
ManifoldFR Mar 20, 2025
4656b5f
Fix install dir for Python module
ManifoldFR Mar 20, 2025
ad472d9
EigenSolver.hpp : remove unused include, fixup some rv_policy and
ManifoldFR Mar 20, 2025
755ecf6
Add Eigen version, expose SIMD instruction sets in use.
ManifoldFR Mar 20, 2025
bea40b9
decompositions/llt.hpp : do not define variable cl
ManifoldFR Mar 20, 2025
908d82c
renamed hpp and py files with convention
Lucas-Haubert Mar 20, 2025
e7c98f2
Add spaces between copyright pragma once and includes
Lucas-Haubert Mar 20, 2025
1824c51
Convention in the includes between brackets and quotation marks
Lucas-Haubert Mar 20, 2025
8169153
Removed export values in computation info
Lucas-Haubert Mar 20, 2025
037aff3
Removed compute proxy intermediate function in eigen solver
Lucas-Haubert Mar 20, 2025
71a991b
Put references on return types of lambda functions
Lucas-Haubert Mar 20, 2025
ba56853
Added IdVistor and fwd header
Lucas-Haubert Mar 21, 2025
7b9ab61
Convention templates MatrixType and others with underscore
Lucas-Haubert Mar 21, 2025
7bdbbac
Added implicit conversion from AngleAxis to RotationBase
Lucas-Haubert Mar 21, 2025
f7ee9c9
Corrected argument type in compute and put MatrixType
Lucas-Haubert Mar 21, 2025
1ae3eb7
Debuging minres with incorrect solve method
Lucas-Haubert Mar 21, 2025
a7a5142
Added code for solvers to debug and test
Lucas-Haubert Mar 21, 2025
5e63491
Tests geometry
Lucas-Haubert Mar 25, 2025
277f4e4
Merged the upstream/main for pixi
Lucas-Haubert Mar 25, 2025
d7caee9
Removed commentaries
Lucas-Haubert Mar 25, 2025
a504588
[tests] declare all Python tests
ManifoldFR Mar 25, 2025
5a996d1
quaternion : expose "==" operator, test for it
ManifoldFR Mar 25, 2025
498a72b
merge test_quaternion.py into test_geometry
ManifoldFR Mar 25, 2025
0fa56bc
Add 'scipy' to dependencies
ManifoldFR Mar 25, 2025
de465ea
[decompositions] Remove unused "auto cl = "
ManifoldFR Mar 26, 2025
b004fb9
fwd.hpp : fix warning on gcc
ManifoldFR Mar 26, 2025
f678208
utils/is-approx.hpp : no need to use macro, use "static constexpr int"
ManifoldFR Mar 26, 2025
7143c28
Changes minres file
Lucas-Haubert Mar 26, 2025
29b6da2
nanoeigenpy.hpp : change to be an omnibus header
ManifoldFR Mar 26, 2025
a923753
Remove solvers/sparse-solver-base.hpp
ManifoldFR Mar 26, 2025
5b61dbe
minres.hpp : do not use "EigenBase" as argument type, expose overload…
ManifoldFR Mar 26, 2025
06312b7
fwd.hpp : move eigen typedef macro in there
ManifoldFR Mar 26, 2025
77cc71d
Rename sparse/llt.hpp, sparse/ldlt.hpp
ManifoldFR Mar 26, 2025
99413a2
src/module.cpp : slight refactoring of how solvers are exposed
ManifoldFR Mar 26, 2025
b647e1a
decompisitions/simplicial-llt.hpp : remove redundant include
ManifoldFR Mar 26, 2025
6e2d7ae
solvers/iterative-solver-base.hpp : various enhancements
ManifoldFR Mar 26, 2025
dcc90d6
decompositions/sparse-solver-base.hpp : Use Eigen::Ref of dense vecto…
ManifoldFR Mar 26, 2025
5a736b0
tests/test_simplicial_llt : add sparse RHS test
ManifoldFR Mar 26, 2025
8712598
Rename computation-info.hpp to constants.hpp, expose enum Decompositi…
ManifoldFR Mar 26, 2025
4ca4859
decompositions/SelfAdjointEigenSolver : fix the default argument!
ManifoldFR Mar 26, 2025
a7d8ce7
[decompositions] Removed duplicate iterative solver base visitor, fix…
ManifoldFR Mar 26, 2025
165c2a6
Added and tested cholmod support
Lucas-Haubert Mar 27, 2025
1565885
Add suitesparse dependency
ManifoldFR Mar 27, 2025
a465143
pixi : add 'cholmod' feature, set CI to use 'all' env
ManifoldFR Mar 27, 2025
f87fdf6
Update pixi lockfile
ManifoldFR Mar 27, 2025
2e018ed
Corrected compilation for cholmod
Lucas-Haubert Mar 27, 2025
9fe13ab
Remove unused typedefs and include
ManifoldFR Mar 27, 2025
4782c8d
pixi.toml : properly add env value for cholmod
ManifoldFR Mar 27, 2025
411337b
[tests] cmakelists.txt : simplify logic to add the cholmod Python tests
ManifoldFR Mar 27, 2025
9907401
Cholmod : detect feature at compile-time at header inclusion time, no…
ManifoldFR Mar 27, 2025
34ea4c4
tests/test_minres.py : also test for vector RHS
ManifoldFR Mar 27, 2025
288ae11
Code for accelerate to be tested on mac
Lucas-Haubert Mar 27, 2025
4a45d92
Remove more unused typedefs
ManifoldFR Mar 27, 2025
af021a8
tests/test_minres.py : also test minres.solveWithGuess()
ManifoldFR Mar 27, 2025
5cb4247
New CMakeLists.txt to test for accelerate
Lucas-Haubert Mar 27, 2025
6986955
[decompositions] some ctor changes
ManifoldFR Mar 27, 2025
9bfac6b
decompositions.hpp : use correct define
ManifoldFR Mar 28, 2025
4cac78d
format fwd.hpp
ManifoldFR Mar 28, 2025
b205cf3
Undo cholmod changes
ManifoldFR Mar 28, 2025
2612c34
CMakeLists.txt : add stub generation and installation
ManifoldFR Mar 28, 2025
c92e8fe
solveWithGuess() is a const method, use templated proxy for solve()
ManifoldFR Mar 28, 2025
63c54cb
Remove some is_final()
ManifoldFR Mar 28, 2025
2f421b1
Split module.cpp
ManifoldFR Mar 28, 2025
036d142
[tests] change test_minres.py to test_iterative_solvers.py -- test al…
ManifoldFR Mar 28, 2025
6d79083
Use nb::DMap<...> for iterative solvers' constructors
ManifoldFR Mar 28, 2025
c706782
pre-commit-config : add ruff
ManifoldFR Mar 28, 2025
5716740
Add pytest to pixi deps
ManifoldFR Mar 28, 2025
cb16656
[tests] Rewrite test_iterative_solvers using pytest
ManifoldFR Mar 28, 2025
47a7f41
[tests] test_iterative_solvers: do not test x and x_est (unless initi…
ManifoldFR Mar 28, 2025
7256fb4
[tests] test_iterative_solvers: increase max iters AGAIN
ManifoldFR Mar 28, 2025
aa94719
pre-commit : run ruff
ManifoldFR Mar 28, 2025
b1d4246
Updated CMakeLists.txt for Accelerate
Lucas-Haubert Mar 28, 2025
202ed6a
Add workspace support
ManifoldFR Mar 28, 2025
546496c
CMakeLists.txt : remove some warnings from the CXX flags
ManifoldFR Mar 28, 2025
0fc351a
CMakeLists.txt : support FetchContent & CMake installation for jrl-cm…
ManifoldFR Mar 28, 2025
18bf6ce
Set INSTALL_DOCUMENTATION to OFF by default
ManifoldFR Mar 28, 2025
84aa1c2
Add setup_project_finalize()
ManifoldFR Mar 28, 2025
81b4869
add pytest to readme
ManifoldFR Mar 28, 2025
0157381
Update .gitignore
ManifoldFR Mar 28, 2025
3a03dee
Tests Accelerate
Lucas-Haubert Mar 28, 2025
e457b3c
Minor fix to accelerate.hpp : undef the macro, mark function as inline
ManifoldFR Mar 28, 2025
2632c64
Move MINRES to nanoeigenpy/solvers
ManifoldFR Mar 28, 2025
c1ff59c
Removed useless commentaries and prints
Lucas-Haubert Mar 28, 2025
0793288
Add section on optional features (cholmod, accelerate)
ManifoldFR Mar 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gersemirc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
definitions: [./CMakeLists.txt, ./cmake]
definitions: [./CMakeLists.txt, ./cmake, ./tests]
line_length: 80
indent: 2
warn_about_unknown_commands: false
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pre-commit run -a (format-all, 2025-03-19)
98c85ab243b68db680a0a5f1ccbf238aeb6523ba
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ci:
submodules: true
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v19.1.7
rev: v20.1.0
hooks:
- id: clang-format
types_or: []
Expand All @@ -28,7 +28,7 @@ repos:
doc/doxygen-awesome.*
)$
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.19.0
rev: 0.19.2
hooks:
- id: gersemi
- repo: https://github.com/Lucas-C/pre-commit-hooks
Expand Down
71 changes: 49 additions & 22 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
#
# Copyright 2025 INRIA
#

cmake_minimum_required(VERSION 3.18)

set(PROJECT_NAME nanoeigenpy)
set(PROJECT_URL https://github.com/ManifoldFR/nanoeigenpy)
set(PROJECT_URL https://github.com/Simple-Robotics/nanoeigenpy)
set(PROJECT_DESCRIPTION "Tools for using Eigen with nanobind")
set(PROJECT_CUSTOM_HEADER_EXTENSION "hpp")
set(PROJECT_USE_CMAKE_EXPORT True)

if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0167 NEW)
endif()
if(POLICY CMP0177)
cmake_policy(SET CMP0177 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0177 NEW)
endif()
include(cmake/base.cmake)
include(cmake/ide.cmake)

COMPUTE_PROJECT_ARGS(PROJECT_ARGS LANGUAGES CXX)
project(${PROJECT_NAME} ${PROJECT_ARGS})

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)

find_package(Eigen3 REQUIRED)

add_library(nanoeigenpy_headers INTERFACE)
target_link_libraries(nanoeigenpy_headers INTERFACE Eigen3::Eigen)

find_package(Python REQUIRED COMPONENTS Interpreter Development)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(
Expand All @@ -28,6 +32,11 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
)
endif()

# Find dependencies
ADD_PROJECT_DEPENDENCY(Eigen3 REQUIRED PKG_CONFIG_REQUIRES "eigen3 >= 3.3.1")

find_package(Python REQUIRED COMPONENTS Interpreter Development)

# Detect the installed nanobind package and import it into CMake
execute_process(
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
Expand All @@ -36,29 +45,47 @@ execute_process(
)
find_package(nanobind CONFIG REQUIRED)

file(GLOB nanoeigenpy_SOURCES src/*.cpp)
nanobind_add_module(nanoeigenpy NB_STATIC NB_SUPPRESS_WARNINGS ${nanoeigenpy_SOURCES})
# Setup main targets
file(GLOB_RECURSE ${PROJECT_NAME}_HEADERS include/nanoeigenpy/*.hpp)

add_library(nanoeigenpy_headers INTERFACE)
target_include_directories(
nanoeigenpy_headers
INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
target_link_libraries(nanoeigenpy_headers INTERFACE Eigen3::Eigen)

file(GLOB ${PROJECT_NAME}_SOURCES src/*.cpp)
nanobind_add_module(nanoeigenpy NB_STATIC NB_SUPPRESS_WARNINGS ${nanoeigenpy_SOURCES} ${nanoeigenpy_HEADERS})
target_link_libraries(nanoeigenpy PUBLIC nanoeigenpy_headers)

if(BUILD_TESTING)
add_subdirectory(tests)
endif()

# Install targets
install(
TARGETS nanoeigenpy_headers
TARGETS ${PROJECT_NAME}_headers
EXPORT ${TARGETS_EXPORT_NAME}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
DIRECTORY include/nanoeigenpy
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.hpp"
)

install(
TARGETS nanoeigenpy
TARGETS ${PROJECT_NAME}
EXPORT ${TARGETS_EXPORT_NAME}
LIBRARY DESTINATION ${Python_SITELIB}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

ADD_HEADER_GROUP(${PROJECT_NAME}_HEADERS)
ADD_SOURCE_GROUP(${PROJECT_NAME}_SOURCES)
22 changes: 22 additions & 0 deletions include/nanoeigenpy/computation-info.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// Copyright 2025 INRIA
#pragma once

#include <nanobind/nanobind.h>
#include <Eigen/Core>

namespace nanoeigenpy {
namespace nb = nanobind;
inline void exposeComputationInfo(nb::module_ m) {
nb::enum_<Eigen::ComputationInfo>(m, "ComputationInfo")
.value("Success", Eigen::Success, "Computation was successful.")
.value("NumericalIssue", Eigen::NumericalIssue,
"The provided data did not satisfy the prerequisites.")
.value("NoConvergence", Eigen::NoConvergence,
"Iterative procedure did not converge.")
.value("InvalidInput", Eigen::InvalidInput,
"The inputs are invalid, or the algorithm has been improperly "
"called. "
"When assertions are enabled, such errors trigger an assert.")
.export_values();
}
} // namespace nanoeigenpy
12 changes: 11 additions & 1 deletion include/nanoeigenpy/decompositions.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
/// Copyright 2025 INRIA
#pragma once

#include "nanoeigenpy/decompositions/ldlt.hpp"
#include "nanoeigenpy/decompositions/llt.hpp"
#include "nanoeigenpy/decompositions/ldlt.hpp"
#include "nanoeigenpy/decompositions/minres.hpp"
#include "nanoeigenpy/decompositions/HouseholderQR.hpp"
#include "nanoeigenpy/decompositions/FullPivHouseholderQR.hpp"
#include "nanoeigenpy/decompositions/ColPivHouseholderQR.hpp"
#include "nanoeigenpy/decompositions/CompleteOrthogonalDecomposition.hpp"
#include "nanoeigenpy/decompositions/EigenSolver.hpp"

#include "nanoeigenpy/decompositions/sparse/llt.hpp"
#include "nanoeigenpy/decompositions/sparse/ldlt.hpp"
199 changes: 199 additions & 0 deletions include/nanoeigenpy/decompositions/ColPivHouseholderQR.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/// Copyright 2025 INRIA
#pragma once
#include "base.hpp"
#include <Eigen/QR>

namespace nanoeigenpy {
namespace nb = nanobind;

template <typename MatrixType, typename MatrixOrVector>
MatrixOrVector solve(const Eigen::ColPivHouseholderQR<MatrixType> &c,
const MatrixOrVector &vec) {
return c.solve(vec);
}

template <typename MatrixType>
MatrixType inverse(const Eigen::ColPivHouseholderQR<MatrixType> &c) {
return c.inverse();
}

template <typename MatrixType>
void exposeColPivHouseholderQRSolver(nb::module_ m, const char *name) {
using Solver = Eigen::ColPivHouseholderQR<MatrixType>;
using Scalar = typename MatrixType::Scalar;
using RealScalar = typename MatrixType::RealScalar;
using VectorType = Eigen::Matrix<Scalar, -1, 1>;
auto cl =
nb::class_<Solver>(
m, name,
"This class performs a rank-revealing QR decomposition of a matrix A "
"into matrices P, Q and R such that:\n"
"AP=QR\n"
"by using Householder transformations. Here, P is a permutation "
"matrix, Q a unitary matrix and R an upper triangular matrix.\n"
"\n"
"This decomposition performs column pivoting in order to be "
"rank-revealing and improve numerical stability. It is slower than "
"HouseholderQR, and faster than FullPivHouseholderQR.")

.def(nb::init<>(),
"Default constructor.\n"
"The default constructor is useful in cases in which the "
"user intends to perform decompositions via "
"HouseholderQR.compute(matrix).")
.def(nb::init<Eigen::DenseIndex, Eigen::DenseIndex>(),
nb::arg("rows"), nb::arg("cols"),
"Default constructor with memory preallocation.\n"
"Like the default constructor but with preallocation of the "
"internal data according to the specified problem size. ")
.def(nb::init<const MatrixType &>(), nb::arg("matrix"),
"Constructs a QR factorization from a given matrix.\n"
"This constructor computes the QR factorization of the matrix "
"matrix by calling the method compute().")

.def("info", &Solver::info,
"Reports whether the QR factorization was successful.\n"
"Note: This function always returns Success. It is provided for "
"compatibility with other factorization routines.")

.def("absDeterminant", &Solver::absDeterminant,
"Returns the absolute value of the determinant of the matrix of "
"which *this is the QR decomposition.\n"
"It has only linear complexity (that is, O(n) where n is the "
"dimension of the square matrix) as the QR decomposition has "
"already been computed.\n"
"Note: This is only for square matrices.")
.def("logAbsDeterminant", &Solver::logAbsDeterminant,
"Returns the natural log of the absolute value of the "
"determinant "
"of the matrix of which *this is the QR decomposition.\n"
"It has only linear complexity (that is, O(n) where n is the "
"dimension of the square matrix) as the QR decomposition has "
"already been computed.\n"
"Note: This is only for square matrices. This method is useful "
"to "
"work around the risk of overflow/underflow that's inherent to "
"determinant computation.")
.def("dimensionOfKernel", &Solver::dimensionOfKernel,
"Returns the dimension of the kernel of the matrix of which "
"*this "
"is the QR decomposition.")
.def("isInjective", &Solver::isInjective,
"Returns true if the matrix associated with this QR "
"decomposition "
"represents an injective linear map, i.e. has trivial kernel; "
"false otherwise.\n"
"\n"
"Note: This method has to determine which pivots should be "
"considered nonzero. For that, it uses the threshold value that "
"you can control by calling setThreshold(threshold).")
.def(
"isInvertible", &Solver::isInvertible,
"Returns true if the matrix associated with the QR decomposition "
"is invertible.\n"
"\n"
"Note: This method has to determine which pivots should be "
"considered nonzero. For that, it uses the threshold value that "
"you can control by calling setThreshold(threshold).")
.def("isSurjective", &Solver::isSurjective,
"Returns true if the matrix associated with this QR "
"decomposition "
"represents a surjective linear map; false otherwise.\n"
"\n"
"Note: This method has to determine which pivots should be "
"considered nonzero. For that, it uses the threshold value that "
"you can control by calling setThreshold(threshold).")
.def("maxPivot", &Solver::maxPivot,
"Returns the absolute value of the biggest pivot, i.e. the "
"biggest diagonal coefficient of U.")
.def(
"nonzeroPivots", &Solver::nonzeroPivots,
"Returns the number of nonzero pivots in the QR decomposition. "
"Here nonzero is meant in the exact sense, not in a fuzzy sense. "
"So that notion isn't really intrinsically interesting, but it "
"is "
"still useful when implementing algorithms.")
.def("rank", &Solver::rank,
"Returns the rank of the matrix associated with the QR "
"decomposition.\n"
"\n"
"Note: This method has to determine which pivots should be "
"considered nonzero. For that, it uses the threshold value that "
"you can control by calling setThreshold(threshold).")

.def(
"setThreshold",
[](Solver &c, RealScalar const &threshold) {
return c.setThreshold(threshold);
},
nb::arg("threshold"),
"Allows to prescribe a threshold to be used by certain methods, "
"such as rank(), who need to determine when pivots are to be "
"considered nonzero. This is not used for the QR decomposition "
"itself.\n"
"\n"
"When it needs to get the threshold value, Eigen calls "
"threshold(). By default, this uses a formula to automatically "
"determine a reasonable threshold. Once you have called the "
"present method setThreshold(const RealScalar&), your value is "
"used instead.\n"
"\n"
"Note: A pivot will be considered nonzero if its absolute value "
"is strictly greater than |pivot| ⩽ threshold×|maxpivot| where "
"maxpivot is the biggest pivot.",
nb::rv_policy::reference)
.def(
"threshold", &Solver::threshold,
"Returns the threshold that will be used by certain methods such "
"as rank().")

.def("matrixQR", &Solver::matrixQR,
"Returns the matrix where the Householder QR decomposition is "
"stored in a LAPACK-compatible way.",
nb::rv_policy::copy)
.def("matrixR", &Solver::matrixR,
"Returns the matrix where the result Householder QR is stored.",
nb::rv_policy::copy)

.def(
"compute",
[](Solver &c, VectorType const &matrix) {
return c.compute(matrix);
},
nb::arg("matrix"),
"Computes the QR factorization of given matrix.",
nb::rv_policy::reference)

.def(
"inverse",
[](Solver const &c) -> MatrixType { return inverse(c); },
"Returns the inverse of the matrix associated with the QR "
"decomposition.")

.def(
"solve",
[](Solver const &c, VectorType const &b) -> VectorType {
return solve(c, b);
},
nb::arg("b"),
"Returns the solution x of A x = B using the current "
"decomposition of A where b is a right hand side vector.")
.def(
"solve",
[](Solver const &c, MatrixType const &B) -> MatrixType {
return solve(c, B);
},
nb::arg("B"),
"Returns the solution X of A X = B using the current "
"decomposition of A where B is a right hand side matrix.")

.def(
"id",
[](Solver const &c) -> int64_t {
return reinterpret_cast<int64_t>(&c);
},
"Returns the unique identity of an object.\n"
"For objects held in C++, it corresponds to its memory address.");
}

} // namespace nanoeigenpy
Loading