Commit 3e231c2474f7d31835dcd115a13190cfc5ba771f
1 parent
1e6d133f
Alternative reduce with specifiable precision
Showing
2 changed files
with
40 additions
and
2 deletions
@@ -49,6 +49,22 @@ impl Continuous { | @@ -49,6 +49,22 @@ impl Continuous { | ||
49 | inner(&mut v, x, a0, 0, 1, a0); | 49 | inner(&mut v, x, a0, 0, 1, a0); |
50 | Continuous(v) | 50 | Continuous(v) |
51 | } | 51 | } |
52 | + | ||
53 | + pub fn into_prec(&self, prec :usize) -> Fractional { | ||
54 | + let Continuous(c) = self; | ||
55 | + let p = if prec <= c.len() { prec } else { c.len() }; | ||
56 | + | ||
57 | + let to_frac = |acc :Fractional, x :&i64| { | ||
58 | + let Fractional(an, ad) = acc.noreduce_add((*x).into()); | ||
59 | + Fractional(ad, an) | ||
60 | + }; | ||
61 | + | ||
62 | + let Fractional(n, d) = c[..p] | ||
63 | + . into_iter() | ||
64 | + . rev() | ||
65 | + . fold(Fractional(0, 1), to_frac); | ||
66 | + Fractional(d, n) | ||
67 | + } | ||
52 | } | 68 | } |
53 | 69 | ||
54 | impl From<&Fractional> for Continuous { | 70 | impl From<&Fractional> for Continuous { |
@@ -57,11 +73,12 @@ impl From<&Fractional> for Continuous { | @@ -57,11 +73,12 @@ impl From<&Fractional> for Continuous { | ||
57 | fn inner(mut v :Vec<i64>, f :Fractional) -> Vec<i64> { | 73 | fn inner(mut v :Vec<i64>, f :Fractional) -> Vec<i64> { |
58 | let Fractional(n, d) = f; | 74 | let Fractional(n, d) = f; |
59 | let a = n / d; | 75 | let a = n / d; |
60 | - let Fractional(_n, _d) = f - a.into(); | 76 | + let Fractional(_n, _d) = f.noreduce_sub(a.into()); |
61 | 77 | ||
62 | v.push(a); | 78 | v.push(a); |
63 | match _n { | 79 | match _n { |
64 | 1 => { v.push(_d); v }, | 80 | 1 => { v.push(_d); v }, |
81 | + 0 => v, | ||
65 | _ => inner(v, Fractional(_d, _n)), | 82 | _ => inner(v, Fractional(_d, _n)), |
66 | } | 83 | } |
67 | } | 84 | } |
@@ -28,6 +28,8 @@ use std::fmt::{Formatter, Display}; | @@ -28,6 +28,8 @@ use std::fmt::{Formatter, Display}; | ||
28 | use std::num::TryFromIntError; | 28 | use std::num::TryFromIntError; |
29 | use std::ops::{Add,Sub,Neg,Mul,Div}; | 29 | use std::ops::{Add,Sub,Neg,Mul,Div}; |
30 | 30 | ||
31 | +use crate::continuous::Continuous; | ||
32 | + | ||
31 | #[derive(Debug, Eq, Clone, Copy)] | 33 | #[derive(Debug, Eq, Clone, Copy)] |
32 | pub struct Fractional (pub i64, pub i64); | 34 | pub struct Fractional (pub i64, pub i64); |
33 | 35 | ||
@@ -67,9 +69,28 @@ impl Fractional { | @@ -67,9 +69,28 @@ impl Fractional { | ||
67 | Self(1, _n / _d) | 69 | Self(1, _n / _d) |
68 | } | 70 | } |
69 | } else { | 71 | } else { |
70 | - Self(n / hcf(n, d), d / hcf(n, d)) | 72 | + //Self(n / hcf(n, d), d / hcf(n, d)) |
73 | + let regular_reduced = self; | ||
74 | + let cont :Continuous = (®ular_reduced).into(); | ||
75 | + cont.into_prec(5) | ||
71 | } | 76 | } |
72 | } | 77 | } |
78 | + | ||
79 | + pub fn noreduce_add(self, other: Self) -> Self { | ||
80 | + let Fractional(n1, d1) = self; | ||
81 | + let Fractional(n2, d2) = other; | ||
82 | + let n = n1 * (self.gcd(other) / d1) + n2 * (self.gcd(other) / d2); | ||
83 | + Self(n, self.gcd(other)) | ||
84 | + } | ||
85 | + | ||
86 | + pub fn noreduce_sub(self, other: Self) -> Self { | ||
87 | + self.noreduce_add(other.noreduce_neg()) | ||
88 | + } | ||
89 | + | ||
90 | + pub fn noreduce_neg(self) -> Self { | ||
91 | + let Fractional(n, d) = self; | ||
92 | + Self(-n, d) | ||
93 | + } | ||
73 | } | 94 | } |
74 | 95 | ||
75 | impl From<i64> for Fractional { | 96 | impl From<i64> for Fractional { |
Please
register
or
login
to post a comment