RingStore

Trait RingStore 

Source
pub trait RingStore: Sized {
    type Type: RingBase + ?Sized;

Show 53 methods // Required method fn get_ring<'a>(&'a self) -> &'a Self::Type; // Provided methods fn clone_el(&self, val: &El<Self>) -> El<Self> { ... } fn add_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>) { ... } fn add_assign(&self, lhs: &mut El<Self>, rhs: El<Self>) { ... } fn sub_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>) { ... } fn sub_self_assign(&self, lhs: &mut El<Self>, rhs: El<Self>) { ... } fn sub_self_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>) { ... } fn negate_inplace(&self, lhs: &mut El<Self>) { ... } fn mul_assign(&self, lhs: &mut El<Self>, rhs: El<Self>) { ... } fn mul_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>) { ... } fn zero(&self) -> El<Self> { ... } fn one(&self) -> El<Self> { ... } fn neg_one(&self) -> El<Self> { ... } fn eq_el(&self, lhs: &El<Self>, rhs: &El<Self>) -> bool { ... } fn is_zero(&self, value: &El<Self>) -> bool { ... } fn is_one(&self, value: &El<Self>) -> bool { ... } fn is_neg_one(&self, value: &El<Self>) -> bool { ... } fn is_commutative(&self) -> bool { ... } fn is_noetherian(&self) -> bool { ... } fn negate(&self, value: El<Self>) -> El<Self> { ... } fn sub_assign(&self, lhs: &mut El<Self>, rhs: El<Self>) { ... } fn add_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn add_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self> { ... } fn add_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn add(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self> { ... } fn sub_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn sub_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self> { ... } fn sub_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn sub(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self> { ... } fn mul_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn mul_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self> { ... } fn mul_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> { ... } fn mul(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self> { ... } fn square(&self, value: &mut El<Self>) { ... } fn fma(&self, lhs: &El<Self>, rhs: &El<Self>, summand: El<Self>) -> El<Self> { ... } fn coerce<S>(&self, from: &S, el: El<S>) -> El<Self> where S: RingStore, Self::Type: CanHomFrom<S::Type> { ... } fn into_identity(self) -> Identity<Self> { ... } fn identity<'a>(&'a self) -> Identity<&'a Self> { ... } fn into_can_hom<S>(self, from: S) -> Result<CanHom<S, Self>, (S, Self)> where Self: Sized, S: RingStore, Self::Type: CanHomFrom<S::Type> { ... } fn into_can_iso<S>(self, from: S) -> Result<CanIso<S, Self>, (S, Self)> where Self: Sized, S: RingStore, Self::Type: CanIsoFromTo<S::Type> { ... } fn can_hom<'a, S>(&'a self, from: &'a S) -> Option<CanHom<&'a S, &'a Self>> where S: RingStore, Self::Type: CanHomFrom<S::Type> { ... } fn can_iso<'a, S>(&'a self, from: &'a S) -> Option<CanIso<&'a S, &'a Self>> where S: RingStore, Self::Type: CanIsoFromTo<S::Type> { ... } fn into_int_hom(self) -> IntHom<Self> { ... } fn int_hom<'a>(&'a self) -> IntHom<&'a Self> { ... } fn sum<I>(&self, els: I) -> El<Self> where I: IntoIterator<Item = El<Self>> { ... } fn try_sum<I, E>(&self, els: I) -> Result<El<Self>, E> where I: IntoIterator<Item = Result<El<Self>, E>> { ... } fn prod<I>(&self, els: I) -> El<Self> where I: IntoIterator<Item = El<Self>> { ... } fn pow(&self, x: El<Self>, power: usize) -> El<Self> { ... } fn pow_gen<R: RingStore>( &self, x: El<Self>, power: &El<R>, integers: R, ) -> El<Self> where R::Type: IntegerRing { ... } fn format<'a>( &'a self, value: &'a El<Self>, ) -> RingElementDisplayWrapper<'a, Self> { ... } fn format_within<'a>( &'a self, value: &'a El<Self>, within: EnvBindingStrength, ) -> RingElementDisplayWrapper<'a, Self> { ... } fn println(&self, value: &El<Self>) { ... } fn characteristic<I: RingStore + Copy>(&self, ZZ: I) -> Option<El<I>> where I::Type: IntegerRing { ... }
}
Expand description

Basic trait for objects that store (in some sense) a ring. It can also be considered the user-facing trait for rings, so rings are always supposed to be used through a RingStore-object.

This can be a ring-by-value, a reference to a ring, or really any object that provides access to a RingBase object.

