forked from M-Labs/nalgebra
commit
12cd98ad64
@ -7,24 +7,24 @@ use na::DefaultAllocator;
|
|||||||
use crate::traits::{Alloc, Number, Dimension};
|
use crate::traits::{Alloc, Number, Dimension};
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two vectors.
|
/// Component-wise approximate equality between two vectors.
|
||||||
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<T, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two scalars.
|
/// Component-wise approximate equality between two scalars.
|
||||||
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(x, y, epsilon = epsilon)
|
abs_diff_eq!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two vectors.
|
/// Component-wise approximate non-equality between two vectors.
|
||||||
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<T, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two scalars.
|
/// Component-wise approximate non-equality between two scalars.
|
||||||
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_ne!(x, y, epsilon = epsilon)
|
abs_diff_ne!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ pub fn quat_to_mat3<T: RealNumber>(x: &Qua<T>) -> TMat3<T> {
|
|||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
/// Converts a quaternion to a rotation matrix in homogeneous coordinates.
|
||||||
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
||||||
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,7 @@ where
|
|||||||
assert_eq!(source_minor_indices.len(), values.len());
|
assert_eq!(source_minor_indices.len(), values.len());
|
||||||
let nnz = values.len();
|
let nnz = values.len();
|
||||||
|
|
||||||
// Count the number of occurences of each minor index
|
// Count the number of occurrences of each minor index
|
||||||
let mut minor_counts = vec![0; minor_dim];
|
let mut minor_counts = vec![0; minor_dim];
|
||||||
for minor_idx in source_minor_indices {
|
for minor_idx in source_minor_indices {
|
||||||
minor_counts[*minor_idx] += 1;
|
minor_counts[*minor_idx] += 1;
|
||||||
|
@ -98,7 +98,7 @@ where
|
|||||||
|
|
||||||
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
||||||
/// This will not return an error even if the patterns don't match.
|
/// This will not return an error even if the patterns don't match.
|
||||||
/// Should be used for situations where pattern creation immediately preceeds multiplication.
|
/// Should be used for situations where pattern creation immediately precedes multiplication.
|
||||||
///
|
///
|
||||||
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
||||||
pub fn spmm_csc_prealloc_unchecked<T>(
|
pub fn spmm_csc_prealloc_unchecked<T>(
|
||||||
|
@ -89,7 +89,7 @@ where
|
|||||||
|
|
||||||
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
||||||
/// This will not return an error even if the patterns don't match.
|
/// This will not return an error even if the patterns don't match.
|
||||||
/// Should be used for situations where pattern creation immediately preceeds multiplication.
|
/// Should be used for situations where pattern creation immediately precedes multiplication.
|
||||||
///
|
///
|
||||||
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
||||||
pub fn spmm_csr_prealloc_unchecked<T>(
|
pub fn spmm_csr_prealloc_unchecked<T>(
|
||||||
|
@ -20,9 +20,9 @@ use std::mem::MaybeUninit;
|
|||||||
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
||||||
/// same `Buffer` type.
|
/// same `Buffer` type.
|
||||||
pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
|
pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
|
||||||
/// The type of buffer this allocator can instanciate.
|
/// The type of buffer this allocator can instantiate.
|
||||||
type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
|
type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
|
||||||
/// The type of buffer with uninitialized components this allocator can instanciate.
|
/// The type of buffer with uninitialized components this allocator can instantiate.
|
||||||
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
|
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
|
||||||
|
|
||||||
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
||||||
|
@ -1077,7 +1077,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move the elements of `data` in such a way that the matrix with
|
// Move the elements of `data` in such a way that the matrix with
|
||||||
// the rows `[i, i + nremove[` deleted is represented in a contigous
|
// the rows `[i, i + nremove[` deleted is represented in a contiguous
|
||||||
// way in `data` after this method completes.
|
// way in `data` after this method completes.
|
||||||
// Every deleted element are manually dropped by this method.
|
// Every deleted element are manually dropped by this method.
|
||||||
unsafe fn compress_rows<T: Scalar>(
|
unsafe fn compress_rows<T: Scalar>(
|
||||||
|
@ -39,7 +39,7 @@ macro_rules! iterator {
|
|||||||
let ptr = storage.$ptr();
|
let ptr = storage.$ptr();
|
||||||
|
|
||||||
// If we have a size of 0, 'ptr' must be
|
// If we have a size of 0, 'ptr' must be
|
||||||
// dangling. Howver, 'inner_offset' might
|
// dangling. However, 'inner_offset' might
|
||||||
// not be zero if only one dimension is zero, so
|
// not be zero if only one dimension is zero, so
|
||||||
// we don't want to call 'offset'.
|
// we don't want to call 'offset'.
|
||||||
// This pointer will never actually get used
|
// This pointer will never actually get used
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
use rayon::iter::plumbing::Producer;
|
use rayon::iter::plumbing::Producer;
|
||||||
use rayon::{iter::plumbing::bridge, prelude::*};
|
use rayon::{iter::plumbing::bridge, prelude::*};
|
||||||
|
|
||||||
/// A rayon parallel iterator over the colums of a matrix. It is created
|
/// A rayon parallel iterator over the columns of a matrix. It is created
|
||||||
/// using the [`par_column_iter`] method of [`Matrix`].
|
/// using the [`par_column_iter`] method of [`Matrix`].
|
||||||
///
|
///
|
||||||
/// *Only available if compiled with the feature `rayon`.*
|
/// *Only available if compiled with the feature `rayon`.*
|
||||||
@ -89,7 +89,7 @@ pub struct ParColumnIterMut<
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
|
||||||
/// *only availabe if compiled with the feature `rayon`*
|
/// *only available if compiled with the feature `rayon`*
|
||||||
impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S>
|
impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S>
|
||||||
where
|
where
|
||||||
R: Dim,
|
R: Dim,
|
||||||
@ -161,7 +161,7 @@ where
|
|||||||
S: Sync,
|
S: Sync,
|
||||||
{
|
{
|
||||||
/// Iterate through the columns of the matrix in parallel using rayon.
|
/// Iterate through the columns of the matrix in parallel using rayon.
|
||||||
/// This iterates over *immutable* references ot the columns of the matrix,
|
/// This iterates over *immutable* references to the columns of the matrix,
|
||||||
/// if *mutable* access to the columns is required, use [`par_column_iter_mut`]
|
/// if *mutable* access to the columns is required, use [`par_column_iter_mut`]
|
||||||
/// instead.
|
/// instead.
|
||||||
///
|
///
|
||||||
|
@ -34,7 +34,7 @@ pub unsafe trait InitStatus<T>: Copy {
|
|||||||
/// A type implementing `InitStatus` indicating that the value is completely initialized.
|
/// A type implementing `InitStatus` indicating that the value is completely initialized.
|
||||||
pub struct Init;
|
pub struct Init;
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
/// A type implementing `InitStatus` indicating that the value is completely unitialized.
|
/// A type implementing `InitStatus` indicating that the value is completely uninitialized.
|
||||||
pub struct Uninit;
|
pub struct Uninit;
|
||||||
|
|
||||||
unsafe impl<T> InitStatus<T> for Init {
|
unsafe impl<T> InitStatus<T> for Init {
|
||||||
|
@ -148,7 +148,7 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Avoid double-free by forgetting `self` because its data buffer has
|
// Avoid double-free by forgetting `self` because its data buffer has
|
||||||
// been transfered to `new_data`.
|
// been transferred to `new_data`.
|
||||||
std::mem::forget(self);
|
std::mem::forget(self);
|
||||||
new_data
|
new_data
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ impl<T: SimdRealField> Isometry3<T> {
|
|||||||
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
|
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
|
||||||
/// and a spherical interpolation for the rotation part.
|
/// and a spherical interpolation for the rotation part.
|
||||||
///
|
///
|
||||||
/// Retuns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
|
/// Returns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
|
||||||
/// is not well-defined).
|
/// is not well-defined).
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
@ -118,7 +118,7 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
|
|||||||
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
|
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
|
||||||
/// and a spherical interpolation for the rotation part.
|
/// and a spherical interpolation for the rotation part.
|
||||||
///
|
///
|
||||||
/// Retuns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
|
/// Returns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
|
||||||
/// is not well-defined).
|
/// is not well-defined).
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
|
@ -1577,7 +1577,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||||
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
// TODO: would it be useful performance-wise not to call inverse explicitly (i-e. implement
|
||||||
// the inverse transformation explicitly here) ?
|
// the inverse transformation explicitly here) ?
|
||||||
self.inverse() * pt
|
self.inverse() * pt
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ macro_rules! category_mul_impl(
|
|||||||
)*}
|
)*}
|
||||||
);
|
);
|
||||||
|
|
||||||
// We require stability uppon multiplication.
|
// We require stability upon multiplication.
|
||||||
impl<T: TCategory> TCategoryMul<T> for T {
|
impl<T: TCategory> TCategoryMul<T> for T {
|
||||||
type Representative = T;
|
type Representative = T;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
||||||
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
// TODO: would it be useful performance-wise not to call inverse explicitly (i-e. implement
|
||||||
// the inverse transformation explicitly here) ?
|
// the inverse transformation explicitly here) ?
|
||||||
self.inverse() * pt
|
self.inverse() * pt
|
||||||
}
|
}
|
||||||
|
@ -724,7 +724,7 @@ where
|
|||||||
|
|
||||||
/// Sort the estimated components of the SVD by its singular values in descending order.
|
/// Sort the estimated components of the SVD by its singular values in descending order.
|
||||||
/// Such an ordering is often implicitly required when the decompositions are used for estimation or fitting purposes.
|
/// Such an ordering is often implicitly required when the decompositions are used for estimation or fitting purposes.
|
||||||
/// Using this function is only required if `new_unordered` or `try_new_unorderd` were used and the specific sorting is required afterward.
|
/// Using this function is only required if `new_unordered` or `try_new_unordered` were used and the specific sorting is required afterward.
|
||||||
pub fn sort_by_singular_values(&mut self) {
|
pub fn sort_by_singular_values(&mut self) {
|
||||||
const VALUE_PROCESSED: usize = usize::MAX;
|
const VALUE_PROCESSED: usize = usize::MAX;
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove dupliate entries on a sorted CsMatrix.
|
// Remove duplicate entries on a sorted CsMatrix.
|
||||||
pub(crate) fn dedup(&mut self)
|
pub(crate) fn dedup(&mut self)
|
||||||
where
|
where
|
||||||
T: Zero + ClosedAdd,
|
T: Zero + ClosedAdd,
|
||||||
|
@ -123,7 +123,7 @@ fn symmetric_eigen_singular_24x24() {
|
|||||||
//
|
//
|
||||||
// /*
|
// /*
|
||||||
// * NOTE: for the following tests, we use only upper-triangular matrices.
|
// * NOTE: for the following tests, we use only upper-triangular matrices.
|
||||||
// * Thes ensures the schur decomposition will work, and allows use to test the eigenvector
|
// * This ensures the schur decomposition will work, and allows use to test the eigenvector
|
||||||
// * computation.
|
// * computation.
|
||||||
// */
|
// */
|
||||||
// fn eigen(n: usize) -> bool {
|
// fn eigen(n: usize) -> bool {
|
||||||
@ -134,11 +134,11 @@ fn symmetric_eigen_singular_24x24() {
|
|||||||
// verify_eigenvectors(m, eig)
|
// verify_eigenvectors(m, eig)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// fn eigen_with_adjascent_duplicate_diagonals(n: usize) -> bool {
|
// fn eigen_with_adjacent_duplicate_diagonals(n: usize) -> bool {
|
||||||
// let n = cmp::max(1, cmp::min(n, 10));
|
// let n = cmp::max(1, cmp::min(n, 10));
|
||||||
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
|
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
|
||||||
//
|
//
|
||||||
// // Suplicate some adjascent diagonal elements.
|
// // Suplicate some adjacent diagonal elements.
|
||||||
// for i in 0 .. n / 2 {
|
// for i in 0 .. n / 2 {
|
||||||
// m[(i * 2 + 1, i * 2 + 1)] = m[(i * 2, i * 2)];
|
// m[(i * 2 + 1, i * 2 + 1)] = m[(i * 2, i * 2)];
|
||||||
// }
|
// }
|
||||||
@ -147,7 +147,7 @@ fn symmetric_eigen_singular_24x24() {
|
|||||||
// verify_eigenvectors(m, eig)
|
// verify_eigenvectors(m, eig)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// fn eigen_with_nonadjascent_duplicate_diagonals(n: usize) -> bool {
|
// fn eigen_with_nonadjacent_duplicate_diagonals(n: usize) -> bool {
|
||||||
// let n = cmp::max(3, cmp::min(n, 10));
|
// let n = cmp::max(3, cmp::min(n, 10));
|
||||||
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
|
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user