refactor poly
This commit is contained in:
151
src/poly/flat.rs
151
src/poly/flat.rs
@@ -1,15 +1,10 @@
|
|||||||
use itertools::Itertools;
|
|
||||||
use std::fmt::{self, Display};
|
|
||||||
|
|
||||||
use std::ops::{Add, BitXor, Mul, Sub};
|
|
||||||
|
|
||||||
use super::var::{StaticVar, Var};
|
|
||||||
use crate::fmt::num_to_superscript;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::var::Var;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Poly<V: Var> {
|
pub struct Poly<V: Var> {
|
||||||
mono: HashMap<Mono<V>, i32>,
|
pub(crate) mono: HashMap<Mono<V>, i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Var> Default for Poly<V> {
|
impl<V: Var> Default for Poly<V> {
|
||||||
@@ -20,21 +15,6 @@ impl<V: Var> Default for Poly<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Var> Display for Poly<V> {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
match self.mono.is_empty() {
|
|
||||||
true => write!(fmt, "∅"),
|
|
||||||
false => write!(
|
|
||||||
fmt,
|
|
||||||
"{}",
|
|
||||||
self.mono
|
|
||||||
.iter()
|
|
||||||
.map(|(m, c)| format!("{}{}", c, m))
|
|
||||||
.join(" + ")
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var, T: IntoIterator> From<T> for Poly<V>
|
impl<V: Var, T: IntoIterator> From<T> for Poly<V>
|
||||||
where
|
where
|
||||||
@@ -113,128 +93,3 @@ impl<V: Var, U: Into<V>> FromIterator<(U, u32)> for Mono<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Var> Display for Mono<V> {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
write!(
|
|
||||||
fmt,
|
|
||||||
"{}",
|
|
||||||
self.term
|
|
||||||
.iter()
|
|
||||||
.map(|(t, p)| match p {
|
|
||||||
1 => format!("{t}"),
|
|
||||||
_ => format!("{t}{}", num_to_superscript(p.to_string())),
|
|
||||||
})
|
|
||||||
.join("")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitXor<u32> for StaticVar {
|
|
||||||
type Output = Mono<StaticVar>;
|
|
||||||
|
|
||||||
fn bitxor(self, exp: u32) -> Self::Output {
|
|
||||||
[(self, exp)].into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> BitXor<u32> for &'a StaticVar {
|
|
||||||
type Output = Mono<StaticVar>;
|
|
||||||
|
|
||||||
fn bitxor(self, exp: u32) -> Self::Output {
|
|
||||||
[(self.clone(), exp)].into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var> Mul for Mono<V> {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn mul(self, other: Mono<V>) -> Self::Output {
|
|
||||||
let mut a_term = self.term.into_iter().peekable();
|
|
||||||
let mut b_term = other.term.into_iter().peekable();
|
|
||||||
|
|
||||||
let mut result: Vec<(V, u32)> = Default::default();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match (a_term.peek(), b_term.peek()) {
|
|
||||||
(Some((a_var, _)), Some((b_var, _))) => {
|
|
||||||
if a_var < b_var {
|
|
||||||
result.push(a_term.next().unwrap());
|
|
||||||
} else if a_var > b_var {
|
|
||||||
result.push(b_term.next().unwrap());
|
|
||||||
} else {
|
|
||||||
let (var, a_exp) = a_term.next().unwrap();
|
|
||||||
let (_, b_exp) = b_term.next().unwrap();
|
|
||||||
result.push((var, a_exp + b_exp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Some(a), None) => {
|
|
||||||
result.push(a.clone());
|
|
||||||
a_term.next();
|
|
||||||
}
|
|
||||||
(None, Some(b)) => {
|
|
||||||
result.push(b.clone());
|
|
||||||
b_term.next();
|
|
||||||
}
|
|
||||||
(None, None) => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mono { term: result }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var> Mul<Mono<V>> for i32 {
|
|
||||||
type Output = Poly<V>;
|
|
||||||
|
|
||||||
fn mul(self, mono: Mono<V>) -> Self::Output {
|
|
||||||
let mut poly: HashMap<Mono<V>, i32> = Default::default();
|
|
||||||
|
|
||||||
poly.insert(mono, self);
|
|
||||||
|
|
||||||
Poly { mono: poly }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var> Mul for Poly<V> {
|
|
||||||
type Output = Poly<V>;
|
|
||||||
|
|
||||||
fn mul(self, other: Poly<V>) -> Self::Output {
|
|
||||||
let mut result = Poly::default();
|
|
||||||
for (m1, c1) in &self.mono {
|
|
||||||
for (m2, c2) in &other.mono {
|
|
||||||
let entry = result.mono.entry(m1.clone() * m2.clone()).or_insert(0);
|
|
||||||
*entry += c1 * c2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.mono.retain(|_, &mut c| c != 0);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var> Add for Poly<V> {
|
|
||||||
type Output = Poly<V>;
|
|
||||||
|
|
||||||
fn add(mut self, other: Poly<V>) -> Self::Output {
|
|
||||||
for (mono, coeff) in other.mono {
|
|
||||||
let entry = self.mono.entry(mono).or_insert(0);
|
|
||||||
*entry += coeff;
|
|
||||||
}
|
|
||||||
self.mono.retain(|_, &mut coeff| coeff != 0);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V: Var> Sub for Poly<V> {
|
|
||||||
type Output = Poly<V>;
|
|
||||||
|
|
||||||
fn sub(mut self, other: Poly<V>) -> Self::Output {
|
|
||||||
for (mono, coeff) in other.mono {
|
|
||||||
let entry = self.mono.entry(mono).or_insert(0);
|
|
||||||
*entry -= coeff;
|
|
||||||
}
|
|
||||||
self.mono.retain(|_, &mut coeff| coeff != 0);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
59
src/poly/fmt.rs
Normal file
59
src/poly/fmt.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use crate::fmt::{num_to_subscript, num_to_superscript};
|
||||||
|
use crate::poly::flat::{Mono, Poly};
|
||||||
|
use crate::poly::var::{StaticVar, Var};
|
||||||
|
|
||||||
|
impl Display for StaticVar {
|
||||||
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
let num_indices = self.indices.len();
|
||||||
|
match num_indices {
|
||||||
|
0 => write!(fmt, "{}", self.name),
|
||||||
|
_ => write!(
|
||||||
|
fmt,
|
||||||
|
"{}{}",
|
||||||
|
self.name,
|
||||||
|
self.indices
|
||||||
|
.iter()
|
||||||
|
.map(|x: &u32| num_to_subscript(x.to_string()))
|
||||||
|
.join(",")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Display for Poly<V> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
match self.mono.is_empty() {
|
||||||
|
true => write!(fmt, "∅"),
|
||||||
|
false => write!(
|
||||||
|
fmt,
|
||||||
|
"{}",
|
||||||
|
self.mono
|
||||||
|
.iter()
|
||||||
|
.map(|(m, c)| format!("{}{}", c, m))
|
||||||
|
.join(" + ")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<V: Var> Display for Mono<V> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
write!(
|
||||||
|
fmt,
|
||||||
|
"{}",
|
||||||
|
self.term
|
||||||
|
.iter()
|
||||||
|
.map(|(t, p)| match p {
|
||||||
|
1 => format!("{t}"),
|
||||||
|
_ => format!("{t}{}", num_to_superscript(p.to_string())),
|
||||||
|
})
|
||||||
|
.join("")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
pub mod flat;
|
pub mod flat;
|
||||||
pub mod var;
|
pub mod var;
|
||||||
|
pub mod ops;
|
||||||
|
pub mod fmt;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
|||||||
115
src/poly/ops.rs
Normal file
115
src/poly/ops.rs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::ops::{Add, BitXor, Mul, Sub};
|
||||||
|
|
||||||
|
use crate::poly::flat::{Mono, Poly};
|
||||||
|
use crate::poly::var::{StaticVar, Var};
|
||||||
|
|
||||||
|
impl BitXor<u32> for StaticVar {
|
||||||
|
type Output = Mono<StaticVar>;
|
||||||
|
|
||||||
|
fn bitxor(self, exp: u32) -> Self::Output {
|
||||||
|
[(self, exp)].into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BitXor<u32> for &'a StaticVar {
|
||||||
|
type Output = Mono<StaticVar>;
|
||||||
|
|
||||||
|
fn bitxor(self, exp: u32) -> Self::Output {
|
||||||
|
[(self.clone(), exp)].into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Mul for Mono<V> {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, other: Mono<V>) -> Self::Output {
|
||||||
|
let mut a_term = self.term.into_iter().peekable();
|
||||||
|
let mut b_term = other.term.into_iter().peekable();
|
||||||
|
|
||||||
|
let mut result: Vec<(V, u32)> = Default::default();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match (a_term.peek(), b_term.peek()) {
|
||||||
|
(Some((a_var, _)), Some((b_var, _))) => {
|
||||||
|
if a_var < b_var {
|
||||||
|
result.push(a_term.next().unwrap());
|
||||||
|
} else if a_var > b_var {
|
||||||
|
result.push(b_term.next().unwrap());
|
||||||
|
} else {
|
||||||
|
let (var, a_exp) = a_term.next().unwrap();
|
||||||
|
let (_, b_exp) = b_term.next().unwrap();
|
||||||
|
result.push((var, a_exp + b_exp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some(a), None) => {
|
||||||
|
result.push(a.clone());
|
||||||
|
a_term.next();
|
||||||
|
}
|
||||||
|
(None, Some(b)) => {
|
||||||
|
result.push(b.clone());
|
||||||
|
b_term.next();
|
||||||
|
}
|
||||||
|
(None, None) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mono { term: result }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Mul<Mono<V>> for i32 {
|
||||||
|
type Output = Poly<V>;
|
||||||
|
|
||||||
|
fn mul(self, mono: Mono<V>) -> Self::Output {
|
||||||
|
let mut poly: HashMap<Mono<V>, i32> = Default::default();
|
||||||
|
|
||||||
|
poly.insert(mono, self);
|
||||||
|
|
||||||
|
Poly { mono: poly }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Mul for Poly<V> {
|
||||||
|
type Output = Poly<V>;
|
||||||
|
|
||||||
|
fn mul(self, other: Poly<V>) -> Self::Output {
|
||||||
|
let mut result = Poly::default();
|
||||||
|
for (m1, c1) in &self.mono {
|
||||||
|
for (m2, c2) in &other.mono {
|
||||||
|
let entry = result.mono.entry(m1.clone() * m2.clone()).or_insert(0i32);
|
||||||
|
*entry += c1 * c2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.mono.retain(|_, &mut c| c != 0);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Add for Poly<V> {
|
||||||
|
type Output = Poly<V>;
|
||||||
|
|
||||||
|
fn add(mut self, other: Poly<V>) -> Self::Output {
|
||||||
|
for (mono, coeff) in other.mono {
|
||||||
|
let entry = self.mono.entry(mono).or_insert(0);
|
||||||
|
*entry += coeff;
|
||||||
|
}
|
||||||
|
self.mono.retain(|_, &mut coeff| coeff != 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Var> Sub for Poly<V> {
|
||||||
|
type Output = Poly<V>;
|
||||||
|
|
||||||
|
fn sub(mut self, other: Poly<V>) -> Self::Output {
|
||||||
|
for (mono, coeff) in other.mono {
|
||||||
|
let entry = self.mono.entry(mono).or_insert(0);
|
||||||
|
*entry -= coeff;
|
||||||
|
}
|
||||||
|
self.mono.retain(|_, &mut coeff| coeff != 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,14 @@
|
|||||||
use itertools::Itertools;
|
use std::fmt::{Debug, Display};
|
||||||
use std::fmt::{self, Debug, Display, Formatter};
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::fmt::num_to_subscript;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct StaticVar {
|
pub struct StaticVar {
|
||||||
name: &'static str,
|
pub(crate) name: &'static str,
|
||||||
indices: Vec<u32>,
|
pub(crate) indices: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Var: PartialEq + Eq + PartialOrd + Ord + Clone + Hash + Debug + Display {}
|
pub trait Var: PartialEq + Eq + PartialOrd + Ord + Clone + Hash + Debug + Display {}
|
||||||
|
|
||||||
impl Display for StaticVar {
|
|
||||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
let num_indices = self.indices.len();
|
|
||||||
match num_indices {
|
|
||||||
0 => write!(fmt, "{}", self.name),
|
|
||||||
_ => write!(
|
|
||||||
fmt,
|
|
||||||
"{}{}",
|
|
||||||
self.name,
|
|
||||||
self.indices
|
|
||||||
.iter()
|
|
||||||
.map(|x| num_to_subscript(x.to_string()))
|
|
||||||
.join(",")
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Var for StaticVar {}
|
impl Var for StaticVar {}
|
||||||
|
|
||||||
@@ -71,3 +51,4 @@ macro_rules! var {
|
|||||||
::circuit_cas::poly::var::StaticVar::from(($name, $idx1, $idx2))
|
::circuit_cas::poly::var::StaticVar::from(($name, $idx1, $idx2))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user