As opposed to RingBase, which is responsible for the functionality and ring operations, this trait is solely responsible for the storage. The two basic implementors are RingValue and RingRef, which just wrap a value resp. reference to a RingBase object. Building on that, every object that wraps a RingStore object can implement again RingStore. This applies in particular to implementors of Deref<Target: RingStore>, for whom there is a blanket implementation.

§Example

fn add_in_ring<R: RingStore>(ring: R, a: El<R>, b: El<R>) -> El<R> {
    ring.add(a, b)
}
 
let ring: RingValue<StaticRingBase<i64>> = StaticRing::<i64>::RING;
assert_el_eq!(ring, 7, add_in_ring(ring, 3, 4));
assert_el_eq!(ring, 7, add_in_ring(&ring, 3, 4));
assert_el_eq!(ring, 7, add_in_ring(Rc::new(ring), 3, 4));

§What does this do?

We need a framework that allows nesting rings, e.g. to provide a polynomial ring over a finite field - say PolyRing<FiniteRing + Field>. However, the simplest implementation

struct PolyRing<BaseRing: Ring> { /* omitted */ }

would have the effect that PolyRing<FiniteRing + Field> and PolyRing<&FiniteRing + Field> are entirely different types. While implementing relationships between them is possible, the approach does not scale well when we consider many rings and multiple layers of nesting.

§Note for implementors

Generally speaking it is not recommended to overwrite any of the default-implementations of ring functionality, as this is against the spirit of this trait. Instead, just provide an implementation of get_ring() and put ring functionality in a custom implementation of RingBase.

Required Associated Types§

Source

type Type: RingBase + ?Sized

The type of the stored ring.

Required Methods§

Source

fn get_ring<'a>(&'a self) -> &'a Self::Type

Returns a reference to the stored ring.

Provided Methods§

Source

fn clone_el(&self, val: &El<Self>) -> El<Self>

Source

fn add_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>)

Source

fn add_assign(&self, lhs: &mut El<Self>, rhs: El<Self>)

Source

fn sub_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>)

Source

fn sub_self_assign(&self, lhs: &mut El<Self>, rhs: El<Self>)

Source

fn sub_self_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>)

Source

fn negate_inplace(&self, lhs: &mut El<Self>)

Source

fn mul_assign(&self, lhs: &mut El<Self>, rhs: El<Self>)

Source

fn mul_assign_ref(&self, lhs: &mut El<Self>, rhs: &El<Self>)

Source

fn zero(&self) -> El<Self>

Source

fn one(&self) -> El<Self>

Source

fn neg_one(&self) -> El<Self>

Source

fn eq_el(&self, lhs: &El<Self>, rhs: &El<Self>) -> bool

Source

fn is_zero(&self, value: &El<Self>) -> bool

Source

fn is_one(&self, value: &El<Self>) -> bool

Source

fn is_neg_one(&self, value: &El<Self>) -> bool

Source

fn is_commutative(&self) -> bool

Source

fn is_noetherian(&self) -> bool

Source

fn negate(&self, value: El<Self>) -> El<Self>

Source

fn sub_assign(&self, lhs: &mut El<Self>, rhs: El<Self>)

Source

fn add_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn add_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self>

Source

