#abstract-algebra #numeric

nightly un_algebra

Simple implementations of selected abstract algebraic structures--including groups, rings, and fields. Intended for self-study of abstract algebra concepts and not for production use.

16 releases (8 breaking)

0.9.0 Dec 7, 2019
0.8.0 Jul 28, 2019
0.7.0 May 15, 2019
0.4.0 Jan 31, 2019
0.1.0 Jul 16, 2018

#741 in Math

31 downloads per month

MIT license

145KB
2.5K SLoC

un_algebra

crate link documentation rustc version license

Simple Rust implementations of selected abstract algebraic structures.

Synopsis

Mathematical abstract algebra is built on a rich collection of algebraic structures. Learning about these structures can give non-mathematicians insights into the mathematical entities they need to work with--for example, real numbers, complex numbers, vectors, matrices, and permutations. By definition, these structures must comply with sets of axioms and properties, which are in turn a rich source of properties for generative testing.

un_algebra (_un_derstanding _algebra_) is a simple implementation of selected algebraic structures in Rust. I hope it is useful for developers learning abstract algebra concepts for the first time. Currently this crate provides magma, semigroup, quasigroup, monoid, group, ring and field structure implementations as well as equivalence and inequality relations on sets.

Documentation

See https://docs.rs/un_algebra

Contributions

Please refer to the contributing guide.

Installation

Add un_algebra to your Cargo.toml dependencies:

[dependencies]
un_algebra = "0.*.0"

Stability

un_algebra is still under pre-version 1.0 development, with a number of outstanding design and implementation issues. Breaking changes are likely to the crate API.

Production use

un_algebra is intended to support self-study of abstract algebraic structures--it is not optimized for use in a production environment. For production environments I recommend using a more sophisticated library like alga.

Compatibility

un_algebra uses 2018 edition features but unfortunately requires Rust nightly as it uses the (experimental) external documentation feature.

Errors

I'm not a mathematician so my implementation of the various structures and their respective axioms in un_algebra may not be strictly correct. Please let me know of any errors.

Axioms and properties

All un_algebra structure traits have associated predicate functions that implement the structure axioms. Some structures also have associated predicate functions that implement derived properties of the structure.

These properties are not strictly necessary since they can be derived from the axioms, but they do allow richer generative testing of trait implementations, especially those using floating point numbers.

The crate axiom and property functions are bundled into "laws" traits, with a blanket implementation for each axiom or property associated trait.

Examples

un_algebra implements the relevant structure traits for all the Rust standard library integer and floating point types, for example, an additive group for integer types i8, i16, i32, etc.

The Rust standard library has no support for complex numbers (ℂ) or rational numbers (ℚ) so I've used the complex and rational types from the [num] crate and implemented examples using both these numeric types.

In addition, the crate examples directory contains abstract structure implementations of selected concepts, for example, finite fields.

Example

Rust's i128 type forms several un_algebra algebraic structures, starting with additive and multiplicative magmas (with "wrapping" or modular arithmetic):

use un_algebra::prelude::*;

impl AddMagma for i128 {
  fn add(&self, other: &Self) -> Self {
    self.wrapping_add(other)
  }
}

impl MulMagma for i128 {
  fn mul(&self, other: &Self) -> Self {
    self.wrapping_mul(other)
  }
}

i128 also forms additive and multiplicative semigroups:

impl AddSemigroup for i128 {}

impl MulSemigroup for i128 {}

And additive and multiplicative monoids with one and zero as the monoid identities:

impl AddMonoid for i128 {
  fn zero() -> Self {
    0
  }
}

impl MulMonoid for i128 {
  fn one() -> Self {
    1
  }
}

i128 also forms an additive group and additive commutative group (with "wrapping" or modular negation), but not a multiplicative group, as the integers have no closed division operation:

impl AddGroup for i128 {
  fn negate(&self) -> Self {
    self.wrapping_neg()
  }
}

impl AddComGroup for i128 {}

And a ring and commutative ring:

impl Ring for i128 {}

impl CommRing for i128 {}

References

Please refer to the reading document for more background on each structure and its associated axioms and properties.

License

This project is licensed under the MIT license (see LICENSE.txt or https://opensource.org/licenses/MIT).

Dependencies

~4.5MB
~89K SLoC