Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various refactorings #1470

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
8 changes: 3 additions & 5 deletions nalgebra-glm/src/gtx/rotate_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ use crate::RealNumber;

/// Build the rotation matrix needed to align `normal` and `up`.
pub fn orientation<T: RealNumber>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
if let Some(r) = Rotation3::rotation_between(normal, up) {
r.to_homogeneous()
} else {
TMat4::identity()
}
Rotation3::rotation_between(normal, up)
.map(|x| r.homogenous())
.unwrap_or(|| TMat4::identity())
}

/// Rotate a two dimensional vector.
Expand Down
42 changes: 20 additions & 22 deletions nalgebra-sparse/src/ops/serial/csc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,31 +212,29 @@ fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
// and the matrix might actually *be* lower triangular, which would induce
// a severe penalty)
let diag_csc_index = l_col_k.row_indices().iter().position(|&i| i == k);
if let Some(diag_csc_index) = diag_csc_index {
let l_kk = l_col_k.values()[diag_csc_index].clone();

if l_kk != T::zero() {
// Update entry associated with diagonal
x_col_j[k] /= l_kk;
// Copy value after updating (so we don't run into the borrow checker)
let x_kj = x_col_j[k].clone();

let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];

// Note: The remaining entries are below the diagonal
for (&i, l_ik) in row_indices.iter().zip(l_values) {
let x_ij = &mut x_col_j[i];
*x_ij -= l_ik.clone() * x_kj.clone();
}
let Some(diag_csc_index) = diag_csc_index else {
return spsolve_encountered_zero_diagonal();
};
let l_kk = l_col_k.values()[diag_csc_index].clone();

x_col_j[k] = x_kj;
} else {
return spsolve_encountered_zero_diagonal();
}
} else {
if l_kk.is_zero() {
return spsolve_encountered_zero_diagonal();
}
// Update entry associated with diagonal
x_col_j[k] /= l_kk;
// Copy value after updating (so we don't run into the borrow checker)
let x_kj = x_col_j[k].clone();

let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];

// Note: The remaining entries are below the diagonal
for (&i, l_ik) in row_indices.iter().zip(l_values) {
let x_ij = &mut x_col_j[i];
*x_ij -= l_ik.clone() * x_kj.clone();
}

x_col_j[k] = x_kj;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/base/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,13 @@ where
/// iter::empty::<DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics!
/// ```
fn sum<I: Iterator<Item = OMatrix<T, Dyn, C>>>(mut iter: I) -> OMatrix<T, Dyn, C> {
if let Some(first) = iter.next() {
iter.fold(first, |acc, x| acc + x)
} else {
panic!("Cannot compute `sum` of empty iterator.")
let mut ret = iter
.next()
.expect("Cannot compute `sum` of empty iterator.");
while let Some(next) = iter.next() {
ret += next;
}
ret
Ralith marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/geometry/isometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use crate::base::storage::Owned;
use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar, Unit};
use crate::geometry::{AbstractRotation, Point, Translation};

use crate::{Isometry3, Quaternion, Vector3, Vector4};

#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;

Expand Down
43 changes: 16 additions & 27 deletions src/geometry/quaternion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<T: Scalar> PartialEq for Quaternion<T> {

impl<T: Scalar + Zero> Default for Quaternion<T> {
fn default() -> Self {
Quaternion {
Self {
coords: Vector4::zeros(),
}
}
Expand Down Expand Up @@ -468,17 +468,14 @@ where
where
T: RealField,
{
if let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) {
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) {
let angle = q.angle() / crate::convert(2.0f64);

(n, angle, Some(axis))
} else {
(n, T::zero(), None)
}
} else {
(T::zero(), T::zero(), None)
}
let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) else {
return (T::zero(), T::zero(), None);
};
let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) else {
return (n, T::zero(), None);
};
let angle = q.angle() / crate::convert(2.0f64);
(n, angle, Some(axis))
}

/// Compute the natural logarithm of a quaternion.
Expand Down Expand Up @@ -1319,11 +1316,9 @@ where
where
T: RealField,
{
if let Some(axis) = self.axis() {
axis.into_inner() * self.angle()
} else {
Vector3::zero()
}
self.axis()
.map(|axis| axis.into_inner() * self.angle())
.unwrap_or_else(|| <_>::zero())
}

/// The rotation axis and angle in (0, pi] of this unit quaternion.
Expand Down Expand Up @@ -1380,11 +1375,7 @@ where
where
T: RealField,
{
if let Some(v) = self.axis() {
Quaternion::from_imag(v.into_inner() * self.angle())
} else {
Quaternion::zero()
}
Quaternion::from_imag(self.scaled_axis())
}

/// Raise the quaternion to a given floating power.
Expand All @@ -1409,11 +1400,9 @@ where
where
T: RealField,
{
if let Some(v) = self.axis() {
Self::from_axis_angle(&v, self.angle() * n)
} else {
Self::identity()
}
self.axis()
.map(|v| Self::from_axis_angle(&v, self.angle() * n))
.unwrap_or_else(|| Self::identity())
}

/// Builds a rotation matrix from this unit quaternion.
Expand Down
61 changes: 30 additions & 31 deletions src/linalg/symmetric_eigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,38 +151,37 @@ where
for i in start..n {
let j = i + 1;

if let Some((rot, norm)) = GivensRotation::cancel_y(&vec) {
if i > start {
// Not the first iteration.
off_diag[i - 1] = norm;
}

let mii = diag[i].clone();
let mjj = diag[j].clone();
let mij = off_diag[i].clone();

let cc = rot.c() * rot.c();
let ss = rot.s() * rot.s();
let cs = rot.c() * rot.s();

let b = cs.clone() * crate::convert(2.0) * mij.clone();

diag[i] = (cc.clone() * mii.clone() + ss.clone() * mjj.clone()) - b.clone();
diag[j] = (ss.clone() * mii.clone() + cc.clone() * mjj.clone()) + b;
off_diag[i] = cs * (mii - mjj) + mij * (cc - ss);

if i != n - 1 {
vec.x = off_diag[i].clone();
vec.y = -rot.s() * off_diag[i + 1].clone();
off_diag[i + 1] *= rot.c();
}

if let Some(ref mut q) = q_mat {
let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s()));
rot.inverse().rotate_rows(&mut q.fixed_columns_mut::<2>(i));
}
} else {
let Some((rot, norm)) = GivensRotation::cancel_y(&vec) else {
break;
};
if i > start {
// Not the first iteration.
off_diag[i - 1] = norm;
}

let mii = diag[i].clone();
let mjj = diag[j].clone();
let mij = off_diag[i].clone();

let cc = rot.c() * rot.c();
let ss = rot.s() * rot.s();
let cs = rot.c() * rot.s();

let b = cs.clone() * crate::convert(2.0) * mij.clone();

diag[i] = (cc.clone() * mii.clone() + ss.clone() * mjj.clone()) - b.clone();
diag[j] = (ss.clone() * mii.clone() + cc.clone() * mjj.clone()) + b;
off_diag[i] = cs * (mii - mjj) + mij * (cc - ss);

if i != n - 1 {
vec.x = off_diag[i].clone();
vec.y = -rot.s() * off_diag[i + 1].clone();
off_diag[i + 1] *= rot.c();
}

if let Some(ref mut q) = q_mat {
let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s()));
rot.inverse().rotate_rows(&mut q.fixed_columns_mut::<2>(i));
}
}

Expand Down