mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-12 21:08:45 +00:00
Assignment 6 Done
This commit is contained in:
@@ -33,55 +33,55 @@ pub fn from_usize<T: Semiring>(value: usize) -> T {
|
||||
|
||||
impl Semiring for u64 {
|
||||
fn zero() -> Self {
|
||||
todo!()
|
||||
0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
todo!()
|
||||
1
|
||||
}
|
||||
|
||||
fn add(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self + rhs
|
||||
}
|
||||
|
||||
fn mul(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Semiring for i64 {
|
||||
fn zero() -> Self {
|
||||
todo!()
|
||||
0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
todo!()
|
||||
1
|
||||
}
|
||||
|
||||
fn add(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self + rhs
|
||||
}
|
||||
|
||||
fn mul(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Semiring for f64 {
|
||||
fn zero() -> Self {
|
||||
todo!()
|
||||
0.0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
todo!()
|
||||
1.0
|
||||
}
|
||||
|
||||
fn add(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self + rhs
|
||||
}
|
||||
|
||||
fn mul(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,42 +105,91 @@ pub struct Polynomial<C: Semiring> {
|
||||
|
||||
impl<C: Semiring> Semiring for Polynomial<C> {
|
||||
fn zero() -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
coefficients: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
coefficients: HashMap::from([(0, C::one())]),
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
let mut coefficients = self.coefficients.clone();
|
||||
|
||||
for (deg, coef) in &rhs.coefficients {
|
||||
_ = coefficients
|
||||
.entry(*deg)
|
||||
.and_modify(|value| *value = value.add(coef))
|
||||
.or_insert(coef.clone());
|
||||
}
|
||||
|
||||
coefficients.retain(|_, coef| *coef != C::zero());
|
||||
|
||||
Self { coefficients }
|
||||
}
|
||||
|
||||
fn mul(&self, rhs: &Self) -> Self {
|
||||
todo!()
|
||||
let mut coefficients: HashMap<u64, C> = HashMap::new();
|
||||
|
||||
for (ldeg, lcoef) in &self.coefficients {
|
||||
for (rdeg, rcoef) in &rhs.coefficients {
|
||||
let coef = lcoef.mul(rcoef);
|
||||
_ = coefficients
|
||||
.entry(ldeg + rdeg)
|
||||
.and_modify(|value| *value = value.add(&coef))
|
||||
.or_insert(coef);
|
||||
}
|
||||
}
|
||||
|
||||
coefficients.retain(|_, coef| *coef != C::zero());
|
||||
|
||||
Self { coefficients }
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Semiring> Polynomial<C> {
|
||||
/// Constructs polynomial `x`.
|
||||
pub fn x() -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
coefficients: HashMap::from([(1, C::one())]),
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluates the polynomial with the given value.
|
||||
pub fn eval(&self, value: C) -> C {
|
||||
todo!()
|
||||
let mut result = C::zero();
|
||||
|
||||
for (deg, coef) in &self.coefficients {
|
||||
let mut xn = C::one();
|
||||
let mut n = 0;
|
||||
|
||||
while n < *deg {
|
||||
xn = xn.mul(&value);
|
||||
n += 1;
|
||||
}
|
||||
|
||||
result = result.add(&coef.mul(&xn));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Constructs polynomial `ax^n`.
|
||||
pub fn term(a: C, n: u64) -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
coefficients: HashMap::from([(n, a)]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Semiring> From<C> for Polynomial<C> {
|
||||
fn from(value: C) -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
coefficients: HashMap::from([(0, value)]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +213,30 @@ impl<C: Semiring> std::str::FromStr for Polynomial<C> {
|
||||
type Err = (); // Ignore this for now...
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
todo!()
|
||||
let mut coefficients: HashMap<u64, C> = HashMap::new();
|
||||
|
||||
for term in s.split(" + ") {
|
||||
let has_x: bool = term.contains('x');
|
||||
let has_power = term.contains('^');
|
||||
|
||||
let deg: u64 = if has_power {
|
||||
term.split("^").nth(1).unwrap().parse().unwrap()
|
||||
} else if has_x {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let coef: usize = if has_x && term.find("x").unwrap() == 0 {
|
||||
1
|
||||
} else if has_x {
|
||||
term.split("x").nth(0).unwrap().parse().unwrap()
|
||||
} else {
|
||||
term.parse().unwrap()
|
||||
};
|
||||
|
||||
let _unused = coefficients.insert(deg, from_usize(coef));
|
||||
}
|
||||
|
||||
Ok(Self { coefficients })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,39 @@ impl Rational {
|
||||
}
|
||||
}
|
||||
|
||||
fn gcd(a: isize, b: isize) -> isize {
|
||||
if b == 0 {
|
||||
a
|
||||
} else {
|
||||
gcd(b, a % b)
|
||||
}
|
||||
}
|
||||
|
||||
fn lcm(a: isize, b: isize) -> isize {
|
||||
(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
fn normalize(r: &Rational) -> Rational {
|
||||
let factor = if r.denominator < 0 { -1 } else { 1 };
|
||||
Rational {
|
||||
numerator: r.numerator * factor,
|
||||
denominator: r.denominator * factor,
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Rational {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
todo!()
|
||||
let lcm = lcm(self.denominator, rhs.denominator);
|
||||
let num =
|
||||
self.numerator * (lcm / self.denominator) + rhs.numerator * (lcm / rhs.denominator);
|
||||
let gcd = gcd(num, lcm);
|
||||
|
||||
normalize(&Self {
|
||||
numerator: num / gcd,
|
||||
denominator: lcm / gcd,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +78,14 @@ impl Mul for Rational {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
todo!()
|
||||
let num = self.numerator * rhs.numerator;
|
||||
let den = self.denominator * rhs.denominator;
|
||||
let gcd = gcd(num, den) * (if den < 0 { -1 } else { 1 });
|
||||
|
||||
normalize(&Self {
|
||||
numerator: num / gcd,
|
||||
denominator: den / gcd,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +93,7 @@ impl Sub for Rational {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
todo!()
|
||||
self + (MINUS_ONE * rhs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +101,10 @@ impl Div for Rational {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
todo!()
|
||||
self.mul(Self {
|
||||
numerator: rhs.denominator,
|
||||
denominator: rhs.numerator,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +122,7 @@ pub trait Differentiable: Clone {
|
||||
impl Differentiable for Rational {
|
||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Constant_term_rule>
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
ZERO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,19 +146,31 @@ pub enum SingletonPolynomial {
|
||||
impl SingletonPolynomial {
|
||||
/// Creates a new const polynomial.
|
||||
pub fn new_c(r: Rational) -> Self {
|
||||
todo!()
|
||||
SingletonPolynomial::Const(r)
|
||||
}
|
||||
|
||||
/// Creates a new polynomial.
|
||||
pub fn new_poly(coeff: Rational, power: Rational) -> Self {
|
||||
todo!()
|
||||
SingletonPolynomial::Polynomial { coeff, power }
|
||||
}
|
||||
}
|
||||
|
||||
impl Differentiable for SingletonPolynomial {
|
||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Power_rule>
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Const(_) => Self::Const(ZERO),
|
||||
Self::Polynomial { coeff, power } => {
|
||||
if *power == ONE {
|
||||
Self::Const(*coeff)
|
||||
} else {
|
||||
Self::Polynomial {
|
||||
coeff: *coeff * *power,
|
||||
power: *power - ONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +181,7 @@ pub struct Exp;
|
||||
impl Exp {
|
||||
/// Creates a new exponential function.
|
||||
pub fn new() -> Self {
|
||||
todo!()
|
||||
Exp {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +194,7 @@ impl Default for Exp {
|
||||
impl Differentiable for Exp {
|
||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_exponential_and_logarithmic_functions>
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,19 +218,24 @@ pub enum Trignometric {
|
||||
impl Trignometric {
|
||||
/// Creates a new sine function.
|
||||
pub fn new_sine(coeff: Rational) -> Self {
|
||||
todo!()
|
||||
Trignometric::Sine { coeff }
|
||||
}
|
||||
|
||||
/// Creates a new cosine function.
|
||||
pub fn new_cosine(coeff: Rational) -> Self {
|
||||
todo!()
|
||||
Trignometric::Cosine { coeff }
|
||||
}
|
||||
}
|
||||
|
||||
impl Differentiable for Trignometric {
|
||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_trigonometric_functions>
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Sine { coeff } => Self::Cosine { coeff: *coeff },
|
||||
Self::Cosine { coeff } => Self::Sine {
|
||||
coeff: MINUS_ONE * *coeff,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +254,12 @@ pub enum BaseFuncs {
|
||||
|
||||
impl Differentiable for BaseFuncs {
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Const(_) => Self::Const(ZERO),
|
||||
Self::Poly(p) => Self::Poly(p.diff()),
|
||||
Self::Exp(e) => Self::Exp(e.diff()),
|
||||
Self::Trig(t) => Self::Trig(t.diff()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,14 +282,41 @@ pub enum ComplexFuncs<F> {
|
||||
|
||||
impl<F: Differentiable> Differentiable for Box<F> {
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
Box::new(self.deref().diff())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Differentiable> Differentiable for ComplexFuncs<F> {
|
||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Elementary_rules_of_differentiation>
|
||||
fn diff(&self) -> Self {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Func(f) => Self::Func(f.diff()),
|
||||
Self::Add(lhs, rhs) => Self::Add(lhs.diff(), rhs.diff()),
|
||||
Self::Sub(lhs, rhs) => Self::Sub(lhs.diff(), rhs.diff()),
|
||||
Self::Mul(lhs, rhs) => {
|
||||
let diff_lhs = lhs.diff();
|
||||
let diff_rhs = rhs.diff();
|
||||
Self::Add(
|
||||
Box::new(Self::Mul(diff_lhs, rhs.clone())),
|
||||
Box::new(Self::Mul(lhs.clone(), diff_rhs)),
|
||||
)
|
||||
}
|
||||
Self::Div(lhs, rhs) => {
|
||||
let diff_lhs = lhs.diff();
|
||||
let diff_rhs = rhs.diff();
|
||||
Self::Div(
|
||||
Box::new(Self::Sub(
|
||||
Box::new(Self::Mul(diff_lhs, rhs.clone())),
|
||||
Box::new(Self::Mul(lhs.clone(), diff_rhs)),
|
||||
)),
|
||||
Box::new(Self::Mul(rhs.clone(), rhs.clone())),
|
||||
)
|
||||
}
|
||||
Self::Comp(outer, inner) => Self::Mul(
|
||||
Box::new(Self::Comp(outer.diff(), inner.clone())),
|
||||
inner.diff(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,37 +328,55 @@ pub trait Evaluate {
|
||||
|
||||
impl Evaluate for Rational {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
(self.numerator as f64) / (self.denominator as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for SingletonPolynomial {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Const(r) => r.evaluate(x),
|
||||
Self::Polynomial { coeff, power } => x.powf(power.evaluate(x)) * coeff.evaluate(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for Exp {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
x.exp()
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for Trignometric {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Sine { coeff } => coeff.evaluate(x) * x.sin(),
|
||||
Self::Cosine { coeff } => coeff.evaluate(x) * x.cos(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for BaseFuncs {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Const(r) => r.evaluate(x),
|
||||
Self::Poly(p) => p.evaluate(x),
|
||||
Self::Exp(e) => e.evaluate(x),
|
||||
Self::Trig(t) => t.evaluate(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Evaluate> Evaluate for ComplexFuncs<F> {
|
||||
fn evaluate(&self, x: f64) -> f64 {
|
||||
todo!()
|
||||
match self {
|
||||
Self::Func(f) => f.evaluate(x),
|
||||
Self::Add(lhs, rhs) => lhs.evaluate(x) + rhs.evaluate(x),
|
||||
Self::Sub(lhs, rhs) => lhs.evaluate(x) - rhs.evaluate(x),
|
||||
Self::Mul(lhs, rhs) => lhs.evaluate(x) * rhs.evaluate(x),
|
||||
Self::Div(lhs, rhs) => lhs.evaluate(x) / rhs.evaluate(x),
|
||||
Self::Comp(outer, inner) => outer.evaluate(inner.evaluate(x)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user