7 changed files with 424 additions and 275 deletions
-
88fractional/src/continuous.rs
-
147fractional/src/fractional.rs
-
10fractional/src/lib.rs
-
44fractional/src/main.rs
-
102fractional/src/transform.rs
-
238fractional/src/trigonometry.rs
-
50fractional/src/vector.rs
@ -0,0 +1,88 @@ |
|||
//
|
|||
// A «continued fraction» is a representation of a fraction as a vector
|
|||
// of integrals… Irrational fractions will result in infinite most of the
|
|||
// time repetitive vectors. They can be used to get a resonable approximation
|
|||
// for sqrt on fractionals.
|
|||
//
|
|||
// Georg Hopp <georg@steffers.org>
|
|||
//
|
|||
// Copyright © 2019 Georg Hopp
|
|||
//
|
|||
// This program is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// This program is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
//
|
|||
use crate::Fractional;
|
|||
|
|||
#[derive(Debug)]
|
|||
pub struct Continuous (Vec<i64>);
|
|||
|
|||
impl Continuous {
|
|||
// calculate a sqrt as continued fraction sequence. Taken from:
|
|||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#
|
|||
// Continued_fraction_expansion
|
|||
pub fn sqrt(x :i64, a0 :i64) -> Self {
|
|||
fn inner(mut v :Vec<i64>,
|
|||
x :i64,
|
|||
a0 :i64,
|
|||
mn :i64,
|
|||
dn :i64,
|
|||
an :i64) -> Vec<i64> {
|
|||
let mn_1 = dn * an - mn;
|
|||
let dn_1 = (x - mn_1 * mn_1) / dn;
|
|||
let an_1 = (a0 + mn_1) / dn_1;
|
|||
|
|||
v.push(an);
|
|||
|
|||
// The convergence criteria „an_1 == 2 * a0“ is not good for
|
|||
// very small x thus I decided to break the iteration at constant
|
|||
// time. Which is the 10 below.
|
|||
match v.len() {
|
|||
10 => v,
|
|||
_ => inner(v, x, a0, mn_1, dn_1, an_1),
|
|||
}
|
|||
}
|
|||
|
|||
Continuous(inner(Vec::new(), x, a0, 0, 1, a0))
|
|||
}
|
|||
}
|
|||
|
|||
impl From<&Fractional> for Continuous {
|
|||
// general continous fraction form of a fractional...
|
|||
fn from(x :&Fractional) -> Self {
|
|||
fn inner(mut v :Vec<i64>, f :Fractional) -> Vec<i64> {
|
|||
let Fractional(n, d) = f;
|
|||
let a = n / d;
|
|||
let Fractional(_n, _d) = f - a.into();
|
|||
|
|||
v.push(a);
|
|||
match _n {
|
|||
1 => { v.push(_d); v },
|
|||
_ => inner(v, Fractional(_d, _n)),
|
|||
}
|
|||
}
|
|||
|
|||
Continuous(inner(Vec::new(), *x))
|
|||
}
|
|||
}
|
|||
|
|||
impl Into<Fractional> for &Continuous {
|
|||
fn into(self) -> Fractional {
|
|||
let Continuous(c) = self;
|
|||
let Fractional(n, d) = c.iter().rev().fold( Fractional(0, 1)
|
|||
, |acc, x| {
|
|||
let Fractional(an, ad) = acc + (*x).into();
|
|||
Fractional(ad, an)
|
|||
});
|
|||
Fractional(d, n)
|
|||
}
|
|||
}
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue