2017-08-03 01:37:44 +08:00
|
|
|
//! Construction of givens rotations.
|
|
|
|
|
|
|
|
use alga::general::Real;
|
|
|
|
use num_complex::Complex;
|
|
|
|
|
2018-05-19 23:15:15 +08:00
|
|
|
use base::dimension::U2;
|
|
|
|
use base::storage::Storage;
|
|
|
|
use base::Vector;
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
|
|
use geometry::UnitComplex;
|
|
|
|
|
|
|
|
/// Computes the rotation `R` required such that the `y` component of `R * v` is zero.
|
|
|
|
///
|
|
|
|
/// Returns `None` if no rotation is needed (i.e. if `v.y == 0`). Otherwise, this returns the norm
|
|
|
|
/// of `v` and the rotation `r` such that `R * v = [ |v|, 0.0 ]^t` where `|v|` is the norm of `v`.
|
|
|
|
pub fn cancel_y<N: Real, S: Storage<N, U2>>(v: &Vector<N, U2, S>) -> Option<(UnitComplex<N>, N)> {
|
|
|
|
if !v[1].is_zero() {
|
|
|
|
let c = Complex::new(v[0], -v[1]);
|
|
|
|
Some(UnitComplex::from_complex_and_get(c))
|
2018-02-02 19:26:35 +08:00
|
|
|
} else {
|
2017-08-03 01:37:44 +08:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Computes the rotation `R` required such that the `x` component of `R * v` is zero.
|
|
|
|
///
|
|
|
|
/// Returns `None` if no rotation is needed (i.e. if `v.x == 0`). Otherwise, this returns the norm
|
|
|
|
/// of `v` and the rotation `r` such that `R * v = [ 0.0, |v| ]^t` where `|v|` is the norm of `v`.
|
|
|
|
pub fn cancel_x<N: Real, S: Storage<N, U2>>(v: &Vector<N, U2, S>) -> Option<(UnitComplex<N>, N)> {
|
|
|
|
if !v[0].is_zero() {
|
|
|
|
let c = Complex::new(v[1], v[0]);
|
|
|
|
Some(UnitComplex::from_complex_and_get(c))
|
2018-02-02 19:26:35 +08:00
|
|
|
} else {
|
2017-08-03 01:37:44 +08:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|