Algebraeon is a computational algebra system (CAS) written purely in Rust. It implements algorithms for working with matrices, polynomials, algebraic numbers, factorizations, etc. The focus is on exact algebraic computations over approximate numerical solutions. Algebraeon is in early stages of development and the API subject to change. Algebraeon uses Malachite under the hood for arbitrary sized integer and rational numbers.
See the user guide (a work in progress) to get started.
Contributions are welcome and I am happy to do some hand-holding to help out new contributors. See below for the best ways to contribute.
There is for informal discussions on the project.
The latest published version of Algebraeon is hosted on crates.io here and the formal documentation for the most recent release is here.
To factor large integers using Algebraeon
use algebraeon::nzq::Natural;
use algebraeon::rings::natural::NaturalFns;
use algebraeon::sets::structure::ToStringSignature;
use algebraeon::{
rings::natural::factorization::NaturalCanonicalFactorizationStructure,
sets::structure::MetaType,
};
use std::str::FromStr;
let n = Natural::from_str("706000565581575429997696139445280900").unwrap();
let f = n.clone().factor().unwrap();
println!(
"{} = {}",
n,
Natural::structure().factorizations().to_string(&f)
);
/*
Output:
706000565581575429997696139445280900 = 2^2 × 5^2 × 6988699669998001 × 1010203040506070809
*/Algebraeon implements Lenstra elliptic-curve factorization for quickly finding prime factors with around 20 digits.
Factor the polynomials
use algebraeon::rings::{polynomial::*, structure::*};
use algebraeon::nzq::Integer;
let x = &Polynomial::<Integer>::var().into_ergonomic();
let f = (x.pow(2) - 5*x + 6).into_verbose();
println!("f(λ) = {}", f.factor().unwrap());
/*
Output:
f(λ) = 1 * ((-2)+λ) * ((-3)+λ)
*/
let f = (x.pow(15) - 1).into_verbose();
println!("f(λ) = {}", f.factor().unwrap());
/*
Output:
f(λ) = 1 * ((-1)+λ) * (1+λ+λ^2) * (1+λ+λ^2+λ^3+λ^4) * (1+(-1)λ+λ^3+(-1)λ^4+λ^5+(-1)λ^7+λ^8)
*/so
Find the general solution to the linear system
for integers
use algebraeon::nzq::Integer;
use algebraeon::rings::module::finitely_free_module::RingToFinitelyFreeModuleSignature;
use algebraeon::rings::matrix::Matrix;
use algebraeon::sets::structure::MetaType;
let m = Matrix::<Integer>::from_rows(vec![vec![3, 4, 1], vec![2, 1, 2], vec![1, 3, -1]]);
let y = vec![5.into(), 5.into(), 3.into()];
for x in Integer::structure()
.free_module(3)
.affine_subsets()
.affine_basis(&m.row_solution_set(&y))
{
println!("{:?}", x);
}
/*
Output:
[Integer(0), Integer(2), Integer(1)]
[Integer(1), Integer(1), Integer(0)]
*/so two solutions are given by
where
Find all complex roots of the polynomial
use algebraeon::rings::parsing::parse_integer_polynomial;
let f = parse_integer_polynomial("x^5 + x^2 - x + 1", "x").unwrap();
// Find the complex roots of f(x)
for root in f.all_complex_roots() {
println!("root {} of degree {}", root, root.degree());
}
/*
Output:
root ≈-1.328 of degree 3
root ≈0.662-0.559i of degree 3
root ≈0.662+0.559i of degree 3
root -i of degree 2
root i of degree 2
*/Despite the output, the roots found are not numerical approximations. Rather, they are stored internally as exact algebraic numbers by using isolating boxes in the complex plane and isolating intervals on the real line.
Use the issue tracker if you have questions, feature requests, bugs reports, etc.
If you're unsure what you could do to help:
- Have a look through the issue tracker for unassigned issues and leave a comment.
- Ask in the discord server.
Algebraeon is organized as a cargo workspace. Run cargo test in the root directory to build and run all tests.
A suggested workflow for getting started:
- Checkout the repository.
- Create a new binary in
examples/src/bin, for examplemy_main.rs. - Copy an example into
my_main.rs. - Run it with
cargo run --bin my_mainin the root directory.
To submit changes for inclusion in the main branch: Fork this repository, make changes, and submit a pull request.
Use of AI is fine in contributions subjet to the following requests:
- Please outline in a PR comment the extent to which AI has been used.
- Ensure every AI generated line has been understood by a human.
- Don't use AI to write code and tests for that code.
If you wish to contribute code we ask that you sign a CLA. The CLA allows us to relicense future versions of Algebraeon, including your contribution, under any licences the Free Software Foundation classifies as a Free Software Licence and which are approved by the Open Source Initiative as Open Source licences. It does not allow us to relicense of your contribution under any other more restrictive licences. The CLA can be signed on GitHub once you submit a pull request.