luna-poly
luna-poly provides canonical polynomial types for MoonBit: dense univariate polynomials, multivariate polynomials as sorted term arrays or ordered maps, and polynomials over named variables with evaluation, partial evaluation and substitution. Every type comes in an immutable flavour, where polynomials are values, and a mutable flavour, where explicitly named methods update a container in place. This manual describes version 0.2.0.
What you get
- Canonical forms. Every representation removes zero terms and keeps one normal form, so
==is equality of polynomials. - A shared monomial model. Exponent vectors without a fixed number of variables, ordered by a graded monomial order.
- Algorithms with stated costs. Schoolbook and Karatsuba multiplication, Horner evaluation, composition, formal derivatives, binary powers, and simultaneous substitution as a ring homomorphism.
- Generic code. Small capability traits, operation records, and the algebra traits of
luna-genericre-exported by both facades. - Named variables through variable contexts, bridged to
type_theorynames. - Checked variants of every partial operation, returning
Noneinstead of aborting.
Packages
| Package | Role | Pages |
|---|---|---|
core | exponent vectors, variables and contexts, shapes, capability traits, operation records | API · tutorial · design |
immut | facade of the immutable layer | API · tutorial · design |
immut/dense | immutable dense univariate DensePolynomial | API · tutorial · design |
immut/term | immutable sorted-term TermPolynomial | API · tutorial · design |
immut/sparse | immutable ordered-map SparsePolynomial | API · tutorial · design |
immut/context | immutable named-variable ContextPolynomial and substitution | API · tutorial · design |
mutable | facade of the mutable layer | API · tutorial · design |
mutable/dense | mutable DensePolynomial | API · tutorial · design |
mutable/term | mutable TermPolynomial | API · tutorial · design |
mutable/sparse | mutable SparsePolynomial | API · tutorial · design |
mutable/context | mutable ContextPolynomial | API · tutorial · design |
internal | module-private helpers (natural powers) | API · tutorial · design |
consistency | test-only package checking that layers and representations agree | API · tutorial · design |
The architecture guide shows how the packages depend on each other.
Reading paths
New to the library. Read the immut tutorial, then the tutorial of the representation you need: dense for one variable, term or sparse for several, context for named variables and substitution.
Using it in an application. Keep the immut API and the per-representation API pages at hand; they state every precondition, failure case and cost. Read the mutable tutorial when profiling shows that intermediate values matter.
Writing generic code or a new representation. Read the core tutorial and the core design, which derives the monomial order and explains the capability traits and operation records.
Contributing. Read the architecture guide, the design pages of the packages you touch, the consistency page, and the contributing guide.
Requirements and installation
luna-poly needs the MoonBit toolchain with moonc 0.10 or later. Add it to a module with
moon add Luna-Flow/luna-poly@0.2.0
and import a facade in moon.pkg:
import {
"Luna-Flow/luna-poly/immut",
}
It depends on Luna-Flow/luna-generic, Luna-Flow/arithmetic and Luna-Flow/type_theory, which moon installs automatically.
A first example
test "first example" {
let p = @immut.DensePolynomial::from_coefficients([1, 2, 3])
inspect(p.pow(2).eval(2), content="289")
let ctx = @immut.VariableContext::from_names(["x", "y"])
let x = ctx.require_variable("x")
let y = ctx.require_variable("y")
let q = @immut.ContextPolynomial::from_named_terms_as_sparse(ctx, [
([(x, 2U)], 1),
([(x, 1U), (y, 1U)], 3),
([], 4),
])
inspect(q.eval_named([(x, 2), (y, 5)]), content="38")
inspect(q.eval_partial([(x, 2)]), content="8 + 6 * y")
}
Version 0.2.0 layout
Version 0.2.0 replaced the former single root package by core, the implementation packages and the two facades. Import Luna-Flow/luna-poly/immut or Luna-Flow/luna-poly/mutable explicitly; code written for the old root package does not compile unchanged.