Setup for 1.0.0 release#6
Merged
MitchellThompkins merged 324 commits intomainfrom Mar 29, 2026
Merged
Conversation
Enable -Werror and Resolve Compiler Warnings
Build System Simplification and Enhanced Test Coverage
Only build and publish container on develop/main
Add a DSP example.
…ere the formatting is not applied
Add clang support and testing (add but don't run clang format)
* inlude example outputs in CI * address MR feedback * add example * split examples out into separate jobs * update actions dep * update CI deps to latest * make a matrix * be more agile to Dockerfile changes * simple test * try to force dockerfile changes to be honored in PR * use concurrency grouping * deconflict concurrency across event types * Revert "simple test" This reverts commit 7ddea1b. * Reapply "simple test" This reverts commit 7b67f87. * Revert "Reapply "simple test"" This reverts commit 3a3c201. * now with change * Revert "now with change" This reverts commit c4e04f4. * be more robust to Dockerfile changes * test with dockerfile change * Revert "test with dockerfile change" This reverts commit a6fe94b. * KISS with just now allowing Actions on all push events * force dockerfile change * Revert "force dockerfile change" This reverts commit e25eb87. * forward make options * use dev container as backing image * update alpine image * make git hooks setup non-fatal * fix formatting error with update clange-format dependency * don't let Eigen build for examples * slimpify build into 1 step * update docker dependency * force set -3 * The container image was recently updated (commit da847dc update alpine image). A newer Alpine image means a newer clang, and newer clang added -Wcharacter-conversion which gets promoted to an error by -Werror. The googletest code hasn't changed — the compiler just got stricter. * update google test dependency to avoid more agressive Werrors * use more modern compiler catch * fail dc-motor-build on static assert properly * Localize all test code dependency * do some serious CMakeLists.txt cleanup * exlude examples from make build * I removed the githooks dir anyway a while ago so I shouldn't need this * address MR feedback
* inlude example outputs in CI * address MR feedback * add example * split examples out into separate jobs * update actions dep * update CI deps to latest * make a matrix * be more agile to Dockerfile changes * simple test * try to force dockerfile changes to be honored in PR * use concurrency grouping * deconflict concurrency across event types * Revert "simple test" This reverts commit 7ddea1b. * Reapply "simple test" This reverts commit 7b67f87. * Revert "Reapply "simple test"" This reverts commit 3a3c201. * now with change * Revert "now with change" This reverts commit c4e04f4. * be more robust to Dockerfile changes * test with dockerfile change * Revert "test with dockerfile change" This reverts commit a6fe94b. * KISS with just now allowing Actions on all push events * force dockerfile change * Revert "force dockerfile change" This reverts commit e25eb87. * forward make options * use dev container as backing image * update alpine image * make git hooks setup non-fatal * fix formatting error with update clange-format dependency * don't let Eigen build for examples * slimpify build into 1 step * update docker dependency * force set -3 * The container image was recently updated (commit da847dc update alpine image). A newer Alpine image means a newer clang, and newer clang added -Wcharacter-conversion which gets promoted to an error by -Werror. The googletest code hasn't changed — the compiler just got stricter. * update google test dependency to avoid more agressive Werrors * use more modern compiler catch * fail dc-motor-build on static assert properly * Localize all test code dependency * do some serious CMakeLists.txt cleanup * exlude examples from make build * will this pass with no compiler limits raised * forgot to comment these out * did not mean to comment this out * Remove compiler limit raises and add some documentation about why, also, explain why macos is still slow to run tests * I tried to get macos to test faster but it seems not to matter * update test with reason for slowdown * Update readme wording. Add back in macro as an option. Update documentation. * slight wording update * address MR feedback * Minor feedback * rename
* preserve container history * address MR feedback
* add these options
* add ateict flags
* revert float tests
* enforce {} styling
* add whitespaces to generation script
* check in white-spaces
* use more generic comparison function name for floating point types
* don't use temporary tolerance variables
* make this match develop
* tell the compiler to treat Eigen's headers as system headers (like
/usr/include). GCC and Clang then suppress all warnings originating from
those files so strict flags like -Wduplicated-branches won't fire
on Eigen's own code, only on ours.
Without SYSTEM, the compiler treats Eigen headers the same as our own
source, and -Werror turns Eigen's internal warnings into build failures
I can't fix.
* GCC does warn about float to double promotion with -Wdouble-promotion,
but only when you actually use the default argument. Clang is stricter —
it evaluates and warns about the default argument expression at the
point of instantiation of the template signature, even before the
default is used in a call.
In the test code, nearlyEqual<double> is called without explicitly
passing epsilon/relth, so both compilers should in theory flag it. But
GCC's implementation of -Wdouble-promotion has known blind spots with
template default arguments — it doesn't consistently diagnose the
promotion when it happens inside a default argument
expression during template instantiation. Clang does.
* update naming to be consistent
* update comments to explain function
* be explicit about cast
* Correct missing braces
* address MR fedback
* use an interface library to apply compiler flags for the tests
* address MR feedback for matching parametr types
* update per MR feedback
* lint
* change zpproxEqual to better reflect function intent
* remove more kTol nonsense
* Remove more kTol references
* lint
* apply bugfix and more robust tests
* stop using hard-coded matrix size in template that was silly
* add better tests
* address MR feedback for magic numbers
* allow float symetric comparisions to actually work, but enforce the parameterized version to leverage floats. Also give coding guidelines.
* light code cleanup for early return version
* Start adding support for cross compilation tests * cleaning up github ci files * build? * updated how dockerfile pulls cross compiler toolchain * change hwo things get built * let claude churn on trying to get these tests to compile * try to get these tests to build * try with this cross_compile_verify source * try explictly setting compile options, and letting test TU's compile against stubs * remove these cros compilation target tests since they're covered by main * remove extra compiler tests, they're not very valuable * make using local image a bit more ergonomic * fix leaking test deps into matrix lib, check sha256 checksum of arm, make test executables private * Let dockerfile manage arm dependency * update comments * break out tests into compile-time and run-time (for verification against eigen) * address MR fb * split out some of the eigen tests to constepxr variatns * add comments and rename tests * add dedicated makefile commands * collapse all eigen tests into a single file * add build dir first * makefile clean-up and updates * use modern cmake * add commands to remove cached cross compiler builds * remove other targets
* add explanation for trig iteration limit and update .gitignore * add refernce * add tan * lint * add comments explaining * update comment
* co-locate test files * I think updating the container changed octave and LAPACK gave me slightly different values for the generated test cases so I decided to pin deps in the container * add explanation to test-case generator * use true clustered eigenvalues * use more robust randn to get normalized random distribution * coderrabbitai is right that I'll probably end up breaking packages. There may be slight drift in re-generated test cases so leave it that way for now * correct comments and error on unknown matrix type * use normally distrbuted srandn * regenerate and reformat but sparse matricies now fail * lower sparsity and justify it * regen slightly * correct comment * update comment
Co-authored-by: Mitchell Thompkins <mitchell.thompkins@pm.me>
Co-authored-by: Mitchell Thompkins <mitchell.thompkins@pm.me>
…mposition docs (#42) * make this a definition and add reference * readme update * add comments for decompositions and update docker file and .env * pull this in via shell * comment to re-generate images * comment update * force rule to update container tag * check against base branch * address MR feedback * just use ... syntax * try something new * try to get a deeper history to use ... syntax
* cleanup population example slightly and tighten up language * update examples and co-locate butterworht example * readme clean-up * more language update * update consteig usage * tighten up language * update constraints and fix references * apply mr fixes, make why is this useful more apparent * readme update * tighten up lanauge and add comment in example * improve bash rendering * remove 2nd person voice * tighten up first 2 paragraphs * clean up language here * light clean-up * slight updates * align consteig * slight language cleanup * update refernce * more language cleanup * citations and langauge cleanup * more languge updates * language update * update * updates * add comment explaining usage of non-constexpr arthimetic * fix mk tags * MR feedback
…ess, and rename legacy functions (#44) * make this a definition and add reference * readme update * add comments for decompositions and update docker file and .env * pull this in via shell * align with eigen api * make _data a private accessor * try new bracet syntax * attempt to address bracing issues, regenerate test cases as a result, and lint * add back in these cases * add these back in * align more closely with eigen api * add tests to validate new member functions * Allow for eigenvalues() and eigenvectors() to be called on matrix * enforce compile time comparison * add constexpr helper * lint * add check and comment explaning why * Align with Eigen's Eigensolver to match their API. Remove ugly invocation from the matrix class * invoke via namespace * add is_float static assert check to fail early if users call these functions with incompatible types * pass reference * make these references too
* update i/j to row/col * add free function for flat matrix definition * i/j -> row/col
* ignore all generated things * regenerate this w/o formatting
* add profiling first pass * add profiling scripts * revert eigen changes * add profiling * add more cases * update profiling * update readme * update this to remove time stamp * DRY * pull in function * exclude generated files from formatting * remove formatting * regenerate profiling cases * missed checking these in * allow failure to capture time * capture failures * add more plots * add matrix helper * check in raw data * use itertools * massage profiling data * correctly apply compiler limits * cmake overhead causes profiling to be very slow, so extract args from compile_commands.json and manually apply them * update data * clean up profile generation and plotting * clean-up * add in lfs png * update readme * do not check in so many files * readme update * clean dir * check in generated cases * do not check in this file * update readme * reran profiling * support macos * add uv to Dockerfile * bump tag * re-ran profiling and update readme * ran uv in container and update tool to pull in deps * remove this * include os name in data * do not need pyproject * address MR feedback * reran profiling with new data * address MR * get feedback * regenerate test cases determanistically * workflow dispatch to use same technique as PR for finding Dockerfile changes * fix diff command * more git diff fix * change diff stragety to support busybox * address MR feedback; * clean up documentation * update readme * more clean-up * clean up redundant language * readme clean-up
* first pass at generating docs * update * fix * readme update * clean-up * update code docs * start migrating docs * add a performance md * clean up index * tighten up language * language update * language corrections * slight update * updates * docs update * use consistent titling * update LICENSE and NOTICE * update language * get rid of weird ASCII symbols * pare down README.md * Add development.md * move things around * slight update * more updates * lots of updates * host this temporarily * lint * language update * move images around * update workflow and see if symlinks are correct * run pipeline on push * git lfs * this is almost certaintly not the issue * fix gitattributes * this feels like it will not work * update doxy * reorder * address feedback * address MR feedback * forgot this * address MR feedback * better test name * supposedly this will fix the image location * address MR feedback * fix link * I think git lfs was messed up? * try to address CI failure for check-generated * re-order sections slightly * target develop * minor permissions and workflow update
* see what changed * force architecture selection for OPENBLAS * regenerate test cases * add schedule * try using ZEN3 since that's what I used locally * revert (sort of) the cases changes. I changed the solver BLAS was using to be the same one I use. I'm hoping that it causes the gitlab runner to be consistent but who knows * do not overwrite container on scheduled jobs * go back to build and test * add slight wording update
* make references point to main now * use main for badge
Owner
Author
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
Owner
Author
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
I started working on this set of changes a number of years ago and have only gotten around to completing the implementation recently. This adds a numerically accurate eigenvalue and eigenvector solver, many more tests (compile-time and run-time against both Octave generated references and Eigen respectively), examples, and some theory discussion, along with the CI/CD, build system, and documentation infrastructure needed to support a proper public release.
CI/CD
main.ymlfrom a single job to a matrix pipeline: separatelint,build-and-test(GCC + Clang),cross-compile(ARM GCC + Clang),check-generated, anddc-motor-failjobs.docs.ymlto build and deploy the MkDocs + Doxygen site to GitHub Pages on pushes tomain..env) and SHA; a CI guard enforces thatDockerfileand.envchange together.Build system
CMakeLists.txt: upgraded to C++17, renamed project toconsteig, added strictconsteig_warningsinterface target (-Wall -Wextra -pedantic -Werror+ extended set),CONSTEIG_BUILD_TESTSandCONSTEIG_COMPILE_ONLYoptions,consteig_raise_compiler_limits()helper, and FetchContent-compatible structure.Makefile: added per-compiler targets (build.gcc,test.clang, etc.), cross-compile targets (cross.arm-gcc,cross.arm-clang),check-format,generate-test-cases,check-generated,test-dc-motor-fail, andprofile.Dockerfile: updated Alpine 3.14 -> 3.23, added ARM GNU toolchain (15.2),clang-extra-tools,octave, anduv.Cross-compilation
cmake/toolchains/arm-none-eabi-gcc.cmakeandarm-none-eabi-clang.cmakefor bare-metal ARM targets.CONSTEIG_COMPILE_ONLYmode compiles to.ofiles only (no linker step), exercising allstatic_assertchecks without a C runtime.Library
Expanded eigen value solver to route symmetric and non-symmetric matrices to different algorithms. The old solver used a simple explicit single-shift QR loop with a hardcoded convergence threshold and no preprocessing. The new implementation routes symmetric matrices through a single-shift QR path (sufficient since real eigenvalues are guaranteed) and non-symmetric matrices through the full Francis implicit double-shift QR algorithm (with both matrix balancing (Parlett & Reinsch 1969) and Hessenberg reduction as preprocessing. The double-shift path handles complex conjugate pairs simultaneously using real arithmetic, with Wilkinson shifts for quadratic convergence, LAPACK-style exceptional shifts every 10 iterations to prevent stalling, and a dual-mode deflation criterion (relative to matrix norm + absolute against machine epsilon). The deflation was critical for keeping compile times tractable across the expanded robustness test suite; otherwise compilation times exploded but with no real improvement on accuracy.
The old solver used a simple explicit single-shift QR loop with a hardcoded convergence threshold and no preprocessing. The new implementation uses the Francis implicit double-shift QR algorithm: the input is first balanced (Parlett & Reinsch 1969) and reduced to Hessenberg form, then a bulge-chasing step handles complex
conjugate pairs simultaneously using real arithmetic, with Wilkinson shifts for quadratic convergence, LAPACK-style exceptional shifts every 10 iterations to prevent
stalling, and a dual-mode deflation criterion (relative + absolute against machine epsilon) that was critical for keeping compile times tractable across the expanded
robustness test suite.
New
consteig_types.hppintroducingconsteig::Size; replaced allsize_tuses in library and test code.consteig_options.hpp: expanded with Doxygen@defgroup configdocumentation; addedCONSTEIG_MAX_ITER,CONSTEIG_BALANCE_CONVERGENCE_THRESHOLD,E_CONST,PI_CONST,CONSTEIG_TRIG_MAX_ITER, andCONSTEIG_USE_LONG_DOUBLE.array/array.hpp: addedconst T* data()overload and full Doxygen comments.eigen/eigen.hpp,matrix/,math/: reformatted to Microsoft/clang-format style; explicit casts for Eigen indexing; hardcoded tolerances replaced with named constants.Tests
eigen/tests/generated_*): adds robustness categories including defective, nearly defective, clustered eigenvalues, companion, and Hamiltonian matrices.dc-motor-failtest verifies that bad PID gains trigger astatic_assertat build time.Documentation
docs/: getting-started guide, configuration reference, decompositions/eigensolvers/math-functions/matrix guides, example walkthroughs (Butterworth filter, DC motor control, population dynamics), verification and performance pages.Legal / project
LICENSE(Apache 2.0) andNOTICE(attributing GCE-Math).README.md,AGENT.md(withCLAUDE.md/GEMINI.mdsymlinks),.clang-format,.coderabbit.yaml,.gitattributes(LFS for profiling/docs PNGs).Octave
octave/development_scripts/.generate_test_cases.mupdated to produce the expanded robustness test cases.generate_profiling_cases.mfor compile-time profiling.Profiling
profiling/CMakeLists.txt,run_profiling.sh,analyze_results.py, GCC 15.2.0 baseline results.