pub trait FloatType: Sized + Copy + Debug + From<i16> + PartialEq + PartialOrd + Neg<Output = Self> + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Div<Output = Self> {
Show 13 methods
fn zero() -> Self;
fn one() -> Self;
fn one_third() -> Self;
fn pi() -> Self;
fn two_third_pi() -> Self;
fn sqrt(self) -> Self;
fn atan(self) -> Self;
fn acos(self) -> Self;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn abs(self) -> Self;
fn powf(self, n: Self) -> Self;
fn cbrt(self) -> Self { ... }
}
Expand description
Generic type that lists functions and constants needed in calculations. Default implementations for f32 and f64 are provided.
Required Methods§
fn zero() -> Self
fn one() -> Self
fn one_third() -> Self
fn pi() -> Self
fn two_third_pi() -> Self
fn sqrt(self) -> Self
fn atan(self) -> Self
fn acos(self) -> Self
fn sin(self) -> Self
fn cos(self) -> Self
fn abs(self) -> Self
fn powf(self, n: Self) -> Self
Provided Methods§
sourcefn cbrt(self) -> Self
fn cbrt(self) -> Self
The cubic root function is pow(x, 1/3) accepting negative arguments
Examples found in repository?
src/analytical/cubic_normalized.rs (line 69)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
pub fn find_roots_cubic_normalized<F: FloatType>(a2: F, a1: F, a0: F) -> Roots<F> {
let _2 = F::from(2i16);
let _3 = F::from(3i16);
let _4 = F::from(4i16);
let _9 = F::from(9i16);
let _18 = F::from(18i16);
let _27 = F::from(27i16);
let _54 = F::from(54i16);
let q = (_3 * a1 - a2 * a2) / _9;
let r = (_9 * a2 * a1 - _27 * a0 - _2 * a2 * a2 * a2) / _54;
let q3 = q * q * q;
let d = q3 + r * r;
let a2_div_3 = a2 / _3;
if d < F::zero() {
let phi_3 = (r / (-q3).sqrt()).acos() / _3;
let sqrt_q_2 = _2 * (-q).sqrt();
Roots::One([sqrt_q_2 * phi_3.cos() - a2_div_3])
.add_new_root(sqrt_q_2 * (phi_3 - F::two_third_pi()).cos() - a2_div_3)
.add_new_root(sqrt_q_2 * (phi_3 + F::two_third_pi()).cos() - a2_div_3)
} else {
let sqrt_d = d.sqrt();
let s = (r + sqrt_d).cbrt();
let t = (r - sqrt_d).cbrt();
if s == t {
if s + t == F::zero() {
Roots::One([s + t - a2_div_3])
} else {
Roots::One([s + t - a2_div_3]).add_new_root(-(s + t) / _2 - a2_div_3)
}
} else {
Roots::One([s + t - a2_div_3])
}
}
}
More examples
src/analytical/cubic_depressed.rs (line 53)
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
pub fn find_roots_cubic_depressed<F: FloatType>(a1: F, a0: F) -> Roots<F> {
let _2 = F::from(2i16);
let _3 = F::from(3i16);
let _4 = F::from(4i16);
let _9 = F::from(9i16);
let _18 = F::from(18i16);
let _27 = F::from(27i16);
let _54 = F::from(54i16);
if a1 == F::zero() {
Roots::One([-a0.cbrt()])
} else if a0 == F::zero() {
super::quadratic::find_roots_quadratic(F::one(), F::zero(), a1).add_new_root(F::zero())
} else {
let d = a0 * a0 / _4 + a1 * a1 * a1 / _27;
if d < F::zero() {
// n*a0^2 + m*a1^3 < 0 => a1 < 0
let a = (-_4 * a1 / _3).sqrt();
let phi = (-_4 * a0 / (a * a * a)).acos() / _3;
Roots::One([a * phi.cos()])
.add_new_root(a * (phi + F::two_third_pi()).cos())
.add_new_root(a * (phi - F::two_third_pi()).cos())
} else {
let sqrt_d = d.sqrt();
let a0_div_2 = a0 / _2;
let x1 = (sqrt_d - a0_div_2).cbrt() - (sqrt_d + a0_div_2).cbrt();
if d == F::zero() {
// one real root and one double root
Roots::One([x1]).add_new_root(a0_div_2)
} else {
// one real root
Roots::One([x1])
}
}
}
}
src/analytical/cubic.rs (line 87)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
pub fn find_roots_cubic<F: FloatType>(a3: F, a2: F, a1: F, a0: F) -> Roots<F> {
// Handle non-standard cases
if a3 == F::zero() {
// a3 = 0; a2*x^2+a1*x+a0=0; solve quadratic equation
super::quadratic::find_roots_quadratic(a2, a1, a0)
} else if a2 == F::zero() {
// a2 = 0; a3*x^3+a1*x+a0=0; solve depressed cubic equation
super::cubic_depressed::find_roots_cubic_depressed(a1 / a3, a0 / a3)
} else if a3 == F::one() {
// solve normalized cubic expression
super::cubic_normalized::find_roots_cubic_normalized(a2, a1, a0)
} else {
let _2 = F::from(2i16);
let _3 = F::from(3i16);
let _4 = F::from(4i16);
let _9 = F::from(9i16);
let _18 = F::from(18i16);
let _27 = F::from(27i16);
// standard case
let d = _18 * a3 * a2 * a1 * a0 - _4 * a2 * a2 * a2 * a0 + a2 * a2 * a1 * a1
- _4 * a3 * a1 * a1 * a1
- _27 * a3 * a3 * a0 * a0;
let d0 = a2 * a2 - _3 * a3 * a1;
let d1 = _2 * a2 * a2 * a2 - _9 * a3 * a2 * a1 + _27 * a3 * a3 * a0;
if d < F::zero() {
// one real root
let sqrt = (-_27 * a3 * a3 * d).sqrt();
let c = F::cbrt(if d1 < F::zero() { d1 - sqrt } else { d1 + sqrt } / _2);
let x = -(a2 + c + d0 / c) / (_3 * a3);
Roots::One([x])
} else if d == F::zero() {
// multiple roots
if d0 == F::zero() {
// triple root
Roots::One([-a2 / (a3 * _3)])
} else {
// single root and double root
Roots::One([(_9 * a3 * a0 - a2 * a1) / (d0 * _2)])
.add_new_root((_4 * a3 * a2 * a1 - _9 * a3 * a3 * a0 - a2 * a2 * a2) / (a3 * d0))
}
} else {
// three real roots
let c3_img = F::sqrt(_27 * a3 * a3 * d) / _2;
let c3_real = d1 / _2;
let c3_module = F::sqrt(c3_img * c3_img + c3_real * c3_real);
let c3_phase = _2 * F::atan(c3_img / (c3_real + c3_module));
let c_module = F::cbrt(c3_module);
let c_phase = c3_phase / _3;
let c_real = c_module * F::cos(c_phase);
let c_img = c_module * F::sin(c_phase);
let x0_real = -(a2 + c_real + (d0 * c_real) / (c_module * c_module)) / (_3 * a3);
let e_real = -F::one() / _2;
let e_img = F::sqrt(_3) / _2;
let c1_real = c_real * e_real - c_img * e_img;
let c1_img = c_real * e_img + c_img * e_real;
let x1_real = -(a2 + c1_real + (d0 * c1_real) / (c1_real * c1_real + c1_img * c1_img)) / (_3 * a3);
let c2_real = c1_real * e_real - c1_img * e_img;
let c2_img = c1_real * e_img + c1_img * e_real;
let x2_real = -(a2 + c2_real + (d0 * c2_real) / (c2_real * c2_real + c2_img * c2_img)) / (_3 * a3);
Roots::One([x0_real]).add_new_root(x1_real).add_new_root(x2_real)
}
}
}