feat(*): Approximations + fix print
This commit is contained in:
parent
0628e54d6e
commit
36362458c8
|
@ -10,16 +10,16 @@ pub mod maths;
|
||||||
|
|
||||||
pub fn format(v: &Vec<GaussianRational>) -> String {
|
pub fn format(v: &Vec<GaussianRational>) -> String {
|
||||||
let mut format;
|
let mut format;
|
||||||
format = v[0].format();
|
format = v[0].format(false);
|
||||||
if v.len() > 1 {
|
if v.len() > 1 {
|
||||||
if format == "" {
|
if format == "" {
|
||||||
format = format!("{}x", v[1].format());
|
format = format!("{}x", v[1].format(true));
|
||||||
} else {
|
} else {
|
||||||
format = format!("{format} + {}x", v[1].format());
|
format = format!("{format} + {}x", v[1].format(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i in 2..v.len() {
|
for i in 2..v.len() {
|
||||||
let tmp = v[i].format();
|
let tmp = v[i].format(true);
|
||||||
if tmp != "" {
|
if tmp != "" {
|
||||||
if format == ""{
|
if format == ""{
|
||||||
format = format!("{tmp}x^{i}");
|
format = format!("{tmp}x^{i}");
|
||||||
|
|
|
@ -20,6 +20,7 @@ fn main() {
|
||||||
println!("{} = 0", computorv1::format(&evaluated));
|
println!("{} = 0", computorv1::format(&evaluated));
|
||||||
computorv1::maths::solver::solve(evaluated);
|
computorv1::maths::solver::solve(evaluated);
|
||||||
} else {
|
} else {
|
||||||
|
println!("{} is equal to:", args[1]);
|
||||||
println!("{}", computorv1::format(&evaluated));
|
println!("{}", computorv1::format(&evaluated));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
52
src/maths.rs
52
src/maths.rs
|
@ -16,6 +16,34 @@ fn one() -> GaussianRational {
|
||||||
GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1))
|
GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn approx_sqrt_f64(n: f64) -> f64 {
|
||||||
|
let n = n as f64;
|
||||||
|
let mut result = n + 1.;
|
||||||
|
let mut factor = 1.;
|
||||||
|
while factor > f64::EPSILON {
|
||||||
|
while result * result > n {
|
||||||
|
result /= 1. + factor;
|
||||||
|
}
|
||||||
|
result *= 1. + factor;
|
||||||
|
factor /= 2.;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn approx_sqrt(n: i128) -> f64 {
|
||||||
|
let n = n as f64;
|
||||||
|
let mut result = n;
|
||||||
|
let mut factor = 1.;
|
||||||
|
while factor > f64::EPSILON {
|
||||||
|
while result * result > n {
|
||||||
|
result /= 1. + factor;
|
||||||
|
}
|
||||||
|
result *= 1. + factor;
|
||||||
|
factor /= 2.;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prime_factors(mut n: i128) -> Vec<i128> {
|
fn get_prime_factors(mut n: i128) -> Vec<i128> {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return [0].to_vec();
|
return [0].to_vec();
|
||||||
|
@ -106,6 +134,9 @@ impl Rational {
|
||||||
copy.denominator *= 5;
|
copy.denominator *= 5;
|
||||||
five_count += 1;
|
five_count += 1;
|
||||||
}
|
}
|
||||||
|
if copy.numerator < 0 {
|
||||||
|
copy.numerator *= -1;
|
||||||
|
}
|
||||||
format!("{}.{}", copy.numerator / copy.denominator, copy.numerator % copy.denominator)
|
format!("{}.{}", copy.numerator / copy.denominator, copy.numerator % copy.denominator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,12 +280,13 @@ impl GaussianRational {
|
||||||
GaussianRational::new(self.real, -1 * self.imaginary)
|
GaussianRational::new(self.real, -1 * self.imaginary)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(&self) -> String {
|
pub fn format(&self, parenthesis: bool) -> String {
|
||||||
match (self.real().is_zero(), self.imaginary.is_zero()) {
|
match (self.real().is_zero(), self.imaginary.is_zero(), parenthesis) {
|
||||||
(true, true) => format!(""),
|
(true, true, _) => format!(""),
|
||||||
(true, false) => format!("{}i", self.imaginary.format()),
|
(true, false, _) => format!("{}i", self.imaginary.format()),
|
||||||
(false, true) => format!("{}", self.real.format()),
|
(false, true, _) => format!("{}", self.real.format()),
|
||||||
(false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format())
|
(false, false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format()),
|
||||||
|
(false, false, true) => format!("({} + {}i)", self.real.format(), self.imaginary.format())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,10 +521,10 @@ mod tests {
|
||||||
let b = GaussianRational::new(zero, rational);
|
let b = GaussianRational::new(zero, rational);
|
||||||
let c = GaussianRational::new(whole, zero);
|
let c = GaussianRational::new(whole, zero);
|
||||||
let d = GaussianRational::new(whole, rational);
|
let d = GaussianRational::new(whole, rational);
|
||||||
assert_eq!(a.format(), String::from(""));
|
assert_eq!(a.format(false), String::from(""));
|
||||||
assert_eq!(b.format(), String::from("5/3i"));
|
assert_eq!(b.format(false), String::from("5/3i"));
|
||||||
assert_eq!(c.format(), String::from("5"));
|
assert_eq!(c.format(false), String::from("5"));
|
||||||
assert_eq!(d.format(), String::from("5 + 5/3i"));
|
assert_eq!(d.format(false), String::from("5 + 5/3i"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn degree_one(equation: Vec<GaussianRational>) {
|
||||||
println!("Polynomial degree: 1");
|
println!("Polynomial degree: 1");
|
||||||
let x = minus_one() * equation[0] / equation[1];
|
let x = minus_one() * equation[0] / equation[1];
|
||||||
println!("The solution is");
|
println!("The solution is");
|
||||||
let mut format = x.format();
|
let mut format = x.format(false);
|
||||||
if format == "" {
|
if format == "" {
|
||||||
format = String::from("0");
|
format = String::from("0");
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ fn simplify_sqrt(n: i128) -> (i128, i128) {
|
||||||
(natural, irrational)
|
(natural, irrational)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Eric Naslund for the math https://math.stackexchange.com/questions/44406/how-do-i-get-the-square-root-of-a-complex-number
|
||||||
fn comp_sqrt(c: GaussianRational) -> MyCompSqrt {
|
fn comp_sqrt(c: GaussianRational) -> MyCompSqrt {
|
||||||
let real = c.real();
|
let real = c.real();
|
||||||
let imag = c.imaginary();
|
let imag = c.imaginary();
|
||||||
|
@ -107,7 +108,7 @@ fn comp_sqrt(c: GaussianRational) -> MyCompSqrt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_strings(left_part: Rational, sqrt_delta: MySqrt) -> (String, String, String, String, String, String) {
|
fn get_strings(left_part: Rational, sqrt_delta: &MySqrt) -> (String, String, String, String, String, String) {
|
||||||
let mut a = left_part.numerator;
|
let mut a = left_part.numerator;
|
||||||
let mut b = sqrt_delta.numerator_natural;
|
let mut b = sqrt_delta.numerator_natural;
|
||||||
if b < 0 {
|
if b < 0 {
|
||||||
|
@ -191,12 +192,12 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
||||||
|
|
||||||
let b = b / GaussianRational::new(Rational::new(-2, 1), Rational::new(0, 1));
|
let b = b / GaussianRational::new(Rational::new(-2, 1), Rational::new(0, 1));
|
||||||
|
|
||||||
let mut sign = '+';
|
let mut sign = '±';
|
||||||
if sqrt_delta.sign < 0 {
|
if sqrt_delta.sign < 0 {
|
||||||
sign = '-';
|
sign = '∓';
|
||||||
}
|
}
|
||||||
|
|
||||||
let (s1, s2, s3, s4, s5, s6) = get_strings(sqrt_delta.rational, sqrt_delta.sqrt);
|
let (s1, s2, s3, s4, s5, s6) = get_strings(sqrt_delta.rational, &sqrt_delta.sqrt);
|
||||||
let mut string1 = String::from("");
|
let mut string1 = String::from("");
|
||||||
let mut string2 = String::from("");
|
let mut string2 = String::from("");
|
||||||
let mut string3 = String::from("");
|
let mut string3 = String::from("");
|
||||||
|
@ -218,7 +219,7 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
||||||
}
|
}
|
||||||
|
|
||||||
string1 = format!("{string1} /{s1}\\ ");
|
string1 = format!("{string1} /{s1}\\ ");
|
||||||
string2 = format!("{string2} + sqrt | {s2} | ");
|
string2 = format!("{string2} ± sqrt | {s2} | ");
|
||||||
string3 = format!("{string3} \\{s3}/ ");
|
string3 = format!("{string3} \\{s3}/ ");
|
||||||
|
|
||||||
if b.imaginary.numerator != 0 {
|
if b.imaginary.numerator != 0 {
|
||||||
|
@ -241,9 +242,19 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
||||||
string2 = format!("{string2}{sign} sqrt | {s5} | i");
|
string2 = format!("{string2}{sign} sqrt | {s5} | i");
|
||||||
string3 = format!("{string3} \\{s6}/ ");
|
string3 = format!("{string3} \\{s6}/ ");
|
||||||
|
|
||||||
|
println!("The two solutions are:");
|
||||||
println!("{string1}");
|
println!("{string1}");
|
||||||
println!("{string2}");
|
println!("{string2}");
|
||||||
println!("{string3}");
|
println!("{string3}");
|
||||||
|
println!("Approximations:");
|
||||||
|
let sqrt = sqrt_delta.sqrt.numerator_natural as f64 * approx_sqrt(sqrt_delta.sqrt.numerator_irrational);
|
||||||
|
let left = b.real.numerator as f64 / b.real.denominator as f64;
|
||||||
|
let left_sqrt = approx_sqrt_f64((sqrt_delta.rational.numerator as f64 + sqrt) / sqrt_delta.rational.denominator as f64);
|
||||||
|
|
||||||
|
let right = b.imaginary.numerator as f64 / b.imaginary.denominator as f64;
|
||||||
|
let right_sqrt = sqrt_delta.sign as f64 * approx_sqrt_f64((-sqrt_delta.rational.numerator as f64 + sqrt) / sqrt_delta.rational.denominator as f64);
|
||||||
|
println!("{}", format!("{} + {}i", left + left_sqrt, right + right_sqrt).split("+ -").collect::<Vec<_>>().join("- "));
|
||||||
|
println!("{}", format!("{} + {}i", left - left_sqrt, right - right_sqrt).split("+ -").collect::<Vec<_>>().join("- "));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sqrt(n: Rational, a: Rational) -> MySqrt {
|
fn sqrt(n: Rational, a: Rational) -> MySqrt {
|
||||||
|
@ -320,6 +331,20 @@ fn print_degree_two_real(left_part: Rational, sqrt_delta: MySqrt, imaginary: boo
|
||||||
println!("{}{string}", " ".repeat(4 + (len - string.chars().count()) / 2));
|
println!("{}{string}", " ".repeat(4 + (len - string.chars().count()) / 2));
|
||||||
println!("x = {}", "-".repeat(len));
|
println!("x = {}", "-".repeat(len));
|
||||||
println!("{}{d}", " ".repeat(4 + (len - d.to_string().len()) / 2));
|
println!("{}{d}", " ".repeat(4 + (len - d.to_string().len()) / 2));
|
||||||
|
let mut right = (sqrt_delta.numerator_natural as f64 * approx_sqrt(sqrt_delta.numerator_irrational)) / left_part.denominator as f64;
|
||||||
|
let left = left_part.numerator as f64 / left_part.denominator as f64;
|
||||||
|
if right < 0. {
|
||||||
|
right *= -1.;
|
||||||
|
}
|
||||||
|
println!("Approximations:");
|
||||||
|
if imaginary == true {
|
||||||
|
println!("{} - {}i", left, right);
|
||||||
|
println!("{} + {}i", left, right);
|
||||||
|
} else {
|
||||||
|
println!("{}", left - right);
|
||||||
|
println!("{}", left + right);
|
||||||
|
|
||||||
|
}
|
||||||
} else if string.len() > 0 {
|
} else if string.len() > 0 {
|
||||||
println!("x = {string}");
|
println!("x = {string}");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue