forked from M-Labs/nalgebra
Checkpoint #9
This commit is contained in:
parent
c3f869e017
commit
87fe2b30df
@ -311,7 +311,7 @@ impl From<SparsityPatternFormatError> for SparseFormatError {
|
||||
}
|
||||
|
||||
impl fmt::Display for SparsityPatternFormatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
SparsityPatternFormatError::InvalidOffsetArrayLength => {
|
||||
write!(f, "Length of offset array is not equal to (major_dim + 1).")
|
||||
|
@ -798,7 +798,7 @@ where
|
||||
impl<T, R1: Dim, C1: Dim, S: StorageMut<MaybeUninit<T>, R1, C1>> Matrix<MaybeUninit<T>, R1, C1, S>
|
||||
where
|
||||
T: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
||||
DefaultAllocator: Allocator<T, R1, C1>,
|
||||
// DefaultAllocator: Allocator<T, R1, C1>,
|
||||
{
|
||||
/// Computes `alpha * a * b`, where `a` and `b` are matrices, and `alpha` is
|
||||
/// a scalar.
|
||||
|
@ -146,7 +146,7 @@ macro_rules! component_binop_impl(
|
||||
);
|
||||
|
||||
/// # Componentwise operations
|
||||
impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
|
||||
impl<T:Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
|
||||
component_binop_impl!(
|
||||
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
|
||||
r"
|
||||
|
@ -683,7 +683,7 @@ where
|
||||
{
|
||||
/// Creates a new uninitialized matrix or vector.
|
||||
#[inline]
|
||||
pub fn new_uninitialized(nrows: usize) -> OMatrix<MaybeUninit<T>, Dynamic, C> {
|
||||
pub fn new_uninitialized(nrows: usize) -> OMatrix<MaybeUninit<T>, Dynamic, C> {
|
||||
Self::new_uninitialized_generic(Dynamic::new(nrows), C::name())
|
||||
}
|
||||
}
|
||||
@ -705,7 +705,10 @@ where
|
||||
{
|
||||
/// Creates a new uninitialized matrix or vector.
|
||||
#[inline]
|
||||
pub fn new_uninitialized(nrows: usize, ncols: usize) -> OMatrix<MaybeUninit<T>, Dynamic, Dynamic> {
|
||||
pub fn new_uninitialized(
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
) -> OMatrix<MaybeUninit<T>, Dynamic, Dynamic> {
|
||||
Self::new_uninitialized_generic(Dynamic::new(nrows), Dynamic::new(ncols))
|
||||
}
|
||||
}
|
||||
@ -899,13 +902,11 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<T, R, C> Arbitrary for OMatrix<T, R, C>
|
||||
impl<T, R: Dim, C: Dim> Arbitrary for OMatrix<T, R, C>
|
||||
where
|
||||
R: Dim,
|
||||
C: Dim,
|
||||
T: Arbitrary + Send,
|
||||
DefaultAllocator: Allocator<T, R, C>,
|
||||
Owned<T, R, C>: Clone + Send,
|
||||
Owned<T, R, C>: Clone+Send,
|
||||
{
|
||||
#[inline]
|
||||
fn arbitrary(g: &mut Gen) -> Self {
|
||||
|
@ -82,7 +82,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> IntoIterator for &'a Matrix<T, R, C, S> {
|
||||
impl<'a, T, R: Dim, C: Dim, S: Storage<T, R, C>> IntoIterator for &'a Matrix<T, R, C, S> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = MatrixIter<'a, T, R, C, S>;
|
||||
|
||||
@ -92,9 +92,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> IntoIterator for &'a Ma
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> IntoIterator
|
||||
for &'a mut Matrix<T, R, C, S>
|
||||
{
|
||||
impl<'a, T, R: Dim, C: Dim, S: StorageMut<T, R, C>> IntoIterator for &'a mut Matrix<T, R, C, S> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = MatrixIterMut<'a, T, R, C, S>;
|
||||
|
||||
@ -111,11 +109,13 @@ impl<T, const D: usize> From<[T; D]> for SVector<T, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, const D: usize> From<SVector<T, D>> for [T; D] {
|
||||
impl<T, const D: usize> From<SVector<T, D>> for [T; D] {
|
||||
#[inline]
|
||||
fn from(vec: SVector<T, D>) -> Self {
|
||||
// TODO: unfortunately, we must clone because we can move out of an array.
|
||||
vec.data.0[0].clone()
|
||||
|
||||
// Counterpoint: this seems to work?
|
||||
vec.data.0[0]
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn from(arr: [T; D]) -> Self {
|
||||
SVector::<T, D>::from(arr).transpose()
|
||||
SVector::<T, D>::from(arr).transpose_into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut};
|
||||
use crate::base::{Matrix, Scalar};
|
||||
use crate::base::Matrix;
|
||||
|
||||
/*
|
||||
*
|
||||
@ -23,7 +23,7 @@ macro_rules! coords_impl(
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
|
||||
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
||||
pub struct $T<T: Scalar> {
|
||||
pub struct $T<T> {
|
||||
$(pub $comps: T),*
|
||||
}
|
||||
}
|
||||
@ -31,7 +31,7 @@ macro_rules! coords_impl(
|
||||
|
||||
macro_rules! deref_impl(
|
||||
($R: ty, $C: ty; $Target: ident) => {
|
||||
impl<T: Scalar, S> Deref for Matrix<T, $R, $C, S>
|
||||
impl<T, S> Deref for Matrix<T, $R, $C, S>
|
||||
where S: ContiguousStorage<T, $R, $C> {
|
||||
type Target = $Target<T>;
|
||||
|
||||
@ -41,7 +41,7 @@ macro_rules! deref_impl(
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, S> DerefMut for Matrix<T, $R, $C, S>
|
||||
impl<T, S> DerefMut for Matrix<T, $R, $C, S>
|
||||
where S: ContiguousStorageMut<T, $R, $C> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
|
@ -70,7 +70,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
for (destination, source) in irows.clone().enumerate() {
|
||||
unsafe {
|
||||
*res.vget_unchecked_mut(destination) =
|
||||
MaybeUninit::new(src.vget_unchecked(*source).inlined_clone());
|
||||
MaybeUninit::new(src.vget_unchecked(*source).clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,11 +106,12 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// # Set rows, columns, and diagonal
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Fills the diagonal of this matrix with the content of the given vector.
|
||||
#[inline]
|
||||
pub fn set_diagonal<R2: Dim, S2>(&mut self, diag: &Vector<T, R2, S2>)
|
||||
where
|
||||
T: Clone,
|
||||
R: DimMin<C>,
|
||||
S2: Storage<T, R2>,
|
||||
ShapeConstraint: DimEq<DimMinimum<R, C>, R2>,
|
||||
@ -120,7 +121,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions.");
|
||||
|
||||
for i in 0..min_nrows_ncols {
|
||||
unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone() }
|
||||
unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,6 +144,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
#[inline]
|
||||
pub fn set_row<C2: Dim, S2>(&mut self, i: usize, row: &RowVector<T, C2, S2>)
|
||||
where
|
||||
T: Clone,
|
||||
S2: Storage<T, U1, C2>,
|
||||
ShapeConstraint: SameNumberOfColumns<C, C2>,
|
||||
{
|
||||
@ -153,6 +155,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
#[inline]
|
||||
pub fn set_column<R2: Dim, S2>(&mut self, i: usize, column: &Vector<T, R2, S2>)
|
||||
where
|
||||
T: Clone,
|
||||
S2: Storage<T, R2, U1>,
|
||||
ShapeConstraint: SameNumberOfRows<R, R2>,
|
||||
{
|
||||
@ -270,7 +273,7 @@ impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
impl<T: Clone, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
/// Copies the upper-triangle of this matrix to its lower-triangular part.
|
||||
///
|
||||
/// This makes the matrix symmetric. Panics if the matrix is not square.
|
||||
@ -281,7 +284,7 @@ impl<T: Scalar, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
for j in 0..dim {
|
||||
for i in j + 1..dim {
|
||||
unsafe {
|
||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone();
|
||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,7 +299,7 @@ impl<T: Scalar, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
for j in 1..self.ncols() {
|
||||
for i in 0..j {
|
||||
unsafe {
|
||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone();
|
||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -304,7 +307,7 @@ impl<T: Scalar, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
}
|
||||
|
||||
/// # In-place swapping
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Swaps two rows in-place.
|
||||
#[inline]
|
||||
pub fn swap_rows(&mut self, irow1: usize, irow2: usize) {
|
||||
@ -340,7 +343,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
*
|
||||
*/
|
||||
/// # Rows and columns removal
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T: Clone, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/*
|
||||
*
|
||||
* Column removal.
|
||||
@ -569,7 +572,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// # Rows and columns insertion
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T: Clone, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/*
|
||||
*
|
||||
* Columns insertion.
|
||||
@ -738,7 +741,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// # Resizing and reshaping
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T: Clone, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Resizes this matrix so that it contains `new_nrows` rows and `new_ncols` columns.
|
||||
///
|
||||
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
|
||||
@ -846,7 +849,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
if new_ncols.value() > ncols {
|
||||
res.columns_range_mut(ncols..).fill(val.inlined_clone());
|
||||
res.columns_range_mut(ncols..).fill(val.clone());
|
||||
}
|
||||
|
||||
if new_nrows.value() > nrows {
|
||||
@ -928,7 +931,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// # In-place resizing
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T: Scalar> OMatrix<T, Dynamic, Dynamic> {
|
||||
impl<T: Clone> OMatrix<T, Dynamic, Dynamic> {
|
||||
/// Resizes this matrix in-place.
|
||||
///
|
||||
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
|
||||
@ -948,7 +951,7 @@ impl<T: Scalar> OMatrix<T, Dynamic, Dynamic> {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T: Scalar, C: Dim> OMatrix<T, Dynamic, C>
|
||||
impl<T: Clone, C: Dim> OMatrix<T, Dynamic, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, Dynamic, C>,
|
||||
{
|
||||
@ -971,7 +974,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T: Scalar, R: Dim> OMatrix<T, R, Dynamic>
|
||||
impl<T: Clone, R: Dim> OMatrix<T, R, Dynamic>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, Dynamic>,
|
||||
{
|
||||
@ -993,13 +996,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn compress_rows<T: Scalar>(
|
||||
data: &mut [T],
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
i: usize,
|
||||
nremove: usize,
|
||||
) {
|
||||
unsafe fn compress_rows<T>(data: &mut [T], nrows: usize, ncols: usize, i: usize, nremove: usize) {
|
||||
let new_nrows = nrows - nremove;
|
||||
|
||||
if new_nrows == 0 || ncols == 0 {
|
||||
@ -1032,13 +1029,7 @@ unsafe fn compress_rows<T: Scalar>(
|
||||
|
||||
// Moves entries of a matrix buffer to make place for `ninsert` emty rows starting at the `i-th` row index.
|
||||
// The `data` buffer is assumed to contained at least `(nrows + ninsert) * ncols` elements.
|
||||
unsafe fn extend_rows<T: Scalar>(
|
||||
data: &mut [T],
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
i: usize,
|
||||
ninsert: usize,
|
||||
) {
|
||||
unsafe fn extend_rows<T>(data: &mut [T], nrows: usize, ncols: usize, i: usize, ninsert: usize) {
|
||||
let new_nrows = nrows + ninsert;
|
||||
|
||||
if new_nrows == 0 || ncols == 0 {
|
||||
@ -1070,7 +1061,6 @@ unsafe fn extend_rows<T: Scalar>(
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T, R, S> Extend<T> for Matrix<T, R, Dynamic, S>
|
||||
where
|
||||
T: Scalar,
|
||||
R: Dim,
|
||||
S: Extend<T>,
|
||||
{
|
||||
@ -1118,7 +1108,6 @@ where
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T, S> Extend<T> for Matrix<T, Dynamic, U1, S>
|
||||
where
|
||||
T: Scalar,
|
||||
S: Extend<T>,
|
||||
{
|
||||
/// Extend the number of rows of a `Vector` with elements
|
||||
@ -1137,12 +1126,9 @@ where
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<T, R, S, RV, SV> Extend<Vector<T, RV, SV>> for Matrix<T, R, Dynamic, S>
|
||||
impl<T, R: Dim, S, RV: Dim, SV> Extend<Vector<T, RV, SV>> for Matrix<T, R, Dynamic, S>
|
||||
where
|
||||
T: Scalar,
|
||||
R: Dim,
|
||||
S: Extend<Vector<T, RV, SV>>,
|
||||
RV: Dim,
|
||||
SV: Storage<T, RV>,
|
||||
ShapeConstraint: SameNumberOfRows<R, RV>,
|
||||
{
|
||||
|
@ -716,7 +716,34 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
self.transpose_to(&mut res);
|
||||
|
||||
unsafe {
|
||||
// Safety: res is now fully initialized due to the guarantees of transpose_to.
|
||||
// Safety: res is now fully initialized due to the guarantees of transpose_to.
|
||||
res.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
/// Transposes `self`. Does not require `T: Clone` like its other counteparts.
|
||||
pub fn transpose_into(self) -> OMatrix<T, C, R>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, C, R>,
|
||||
{
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
let mut res = OMatrix::new_uninitialized_generic(ncols, nrows);
|
||||
|
||||
let (nrows, ncols) = res.shape();
|
||||
|
||||
// TODO: optimize that.
|
||||
for i in 0..nrows {
|
||||
for j in 0..ncols {
|
||||
unsafe {
|
||||
*res.get_unchecked_mut((j, i)) = MaybeUninit::new(*self.get_unchecked((i, j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BEEP! BEEP! There's a double drop here that needs to be fixed.
|
||||
|
||||
unsafe {
|
||||
// Safety: res is now fully initialized due to the guarantees of transpose_to.
|
||||
res.assume_init()
|
||||
}
|
||||
}
|
||||
@ -728,13 +755,12 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Returns a matrix containing the result of `f` applied to each of its entries.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn map<T2: Clone, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
|
||||
pub fn map<T2, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
|
||||
where
|
||||
T: Clone,
|
||||
DefaultAllocator: Allocator<T2, R, C>,
|
||||
{
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
|
||||
let mut res = OMatrix::new_uninitialized_generic(nrows, ncols);
|
||||
|
||||
for j in 0..ncols.value() {
|
||||
@ -1283,6 +1309,8 @@ impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BEEP BEEEP!!!!! I'm double-freeing! OH NO!!!! (todo)
|
||||
}
|
||||
|
||||
/// Fills this matrix with the content of the transpose another one via clones.
|
||||
@ -1359,6 +1387,8 @@ impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BEEP BEEPP! Same thing as the non-transpose method, this is UB.
|
||||
}
|
||||
|
||||
// TODO: rename `apply` to `apply_mut` and `apply_into` to `apply`?
|
||||
@ -1370,6 +1400,51 @@ impl<T, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Dim, C: Dim, S: StorageMut<MaybeUninit<T>, R, C>> Matrix<MaybeUninit<T>, R, C, S> {
|
||||
/// Initializes this matrix with the content of another one via clones. Both must have the same shape.
|
||||
#[inline]
|
||||
pub fn copy_init_from<R2: Dim, C2: Dim, SB>(&mut self, other: &Matrix<T, R2, C2, SB>)
|
||||
where
|
||||
T: Clone,
|
||||
SB: Storage<T, R2, C2>,
|
||||
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
||||
{
|
||||
self.copy_from_fn(other, |e| MaybeUninit::new(e.clone()))
|
||||
}
|
||||
|
||||
/// Initializes this matrix with the content of another one, after applying a function to
|
||||
/// the entries of the other matrix. Both must have the same shape.
|
||||
#[inline]
|
||||
pub fn move_init_from<R2: Dim, C2: Dim, SB>(&mut self, other: Matrix<T, R2, C2, SB>)
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
||||
{
|
||||
self.move_from_fn(other, MaybeUninit::new)
|
||||
}
|
||||
|
||||
/// Initializes this matrix with the content of the transpose another one via clones.
|
||||
#[inline]
|
||||
pub fn tr_copy_init_from<R2: Dim, C2: Dim, SB>(&mut self, other: &Matrix<T, R2, C2, SB>)
|
||||
where
|
||||
T: Clone,
|
||||
SB: Storage<T, R2, C2>,
|
||||
ShapeConstraint: DimEq<R, C2> + SameNumberOfColumns<C, R2>,
|
||||
{
|
||||
self.tr_copy_from_fn(other, |e| MaybeUninit::new(e.clone()))
|
||||
}
|
||||
|
||||
/// Initializes this matrix with the content of the transpose another one via moves.
|
||||
#[inline]
|
||||
pub fn tr_move_init_from<R2: Dim, C2: Dim, SB>(&mut self, other: Matrix<T, R2, C2, SB>)
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
ShapeConstraint: DimEq<R, C2> + SameNumberOfColumns<C, R2>,
|
||||
{
|
||||
self.tr_move_from_fn(other, MaybeUninit::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// Gets a reference to the i-th element of this column vector without bound checking.
|
||||
#[inline]
|
||||
@ -2185,9 +2260,8 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<T, R, C, S>>
|
||||
impl<T: AbsDiffEq, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<T, R, C, S>>
|
||||
where
|
||||
T: Scalar + AbsDiffEq,
|
||||
S: Storage<T, R, C>,
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
@ -2204,9 +2278,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<T, R, C, S>>
|
||||
impl<T: RelativeEq, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<T, R, C, S>>
|
||||
where
|
||||
T: Scalar + RelativeEq,
|
||||
S: Storage<T, R, C>,
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
@ -2227,9 +2300,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<T, R, C, S>>
|
||||
impl<T: UlpsEq, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<T, R, C, S>>
|
||||
where
|
||||
T: Scalar + UlpsEq,
|
||||
S: Storage<T, R, C>,
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
@ -2244,9 +2316,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Dim, C: Dim, S> Hash for Matrix<T, R, C, S>
|
||||
impl<T: Hash, R: Dim, C: Dim, S> Hash for Matrix<T, R, C, S>
|
||||
where
|
||||
T: Hash,
|
||||
S: Storage<T, R, C>,
|
||||
{
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
|
@ -9,11 +9,9 @@ use crate::base::{DefaultAllocator, OMatrix, Scalar};
|
||||
* Simd structures.
|
||||
*
|
||||
*/
|
||||
impl<T, R, C> SimdValue for OMatrix<T, R, C>
|
||||
impl<T, R: Dim, C: Dim> SimdValue for OMatrix<T, R, C>
|
||||
where
|
||||
T: Scalar + SimdValue,
|
||||
R: Dim,
|
||||
C: Dim,
|
||||
T::Element: Scalar,
|
||||
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||
{
|
||||
|
@ -645,7 +645,7 @@ impl<T, R1: Dim, C1: Dim, R2: Dim, SA, SB> MulAssign<Matrix<T, R2, C1, SB>>
|
||||
where
|
||||
T: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
||||
SB: Storage<T, R2, C1>,
|
||||
SA: ContiguousStorageMut<T, R1, C1> + Clone,
|
||||
SA: ContiguousStorageMut<T, R1, C1> ,
|
||||
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
|
||||
DefaultAllocator: Allocator<T, R1, C1> + InnerAllocator<T, R1, C1, Buffer = SA>,
|
||||
{
|
||||
@ -660,7 +660,7 @@ impl<'b, T, R1: Dim, C1: Dim, R2: Dim, SA, SB> MulAssign<&'b Matrix<T, R2, C1, S
|
||||
where
|
||||
T: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
||||
SB: Storage<T, R2, C1>,
|
||||
SA: ContiguousStorageMut<T, R1, C1> + Clone,
|
||||
SA: ContiguousStorageMut<T, R1, C1> ,
|
||||
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
|
||||
// TODO: this is too restrictive. See comments for the non-ref version.
|
||||
DefaultAllocator: Allocator<T, R1, C1> + InnerAllocator<T, R1, C1, Buffer = SA>,
|
||||
@ -796,7 +796,6 @@ where
|
||||
ShapeConstraint: SameNumberOfRows<R3, R1>
|
||||
+ SameNumberOfColumns<C3, C2>
|
||||
+ AreMultipliable<R1, C1, R2, C2>,
|
||||
DefaultAllocator: Allocator<T, R3, C3>,
|
||||
{
|
||||
out.gemm_z(T::one(), self, rhs);
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ pub trait Scalar: 'static + Clone + Debug {
|
||||
fn inlined_clone(&self) -> Self;
|
||||
}
|
||||
|
||||
// Unfortunately, this blanket impl leads to many misleading compiler messages
|
||||
// telling you to implement Copy, even though Scalar is what's really needed.
|
||||
impl<T: 'static + Copy + Debug> Scalar for T {
|
||||
#[inline(always)]
|
||||
fn inlined_clone(&self) -> T {
|
||||
|
@ -7,7 +7,7 @@ use num::Zero;
|
||||
use simba::scalar::{ClosedAdd, Field, SupersetOf};
|
||||
|
||||
/// # Folding on columns and rows
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Returns a row vector where each element is the result of the application of `f` on the
|
||||
/// corresponding column of the original matrix.
|
||||
#[inline]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::base::{DimName, Scalar, ToTypenum, Vector, Vector2, Vector3};
|
||||
use crate::base::{DimName, ToTypenum, Vector, Vector2, Vector3};
|
||||
use crate::storage::Storage;
|
||||
use typenum::{self, Cmp, Greater};
|
||||
|
||||
@ -11,7 +11,7 @@ macro_rules! impl_swizzle {
|
||||
#[must_use]
|
||||
pub fn $name(&self) -> $Result<T>
|
||||
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||
$Result::new($(self[$i].inlined_clone()),*)
|
||||
$Result::new($(self[$i].clone()),*)
|
||||
}
|
||||
)*
|
||||
)*
|
||||
@ -19,7 +19,7 @@ macro_rules! impl_swizzle {
|
||||
}
|
||||
|
||||
/// # Swizzling
|
||||
impl<T: Scalar, D, S: Storage<T, D>> Vector<T, D, S>
|
||||
impl<T: Clone, D, S: Storage<T, D>> Vector<T, D, S>
|
||||
where
|
||||
D: DimName + ToTypenum,
|
||||
{
|
||||
|
@ -2,15 +2,15 @@
|
||||
#![allow(clippy::op_ref)]
|
||||
|
||||
use crate::{
|
||||
Isometry3, Matrix4, Normed, OVector, Point3, Quaternion, Scalar, SimdRealField, Translation3,
|
||||
Unit, UnitQuaternion, Vector3, Zero, U8,
|
||||
Isometry3, Matrix4, Normed, OVector, Point3, Quaternion, SimdRealField, Translation3, Unit,
|
||||
UnitQuaternion, Vector3, Zero, U8,
|
||||
};
|
||||
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::fmt;
|
||||
|
||||
use simba::scalar::{ClosedNeg, RealField};
|
||||
use simba::scalar::RealField;
|
||||
|
||||
/// A dual quaternion.
|
||||
///
|
||||
@ -251,10 +251,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<T: SimdRealField> Serialize for DualQuaternion<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
impl<T: Serialize> Serialize for DualQuaternion<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
@ -264,10 +261,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<'a, T: SimdRealField> Deserialize<'a> for DualQuaternion<T>
|
||||
where
|
||||
T: Deserialize<'a>,
|
||||
{
|
||||
impl<'a, T: Deserialize<'a>> Deserialize<'a> for DualQuaternion<T> {
|
||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||
where
|
||||
Des: Deserializer<'a>,
|
||||
@ -283,7 +277,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField> DualQuaternion<T> {
|
||||
impl<T> DualQuaternion<T> {
|
||||
fn to_vector(self) -> OVector<T, U8> {
|
||||
(*self.as_ref()).into()
|
||||
}
|
||||
@ -341,14 +335,14 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for DualQuaternion<T> {
|
||||
/// A unit quaternions. May be used to represent a rotation followed by a translation.
|
||||
pub type UnitDualQuaternion<T> = Unit<DualQuaternion<T>>;
|
||||
|
||||
impl<T: Scalar + ClosedNeg + PartialEq + SimdRealField> PartialEq for UnitDualQuaternion<T> {
|
||||
impl<T: PartialEq> PartialEq for UnitDualQuaternion<T> {
|
||||
#[inline]
|
||||
fn eq(&self, rhs: &Self) -> bool {
|
||||
self.as_ref().eq(rhs.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + ClosedNeg + Eq + SimdRealField> Eq for UnitDualQuaternion<T> {}
|
||||
impl<T: Eq> Eq for UnitDualQuaternion<T> {}
|
||||
|
||||
impl<T: SimdRealField> Normed for DualQuaternion<T> {
|
||||
type Norm = T::SimdRealField;
|
||||
@ -376,10 +370,7 @@ impl<T: SimdRealField> Normed for DualQuaternion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField> UnitDualQuaternion<T>
|
||||
where
|
||||
T::Element: SimdRealField,
|
||||
{
|
||||
impl<T> UnitDualQuaternion<T> {
|
||||
/// The underlying dual quaternion.
|
||||
///
|
||||
/// Same as `self.as_ref()`.
|
||||
@ -398,7 +389,12 @@ where
|
||||
pub fn dual_quaternion(&self) -> &DualQuaternion<T> {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField> UnitDualQuaternion<T>
|
||||
where
|
||||
T::Element: SimdRealField,
|
||||
{
|
||||
/// Compute the conjugate of this unit quaternion.
|
||||
///
|
||||
/// # Example
|
||||
@ -600,7 +596,7 @@ where
|
||||
#[must_use]
|
||||
pub fn sclerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
T: RealField + RelativeEq<Epsilon = T>,
|
||||
{
|
||||
self.try_sclerp(other, t, T::default_epsilon())
|
||||
.expect("DualQuaternion sclerp: ambiguous configuration.")
|
||||
@ -620,7 +616,7 @@ where
|
||||
#[must_use]
|
||||
pub fn try_sclerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
T: RealField + RelativeEq<Epsilon = T>,
|
||||
{
|
||||
let two = T::one() + T::one();
|
||||
let half = T::one() / two;
|
||||
@ -895,7 +891,7 @@ impl<T: RealField> Default for UnitDualQuaternion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField + fmt::Display> fmt::Display for UnitDualQuaternion<T> {
|
||||
impl<T: RealField+fmt::Display> fmt::Display for UnitDualQuaternion<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(axis) = self.rotation().axis() {
|
||||
let axis = axis.into_inner();
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
DualQuaternion, Isometry3, Quaternion, Scalar, SimdRealField, Translation3, UnitDualQuaternion,
|
||||
DualQuaternion, Isometry3, Quaternion, SimdRealField, Translation3, UnitDualQuaternion,
|
||||
UnitQuaternion,
|
||||
};
|
||||
use num::{One, Zero};
|
||||
@ -7,7 +7,7 @@ use num::{One, Zero};
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
use simba::scalar::SupersetOf;
|
||||
|
||||
impl<T: Scalar> DualQuaternion<T> {
|
||||
impl<T> DualQuaternion<T> {
|
||||
/// Creates a dual quaternion from its rotation and translation components.
|
||||
///
|
||||
/// # Example
|
||||
@ -60,7 +60,7 @@ impl<T: Scalar> DualQuaternion<T> {
|
||||
/// let q2 = q.cast::<f32>();
|
||||
/// assert_eq!(q2, DualQuaternion::from_real(Quaternion::new(1.0f32, 2.0, 3.0, 4.0)));
|
||||
/// ```
|
||||
pub fn cast<To: Scalar>(self) -> DualQuaternion<To>
|
||||
pub fn cast<To>(self) -> DualQuaternion<To>
|
||||
where
|
||||
DualQuaternion<To>: SupersetOf<Self>,
|
||||
{
|
||||
@ -156,7 +156,7 @@ impl<T: SimdRealField> UnitDualQuaternion<T> {
|
||||
/// let q2 = q.cast::<f32>();
|
||||
/// assert_eq!(q2, UnitDualQuaternion::<f32>::identity());
|
||||
/// ```
|
||||
pub fn cast<To: Scalar>(self) -> UnitDualQuaternion<To>
|
||||
pub fn cast<To>(self) -> UnitDualQuaternion<To>
|
||||
where
|
||||
UnitDualQuaternion<To>: SupersetOf<Self>,
|
||||
{
|
||||
|
@ -24,8 +24,7 @@ use crate::geometry::{
|
||||
|
||||
impl<T1, T2> SubsetOf<DualQuaternion<T2>> for DualQuaternion<T1>
|
||||
where
|
||||
T1: SimdRealField,
|
||||
T2: SimdRealField + SupersetOf<T1>,
|
||||
T2: SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> DualQuaternion<T2> {
|
||||
@ -49,8 +48,7 @@ where
|
||||
|
||||
impl<T1, T2> SubsetOf<UnitDualQuaternion<T2>> for UnitDualQuaternion<T1>
|
||||
where
|
||||
T1: SimdRealField,
|
||||
T2: SimdRealField + SupersetOf<T1>,
|
||||
T2: SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> UnitDualQuaternion<T2> {
|
||||
|
@ -56,21 +56,21 @@ use std::ops::{
|
||||
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
|
||||
};
|
||||
|
||||
impl<T: SimdRealField> AsRef<[T; 8]> for DualQuaternion<T> {
|
||||
impl<T> AsRef<[T; 8]> for DualQuaternion<T> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[T; 8] {
|
||||
unsafe { &*(self as *const Self as *const [T; 8]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField> AsMut<[T; 8]> for DualQuaternion<T> {
|
||||
impl<T> AsMut<[T; 8]> for DualQuaternion<T> {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [T; 8] {
|
||||
unsafe { &mut *(self as *mut Self as *mut [T; 8]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField> Index<usize> for DualQuaternion<T> {
|
||||
impl<T> Index<usize> for DualQuaternion<T> {
|
||||
type Output = T;
|
||||
|
||||
#[inline]
|
||||
@ -79,7 +79,7 @@ impl<T: SimdRealField> Index<usize> for DualQuaternion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdRealField> IndexMut<usize> for DualQuaternion<T> {
|
||||
impl<T> IndexMut<usize> for DualQuaternion<T> {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, i: usize) -> &mut T {
|
||||
&mut self.as_mut()[i]
|
||||
|
@ -80,7 +80,6 @@ pub struct Isometry<T, R, const D: usize> {
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
impl<T, R, const D: usize> Abomonation for Isometry<T, R, D>
|
||||
where
|
||||
T: SimdRealField,
|
||||
R: Abomonation,
|
||||
Translation<T, D>: Abomonation,
|
||||
{
|
||||
@ -106,10 +105,7 @@ mod rkyv_impl {
|
||||
use crate::{base::Scalar, geometry::Translation};
|
||||
use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize};
|
||||
|
||||
impl<T: Scalar + Archive, R: Archive, const D: usize> Archive for Isometry<T, R, D>
|
||||
where
|
||||
T::Archived: Scalar,
|
||||
{
|
||||
impl<T: Archive, R: Archive, const D: usize> Archive for Isometry<T, R, D> {
|
||||
type Archived = Isometry<T::Archived, R::Archived, D>;
|
||||
type Resolver = (R::Resolver, <Translation<T, D> as Archive>::Resolver);
|
||||
|
||||
@ -132,8 +128,8 @@ mod rkyv_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + Serialize<S>, R: Serialize<S>, S: Fallible + ?Sized, const D: usize>
|
||||
Serialize<S> for Isometry<T, R, D>
|
||||
impl<T: Serialize<S>, R: Serialize<S>, S: Fallible + ?Sized, const D: usize> Serialize<S>
|
||||
for Isometry<T, R, D>
|
||||
where
|
||||
T::Archived: Scalar,
|
||||
{
|
||||
@ -145,7 +141,7 @@ mod rkyv_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + Archive, R: Archive, _D: Fallible + ?Sized, const D: usize>
|
||||
impl<T: Archive, R: Archive, _D: Fallible + ?Sized, const D: usize>
|
||||
Deserialize<Isometry<T, R, D>, _D> for Isometry<T::Archived, R::Archived, D>
|
||||
where
|
||||
T::Archived: Scalar + Deserialize<T, _D>,
|
||||
@ -160,7 +156,7 @@ mod rkyv_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<T, R, D>
|
||||
impl<T: hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<T, R, D>
|
||||
where
|
||||
Owned<T, Const<D>>: hash::Hash,
|
||||
{
|
||||
@ -170,12 +166,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + Copy, R: Copy, const D: usize> Copy for Isometry<T, R, D> where
|
||||
Owned<T, Const<D>>: Copy
|
||||
{
|
||||
}
|
||||
impl<T: Copy, R: Copy, const D: usize> Copy for Isometry<T, R, D> where Owned<T, Const<D>>: Copy {}
|
||||
|
||||
impl<T: Scalar, R: Clone, const D: usize> Clone for Isometry<T, R, D> {
|
||||
impl<T: Clone, R: Clone, const D: usize> Clone for Isometry<T, R, D> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
@ -638,7 +631,7 @@ where
|
||||
* Display
|
||||
*
|
||||
*/
|
||||
impl<T: RealField + fmt::Display, R, const D: usize> fmt::Display for Isometry<T, R, D>
|
||||
impl<T: Scalar + fmt::Display, R, const D: usize> fmt::Display for Isometry<T, R, D>
|
||||
where
|
||||
R: fmt::Display,
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ use std::fmt;
|
||||
use std::hash;
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
use std::io::{Result as IOResult, Write};
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
@ -20,6 +21,7 @@ use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
||||
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
||||
use crate::base::{Const, DefaultAllocator, OVector};
|
||||
use crate::storage::Owned;
|
||||
use crate::Scalar;
|
||||
|
||||
/// A point in an euclidean space.
|
||||
///
|
||||
@ -41,7 +43,7 @@ use crate::storage::Owned;
|
||||
/// may have some other methods, e.g., `isometry.inverse_transform_point(&point)`. See the documentation
|
||||
/// of said transformations for details.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
// TODO: figure out why #[derive(Clone, Debug)] doesn't work!
|
||||
pub struct OPoint<T, D: DimName>
|
||||
where
|
||||
DefaultAllocator: InnerAllocator<T, D>,
|
||||
@ -66,6 +68,16 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: Clone, D: DimName> Clone for OPoint<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
OVector<T, D>: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self::from(self.coords.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
unsafe impl<T, D: DimName> bytemuck::Zeroable for OPoint<T, D>
|
||||
where
|
||||
@ -151,7 +163,8 @@ where
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn map<T2, F: FnMut(T) -> T2>(&self, f: F) -> OPoint<T2, D>
|
||||
where T:Clone,
|
||||
where
|
||||
T: Clone,
|
||||
DefaultAllocator: Allocator<T2, D>,
|
||||
{
|
||||
self.coords.map(f).into()
|
||||
@ -194,22 +207,44 @@ where
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<D, U1>>
|
||||
where
|
||||
T: One + Clone,
|
||||
D: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
|
||||
{
|
||||
let mut res = OVector::<_, DimNameSum<D, U1>>::new_uninitialized();
|
||||
for i in 0..D::dim() {
|
||||
unsafe {
|
||||
*res.get_unchecked(i) = MaybeUninit::new(self.coords[i].clone());
|
||||
}
|
||||
}
|
||||
|
||||
res[(D::dim(), 0)] = MaybeUninit::new(T::one());
|
||||
|
||||
unsafe { res.assume_init() }
|
||||
}
|
||||
|
||||
pub fn into_homogeneous(self) -> OVector<T, DimNameSum<D, U1>>
|
||||
where
|
||||
T: One,
|
||||
D: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
|
||||
{
|
||||
let mut res = unsafe {
|
||||
crate::unimplemented_or_uninitialized_generic!(
|
||||
<DimNameSum<D, U1> as DimName>::name(),
|
||||
Const::<1>
|
||||
)
|
||||
};
|
||||
res.generic_slice_mut((0, 0), (D::name(), Const::<1>))
|
||||
.copy_from(&self.coords);
|
||||
res[(D::dim(), 0)] = T::one();
|
||||
let mut res = OVector::<_, DimNameSum<D, U1>>::new_uninitialized();
|
||||
|
||||
res
|
||||
// TODO: maybe we can move the whole array at once? Or use `into_iter`
|
||||
// to avoid double-dropping.
|
||||
for i in 0..D::dim() {
|
||||
unsafe {
|
||||
*res.get_unchecked(i) = MaybeUninit::new(self.coords[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix double drop
|
||||
|
||||
res[(D::dim(), 0)] = MaybeUninit::new(T::one());
|
||||
|
||||
unsafe { res.assume_init() }
|
||||
}
|
||||
|
||||
/// Creates a new point with the given coordinates.
|
||||
@ -415,7 +450,7 @@ where
|
||||
/*
|
||||
* inf/sup
|
||||
*/
|
||||
impl<T: SimdPartialOrd, D: DimName> OPoint<T, D>
|
||||
impl<T: Scalar + SimdPartialOrd, D: DimName> OPoint<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
{
|
||||
|
@ -50,9 +50,9 @@ where
|
||||
#[inline]
|
||||
pub fn origin() -> Self
|
||||
where
|
||||
T: Zero,
|
||||
T: Zero + Clone,
|
||||
{
|
||||
Self::from(OVector::from_element(T::zero()))
|
||||
Self::from(OVector::<_, D>::zeros())
|
||||
}
|
||||
|
||||
/// Creates a new point from a slice.
|
||||
@ -70,8 +70,11 @@ where
|
||||
/// assert_eq!(pt, Point3::new(1.0, 2.0, 3.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn from_slice(components: &[T]) -> Self {
|
||||
Self::from(OVector::from_row_slice(components))
|
||||
pub fn from_slice(components: &[T]) -> Self
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
Self::from(OVector::<_, D>::from_row_slice(components))
|
||||
}
|
||||
|
||||
/// Creates a new point from its homogeneous vector representation.
|
||||
@ -175,7 +178,7 @@ where
|
||||
impl<T: Arbitrary + Send, D: DimName> Arbitrary for OPoint<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
crate::base::storage::Owned<T, D>: Send,
|
||||
crate::base::storage::Owned<T, D>: Clone + Send,
|
||||
{
|
||||
#[inline]
|
||||
fn arbitrary(g: &mut Gen) -> Self {
|
||||
|
@ -2,12 +2,11 @@ use num::{One, Zero};
|
||||
use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf};
|
||||
use simba::simd::PrimitiveSimdValue;
|
||||
|
||||
use crate::base::allocator::Allocator;
|
||||
use crate::base::allocator::{Allocator, InnerAllocator};
|
||||
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||
use crate::base::{Const, DefaultAllocator, Matrix, OVector, Scalar};
|
||||
|
||||
use crate::geometry::Point;
|
||||
use crate::storage::Owned;
|
||||
use crate::{DimName, OPoint};
|
||||
|
||||
/*
|
||||
@ -55,7 +54,7 @@ where
|
||||
#[inline]
|
||||
fn to_superset(&self) -> OVector<T2, DimNameSum<D, U1>> {
|
||||
let p: OPoint<T2, D> = self.to_superset();
|
||||
p.to_homogeneous()
|
||||
p.into_homogeneous()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -79,7 +78,7 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn from(t: OPoint<T, D>) -> Self {
|
||||
t.to_homogeneous()
|
||||
t.into_homogeneous()
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +100,7 @@ impl<T, const D: usize> From<Point<T, D>> for [T; D] {
|
||||
|
||||
impl<T, D: DimName> From<OVector<T, D>> for OPoint<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
DefaultAllocator: InnerAllocator<T, D>,
|
||||
{
|
||||
#[inline]
|
||||
fn from(coords: OVector<T, D>) -> Self {
|
||||
@ -109,81 +108,81 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 2]> for Point<T, D>
|
||||
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 2]> for Point<T, D>
|
||||
where
|
||||
T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
|
||||
T::Element: Copy,
|
||||
Owned<T::Element, Const<D>>: Copy,
|
||||
T::Element: Scalar,
|
||||
{
|
||||
#[inline]
|
||||
fn from(arr: [Point<T::Element, D>; 2]) -> Self {
|
||||
Self::from(OVector::from([arr[0].coords, arr[1].coords]))
|
||||
Self::from(OVector::from([
|
||||
arr[0].coords.clone(),
|
||||
arr[1].coords.clone(),
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 4]> for Point<T, D>
|
||||
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 4]> for Point<T, D>
|
||||
where
|
||||
T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
|
||||
T::Element: Copy,
|
||||
Owned<T::Element, Const<D>>: Copy,
|
||||
T::Element: Scalar,
|
||||
{
|
||||
#[inline]
|
||||
fn from(arr: [Point<T::Element, D>; 4]) -> Self {
|
||||
Self::from(OVector::from([
|
||||
arr[0].coords,
|
||||
arr[1].coords,
|
||||
arr[2].coords,
|
||||
arr[3].coords,
|
||||
arr[0].coords.clone(),
|
||||
arr[1].coords.clone(),
|
||||
arr[2].coords.clone(),
|
||||
arr[3].coords.clone(),
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 8]> for Point<T, D>
|
||||
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 8]> for Point<T, D>
|
||||
where
|
||||
T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
|
||||
T::Element: Copy,
|
||||
Owned<T::Element, Const<D>>: Copy,
|
||||
T::Element: Scalar,
|
||||
{
|
||||
#[inline]
|
||||
fn from(arr: [Point<T::Element, D>; 8]) -> Self {
|
||||
Self::from(OVector::from([
|
||||
arr[0].coords,
|
||||
arr[1].coords,
|
||||
arr[2].coords,
|
||||
arr[3].coords,
|
||||
arr[4].coords,
|
||||
arr[5].coords,
|
||||
arr[6].coords,
|
||||
arr[7].coords,
|
||||
arr[0].coords.clone(),
|
||||
arr[1].coords.clone(),
|
||||
arr[2].coords.clone(),
|
||||
arr[3].coords.clone(),
|
||||
arr[4].coords.clone(),
|
||||
arr[5].coords.clone(),
|
||||
arr[6].coords.clone(),
|
||||
arr[7].coords.clone(),
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 16]> for Point<T, D>
|
||||
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 16]>
|
||||
for Point<T, D>
|
||||
where
|
||||
T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
|
||||
T::Element: Copy,
|
||||
Owned<T::Element, Const<D>>: Copy,
|
||||
T::Element: Scalar,
|
||||
{
|
||||
#[inline]
|
||||
fn from(arr: [Point<T::Element, D>; 16]) -> Self {
|
||||
Self::from(OVector::from([
|
||||
arr[0].coords,
|
||||
arr[1].coords,
|
||||
arr[2].coords,
|
||||
arr[3].coords,
|
||||
arr[4].coords,
|
||||
arr[5].coords,
|
||||
arr[6].coords,
|
||||
arr[7].coords,
|
||||
arr[8].coords,
|
||||
arr[9].coords,
|
||||
arr[10].coords,
|
||||
arr[11].coords,
|
||||
arr[12].coords,
|
||||
arr[13].coords,
|
||||
arr[14].coords,
|
||||
arr[15].coords,
|
||||
arr[0].coords.clone(),
|
||||
arr[1].coords.clone(),
|
||||
arr[2].coords.clone(),
|
||||
arr[3].coords.clone(),
|
||||
arr[4].coords.clone(),
|
||||
arr[5].coords.clone(),
|
||||
arr[6].coords.clone(),
|
||||
arr[7].coords.clone(),
|
||||
arr[8].coords.clone(),
|
||||
arr[9].coords.clone(),
|
||||
arr[10].coords.clone(),
|
||||
arr[11].coords.clone(),
|
||||
arr[12].coords.clone(),
|
||||
arr[13].coords.clone(),
|
||||
arr[14].coords.clone(),
|
||||
arr[15].coords.clone(),
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
|
||||
use crate::base::{Scalar, U1, U2, U3, U4, U5, U6};
|
||||
use crate::base::{U1, U2, U3, U4, U5, U6};
|
||||
|
||||
use crate::geometry::OPoint;
|
||||
|
||||
@ -13,7 +13,7 @@ use crate::geometry::OPoint;
|
||||
|
||||
macro_rules! deref_impl(
|
||||
($D: ty, $Target: ident $(, $comps: ident)*) => {
|
||||
impl<T: Scalar> Deref for OPoint<T, $D>
|
||||
impl<T> Deref for OPoint<T, $D>
|
||||
{
|
||||
type Target = $Target<T>;
|
||||
|
||||
@ -23,7 +23,7 @@ macro_rules! deref_impl(
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar> DerefMut for OPoint<T, $D>
|
||||
impl<T> DerefMut for OPoint<T, $D>
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
|
@ -1,10 +1,13 @@
|
||||
use simba::simd::SimdValue;
|
||||
|
||||
use crate::base::OVector;
|
||||
|
||||
use crate::geometry::Point;
|
||||
use crate::Scalar;
|
||||
|
||||
impl<T: SimdValue, const D: usize> SimdValue for Point<T, D> {
|
||||
impl<T: Scalar + SimdValue, const D: usize> SimdValue for Point<T, D>
|
||||
where
|
||||
T::Element: Scalar,
|
||||
{
|
||||
type Element = Point<T::Element, D>;
|
||||
type SimdBool = T::SimdBool;
|
||||
|
||||
|
@ -57,10 +57,10 @@ impl<T: Zero + Clone> Default for Quaternion<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
unsafe impl<T: Scalar> bytemuck::Zeroable for Quaternion<T> where Vector4<T>: bytemuck::Zeroable {}
|
||||
unsafe impl<T> bytemuck::Zeroable for Quaternion<T> where Vector4<T>: bytemuck::Zeroable {}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
unsafe impl<T: Scalar> bytemuck::Pod for Quaternion<T>
|
||||
unsafe impl<T> bytemuck::Pod for Quaternion<T>
|
||||
where
|
||||
Vector4<T>: bytemuck::Pod,
|
||||
T: Copy,
|
||||
@ -68,7 +68,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
impl<T: Scalar> Abomonation for Quaternion<T>
|
||||
impl<T> Abomonation for Quaternion<T>
|
||||
where
|
||||
Vector4<T>: Abomonation,
|
||||
{
|
||||
@ -86,7 +86,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<T: Scalar> Serialize for Quaternion<T>
|
||||
impl<T> Serialize for Quaternion<T>
|
||||
where
|
||||
Owned<T, U4>: Serialize,
|
||||
{
|
||||
@ -99,7 +99,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<'a, T: Scalar> Deserialize<'a> for Quaternion<T>
|
||||
impl<'a, T> Deserialize<'a> for Quaternion<T>
|
||||
where
|
||||
Owned<T, U4>: Deserialize<'a>,
|
||||
{
|
||||
@ -1045,7 +1045,7 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for Quaternion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField + fmt::Display> fmt::Display for Quaternion<T> {
|
||||
impl<T: fmt::Display> fmt::Display for Quaternion<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@ -1097,7 +1097,7 @@ impl<T: SimdRealField> UnitQuaternion<T>
|
||||
where
|
||||
T::Element: SimdRealField,
|
||||
{
|
||||
/// The rotation angle in [0; pi] of this unit quaternion.
|
||||
/// The rotation angle in \[0; pi\] of this unit quaternion.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
|
@ -28,8 +28,7 @@ use crate::geometry::{
|
||||
|
||||
impl<T1, T2> SubsetOf<Quaternion<T2>> for Quaternion<T1>
|
||||
where
|
||||
T1: Scalar,
|
||||
T2: Scalar + SupersetOf<T1>,
|
||||
T2 : SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> Quaternion<T2> {
|
||||
@ -50,9 +49,8 @@ where
|
||||
}
|
||||
|
||||
impl<T1, T2> SubsetOf<UnitQuaternion<T2>> for UnitQuaternion<T1>
|
||||
where
|
||||
T1: Scalar,
|
||||
T2: Scalar + SupersetOf<T1>,
|
||||
where
|
||||
T2: SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> UnitQuaternion<T2> {
|
||||
@ -239,14 +237,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar> From<Vector4<T>> for Quaternion<T> {
|
||||
impl<T> From<Vector4<T>> for Quaternion<T> {
|
||||
#[inline]
|
||||
fn from(coords: Vector4<T>) -> Self {
|
||||
Self { coords }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar> From<[T; 4]> for Quaternion<T> {
|
||||
impl<T> From<[T; 4]> for Quaternion<T> {
|
||||
#[inline]
|
||||
fn from(coords: [T; 4]) -> Self {
|
||||
Self {
|
||||
|
@ -59,12 +59,12 @@ use std::ops::{
|
||||
|
||||
use crate::base::dimension::U3;
|
||||
use crate::base::storage::Storage;
|
||||
use crate::base::{Const, Scalar, Unit, Vector, Vector3};
|
||||
use crate::base::{Const, Unit, Vector, Vector3};
|
||||
use crate::SimdRealField;
|
||||
|
||||
use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion};
|
||||
|
||||
impl<T: Scalar> Index<usize> for Quaternion<T> {
|
||||
impl<T> Index<usize> for Quaternion<T> {
|
||||
type Output = T;
|
||||
|
||||
#[inline]
|
||||
@ -73,7 +73,7 @@ impl<T: Scalar> Index<usize> for Quaternion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar> IndexMut<usize> for Quaternion<T> {
|
||||
impl<T> IndexMut<usize> for Quaternion<T> {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, i: usize) -> &mut T {
|
||||
&mut self.coords[i]
|
||||
@ -371,12 +371,12 @@ quaternion_op_impl!(
|
||||
;
|
||||
self: Rotation<T, 3>, rhs: UnitQuaternion<T>,
|
||||
Output = UnitQuaternion<T>;
|
||||
UnitQuaternion::<T>::from_rotation_matrix(&self) / rhs; );
|
||||
UnitQuaternion::<T>::from_rotation_matrix(&self) / rhs;);
|
||||
|
||||
// UnitQuaternion × Vector
|
||||
quaternion_op_impl!(
|
||||
Mul, mul;
|
||||
SB: Storage<T, Const<3>> ;
|
||||
SB: Storage<T, Const<3>>;
|
||||
self: &'a UnitQuaternion<T>, rhs: &'b Vector<T, Const<3>, SB>,
|
||||
Output = Vector3<T>;
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint};
|
||||
use crate::base::{Const, Matrix, Unit, Vector};
|
||||
use crate::dimension::{Dim, U1};
|
||||
@ -77,40 +79,42 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||
pub fn reflect_rows<R2: Dim, C2: Dim, S2, S3>(
|
||||
&self,
|
||||
lhs: &mut Matrix<T, R2, C2, S2>,
|
||||
work: &mut Vector<T, R2, S3>,
|
||||
work: &mut Vector<MaybeUninit<T>, R2, S3>,
|
||||
) where
|
||||
S2: StorageMut<T, R2, C2>,
|
||||
S3: StorageMut<T, R2>,
|
||||
S3: StorageMut<MaybeUninit<T>, R2>,
|
||||
ShapeConstraint: DimEq<C2, D> + AreMultipliable<R2, C2, D, U1>,
|
||||
{
|
||||
lhs.mul_to(&self.axis, work);
|
||||
let mut work = unsafe { work.assume_init_mut() };
|
||||
|
||||
if !self.bias.is_zero() {
|
||||
work.add_scalar_mut(-self.bias);
|
||||
}
|
||||
|
||||
let m_two: T = crate::convert(-2.0f64);
|
||||
lhs.gerc(m_two, work, &self.axis, T::one());
|
||||
lhs.gerc(m_two, &work, &self.axis, T::one());
|
||||
}
|
||||
|
||||
/// Applies the reflection to the rows of `lhs`.
|
||||
pub fn reflect_rows_with_sign<R2: Dim, C2: Dim, S2, S3>(
|
||||
&self,
|
||||
lhs: &mut Matrix<T, R2, C2, S2>,
|
||||
work: &mut Vector<T, R2, S3>,
|
||||
work: &mut Vector<MaybeUninit<T>, R2, S3>,
|
||||
sign: T,
|
||||
) where
|
||||
S2: StorageMut<T, R2, C2>,
|
||||
S3: StorageMut<T, R2>,
|
||||
S3: StorageMut<MaybeUninit<T>, R2>,
|
||||
ShapeConstraint: DimEq<C2, D> + AreMultipliable<R2, C2, D, U1>,
|
||||
{
|
||||
lhs.mul_to(&self.axis, work);
|
||||
let mut work = unsafe { work.assume_init_mut() };
|
||||
|
||||
if !self.bias.is_zero() {
|
||||
work.add_scalar_mut(-self.bias);
|
||||
}
|
||||
|
||||
let m_two = sign.scale(crate::convert(-2.0f64));
|
||||
lhs.gerc(m_two, work, &self.axis, sign);
|
||||
lhs.gerc(m_two, &work, &self.axis, sign);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ where
|
||||
|
||||
impl<T: Copy, const D: usize> Copy for Rotation<T, D> where Owned<T, Const<D>, Const<D>>: Copy {}
|
||||
|
||||
impl<T, const D: usize> Clone for Rotation<T, D>
|
||||
impl<T: Clone, const D: usize> Clone for Rotation<T, D>
|
||||
where
|
||||
Owned<T, Const<D>, Const<D>>: Clone,
|
||||
{
|
||||
@ -127,7 +127,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
impl<T, const D: usize> Rotation<T, D> {
|
||||
/// Creates a new rotation from the given square matrix.
|
||||
///
|
||||
/// The matrix squareness is checked but not its orthonormality.
|
||||
@ -162,7 +162,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
}
|
||||
|
||||
/// # Conversion to a matrix
|
||||
impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
impl<T, const D: usize> Rotation<T, D> {
|
||||
/// A reference to the underlying matrix representation of this rotation.
|
||||
///
|
||||
/// # Example
|
||||
@ -263,7 +263,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
#[must_use]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: Zero + One,
|
||||
T: Zero + One + Scalar,
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
|
||||
use std::any::Any;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::hash;
|
||||
use std::marker::PhantomData;
|
||||
@ -7,7 +8,7 @@ use std::marker::PhantomData;
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use simba::scalar::RealField;
|
||||
use simba::scalar::{ComplexField, RealField};
|
||||
|
||||
use crate::base::allocator::Allocator;
|
||||
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||
@ -119,7 +120,7 @@ macro_rules! category_mul_impl(
|
||||
)*}
|
||||
);
|
||||
|
||||
// We require stability uppon multiplication.
|
||||
// We require stability upon multiplication.
|
||||
impl<T: TCategory> TCategoryMul<T> for T {
|
||||
type Representative = T;
|
||||
}
|
||||
@ -157,8 +158,7 @@ super_tcategory_impl!(
|
||||
/// It is stored as a matrix with dimensions `(D + 1, D + 1)`, e.g., it stores a 4x4 matrix for a
|
||||
/// 3D transformation.
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Transform<T: RealField, C: TCategory, const D: usize>
|
||||
pub struct Transform<T, C: TCategory, const D: usize>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -167,7 +167,7 @@ where
|
||||
_phantom: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<T: RealField + hash::Hash, C: TCategory, const D: usize> hash::Hash for Transform<T, C, D>
|
||||
impl<T: hash::Hash, C: TCategory, const D: usize> hash::Hash for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -178,7 +178,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField, C: TCategory, const D: usize> Copy for Transform<T, C, D>
|
||||
impl<T: Copy, C: TCategory, const D: usize> Copy for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -186,10 +186,11 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: RealField, C: TCategory, const D: usize> Clone for Transform<T, C, D>
|
||||
impl<T: Clone, C: TCategory, const D: usize> Clone for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
Owned<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
@ -197,8 +198,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug, C: TCategory, const D: usize> Debug for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
Owned<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Transform")
|
||||
.field("matrix", &self.matrix)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<T: RealField, C: TCategory, const D: usize> Serialize for Transform<T, C, D>
|
||||
impl<T, C: TCategory, const D: usize> Serialize for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -213,7 +227,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<'a, T: RealField, C: TCategory, const D: usize> Deserialize<'a> for Transform<T, C, D>
|
||||
impl<'a, T, C: TCategory, const D: usize> Deserialize<'a> for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -231,14 +245,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField + Eq, C: TCategory, const D: usize> Eq for Transform<T, C, D>
|
||||
impl<T: Eq, C: TCategory, const D: usize> Eq for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: RealField, C: TCategory, const D: usize> PartialEq for Transform<T, C, D>
|
||||
impl<T: PartialEq, C: TCategory, const D: usize> PartialEq for Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -249,7 +263,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealField, C: TCategory, const D: usize> Transform<T, C, D>
|
||||
impl<T, C: TCategory, const D: usize> Transform<T, C, D>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
@ -354,7 +368,10 @@ where
|
||||
#[deprecated(
|
||||
note = "This method is redundant with automatic `Copy` and the `.clone()` method and will be removed in a future release."
|
||||
)]
|
||||
pub fn clone_owned(&self) -> Transform<T, C, D> {
|
||||
pub fn clone_owned(&self) -> Transform<T, C, D>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
Transform::from_matrix_unchecked(self.matrix.clone_owned())
|
||||
}
|
||||
|
||||
@ -372,7 +389,10 @@ where
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
self.matrix().clone_owned()
|
||||
}
|
||||
|
||||
@ -401,7 +421,10 @@ where
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
||||
pub fn try_inverse(self) -> Option<Transform<T, C, D>> {
|
||||
pub fn try_inverse(self) -> Option<Transform<T, C, D>>
|
||||
where
|
||||
T: ComplexField,
|
||||
{
|
||||
self.matrix
|
||||
.try_inverse()
|
||||
.map(Transform::from_matrix_unchecked)
|
||||
@ -427,6 +450,7 @@ where
|
||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
||||
pub fn inverse(self) -> Transform<T, C, D>
|
||||
where
|
||||
T: ComplexField,
|
||||
C: SubTCategoryOf<TProjective>,
|
||||
{
|
||||
// TODO: specialize for TAffine?
|
||||
@ -458,7 +482,10 @@ where
|
||||
/// assert!(!t.try_inverse_mut());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn try_inverse_mut(&mut self) -> bool {
|
||||
pub fn try_inverse_mut(&mut self) -> bool
|
||||
where
|
||||
T: ComplexField,
|
||||
{
|
||||
self.matrix.try_inverse_mut()
|
||||
}
|
||||
|
||||
@ -482,6 +509,7 @@ where
|
||||
#[inline]
|
||||
pub fn inverse_mut(&mut self)
|
||||
where
|
||||
T: ComplexField,
|
||||
C: SubTCategoryOf<TProjective>,
|
||||
{
|
||||
let _ = self.matrix.try_inverse_mut();
|
||||
|
@ -29,7 +29,7 @@ pub struct Translation<T, const D: usize> {
|
||||
pub vector: SVector<T, D>,
|
||||
}
|
||||
|
||||
impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Translation<T, D>
|
||||
impl<T: hash::Hash, const D: usize> hash::Hash for Translation<T, D>
|
||||
where
|
||||
Owned<T, Const<D>>: hash::Hash,
|
||||
{
|
||||
@ -38,9 +38,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + Copy, const D: usize> Copy for Translation<T, D> {}
|
||||
impl<T: Copy, const D: usize> Copy for Translation<T, D> {}
|
||||
|
||||
impl<T: Scalar, const D: usize> Clone for Translation<T, D>
|
||||
impl<T: Clone, const D: usize> Clone for Translation<T, D>
|
||||
where
|
||||
Owned<T, Const<D>>: Clone,
|
||||
{
|
||||
@ -53,7 +53,6 @@ where
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
impl<T, const D: usize> Abomonation for Translation<T, D>
|
||||
where
|
||||
T: Scalar,
|
||||
SVector<T, D>: Abomonation,
|
||||
{
|
||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||
@ -70,7 +69,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<T: Scalar, const D: usize> Serialize for Translation<T, D>
|
||||
impl<T, const D: usize> Serialize for Translation<T, D>
|
||||
where
|
||||
Owned<T, Const<D>>: Serialize,
|
||||
{
|
||||
@ -83,7 +82,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Translation<T, D>
|
||||
impl<'a, T, const D: usize> Deserialize<'a> for Translation<T, D>
|
||||
where
|
||||
Owned<T, Const<D>>: Deserialize<'a>,
|
||||
{
|
||||
@ -140,7 +139,7 @@ mod rkyv_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> Translation<T, D> {
|
||||
impl<T, const D: usize> Translation<T, D> {
|
||||
/// Creates a new translation from the given vector.
|
||||
#[inline]
|
||||
#[deprecated(note = "Use `::from` instead.")]
|
||||
@ -166,7 +165,7 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
|
||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
||||
pub fn inverse(&self) -> Translation<T, D>
|
||||
where
|
||||
T: ClosedNeg,
|
||||
T: ClosedNeg + Scalar,
|
||||
{
|
||||
Translation::from(-&self.vector)
|
||||
}
|
||||
@ -193,7 +192,7 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
|
||||
#[must_use]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: Zero + One,
|
||||
T: Zero + One + Scalar,
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||
{
|
||||
@ -224,7 +223,7 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
|
||||
#[inline]
|
||||
pub fn inverse_mut(&mut self)
|
||||
where
|
||||
T: ClosedNeg,
|
||||
T: ClosedNeg + Scalar,
|
||||
{
|
||||
self.vector.neg_mut()
|
||||
}
|
||||
@ -264,16 +263,16 @@ impl<T: Scalar + ClosedSub, const D: usize> Translation<T, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + Eq, const D: usize> Eq for Translation<T, D> {}
|
||||
impl<T: Eq, const D: usize> Eq for Translation<T, D> {}
|
||||
|
||||
impl<T: Scalar + PartialEq, const D: usize> PartialEq for Translation<T, D> {
|
||||
impl<T: PartialEq, const D: usize> PartialEq for Translation<T, D> {
|
||||
#[inline]
|
||||
fn eq(&self, right: &Translation<T, D>) -> bool {
|
||||
self.vector == right.vector
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D>
|
||||
impl<T: AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D>
|
||||
where
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
@ -290,7 +289,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D>
|
||||
impl<T: RelativeEq, const D: usize> RelativeEq for Translation<T, D>
|
||||
where
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
@ -311,7 +310,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D>
|
||||
impl<T: UlpsEq, const D: usize> UlpsEq for Translation<T, D>
|
||||
where
|
||||
T::Epsilon: Copy,
|
||||
{
|
||||
|
@ -26,9 +26,8 @@ use crate::Point;
|
||||
*/
|
||||
|
||||
impl<T1, T2, const D: usize> SubsetOf<Translation<T2, D>> for Translation<T1, D>
|
||||
where
|
||||
T1: Scalar,
|
||||
T2: Scalar + SupersetOf<T1>,
|
||||
where
|
||||
T2: SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> Translation<T2, D> {
|
||||
@ -193,14 +192,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Translation<T, D> {
|
||||
impl<T, const D: usize> From<OVector<T, Const<D>>> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn from(vector: OVector<T, Const<D>>) -> Self {
|
||||
Translation { vector }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<[T; D]> for Translation<T, D> {
|
||||
impl<T, const D: usize> From<[T; D]> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn from(coords: [T; D]) -> Self {
|
||||
Translation {
|
||||
@ -209,14 +208,14 @@ impl<T: Scalar, const D: usize> From<[T; D]> for Translation<T, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<Point<T, D>> for Translation<T, D> {
|
||||
impl<T, const D: usize> From<Point<T, D>> for Translation<T, D> {
|
||||
#[inline]
|
||||
fn from(pt: Point<T, D>) -> Self {
|
||||
Translation { vector: pt.coords }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Scalar, const D: usize> From<Translation<T, D>> for [T; D] {
|
||||
impl<T, const D: usize> From<Translation<T, D>> for [T; D] {
|
||||
#[inline]
|
||||
fn from(t: Translation<T, D>) -> Self {
|
||||
t.vector.into()
|
||||
|
@ -1,10 +1,13 @@
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::allocator::Allocator;
|
||||
use crate::base::{DefaultAllocator, Matrix, OMatrix, OVector, Unit};
|
||||
use crate::dimension::{Const, Dim, DimDiff, DimMin, DimMinimum, DimSub, U1};
|
||||
use crate::storage::Storage;
|
||||
use crate::storage::{Owned, Storage};
|
||||
use crate::{Dynamic, };
|
||||
use simba::scalar::ComplexField;
|
||||
|
||||
use crate::geometry::Reflection;
|
||||
@ -32,7 +35,6 @@ use crate::linalg::householder;
|
||||
OVector<T, DimMinimum<R, C>>: Deserialize<'de>,
|
||||
OVector<T, DimDiff<DimMinimum<R, C>, U1>>: Deserialize<'de>"))
|
||||
)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Bidiagonal<T: ComplexField, R: DimMin<C>, C: Dim>
|
||||
where
|
||||
DimMinimum<R, C>: DimSub<U1>,
|
||||
@ -50,18 +52,58 @@ where
|
||||
upper_diagonal: bool,
|
||||
}
|
||||
|
||||
impl<T: ComplexField, R: DimMin<C>, C: Dim> Clone for Bidiagonal<T, R, C>
|
||||
where
|
||||
DimMinimum<R, C>: DimSub<U1>,
|
||||
DefaultAllocator: Allocator<T, R, C>
|
||||
+ Allocator<T, DimMinimum<R, C>>
|
||||
+ Allocator<T, DimDiff<DimMinimum<R, C>, U1>>,
|
||||
Owned<T, R, C>: Clone,
|
||||
Owned<T, DimMinimum<R, C>>: Clone,
|
||||
Owned<T, DimDiff<DimMinimum<R, C>, U1>>: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
uv: self.uv.clone(),
|
||||
diagonal: self.diagonal.clone(),
|
||||
off_diagonal: self.off_diagonal.clone(),
|
||||
upper_diagonal: self.upper_diagonal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ComplexField, R: DimMin<C>, C: Dim> Copy for Bidiagonal<T, R, C>
|
||||
where
|
||||
DimMinimum<R, C>: DimSub<U1>,
|
||||
DefaultAllocator: Allocator<T, R, C>
|
||||
+ Allocator<T, DimMinimum<R, C>>
|
||||
+ Allocator<T, DimDiff<DimMinimum<R, C>, U1>>,
|
||||
OMatrix<T, R, C>: Copy,
|
||||
OVector<T, DimMinimum<R, C>>: Copy,
|
||||
OVector<T, DimDiff<DimMinimum<R, C>, U1>>: Copy,
|
||||
Owned<T, R, C>: Copy,
|
||||
Owned<T, DimMinimum<R, C>>: Copy,
|
||||
Owned<T, DimDiff<DimMinimum<R, C>, U1>>: Copy,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: ComplexField, R: DimMin<C>, C: Dim> fmt::Debug for Bidiagonal<T, R, C>
|
||||
where
|
||||
DimMinimum<R, C>: DimSub<U1>,
|
||||
DefaultAllocator: Allocator<T, R, C>
|
||||
+ Allocator<T, DimMinimum<R, C>>
|
||||
+ Allocator<T, DimDiff<DimMinimum<R, C>, U1>>,
|
||||
Owned<T, R, C>: fmt::Debug,
|
||||
Owned<T, DimMinimum<R, C>>: fmt::Debug,
|
||||
Owned<T, DimDiff<DimMinimum<R, C>, U1>>: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Bidiagonal")
|
||||
.field("uv", &self.uv)
|
||||
.field("diagonal", &self.diagonal)
|
||||
.field("off_diagonal", &self.off_diagonal)
|
||||
.field("upper_diagonal", &self.upper_diagonal)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ComplexField, R: DimMin<C>, C: Dim> Bidiagonal<T, R, C>
|
||||
where
|
||||
DimMinimum<R, C>: DimSub<U1>,
|
||||
@ -81,25 +123,25 @@ where
|
||||
"Cannot compute the bidiagonalization of an empty matrix."
|
||||
);
|
||||
|
||||
let mut diagonal =
|
||||
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
|
||||
let mut off_diagonal = unsafe {
|
||||
crate::unimplemented_or_uninitialized_generic!(
|
||||
min_nrows_ncols.sub(Const::<1>),
|
||||
Const::<1>
|
||||
)
|
||||
};
|
||||
let mut axis_packed =
|
||||
unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
|
||||
let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, Const::<1>) };
|
||||
let mut diagonal = Matrix::new_uninitialized_generic(min_nrows_ncols, Const::<1>);
|
||||
let mut off_diagonal =
|
||||
Matrix::new_uninitialized_generic(min_nrows_ncols.sub(Const::<1>), Const::<1>);
|
||||
let mut axis_packed = Matrix::new_uninitialized_generic(ncols, Const::<1>);
|
||||
let mut work = Matrix::new_uninitialized_generic(nrows, Const::<1>);
|
||||
|
||||
let upper_diagonal = nrows.value() >= ncols.value();
|
||||
if upper_diagonal {
|
||||
for ite in 0..dim - 1 {
|
||||
householder::clear_column_unchecked(&mut matrix, &mut diagonal[ite], ite, 0, None);
|
||||
householder::clear_column_unchecked(
|
||||
&mut matrix,
|
||||
diagonal[ite].as_mut_ptr(),
|
||||
ite,
|
||||
0,
|
||||
None,
|
||||
);
|
||||
householder::clear_row_unchecked(
|
||||
&mut matrix,
|
||||
&mut off_diagonal[ite],
|
||||
off_diagonal[ite].as_mut_ptr(),
|
||||
&mut axis_packed,
|
||||
&mut work,
|
||||
ite,
|
||||
@ -109,7 +151,7 @@ where
|
||||
|
||||
householder::clear_column_unchecked(
|
||||
&mut matrix,
|
||||
&mut diagonal[dim - 1],
|
||||
diagonal[dim - 1].as_mut_ptr(),
|
||||
dim - 1,
|
||||
0,
|
||||
None,
|
||||
@ -118,7 +160,7 @@ where
|
||||
for ite in 0..dim - 1 {
|
||||
householder::clear_row_unchecked(
|
||||
&mut matrix,
|
||||
&mut diagonal[ite],
|
||||
diagonal[ite].as_mut_ptr(),
|
||||
&mut axis_packed,
|
||||
&mut work,
|
||||
ite,
|
||||
@ -126,7 +168,7 @@ where
|
||||
);
|
||||
householder::clear_column_unchecked(
|
||||
&mut matrix,
|
||||
&mut off_diagonal[ite],
|
||||
off_diagonal[ite].as_mut_ptr(),
|
||||
ite,
|
||||
1,
|
||||
None,
|
||||
@ -135,7 +177,7 @@ where
|
||||
|
||||
householder::clear_row_unchecked(
|
||||
&mut matrix,
|
||||
&mut diagonal[dim - 1],
|
||||
diagonal[dim - 1].as_mut_ptr(),
|
||||
&mut axis_packed,
|
||||
&mut work,
|
||||
dim - 1,
|
||||
@ -145,8 +187,8 @@ where
|
||||
|
||||
Bidiagonal {
|
||||
uv: matrix,
|
||||
diagonal,
|
||||
off_diagonal,
|
||||
diagonal: diagonal.assume_init(),
|
||||
off_diagonal: off_diagonal.assume_init(),
|
||||
upper_diagonal,
|
||||
}
|
||||
}
|
||||
@ -243,23 +285,23 @@ where
|
||||
#[must_use]
|
||||
pub fn v_t(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C> + Allocator<T, Dynamic, U1>,
|
||||
{
|
||||
let (nrows, ncols) = self.uv.data.shape();
|
||||
let min_nrows_ncols = nrows.min(ncols);
|
||||
|
||||
let mut res = Matrix::identity_generic(min_nrows_ncols, ncols);
|
||||
let mut work =
|
||||
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
|
||||
let mut axis_packed =
|
||||
unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
|
||||
let mut work = Matrix::new_uninitialized_generic(min_nrows_ncols, Const::<1>);
|
||||
let mut axis_packed = Matrix::new_uninitialized_generic(ncols, Const::<1>);
|
||||
|
||||
let shift = self.axis_shift().1;
|
||||
|
||||
for i in (0..min_nrows_ncols.value() - shift).rev() {
|
||||
let axis = self.uv.slice_range(i, i + shift..);
|
||||
let mut axis_packed = axis_packed.rows_range_mut(i + shift..);
|
||||
axis_packed.tr_copy_from(&axis);
|
||||
axis_packed.tr_copy_init_from(&axis);
|
||||
let mut axis_packed = unsafe { axis_packed.slice_assume_init() };
|
||||
|
||||
// TODO: sometimes, the axis might have a zero magnitude.
|
||||
let refl = Reflection::new(Unit::new_unchecked(axis_packed), T::zero());
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
use std::fmt;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -9,7 +12,7 @@ use crate::allocator::Allocator;
|
||||
use crate::base::{Const, DefaultAllocator, Matrix, OMatrix, Vector};
|
||||
use crate::constraint::{SameNumberOfRows, ShapeConstraint};
|
||||
use crate::dimension::{Dim, DimAdd, DimDiff, DimSub, DimSum, U1};
|
||||
use crate::storage::{Storage, StorageMut};
|
||||
use crate::storage::{Owned, Storage, StorageMut};
|
||||
|
||||
/// The Cholesky decomposition of a symmetric-definite-positive matrix.
|
||||
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
||||
@ -23,7 +26,6 @@ use crate::storage::{Storage, StorageMut};
|
||||
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D>,
|
||||
OMatrix<T, D, D>: Deserialize<'de>"))
|
||||
)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Cholesky<T: SimdComplexField, D: Dim>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
@ -34,10 +36,34 @@ where
|
||||
impl<T: SimdComplexField, D: Dim> Copy for Cholesky<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
OMatrix<T, D, D>: Copy,
|
||||
Owned<T, D, D>: Copy,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: SimdComplexField, D: Dim> Clone for Cholesky<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
Owned<T, D, D>: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
chol: self.chol.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdComplexField, D: Dim> fmt::Debug for Cholesky<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
Owned<T, D, D>: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Cholesky")
|
||||
.field("chol", &self.chol)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SimdComplexField, D: Dim> Cholesky<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
@ -226,6 +252,8 @@ where
|
||||
DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>> + Allocator<T, R2>,
|
||||
ShapeConstraint: SameNumberOfRows<R2, DimSum<D, U1>>,
|
||||
{
|
||||
// TODO: check that MaybeUninit manipulations are sound!
|
||||
|
||||
let mut col = col.into_owned();
|
||||
// for an explanation of the formulas, see https://en.wikipedia.org/wiki/Cholesky_decomposition#Updating_the_decomposition
|
||||
let n = col.nrows();
|
||||
@ -237,20 +265,20 @@ where
|
||||
assert!(j < n, "j needs to be within the bound of the new matrix.");
|
||||
|
||||
// loads the data into a new matrix with an additional jth row/column
|
||||
let mut chol = unsafe {
|
||||
crate::unimplemented_or_uninitialized_generic!(
|
||||
self.chol.data.shape().0.add(Const::<1>),
|
||||
self.chol.data.shape().1.add(Const::<1>)
|
||||
)
|
||||
};
|
||||
let mut chol = Matrix::new_uninitialized_generic(
|
||||
self.chol.data.shape().0.add(Const::<1>),
|
||||
self.chol.data.shape().1.add(Const::<1>),
|
||||
);
|
||||
|
||||
// TODO: checked that every entry is initialized EXACTLY once.
|
||||
chol.slice_range_mut(..j, ..j)
|
||||
.copy_from(&self.chol.slice_range(..j, ..j));
|
||||
.copy_init_from(&self.chol.slice_range(..j, ..j));
|
||||
chol.slice_range_mut(..j, j + 1..)
|
||||
.copy_from(&self.chol.slice_range(..j, j..));
|
||||
.copy_init_from(&self.chol.slice_range(..j, j..));
|
||||
chol.slice_range_mut(j + 1.., ..j)
|
||||
.copy_from(&self.chol.slice_range(j.., ..j));
|
||||
.copy_init_from(&self.chol.slice_range(j.., ..j));
|
||||
chol.slice_range_mut(j + 1.., j + 1..)
|
||||
.copy_from(&self.chol.slice_range(j.., j..));
|
||||
.copy_init_from(&self.chol.slice_range(j.., j..));
|
||||
|
||||
// update the jth row
|
||||
let top_left_corner = self.chol.slice_range(..j, ..j);
|
||||
@ -266,7 +294,7 @@ where
|
||||
|
||||
// update the center element
|
||||
let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared()));
|
||||
chol[(j, j)] = center_element;
|
||||
chol[(j, j)] = MaybeUninit::new(center_element);
|
||||
|
||||
// update the jth column
|
||||
let bottom_left_corner = self.chol.slice_range(j.., ..j);
|
||||
@ -277,7 +305,9 @@ where
|
||||
&new_rowj_adjoint,
|
||||
T::one() / center_element,
|
||||
);
|
||||
chol.slice_range_mut(j + 1.., j).copy_from(&new_colj);
|
||||
chol.slice_range_mut(j + 1.., j).copy_init_from(&new_colj);
|
||||
|
||||
let chol = unsafe { chol.assume_init() };
|
||||
|
||||
// update the bottom right corner
|
||||
let mut bottom_right_corner = chol.slice_range_mut(j + 1.., j + 1..);
|
||||
@ -298,25 +328,27 @@ where
|
||||
D: DimSub<U1>,
|
||||
DefaultAllocator: Allocator<T, DimDiff<D, U1>, DimDiff<D, U1>> + Allocator<T, D>,
|
||||
{
|
||||
// TODO: check that MaybeUninit manipulations are sound!
|
||||
|
||||
let n = self.chol.nrows();
|
||||
assert!(n > 0, "The matrix needs at least one column.");
|
||||
assert!(j < n, "j needs to be within the bound of the matrix.");
|
||||
|
||||
// loads the data into a new matrix except for the jth row/column
|
||||
let mut chol = unsafe {
|
||||
crate::unimplemented_or_uninitialized_generic!(
|
||||
self.chol.data.shape().0.sub(Const::<1>),
|
||||
self.chol.data.shape().1.sub(Const::<1>)
|
||||
)
|
||||
};
|
||||
let mut chol = Matrix::new_uninitialized_generic(
|
||||
self.chol.data.shape().0.sub(Const::<1>),
|
||||
self.chol.data.shape().1.sub(Const::<1>),
|
||||
);
|
||||
|
||||
chol.slice_range_mut(..j, ..j)
|
||||
.copy_from(&self.chol.slice_range(..j, ..j));
|
||||
.copy_init_from(&self.chol.slice_range(..j, ..j));
|
||||
chol.slice_range_mut(..j, j..)
|
||||
.copy_from(&self.chol.slice_range(..j, j + 1..));
|
||||
.copy_init_from(&self.chol.slice_range(..j, j + 1..));
|
||||
chol.slice_range_mut(j.., ..j)
|
||||
.copy_from(&self.chol.slice_range(j + 1.., ..j));
|
||||
.copy_init_from(&self.chol.slice_range(j + 1.., ..j));
|
||||
chol.slice_range_mut(j.., j..)
|
||||
.copy_from(&self.chol.slice_range(j + 1.., j + 1..));
|
||||
.copy_init_from(&self.chol.slice_range(j + 1.., j + 1..));
|
||||
let chol = unsafe { chol.assume_init() };
|
||||
|
||||
// updates the bottom right corner
|
||||
let mut bottom_right_corner = chol.slice_range_mut(j.., j..);
|
||||
@ -332,14 +364,12 @@ where
|
||||
///
|
||||
/// This helper method is called by `rank_one_update` but also `insert_column` and `remove_column`
|
||||
/// where it is used on a square slice of the decomposition
|
||||
fn xx_rank_one_update<Dm, Sm, Rx, Sx>(
|
||||
fn xx_rank_one_update<Dm: Dim, Sm, Rx: Dim, Sx>(
|
||||
chol: &mut Matrix<T, Dm, Dm, Sm>,
|
||||
x: &mut Vector<T, Rx, Sx>,
|
||||
sigma: T::RealField,
|
||||
) where
|
||||
//T: ComplexField,
|
||||
Dm: Dim,
|
||||
Rx: Dim,
|
||||
Sm: StorageMut<T, Dm, Dm>,
|
||||
Sx: StorageMut<T, Rx, U1>,
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Construction of householder elementary reflections.
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::allocator::Allocator;
|
||||
use crate::base::{DefaultAllocator, OMatrix, OVector, Unit, Vector};
|
||||
use crate::dimension::Dim;
|
||||
@ -46,7 +48,7 @@ pub fn reflection_axis_mut<T: ComplexField, D: Dim, S: StorageMut<T, D>>(
|
||||
#[doc(hidden)]
|
||||
pub fn clear_column_unchecked<T: ComplexField, R: Dim, C: Dim>(
|
||||
matrix: &mut OMatrix<T, R, C>,
|
||||
diag_elt: &mut T,
|
||||
diag_elt: *mut T,
|
||||
icol: usize,
|
||||
shift: usize,
|
||||
bilateral: Option<&mut OVector<T, R>>,
|
||||
@ -57,7 +59,9 @@ pub fn clear_column_unchecked<T: ComplexField, R: Dim, C: Dim>(
|
||||
let mut axis = left.rows_range_mut(icol + shift..);
|
||||
|
||||
let (reflection_norm, not_zero) = reflection_axis_mut(&mut axis);
|
||||
*diag_elt = reflection_norm;
|
||||
unsafe {
|
||||
*diag_elt = reflection_norm;
|
||||
}
|
||||
|
||||
if not_zero {
|
||||
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
||||
@ -74,9 +78,9 @@ pub fn clear_column_unchecked<T: ComplexField, R: Dim, C: Dim>(
|
||||
#[doc(hidden)]
|
||||
pub fn clear_row_unchecked<T: ComplexField, R: Dim, C: Dim>(
|
||||
matrix: &mut OMatrix<T, R, C>,
|
||||
diag_elt: &mut T,
|
||||
axis_packed: &mut OVector<T, C>,
|
||||
work: &mut OVector<T, R>,
|
||||
diag_elt: *mut T,
|
||||
axis_packed: &mut OVector<MaybeUninit<T>, C>,
|
||||
work: &mut OVector<MaybeUninit<T>, R>,
|
||||
irow: usize,
|
||||
shift: usize,
|
||||
) where
|
||||
@ -88,7 +92,7 @@ pub fn clear_row_unchecked<T: ComplexField, R: Dim, C: Dim>(
|
||||
|
||||
let (reflection_norm, not_zero) = reflection_axis_mut(&mut axis);
|
||||
axis.conjugate_mut(); // So that reflect_rows actually cancels the first row.
|
||||
*diag_elt = reflection_norm;
|
||||
unsafe{ *diag_elt = reflection_norm;}
|
||||
|
||||
if not_zero {
|
||||
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
||||
|
Loading…
Reference in New Issue
Block a user