Function roots::find_roots_linear
source · Expand description
Solves a linear equation a1*x + a0 = 0.
Examples
use roots::Roots;
use roots::find_roots_linear;
// Returns Roots::No([]) as '0*x + 1 = 0' has no roots;
let no_root = find_roots_linear(0f32, 1f32);
assert_eq!(no_root, Roots::No([]));
// Returns Roots::Two([0f64]) as '1*x + 0 = 0' has the root 0
let root = find_roots_linear(1f64, 0f64);
assert_eq!(root, Roots::One([0f64]));
// Returns Roots::One([0f32]) as 0 is one of roots of '0*x + 0 = 0'
let zero_root = find_roots_linear(0f32, 0f32);
assert_eq!(zero_root, Roots::One([0f32]));
Examples found in repository?
src/numerical/polynom.rs (line 447)
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
pub fn find_roots_sturm<F>(a: &[F], convergency: &mut dyn Convergency<F>) -> Vec<Result<F, SearchError>>
where
F: FloatType,
{
match a.len() {
0 => Vec::new(),
1 => find_roots_linear(F::one(), a[0]).as_ref().iter().map(|s| Ok(*s)).collect(),
2 => find_roots_quadratic(F::one(), a[0], a[1])
.as_ref()
.iter()
.map(|s| Ok(*s))
.collect(),
3 => find_roots_cubic(F::one(), a[0], a[1], a[2])
.as_ref()
.iter()
.map(|s| Ok(*s))
.collect(),
_ => {
let mut result = Vec::new();
let derivative_polynom = a.derivative_polynom();
match find_root_intervals(a, &derivative_polynom, convergency) {
Ok(root_intervals) => {
for root_interval in &root_intervals {
if let Ok(mut narrowed) = narrow_down(&root_interval, a, &derivative_polynom, convergency) {
result.push(a.find_root(&mut narrowed, convergency));
}
}
}
Err(error) => {
result.push(Err(error));
}
}
result
}
}
}
More examples
src/analytical/quadratic.rs (line 51)
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
pub fn find_roots_quadratic<F: FloatType>(a2: F, a1: F, a0: F) -> Roots<F> {
// Handle non-standard cases
if a2 == F::zero() {
// a2 = 0; a1*x+a0=0; solve linear equation
super::linear::find_roots_linear(a1, a0)
} else {
let _2 = F::from(2i16);
let _4 = F::from(4i16);
// Rust lacks a simple way to convert an integer constant to generic type F
let discriminant = a1 * a1 - _4 * a2 * a0;
if discriminant < F::zero() {
Roots::No([])
} else {
let a2x2 = _2 * a2;
if discriminant == F::zero() {
Roots::One([-a1 / a2x2])
} else {
// To improve precision, do not use the smallest divisor.
// See https://people.csail.mit.edu/bkph/articles/Quadratics.pdf
let sq = discriminant.sqrt();
let (same_sign, diff_sign) = if a1 < F::zero() {
(-a1 + sq, -a1 - sq)
} else {
(-a1 - sq, -a1 + sq)
};
let (x1, x2) = if same_sign.abs() > a2x2.abs() {
let a0x2 = _2 * a0;
if diff_sign.abs() > a2x2.abs() {
// 2*a2 is the smallest divisor, do not use it
(a0x2 / same_sign, a0x2 / diff_sign)
} else {
// diff_sign is the smallest divisor, do not use it
(a0x2 / same_sign, same_sign / a2x2)
}
} else {
// 2*a2 is the greatest divisor, use it
(diff_sign / a2x2, same_sign / a2x2)
};
// Order roots
if x1 < x2 {
Roots::Two([x1, x2])
} else {
Roots::Two([x2, x1])
}
}
}
}
}