use crate::math::tensor::{
AsMutElement, AsMutTensor, AsRefElement, AsRefSlice, AsRefTensor, Tensor,
};
use crate::tensor_traits;
use super::MonomialDegree;
#[derive(PartialEq)]
pub struct Monomial<Cont> {
tensor: Tensor<Cont>,
degree: MonomialDegree,
}
tensor_traits!(Monomial);
impl<Cont> AsRefElement for Monomial<Cont>
where
Monomial<Cont>: AsRefTensor,
{
type Element = <Monomial<Cont> as AsRefTensor>::Element;
fn as_element(&self) -> &Self::Element {
self.as_tensor().first()
}
}
impl<Cont> AsMutElement for Monomial<Cont>
where
Monomial<Cont>: AsMutTensor,
{
type Element = <Monomial<Cont> as AsRefTensor>::Element;
fn as_mut_element(&mut self) -> &mut <Self as AsMutElement>::Element {
self.as_mut_tensor().first_mut()
}
}
impl<Coef> Monomial<Vec<Coef>> {
pub fn allocate(value: Coef, degree: MonomialDegree) -> Monomial<Vec<Coef>> {
Monomial {
tensor: Tensor::from_container(vec![value]),
degree,
}
}
}
impl<Cont> Monomial<Cont> {
pub fn from_container(cont: Cont, degree: MonomialDegree) -> Monomial<Cont>
where
Cont: AsRefSlice,
{
debug_assert!(
cont.as_slice().len() == 1,
"Tried to create a monomial with a container of size different than one"
);
Monomial {
tensor: Tensor::from_container(cont),
degree,
}
}
pub fn get_coefficient(&self) -> &<Self as AsRefElement>::Element
where
Self: AsRefElement,
{
self.as_element()
}
pub fn set_coefficient<Coef>(&mut self, coefficient: Coef)
where
Self: AsMutElement<Element = Coef>,
{
*(self.as_mut_element()) = coefficient;
}
pub fn get_mut_coefficient(&mut self) -> &mut <Self as AsMutElement>::Element
where
Self: AsMutElement,
{
self.as_mut_element()
}
pub fn degree(&self) -> MonomialDegree {
self.degree
}
}