macro_rules! impl_interpolation_base_ring_char_zero {
(<{$($gen_args:tt)*}> InterpolationBaseRing for $self_type:ty where $($constraints:tt)*) => { ... };
(InterpolationBaseRing for $self_type:ty) => { ... };
}Expand description
Generates an implementation of crate::reduce_lift::poly_eval::InterpolationBaseRing
for a ring of characteristic zero. Not that in this case, the only sensible implementation
is trivial, since the ring itself has enough elements for any interpolation task.
ยงExample
// we wrap a `RingBase` here for simplicity, but in practice a wrapper should
// always store a `RingStore` instead
#[derive(PartialEq, Debug)]
struct MyRingWrapper<R: RingBase>(R);
impl<R: RingBase> DelegateRing for MyRingWrapper<R> {
type Element = R::Element;
type Base = R;
fn get_delegate(&self) -> &Self::Base { &self.0 }
fn delegate(&self, x: R::Element) -> R::Element { x }
fn rev_delegate(&self, x: R::Element) -> R::Element { x }
fn delegate_ref<'a>(&self, x: &'a R::Element) -> &'a R::Element { x }
fn delegate_mut<'a>(&self, x: &'a mut R::Element) -> &'a mut R::Element { x }
}
impl<R: RingBase> DelegateRingImplEuclideanRing for MyRingWrapper<R> {}
impl<R: RingBase> DelegateRingImplFiniteRing for MyRingWrapper<R> {}
impl<R: Domain> Domain for MyRingWrapper<R> {}
impl_interpolation_base_ring_char_zero!{ <{ R }> InterpolationBaseRing for MyRingWrapper<R> where R: PrincipalIdealRing + Domain + ComputeResultantRing + Debug }
// now we can use `InterpolationBaseRing`-functionality
let ring = MyRingWrapper(StaticRing::<i64>::RING.into());
let (embedding, points) = ToExtRingMap::for_interpolation(&ring, 3);
assert_eq!(0, points[0]);
assert_eq!(1, points[1]);
assert_eq!(2, points[2]);
// There is a problem here, described in EvalPolyLocallyRing::LocalRingBase.
// Short version: we need to manually impl ComputeResultantRing
impl<R: ComputeResultantRing> ComputeResultantRing for MyRingWrapper<R> {
fn resultant<P>(poly_ring: P, f: El<P>, g: El<P>) -> Self::Element
where P: RingStore + Copy,
P::Type: PolyRing,
<P::Type as RingExtension>::BaseRing: RingStore<Type = Self>
{
let new_poly_ring = DensePolyRing::new(RingRef::new(poly_ring.base_ring().get_ring().get_delegate()), "X");
let hom = new_poly_ring.lifted_hom(&poly_ring, UnwrapHom::new(poly_ring.base_ring().get_ring()));
poly_ring.base_ring().get_ring().rev_delegate(R::resultant(&new_poly_ring, hom.map(f), hom.map(g)))
}
}