{"id":37685193,"url":"https://github.com/colinrford/polynomial_nttp","last_synced_at":"2026-02-26T23:07:23.391Z","repository":{"id":294417248,"uuid":"986838090","full_name":"colinrford/polynomial_nttp","owner":"colinrford","description":"polynomial algebra at compile time","archived":false,"fork":false,"pushed_at":"2026-02-11T01:48:57.000Z","size":335,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-11T06:12:06.772Z","etag":null,"topics":["compile-time-meta-programming","constexpr","cpp-modules","polynomial-algebras","polynomials"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/colinrford.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-20T07:40:27.000Z","updated_at":"2026-02-11T01:48:53.000Z","dependencies_parsed_at":"2025-05-20T10:57:18.371Z","dependency_job_id":null,"html_url":"https://github.com/colinrford/polynomial_nttp","commit_stats":null,"previous_names":["colinrford/polynomial_nttp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/colinrford/polynomial_nttp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colinrford%2Fpolynomial_nttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colinrford%2Fpolynomial_nttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colinrford%2Fpolynomial_nttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colinrford%2Fpolynomial_nttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/colinrford","download_url":"https://codeload.github.com/colinrford/polynomial_nttp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colinrford%2Fpolynomial_nttp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29876408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T22:37:10.609Z","status":"ssl_error","status_checked_at":"2026-02-26T22:37:09.019Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compile-time-meta-programming","constexpr","cpp-modules","polynomial-algebras","polynomials"],"created_at":"2026-01-16T12:31:01.955Z","updated_at":"2026-02-26T23:07:23.385Z","avatar_url":"https://github.com/colinrford.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `lam.polynomial_nttp`\n`lam.polynomial_nttp` is a `c++` module and a part of [LAM](https://www.github.com/colinrford/lam). If instead you prefer a header\nversion, and / or you would like to give it a try, please see\n[here](https://godbolt.org/z/s58zEqKeY) for a Compiler Explorer implementation,\nwhich uses `#include`s rather than `import`s, but it is relatively outdated at this point.\n\n## polynomial_nttp, a [LAM](https://www.github.com/colinrford/lam) library\n`lam.polynomial_nttp` implements a model of a polynomial algebra in one \nindeterminate in `c++` which, as the name suggests, achieves this via \nNon-Type Template Parameters (NTTPs) (it's a wrapped `std::array`; thusly I \ncould only figure out the Division Algorithm / Euclidean Algorithm using NTTPs \n– more on this in a moment). Thanks to NTTPs, combined with recent enhancements \nfor lambdas in `c++20`, a model of a polynomial ring $k[X]$ over a field $k$ \n(hopefully, of any characteristic, but at least a reasonable subset of \ncomputable rationals) works in `constexpr` and `consteval` contexts. Such a \nring $k[X]$ is a Euclidean Domain, in which case we have a Euclidean Algorithm, \nand indeed, in addition to addition, overloading `operator+`, subtraction \n`operator-`, and multiplication `operator*`, all of this can be done, if one \n*truly* insists, at compile time.\n\n| operation      | implemented                                                                                                    | unit-tested                                                                                                                                                                                                                                                                                                                           |\n|----------------|----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| addition       | [`operator+`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L34)            | [`/tests/unit/algebra/binary_add_polynomials.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_add_polynomials.cpp) and [`/tests/unit/algebra/binary_add_polynomial_with_constant.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_add_polynomial_with_constant.cpp)                     |\n| subtraction    | [`operator-`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L205)            | [`/tests/unit/algebra/binary_subtract_polynomials.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_subtract_polynomials.cpp) and [`/tests/unit/algebra/binary_subtract_polynomial_with_constant.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_subtract_polynomial_with_constant.cpp) |\n| multiplication | [`operator*`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L417)            | [`/tests/unit/algebra/binary_multiply_polynomials.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_multiply_polynomials.cpp) and [`/tests/unit/algebra/binary_multiply_polynomial_with_constant.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/binary_multiply_polynomial_with_constant.cpp) |\n| division       | [`division_prototype\u003c\u003e`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L643) | [`/tests/unit/algebra/division.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/division.cpp)                                                                                                                                                                                                                         |\n| derivative     | [`derivative`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L726)           | [`/tests/unit/algebra/derivative.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/derivative.cpp)                                                                                                                                                                                                                     |\n| antiderivative | [`antiderivative`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L746)       | [`/tests/unit/algebra/antiderivative.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/algebra/antiderivative.cpp)                                                                                                                                                                                                             |\n| root-finding   | [`roots\u003c\u003e`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-roots.cppm#L762) | [`/tests/unit/roots/roots.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit/roots/roots.cpp) |\n\nSyntax such as `3 * p + q`, `p - 1.5 * q`, `6 * p * q`, is all possible.\nDividing a polynomial `p` of degree `M` by a polynomial `q` of degree `N`, both\nwith coefficients represented as `double`s, is achieved by\n`division_prototype\u003cdouble, M, p, N, q\u003e()`.\n\nThe biggest flaw of this implementation is division - because it is not\n`operator/`... This author has not (yet?) figured out how to use the choice of\ncontainer / data structure, `std::array` (where the entries are coefficients\n$a_i$, $i = 0, \\ldots, n$) in a Euclidean Algorithm which both i) overloads\n`operator/` and ii) compiles inside `constexpr`, `consteval` contexts. This\ndeeply saddens the author, but at least its still possible to achieve the\nsecond point ii).\n\n## `division_prototype()` (find it in [`src/polynomial_nttp-univariate-algebra.cppm`, line `643`](https://github.com/colinrford/polynomial_nttp/blob/main/src/polynomial_nttp-univariate-algebra.cppm#L643))\nSo, why was this implementation ~~doomed~~ forced from the outset (i.e. the\nauthor's choice to use `std::array`) to rely on NTTPs to achieve simple\npolynomial division at compile time? Well, that's just it, apparently, since\nwe cannot mark function arguments `constexpr` (still true as of `c++23`),\n**it is this author's current conclusion that the only way to return\nappropriately-sized quotients and remainders (at compile time) is to use a\ndynamic data structure (like `std::vector`) for the Euclidean Algorithm while\ntemporarily storing the quotient and remainder in oversized arrays, and\nsubsequently copying the quotient and remainder into \"right-sized\" arrays.**\nThis technique, coined [\"The constexpr 2-step\" by Jason Turner](https://youtu.be/_AefJX66io8),\nis useful, as it is the only (first?) way this author found polynomial division\nwas attainable... (at compile time... (using this implementation...))\n\nNow the astute reader may already realize that a chain reaction has occurred.\nHaving been thrown into the land of template metaprogramming, as\n`division_prototype()` takes 5 template parameters, 4 of which are NTTPs,\nperforming large numbers of tests of such a function requires something like\nthe use of `std::integer_sequence\u003cint, ints...\u003e` and fold expressions.\nOne could use `std::index_sequence` instead, of course.\n\n### implementation\nI have partially documented my approach in the\n[wiki for this repository.](https://github.com/colinrford/polynomial_nttp/wiki/Implementation-of-%60division_prototype()%60)\n\n### testing\nUnit tests for the contents in `polynomial_nttp.cppm` are found in\n[`/tests/unit`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/unit). Currently they will build with a proper `cmake` command, and\nrun with `ctest`. The unit tests all have `if constexpr` statements so that\neven when asserts are turned off the program will `return 0` for passing and\n`return 1` otherwise, and of course this switch is determined at compile time.\nThere is a chance I incorporate a different or additional test mechanism\n(Catch2? gtest?) in the future.\n\n`test_polynomial_nttp.cpp` is an artifact of early development and\nmay eventually be removed; there is an unrefined test file [`tests/stress/thousand_divisions.cpp`](https://github.com/colinrford/polynomial_nttp/blob/main/tests/stress/thousand_divisions.cpp)\ntake note that this may require some compiler flags (`-fconstexpr-steps`)\nto increase the number of iterations, and `clang` may not want to do 1000\nat a time (in my sad experience). currently `tests/stress/thousand_divisions.cpp` is a\nlittle messy, the chosen filenames are kind of lame, and there is some\nredundancy that I plan to reduce into a function soon enough.\n\n## building\n\n### some preliminaries\nDespite limited support, still, as of (circa) October 8, 2025, for `c++`\nmodules, the project will build as a `c++` module. The primary build route\ncurrently provided builds the project using `cmake`, so you will need `cmake`\nat least version `3.30` (use `3.31.6` if you can, otherwise you'll need to\nadjust `CMakeLists.txt`), as well as at least `llvm` version `18.1.1` (newer is\nbetter, given status of module `std`) OR `MSVC` version `14.35`. Minimum\nrequirements can be found\n[on Kitware's announcement for `import std`](https://www.kitware.com/import-std-in-cmake-3-30/).\nSadly `cmake` does not yet support `g++` or `stdlibc++` with `import std`, ~~so I\nhave included a separate `Makefile` intended exclusively for compilation with\n`g++` and `stdlibc++`; `cmake` also does not support `Makefile`s when using\nthis feature, and instead solely relies on / supports `ninja` at this time\n(circa Oct. 8, 2025).~~ In other words, to build with `cmake` you will need\n* `cmake`\n* `ninja`\n* `clang` or `msvc`\n\n~~and to build with the `Makefile`, have at least `g++` version `15.1.0` and be\nwilling to make changes based upon your machine or distribution.~~ I will try to\nelaborate on this in the near future.\n\nFor the `macOS` user, please see [here](https://github.com/colinrford/polynomial_nttp/wiki/Troubles-with-macOS,-Apple-Clang,-and-LLVM-Clang)\nfor details on getting `cmake` to avoid using Apple `clang` and `ld64` (Apple's\n`clang` doesn't support `c++` modules as of circa October 1, 2025;\n`ld64` still linked in my experience).\n\n### building (for real this time)\n1. Grab a copy\n   ```bash\n   git clone https://github.com/colinrford/polynomial_nttp.git\n   ```\n2. Inside a build directory, run `cmake`\n   ```bash\n   cd /to/wherever/you/placed/polynomial_nttp\n   mkdir build \u0026\u0026 cd build\n   cmake ..\n   ```\n   where it is important to note that the `cmake` command likely won't be this\n   pretty, and you will likely need to adjust the command by adding `-G Ninja`\n   and/or `-DCMAKE-TOOLCHAIN-FILE=/path/to/your/cmake/toolchain.cmake` as I\n   have had to do:\n   ```bash\n   cmake -DCMAKE-TOOLCHAIN-FILE=/path/to/your/cmake/toolchain.cmake .. -G Ninja\n   ```\n   You can alternatively add Cmake presets to shorten this command. If this\n   does not execute properly, and you are on `macOS`, please take a look at\n   [this wiki entry.](https://github.com/colinrford/polynomial_nttp/wiki/Troubles-with-macOS,-Apple-Clang,-and-LLVM-Clang)\n3. Run `ninja` to build the project, which will also build tests and examples\n   at this time.\n   ```bash\n   ninja\n   ```\n   If you made it past step 2. successfully, step 3 should hopefully work out\n   okay. If not, and you are on `macOS`, again, take a look\n   [here.](https://github.com/colinrford/polynomial_nttp/wiki/Troubles-with-macOS,-Apple-Clang,-and-LLVM-Clang)\n4. (optional) run `ctest` to run all the unit tests\n   ```bash\n   ctest\n   ```\n\n## thank you for checking out `lam.polynomial_nttp`\nI do not claim this is the first of its kind, but the work here is my own.\nThere are possible blind spots of the author. In its current state, please\nexpect it to work, albeit with an occasional quirk. If you find it does not\nwork for some reason, please alert me somehow, either via GitHub or via\nemail. Any feedback is greatly appreciated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolinrford%2Fpolynomial_nttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcolinrford%2Fpolynomial_nttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolinrford%2Fpolynomial_nttp/lists"}