Configuration¶
consteig has a few options which can be modified. However, these defaults are well tested and modifying them may have non-desirable results such as increased compile times or numerical instability.
User Macros¶
All macros are guarded by #ifndef and can be overridden before including
consteig.hpp or via compiler flags (-DMACRO=value).
CONSTEIG_MAX_ITER¶
Controls the maximum number of iterations allowed for eigenvalue solvers. Increasing this may help difficult matrices converge, but significantly increases compile times and the likelihood of hitting compiler step limits.
#define CONSTEIG_MAX_ITER 1000 // increase for difficult matrices (see consteig_options.hpp for default)
#include <consteig/consteig.hpp>
CONSTEIG_DEFAULT_SYMMETRIC_TOLERANCE¶
A routing threshold used to determine if a matrix is "symmetric enough" to use
the optimized symmetric eigenvalue solver (eig_shifted_qr). If the matrix
symmetry exceeds this tolerance, the library falls back to the more robust but
heavier non-symmetric solver (eig_double_shifted_qr).
#define CONSTEIG_DEFAULT_SYMMETRIC_TOLERANCE 1e-9 // tighter than default (see consteig_options.hpp for default)
#include <consteig/consteig.hpp>
CONSTEIG_BALANCE_CONVERGENCE_THRESHOLD¶
Controls the stopping criterion for the matrix balancing step. A scaling is
applied to a row/column only if it reduces the sum of the row and column norms
by more than this factor. The default value of 0.95 is taken from Algorithm 2
of James, Langou & Lowery 1. Increasing it toward 1.0 runs more balancing
iterations; decreasing it stops earlier.
CONSTEIG_TRIG_MAX_ITER¶
Maximum Taylor series iterations for sin, cos, tan, etc. (default: see
consteig_options.hpp). 14 should suffice for double precision but the
library uses a slightly higher default for good margin.
CONSTEIG_USE_LONG_DOUBLE¶
Forces all internal constexpr eigenvalue calculations to use long double. This
dramatically improves numerical stability for large or pathological matrices but
is very resource-intensive for the compiler and will severely increase compile
times. It is NOT defined by default.
CMake Functions¶
consteig_raise_compiler_limits¶
A convenience CMake function (implemented with function(), not macro(), for
proper variable scoping) that raises -fconstexpr-ops-limit (GCC),
-fconstexpr-steps (Clang), and -fconstexpr-depth on one or more specific
targets to accommodate heavy constexpr workloads. The library itself does not
call this function. Its deflation criterion keeps iteration counts within
default compiler limits. However, users working with very large or pathological
matrices may find it useful to call this on their own targets.
Compiler Flags¶
Raising Constexpr Limits¶
-fconstexpr-steps (Clang) or -fconstexpr-ops-limit (GCC) increase the
maximum number of steps the compiler will execute during constexpr evaluation.
The library's deflation criterion (which includes an absolute check against
machine epsilon in addition to the standard relative check) keeps iteration
counts low enough that default compiler limits are sufficient for the test
suite. However, very large or pathological matrices may still benefit from
raising these limits.
-fconstexpr-depth increases the maximum depth of the constexpr call stack.
Default limits are typically sufficient, but deeply nested computations on
large matrices may require raising this (e.g., to 1024).
# GCC
-fconstexpr-ops-limit=1000000000
# Clang
-fconstexpr-steps=1000000000
# Both
-fconstexpr-depth=1024
Extended Precision (x86)¶
-mfpmath=387 (x86 specific) directs the compiler to use the x87 FPU, which
utilizes 80-bit internal precision. This can improve numeric stability and
accuracy during compile-time evaluation and should be used in conjunction with
-mlong-double-80.
-mlong-double-80 (x86 specific) ensures that long double is 80 bits. When
combined with CONSTEIG_USE_LONG_DOUBLE, this provides extended precision to
the constexpr algorithms, which is often crucial for the stability of operations
like QR decomposition at compile time.
-mfpmath=387 # Use x87 FPU (80-bit internal precision)
-mlong-double-80 # Ensure long double is 80 bits
Combine with CONSTEIG_USE_LONG_DOUBLE for maximum precision.
When to Change Defaults¶
The defaults work for the full test suite (8x8 matrices, including defective Jordan blocks) without modification. Consider changing them only if you encounter:
- Compile errors about constexpr step limits: Raise
-fconstexpr-ops-limitor-fconstexpr-steps - Convergence failures on large matrices: Increase
CONSTEIG_MAX_ITER - Poor accuracy on near-defective matrices: Enable
CONSTEIG_USE_LONG_DOUBLE - Very tight symmetry requirements: Tighten
CONSTEIG_DEFAULT_SYMMETRIC_TOLERANCE
-
James, R., Langou, J., & Lowery, B. R. (2014). On matrix balancing and eigenvector computation ↩