fn add_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn add(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self>

Source

fn sub_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn sub_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self>

Source

fn sub_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn sub(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self>

Source

fn mul_ref(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn mul_ref_fst(&self, lhs: &El<Self>, rhs: El<Self>) -> El<Self>

Source

fn mul_ref_snd(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self>

Source

fn mul(&self, lhs: El<Self>, rhs: El<Self>) -> El<Self>

Source

fn square(&self, value: &mut El<Self>)

Source

fn fma(&self, lhs: &El<Self>, rhs: &El<Self>, summand: El<Self>) -> El<Self>

Source

fn coerce<S>(&self, from: &S, el: El<S>) -> El<Self>
where S: RingStore, Self::Type: CanHomFrom<S::Type>,

Tries to map the given element into this ring.

This will internally construct a homomorphism between the rings, using CanHomFrom. Note that if you want to map many elements between the same rings, it may be faster to construct the homomorphism only once using RingStore::can_hom().

Source

fn into_identity(self) -> Identity<Self>

Returns the identity map self -> self.

Source

fn identity<'a>(&'a self) -> Identity<&'a Self>

Returns the identity map self -> self.

Source

fn into_can_hom<S>(self, from: S) -> Result<CanHom<S, Self>, (S, Self)>
where Self: Sized, S: RingStore, Self::Type: CanHomFrom<S::Type>,

Returns the canonical homomorphism from -> self, if it exists, moving both rings into the CanHom object.

Source

fn into_can_iso<S>(self, from: S) -> Result<CanIso<S, Self>, (S, Self)>
where Self: Sized, S: RingStore, Self::Type: CanIsoFromTo<S::Type>,

Returns the canonical isomorphism from -> self, if it exists, moving both rings into the CanHom object.

Source

fn can_hom<'a, S>(&'a self, from: &'a S) -> Option<CanHom<&'a S, &'a Self>>
where S: RingStore, Self::Type: CanHomFrom<S::Type>,

Returns the canonical homomorphism from -> self, if it exists.

Source

fn can_iso<'a, S>(&'a self, from: &'a S) -> Option<CanIso<&'a S, &'a Self>>
where S: RingStore, Self::Type: CanIsoFromTo<S::Type>,

Returns the canonical isomorphism from -> self, if it exists.

Source

fn into_int_hom(self) -> IntHom<Self>

Returns the homomorphism Z -> self that exists for any ring.

Source

fn int_hom<'a>(&'a self) -> IntHom<&'a Self>

Returns the homomorphism Z -> self that exists for any ring.

Source

fn sum<I>(&self, els: I) -> El<Self>
where I: IntoIterator<Item = El<Self>>,

Computes the sum of all elements returned by the iterator.

This is equivalent to

fn sum<R, I>(ring: R, els: I) -> El<R>
    where R: RingStore,
        I: IntoIterator<Item = El<R>>
{
    els.into_iter().fold(ring.zero(), |a, b| ring.add(a, b))
}

but may be faster.

Source

fn try_sum<I, E>(&self, els: I) -> Result<El<Self>, E>
where I: IntoIterator<Item = Result<El<Self>, E>>,

Equivalent of RingStore::sum() if the producer of the ring elements can fail, in which case summation is aborted and the error returned.

Source

fn prod<I>(&self, els: I) -> El<Self>
where I: IntoIterator<Item = El<Self>>,

Computes the product of all elements returned by the iterator.

This is equivalent to

fn prod<R, I>(ring: R, els: I) -> El<R>
    where R: RingStore,
        I: IntoIterator<Item = El<R>>
{
    els.into_iter().fold(ring.one(), |a, b| ring.mul(a, b))
}

but may be faster.

Source

fn pow(&self, x: El<Self>, power: usize) -> El<Self>

Raises the given element to the given power.

Source

fn pow_gen<R: RingStore>( &self, x: El<Self>, power: &El<R>, integers: R, ) -> El<Self>
where R::Type: IntegerRing,

Raises the given element to the given power, which should be a positive integer belonging to an arbitrary IntegerRing.

This can in particular be used to compute exponentiation when the exponent does not fit in a usize.

Source

fn format<'a>( &'a self, value: &'a El<Self>, ) -> RingElementDisplayWrapper<'a, Self>

Returns an object that represents the given ring element and implements std::fmt::Display, to use as formatting parameter.

§Example
let ring = BigIntRing::RING;
let element = ring.int_hom().map(3);
assert_eq!("3", format!("{}", ring.format(&element)));
Source

fn format_within<'a>( &'a self, value: &'a El<Self>, within: EnvBindingStrength, ) -> RingElementDisplayWrapper<'a, Self>

Returns an object that represents the given ring element and implements std::fmt::Display, to use as formatting parameter. As opposed to RingStore::format(), this function takes an additional argument to specify the context the result is printed in, which is used to determine whether to put the value in parenthesis or not.

§Example
let ring = DensePolyRing::new(StaticRing::<i64>::RING, "X");
let [f, g] = ring.with_wrapped_indeterminate(|X| [X.clone(), X + 1]);
assert_eq!("X", format!("{}", ring.format_within(&f, EnvBindingStrength::Sum)));
assert_eq!("X", format!("{}", ring.format_within(&f, EnvBindingStrength::Product)));
assert_eq!("X + 1", format!("{}", ring.format_within(&g, EnvBindingStrength::Sum)));
assert_eq!("(X + 1)", format!("{}", ring.format_within(&g, EnvBindingStrength::Product)));
Source

fn println(&self, value: &El<Self>)

Prints the given element. Use for quick & dirty debugging.

Source

fn characteristic<I: RingStore + Copy>(&self, ZZ: I) -> Option<El<I>>
where I::Type: IntegerRing,

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<'a, R: RingBase + ?Sized> RingStore for RingRef<'a, R>

Source§

type Type = R

Source§

impl<'a, S: Deref> RingStore for S
where S::Target: RingStore,

Source§

type Type = <<S as Deref>::Target as RingStore>::Type

Source§

impl<R: RingBase> RingStore for RingValue<R>

Source§

type Type = R