Add must_use annotations in src/**/*.rs
This commit is contained in:
parent
d85c10a73c
commit
39aa52d019
@ -193,6 +193,7 @@ where
|
||||
/// ```
|
||||
///
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
@ -221,6 +222,7 @@ where
|
||||
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -248,6 +250,7 @@ where
|
||||
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
|
@ -28,6 +28,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0))
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn abs(&self) -> OMatrix<T, R, C>
|
||||
where
|
||||
T: Signed,
|
||||
@ -49,6 +50,7 @@ macro_rules! component_binop_impl(
|
||||
($($binop: ident, $binop_mut: ident, $binop_assign: ident, $cmpy: ident, $Trait: ident . $op: ident . $op_assign: ident, $desc:expr, $desc_cmpy:expr, $desc_mut:expr);* $(;)*) => {$(
|
||||
#[doc = $desc]
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> MatrixComponentOp<T, R1, C1, R2, C2>
|
||||
where T: $Trait,
|
||||
R2: Dim, C2: Dim,
|
||||
@ -251,6 +253,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
|
||||
/// assert_eq!(u.inf(&v), expected)
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||
where
|
||||
T: SimdPartialOrd,
|
||||
@ -271,6 +274,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
|
||||
/// assert_eq!(u.sup(&v), expected)
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||
where
|
||||
T: SimdPartialOrd,
|
||||
@ -291,6 +295,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
|
||||
/// assert_eq!(u.inf_sup(&v), expected)
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
|
||||
where
|
||||
T: SimdPartialOrd,
|
||||
|
@ -18,6 +18,7 @@ use crate::base::{DefaultAllocator, Matrix, OMatrix, RowVector, Scalar, Vector};
|
||||
impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Extracts the upper triangular part of this matrix (including the diagonal).
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn upper_triangle(&self) -> OMatrix<T, R, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, C>,
|
||||
@ -30,6 +31,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Extracts the lower triangular part of this matrix (including the diagonal).
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lower_triangle(&self) -> OMatrix<T, R, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, C>,
|
||||
@ -42,6 +44,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Creates a new matrix by extracting the given set of rows from `self`.
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix<T, Dynamic, C>
|
||||
where
|
||||
I: IntoIterator<Item = &'a usize>,
|
||||
@ -78,6 +81,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Creates a new matrix by extracting the given set of columns from `self`.
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix<T, R, Dynamic>
|
||||
where
|
||||
I: IntoIterator<Item = &'a usize>,
|
||||
|
@ -485,6 +485,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Produces a view of the data at the given index, or
|
||||
/// `None` if the index is out of bounds.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output>
|
||||
where
|
||||
I: MatrixIndex<'a, T, R, C, S>,
|
||||
@ -506,6 +507,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Produces a view of the data at the given index, or
|
||||
/// panics if the index is out of bounds.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn index<'a, I>(&'a self, index: I) -> I::Output
|
||||
where
|
||||
I: MatrixIndex<'a, T, R, C, S>,
|
||||
@ -527,6 +529,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Produces a view of the data at the given index, without doing
|
||||
/// any bounds checking.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
|
||||
where
|
||||
I: MatrixIndex<'a, T, R, C, S>,
|
||||
|
@ -20,6 +20,7 @@ impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
|
||||
/// let y = Vector3::new(10.0, 20.0, 30.0);
|
||||
/// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7));
|
||||
/// ```
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
@ -45,6 +46,7 @@ impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
|
||||
///
|
||||
/// assert_eq!(v, v2.normalize());
|
||||
/// ```
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
||||
where
|
||||
T: RealField,
|
||||
@ -72,6 +74,7 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
|
||||
///
|
||||
/// assert_eq!(v, v2);
|
||||
/// ```
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp<S2: Storage<T, D>>(
|
||||
&self,
|
||||
rhs: &Unit<Vector<T, D, S2>>,
|
||||
@ -89,6 +92,7 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
|
||||
///
|
||||
/// Returns `None` if the two vectors are almost collinear and with opposite direction
|
||||
/// (in this case, there is an infinity of possible results).
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_slerp<S2: Storage<T, D>>(
|
||||
&self,
|
||||
rhs: &Unit<Vector<T, D, S2>>,
|
||||
|
@ -441,6 +441,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert_eq!(mat.shape(), (3, 4));
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn shape(&self) -> (usize, usize) {
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
(nrows.value(), ncols.value())
|
||||
@ -455,6 +456,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert_eq!(mat.nrows(), 3);
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn nrows(&self) -> usize {
|
||||
self.shape().0
|
||||
}
|
||||
@ -468,6 +470,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert_eq!(mat.ncols(), 4);
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn ncols(&self) -> usize {
|
||||
self.shape().1
|
||||
}
|
||||
@ -483,6 +486,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// // The column strides is the number of steps (here 2) multiplied by the corresponding dimension.
|
||||
/// assert_eq!(mat.strides(), (1, 10));
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn strides(&self) -> (usize, usize) {
|
||||
let (srows, scols) = self.data.strides();
|
||||
(srows.value(), scols.value())
|
||||
@ -501,6 +505,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m[i], m[3]);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn vector_to_matrix_index(&self, i: usize) -> (usize, usize) {
|
||||
let (nrows, ncols) = self.shape();
|
||||
|
||||
@ -529,6 +534,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(unsafe { *ptr }, m[0]);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_ptr(&self) -> *const T {
|
||||
self.data.ptr()
|
||||
}
|
||||
@ -537,6 +543,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// See `relative_eq` from the `RelativeEq` trait for more details.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn relative_eq<R2, C2, SB>(
|
||||
&self,
|
||||
other: &Matrix<T, R2, C2, SB>,
|
||||
@ -559,6 +566,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Tests whether `self` and `rhs` are exactly equal.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn eq<R2, C2, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> bool
|
||||
where
|
||||
T: PartialEq,
|
||||
@ -609,6 +617,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Clones this matrix to one that owns its data.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn clone_owned(&self) -> OMatrix<T, R, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, C>,
|
||||
@ -619,6 +628,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Clones this matrix into one that owns its data. The actual type of the result depends on
|
||||
/// matrix storage combination rules for addition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn clone_owned_sum<R2, C2>(&self) -> MatrixSum<T, R, C, R2, C2>
|
||||
where
|
||||
R2: Dim,
|
||||
@ -692,6 +702,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T: Scalar, 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 = "This function does not mutate self. You should use the return value."]
|
||||
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T2, R, C>,
|
||||
@ -738,6 +749,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// - If the matrix has has least one component, then `init_f` is called with the first component
|
||||
/// to compute the initial value. Folding then continues on all the remaining components of the matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn fold_with<T2>(
|
||||
&self,
|
||||
init_f: impl FnOnce(Option<&T>) -> T2,
|
||||
@ -751,6 +763,7 @@ impl<T: Scalar, 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. Unlike `map`,
|
||||
/// `f` also gets passed the row and column index, i.e. `f(row, col, value)`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn map_with_location<T2: Scalar, F: FnMut(usize, usize, T) -> T2>(
|
||||
&self,
|
||||
mut f: F,
|
||||
@ -778,6 +791,7 @@ impl<T: Scalar, 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 entries of `self` and
|
||||
/// `rhs`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn zip_map<T2, N3, S2, F>(&self, rhs: &Matrix<T2, R, C, S2>, mut f: F) -> OMatrix<N3, R, C>
|
||||
where
|
||||
T2: Scalar,
|
||||
@ -813,6 +827,7 @@ impl<T: Scalar, 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 entries of `self` and
|
||||
/// `b`, and `c`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn zip_zip_map<T2, N3, N4, S2, S3, F>(
|
||||
&self,
|
||||
b: &Matrix<T2, R, C, S2>,
|
||||
@ -860,6 +875,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Folds a function `f` on each entry of `self`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn fold<Acc>(&self, init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc {
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
|
||||
@ -879,6 +895,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Folds a function `f` on each pairs of entries from `self` and `rhs`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn zip_fold<T2, R2, C2, S2, Acc>(
|
||||
&self,
|
||||
rhs: &Matrix<T2, R2, C2, S2>,
|
||||
@ -1238,6 +1255,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||
impl<T: Scalar, 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]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
|
||||
debug_assert!(i < self.nrows(), "Vector index out of bounds.");
|
||||
let i = i * self.strides().0;
|
||||
@ -1258,6 +1276,7 @@ impl<T: Scalar, D: Dim, S: StorageMut<T, D>> Vector<T, D, S> {
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: ContiguousStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Extracts a slice containing the entire matrix entries ordered column-by-columns.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
self.data.as_slice()
|
||||
}
|
||||
@ -1446,6 +1465,7 @@ impl<T: SimdComplexField, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||
impl<T: Scalar, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
/// The diagonal of this matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn diagonal(&self) -> OVector<T, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D>,
|
||||
@ -1457,6 +1477,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
///
|
||||
/// This is a more efficient version of `self.diagonal().map(f)` since this
|
||||
/// allocates only once.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T2, D>,
|
||||
@ -1481,6 +1502,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
|
||||
/// Computes a trace of a square matrix, i.e., the sum of its diagonal elements.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn trace(&self) -> T
|
||||
where
|
||||
T: Scalar + Zero + ClosedAdd,
|
||||
@ -1504,6 +1526,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
/// The symmetric part of `self`, i.e., `0.5 * (self + self.transpose())`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn symmetric_part(&self) -> OMatrix<T, D, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
@ -1520,6 +1543,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||
|
||||
/// The hermitian part of `self`, i.e., `0.5 * (self + self.adjoint())`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn hermitian_part(&self) -> OMatrix<T, D, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D>,
|
||||
@ -1542,6 +1566,7 @@ impl<T: Scalar + Zero + One, D: DimAdd<U1> + IsNotStaticOne, S: Storage<T, D, D>
|
||||
/// Yields the homogeneous matrix for this matrix, i.e., appending an additional dimension and
|
||||
/// and setting the diagonal element to `1`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>>,
|
||||
@ -1562,6 +1587,7 @@ impl<T: Scalar + Zero, D: DimAdd<U1>, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// Computes the coordinates in projective space of this vector, i.e., appends a `0` to its
|
||||
/// coordinates.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
||||
@ -1589,6 +1615,7 @@ impl<T: Scalar + Zero, D: DimAdd<U1>, S: Storage<T, D>> Vector<T, D, S> {
|
||||
impl<T: Scalar + Zero, D: DimAdd<U1>, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// Constructs a new vector of higher dimension by appending `element` to the end of `self`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
||||
@ -1891,6 +1918,7 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<T
|
||||
{
|
||||
/// The perpendicular product between two 2D column vectors, i.e. `a.x * b.y - a.y * b.x`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn perp<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> T
|
||||
where
|
||||
R2: Dim,
|
||||
@ -1920,6 +1948,7 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<T
|
||||
/// Panics if the shape is not 3D vector. In the future, this will be implemented only for
|
||||
/// dynamically-sized matrices and statically-sized 3D matrices.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn cross<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> MatrixCross<T, R, C, R2, C2>
|
||||
where
|
||||
R2: Dim,
|
||||
@ -1993,6 +2022,7 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<T
|
||||
impl<T: Scalar + Field, S: Storage<T, U3>> Vector<T, U3, S> {
|
||||
/// Computes the matrix `M` such that for all vector `v` we have `M * v == self.cross(&v)`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
|
||||
OMatrix::<T, U3, U3>::new(
|
||||
T::zero(),
|
||||
@ -2011,6 +2041,7 @@ impl<T: Scalar + Field, S: Storage<T, U3>> Vector<T, U3, S> {
|
||||
impl<T: SimdComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// The smallest angle between two vectors.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle<R2: Dim, C2: Dim, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> T::SimdRealField
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
|
@ -812,6 +812,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed
|
||||
/// by the range `cols`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slice_range<RowRange, ColRange>(
|
||||
&self,
|
||||
rows: RowRange,
|
||||
@ -830,6 +831,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Slice containing all the rows indexed by the range `rows`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rows_range<RowRange: SliceRange<R>>(
|
||||
&self,
|
||||
rows: RowRange,
|
||||
@ -839,6 +841,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Slice containing all the columns indexed by the range `rows`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn columns_range<ColRange: SliceRange<C>>(
|
||||
&self,
|
||||
cols: ColRange,
|
||||
|
@ -13,6 +13,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(Vector3::new(-1.0, -2.0, -3.0).amax(), 3.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn amax(&self) -> T
|
||||
where
|
||||
T: Zero + SimdSigned + SimdPartialOrd,
|
||||
@ -33,6 +34,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Complex::new(1.0, 3.0)).camax(), 5.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn camax(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -52,6 +54,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(Vector3::new(5u32, 2, 3).max(), 5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn max(&self) -> T
|
||||
where
|
||||
T: SimdPartialOrd + Zero,
|
||||
@ -70,6 +73,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(Vector3::new(10.0, 2.0, 30.0).amin(), 2.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn amin(&self) -> T
|
||||
where
|
||||
T: Zero + SimdPartialOrd + SimdSigned,
|
||||
@ -90,6 +94,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// Complex::new(1.0, 3.0)).camin(), 3.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn camin(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -112,6 +117,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(Vector3::new(5u32, 2, 3).min(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn min(&self) -> T
|
||||
where
|
||||
T: SimdPartialOrd + Zero,
|
||||
@ -136,6 +142,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(mat.icamax_full(), (1, 0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn icamax_full(&self) -> (usize, usize)
|
||||
where
|
||||
T: ComplexField,
|
||||
@ -172,6 +179,7 @@ impl<T: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<T, R, C>> Matri
|
||||
/// assert_eq!(mat.iamax_full(), (1, 2));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn iamax_full(&self) -> (usize, usize) {
|
||||
assert!(!self.is_empty(), "The input matrix must not be empty.");
|
||||
|
||||
@ -209,6 +217,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.icamax(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn icamax(&self) -> usize
|
||||
where
|
||||
T: ComplexField,
|
||||
@ -240,6 +249,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.argmax(), (2, 13));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn argmax(&self) -> (usize, T)
|
||||
where
|
||||
T: PartialOrd,
|
||||
@ -271,6 +281,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.imax(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn imax(&self) -> usize
|
||||
where
|
||||
T: PartialOrd,
|
||||
@ -288,6 +299,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.iamax(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn iamax(&self) -> usize
|
||||
where
|
||||
T: PartialOrd + Signed,
|
||||
@ -319,6 +331,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.argmin(), (1, -15));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn argmin(&self) -> (usize, T)
|
||||
where
|
||||
T: PartialOrd,
|
||||
@ -350,6 +363,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.imin(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn imin(&self) -> usize
|
||||
where
|
||||
T: PartialOrd,
|
||||
@ -367,6 +381,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
||||
/// assert_eq!(vec.iamin(), 0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn iamin(&self) -> usize
|
||||
where
|
||||
T: PartialOrd + Signed,
|
||||
|
@ -158,6 +158,7 @@ impl<T: SimdComplexField> Norm<T> for UniformNorm {
|
||||
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// The squared L2 norm of this vector.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn norm_squared(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -176,6 +177,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// Use `.apply_norm` to apply a custom norm.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn norm(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -187,6 +189,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// Use `.apply_metric_distance` to apply a custom norm.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn metric_distance<R2, C2, S2>(&self, rhs: &Matrix<T, R2, C2, S2>) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -211,6 +214,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(v.apply_norm(&EuclideanNorm), v.norm());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn apply_norm(&self, norm: &impl Norm<T>) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -233,6 +237,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(v1.apply_metric_distance(&v2, &EuclideanNorm), (v1 - v2).norm());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn apply_metric_distance<R2, C2, S2>(
|
||||
&self,
|
||||
rhs: &Matrix<T, R2, C2, S2>,
|
||||
@ -254,6 +259,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// This function is simply implemented as a call to `norm()`
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn magnitude(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -267,6 +273,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// This function is simply implemented as a call to `norm_squared()`
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn magnitude_squared(&self) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -298,6 +305,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// The Lp norm of this matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lp_norm(&self, p: i32) -> T::SimdRealField
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -340,8 +348,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
|
||||
#[must_use = "This function does not mutate self but returns a new clamped version."]
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self but returns a new clamped version."]
|
||||
pub fn cap_magnitude(&self, max: T::RealField) -> OMatrix<T, R, C>
|
||||
where
|
||||
T: ComplexField,
|
||||
@ -357,8 +365,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
|
||||
#[must_use = "This function does not mutate self but returns a new clamped version."]
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self but returns a new clamped version."]
|
||||
pub fn simd_cap_magnitude(&self, max: T::SimdRealField) -> OMatrix<T, R, C>
|
||||
where
|
||||
T: SimdComplexField,
|
||||
|
@ -676,6 +676,7 @@ where
|
||||
{
|
||||
/// Equivalent to `self.transpose() * rhs`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn tr_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
||||
where
|
||||
SB: Storage<T, R2, C2>,
|
||||
@ -692,6 +693,7 @@ where
|
||||
|
||||
/// Equivalent to `self.adjoint() * rhs`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn ad_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
||||
where
|
||||
T: SimdComplexField,
|
||||
@ -801,6 +803,7 @@ where
|
||||
|
||||
/// The kronecker product of two matrices (aka. tensor product of the corresponding linear
|
||||
/// maps).
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn kronecker<R2: Dim, C2: Dim, SB>(
|
||||
&self,
|
||||
rhs: &Matrix<T, R2, C2, SB>,
|
||||
|
@ -20,6 +20,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(mat.len(), 12);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn len(&self) -> usize {
|
||||
let (nrows, ncols) = self.shape();
|
||||
nrows * ncols
|
||||
@ -35,12 +36,14 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert!(!mat.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Indicates if this is a square matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_square(&self) -> bool {
|
||||
let (nrows, ncols) = self.shape();
|
||||
nrows == ncols
|
||||
@ -52,6 +55,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// If the matrix is diagonal, this checks that diagonal elements (i.e. at coordinates `(i, i)`
|
||||
/// for i from `0` to `min(R, C)`) are equal one; and that all other elements are zero.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_identity(&self, eps: T::Epsilon) -> bool
|
||||
where
|
||||
T: Zero + One + RelativeEq,
|
||||
@ -112,6 +116,7 @@ impl<T: ComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// In this definition `Id` is approximately equal to the identity matrix with a relative error
|
||||
/// equal to `eps`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_orthogonal(&self, eps: T::Epsilon) -> bool
|
||||
where
|
||||
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
|
||||
@ -129,6 +134,7 @@ where
|
||||
{
|
||||
/// Checks that this matrix is orthogonal and has a determinant equal to 1.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_special_orthogonal(&self, eps: T) -> bool
|
||||
where
|
||||
D: DimMin<D, Output = D>,
|
||||
@ -139,6 +145,7 @@ where
|
||||
|
||||
/// Returns `true` if this matrix is invertible.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
// TODO: improve this?
|
||||
self.clone_owned().try_inverse().is_some()
|
||||
|
@ -9,6 +9,7 @@ impl<T: Scalar, 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]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn compress_rows(
|
||||
&self,
|
||||
f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
|
||||
@ -35,6 +36,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
///
|
||||
/// This is the same as `self.compress_rows(f).transpose()`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn compress_rows_tr(
|
||||
&self,
|
||||
f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
|
||||
@ -58,6 +60,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
|
||||
/// Returns a column vector resulting from the folding of `f` on each column of this matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn compress_columns(
|
||||
&self,
|
||||
init: OVector<T, R>,
|
||||
@ -95,6 +98,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.sum(), 21.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sum(&self) -> T
|
||||
where
|
||||
T: ClosedAdd + Zero,
|
||||
@ -120,6 +124,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(mint.row_sum(), RowVector2::new(9,12));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_sum(&self) -> RowOVector<T, C>
|
||||
where
|
||||
T: ClosedAdd + Zero,
|
||||
@ -144,6 +149,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(mint.row_sum_tr(), Vector2::new(9,12));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_sum_tr(&self) -> OVector<T, C>
|
||||
where
|
||||
T: ClosedAdd + Zero,
|
||||
@ -168,6 +174,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(mint.column_sum(), Vector3::new(3,7,11));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn column_sum(&self) -> OVector<T, R>
|
||||
where
|
||||
T: ClosedAdd + Zero,
|
||||
@ -197,6 +204,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_relative_eq!(m.variance(), 35.0 / 12.0, epsilon = 1.0e-8);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn variance(&self) -> T
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -226,6 +234,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.row_variance(), RowVector3::new(2.25, 2.25, 2.25));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_variance(&self) -> RowOVector<T, C>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -246,6 +255,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.row_variance_tr(), Vector3::new(2.25, 2.25, 2.25));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_variance_tr(&self) -> OVector<T, C>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -267,6 +277,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_relative_eq!(m.column_variance(), Vector2::new(2.0 / 3.0, 2.0 / 3.0), epsilon = 1.0e-8);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn column_variance(&self) -> OVector<T, R>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -306,6 +317,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.mean(), 3.5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn mean(&self) -> T
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -331,6 +343,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.row_mean(), RowVector3::new(2.5, 3.5, 4.5));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_mean(&self) -> RowOVector<T, C>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -351,6 +364,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.row_mean_tr(), Vector3::new(2.5, 3.5, 4.5));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn row_mean_tr(&self) -> OVector<T, C>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
@ -371,6 +385,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||
/// assert_eq!(m.column_mean(), Vector2::new(2.0, 5.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn column_mean(&self) -> OVector<T, R>
|
||||
where
|
||||
T: Field + SupersetOf<f64>,
|
||||
|
@ -8,6 +8,7 @@ macro_rules! impl_swizzle {
|
||||
$(
|
||||
/// Builds a new vector from components of `self`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn $name(&self) -> $Result<T>
|
||||
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||
$Result::new($(self[$i].inlined_clone()),*)
|
||||
|
@ -95,6 +95,7 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
|
||||
|
||||
/// The underlying data storage.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_vec(&self) -> &Vec<T> {
|
||||
&self.data
|
||||
}
|
||||
@ -129,12 +130,14 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
|
||||
|
||||
/// The number of elements on the underlying vector.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
/// Returns true if the underlying vector contains no elements.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
@ -232,6 +232,7 @@ where
|
||||
/// ));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||
self * (T::one() - t) + other * t
|
||||
}
|
||||
@ -381,6 +382,7 @@ where
|
||||
/// ));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn dual_quaternion(&self) -> &DualQuaternion<T> {
|
||||
self.as_ref()
|
||||
}
|
||||
@ -463,7 +465,6 @@ where
|
||||
/// assert_relative_eq!(inv * unit, UnitDualQuaternion::identity(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
||||
pub fn inverse_mut(&mut self) {
|
||||
let quat = self.as_mut_unchecked();
|
||||
quat.real = Unit::new_unchecked(quat.real).inverse().into_inner();
|
||||
@ -486,6 +487,7 @@ where
|
||||
/// assert_relative_eq!(dq_to * dq1, dq2, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn isometry_to(&self, other: &Self) -> Self {
|
||||
other / self
|
||||
}
|
||||
@ -518,6 +520,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp(&self, other: &Self, t: T) -> DualQuaternion<T> {
|
||||
self.as_ref().lerp(other.as_ref(), t)
|
||||
}
|
||||
@ -546,6 +549,7 @@ where
|
||||
/// ), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
||||
let mut res = self.lerp(other, t);
|
||||
let _ = res.normalize_mut();
|
||||
@ -581,6 +585,7 @@ where
|
||||
/// );
|
||||
/// assert_relative_eq!(dq.translation().vector.y, 3.0, epsilon = 1.0e-6);
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sclerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -600,6 +605,7 @@ where
|
||||
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
||||
/// must be to return `None`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_sclerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -667,6 +673,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rotation(&self) -> UnitQuaternion<T> {
|
||||
Unit::new_unchecked(self.as_ref().real)
|
||||
}
|
||||
@ -686,6 +693,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn translation(&self) -> Translation3<T> {
|
||||
let two = T::one() + T::one();
|
||||
Translation3::from(
|
||||
@ -712,6 +720,7 @@ where
|
||||
/// assert_relative_eq!(iso.translation.vector, translation, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_isometry(&self) -> Isometry3<T> {
|
||||
Isometry3::from_parts(self.translation(), self.rotation())
|
||||
}
|
||||
@ -735,6 +744,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||
self * pt
|
||||
}
|
||||
@ -758,6 +768,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||
self * v
|
||||
}
|
||||
@ -781,6 +792,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||
self.inverse() * pt
|
||||
}
|
||||
@ -805,6 +817,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -830,6 +843,7 @@ where
|
||||
/// );
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -857,6 +871,7 @@ where
|
||||
/// assert_relative_eq!(dq.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||
self.to_isometry().to_homogeneous()
|
||||
}
|
||||
|
@ -267,6 +267,7 @@ where
|
||||
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
|
||||
let inv_rot1 = self.rotation.inverse();
|
||||
let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone();
|
||||
@ -384,6 +385,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, 2.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self * pt
|
||||
}
|
||||
@ -407,6 +409,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self * v
|
||||
}
|
||||
@ -429,6 +432,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(0.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self.rotation
|
||||
.inverse_transform_point(&(pt - &self.translation.vector))
|
||||
@ -453,6 +457,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self.rotation.inverse_transform_vector(v)
|
||||
}
|
||||
@ -476,6 +481,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
||||
self.rotation.inverse_transform_unit_vector(v)
|
||||
}
|
||||
@ -505,6 +511,7 @@ impl<T: SimdRealField, R, const D: usize> Isometry<T, R, D> {
|
||||
/// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
@ -536,6 +543,7 @@ impl<T: SimdRealField, R, const D: usize> Isometry<T, R, D> {
|
||||
/// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_matrix(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
|
@ -26,6 +26,7 @@ impl<T: SimdRealField> Isometry3<T> {
|
||||
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -59,6 +60,7 @@ impl<T: SimdRealField> Isometry3<T> {
|
||||
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -94,6 +96,7 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
|
||||
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -127,6 +130,7 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
|
||||
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -163,6 +167,7 @@ impl<T: SimdRealField> Isometry2<T> {
|
||||
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -199,6 +204,7 @@ impl<T: SimdRealField> IsometryMatrix2<T> {
|
||||
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
|
@ -188,6 +188,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.as_matrix() * inv, Matrix4::identity());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse(&self) -> Matrix4<T> {
|
||||
let mut res = self.to_homogeneous();
|
||||
|
||||
@ -221,6 +222,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_eq!(proj.to_homogeneous(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||
self.matrix
|
||||
}
|
||||
@ -240,6 +242,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_eq!(*proj.as_matrix(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_matrix(&self) -> &Matrix4<T> {
|
||||
&self.matrix
|
||||
}
|
||||
@ -253,6 +256,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_eq!(proj.as_projective().to_homogeneous(), proj.to_homogeneous());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_projective(&self) -> &Projective3<T> {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
@ -266,6 +270,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_eq!(proj.to_projective().to_homogeneous(), proj.to_homogeneous());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_projective(&self) -> Projective3<T> {
|
||||
Projective3::from_matrix_unchecked(self.matrix)
|
||||
}
|
||||
@ -310,6 +315,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.left(), 10.0, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn left(&self) -> T {
|
||||
(-T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
||||
}
|
||||
@ -326,6 +332,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.right(), 1.0, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn right(&self) -> T {
|
||||
(T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
||||
}
|
||||
@ -342,6 +349,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.bottom(), 20.0, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn bottom(&self) -> T {
|
||||
(-T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
||||
}
|
||||
@ -358,6 +366,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.top(), 2.0, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn top(&self) -> T {
|
||||
(T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
||||
}
|
||||
@ -374,6 +383,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.znear(), 1000.0, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn znear(&self) -> T {
|
||||
(T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
||||
}
|
||||
@ -390,6 +400,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.zfar(), 0.1, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn zfar(&self) -> T {
|
||||
(-T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
||||
}
|
||||
@ -422,6 +433,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.project_point(&p8), Point3::new( 1.0, 1.0, 1.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||
Point3::new(
|
||||
self.matrix[(0, 0)] * p[0] + self.matrix[(0, 3)],
|
||||
@ -457,6 +469,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.unproject_point(&p8), Point3::new(10.0, 20.0, -1000.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||
Point3::new(
|
||||
(p[0] - self.matrix[(0, 3)]) / self.matrix[(0, 0)],
|
||||
@ -485,6 +498,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||
/// assert_relative_eq!(proj.project_vector(&v3), Vector3::z() * -2.0 / 999.9);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
||||
where
|
||||
SB: Storage<T, U3>,
|
||||
|
@ -104,6 +104,7 @@ impl<T: RealField> Perspective3<T> {
|
||||
|
||||
/// Retrieves the inverse of the underlying homogeneous matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse(&self) -> Matrix4<T> {
|
||||
let mut res = self.to_homogeneous();
|
||||
|
||||
@ -123,24 +124,28 @@ impl<T: RealField> Perspective3<T> {
|
||||
|
||||
/// Computes the corresponding homogeneous matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||
self.matrix.clone_owned()
|
||||
}
|
||||
|
||||
/// A reference to the underlying homogeneous transformation matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_matrix(&self) -> &Matrix4<T> {
|
||||
&self.matrix
|
||||
}
|
||||
|
||||
/// A reference to this transformation seen as a `Projective3`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_projective(&self) -> &Projective3<T> {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// This transformation seen as a `Projective3`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_projective(&self) -> Projective3<T> {
|
||||
Projective3::from_matrix_unchecked(self.matrix)
|
||||
}
|
||||
@ -161,18 +166,21 @@ impl<T: RealField> Perspective3<T> {
|
||||
|
||||
/// Gets the `width / height` aspect ratio of the view frustum.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn aspect(&self) -> T {
|
||||
self.matrix[(1, 1)] / self.matrix[(0, 0)]
|
||||
}
|
||||
|
||||
/// Gets the y field of view of the view frustum.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn fovy(&self) -> T {
|
||||
(T::one() / self.matrix[(1, 1)]).atan() * crate::convert(2.0)
|
||||
}
|
||||
|
||||
/// Gets the near plane offset of the view frustum.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn znear(&self) -> T {
|
||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
||||
|
||||
@ -182,6 +190,7 @@ impl<T: RealField> Perspective3<T> {
|
||||
|
||||
/// Gets the far plane offset of the view frustum.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn zfar(&self) -> T {
|
||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
||||
|
||||
@ -193,6 +202,7 @@ impl<T: RealField> Perspective3<T> {
|
||||
// TODO: when we get specialization, specialize the Mul impl instead.
|
||||
/// Projects a point. Faster than matrix multiplication.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||
let inverse_denom = -T::one() / p[2];
|
||||
Point3::new(
|
||||
@ -204,6 +214,7 @@ impl<T: RealField> Perspective3<T> {
|
||||
|
||||
/// Un-projects a point. Faster than multiplication by the matrix inverse.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||
let inverse_denom = self.matrix[(2, 3)] / (p[2] + self.matrix[(2, 2)]);
|
||||
|
||||
@ -217,6 +228,7 @@ impl<T: RealField> Perspective3<T> {
|
||||
// TODO: when we get specialization, specialize the Mul impl instead.
|
||||
/// Projects a vector. Faster than matrix multiplication.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
||||
where
|
||||
SB: Storage<T, U3>,
|
||||
|
@ -122,6 +122,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
||||
/// assert_eq!(p.map(|e| e as u32), Point3::new(1, 2, 3));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, f: F) -> Point<T2, D> {
|
||||
self.coords.map(f).into()
|
||||
}
|
||||
@ -161,6 +162,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
||||
/// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: One,
|
||||
@ -199,6 +201,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
||||
/// assert_eq!(p.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn len(&self) -> usize {
|
||||
self.coords.len()
|
||||
}
|
||||
@ -212,6 +215,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
||||
/// assert!(!p.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
@ -246,6 +250,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
||||
|
||||
/// Gets a reference to i-th element of this point without bound-checking.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub unsafe fn get_unchecked(&self, i: usize) -> &T {
|
||||
self.coords.vget_unchecked(i)
|
||||
}
|
||||
@ -378,18 +383,21 @@ impl<T: Scalar + PartialOrd, const D: usize> PartialOrd for Point<T, D> {
|
||||
impl<T: Scalar + SimdPartialOrd, const D: usize> Point<T, D> {
|
||||
/// Computes the infimum (aka. componentwise min) of two points.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inf(&self, other: &Self) -> Point<T, D> {
|
||||
self.coords.inf(&other.coords).into()
|
||||
}
|
||||
|
||||
/// Computes the supremum (aka. componentwise max) of two points.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sup(&self, other: &Self) -> Point<T, D> {
|
||||
self.coords.sup(&other.coords).into()
|
||||
}
|
||||
|
||||
/// Computes the (infimum, supremum) of two points.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inf_sup(&self, other: &Self) -> (Point<T, D>, Point<T, D>) {
|
||||
let (inf, sup) = self.coords.inf_sup(&other.coords);
|
||||
(inf.into(), sup.into())
|
||||
|
@ -191,6 +191,7 @@ where
|
||||
|
||||
/// The imaginary part of this quaternion.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn imag(&self) -> Vector3<T> {
|
||||
self.coords.xyz()
|
||||
}
|
||||
@ -223,6 +224,7 @@ where
|
||||
/// assert_eq!(q1.lerp(&q2, 0.1), Quaternion::new(1.9, 3.8, 5.7, 7.6));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||
self * (T::one() - t) + other * t
|
||||
}
|
||||
@ -238,6 +240,7 @@ where
|
||||
/// assert_eq!(q.vector()[2], 4.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn vector(&self) -> MatrixSlice<T, U3, U1, RStride<T, U4, U1>, CStride<T, U4, U1>> {
|
||||
self.coords.fixed_rows::<3>(0)
|
||||
}
|
||||
@ -251,6 +254,7 @@ where
|
||||
/// assert_eq!(q.scalar(), 1.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scalar(&self) -> T {
|
||||
self.coords[3]
|
||||
}
|
||||
@ -266,6 +270,7 @@ where
|
||||
/// assert_eq!(*q.as_vector(), Vector4::new(2.0, 3.0, 4.0, 1.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn as_vector(&self) -> &Vector4<T> {
|
||||
&self.coords
|
||||
}
|
||||
@ -280,6 +285,7 @@ where
|
||||
/// assert_relative_eq!(q.norm(), 5.47722557, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn norm(&self) -> T {
|
||||
self.coords.norm()
|
||||
}
|
||||
@ -297,6 +303,7 @@ where
|
||||
/// assert_relative_eq!(q.magnitude(), 5.47722557, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn magnitude(&self) -> T {
|
||||
self.norm()
|
||||
}
|
||||
@ -310,6 +317,7 @@ where
|
||||
/// assert_eq!(q.magnitude_squared(), 30.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn norm_squared(&self) -> T {
|
||||
self.coords.norm_squared()
|
||||
}
|
||||
@ -326,6 +334,7 @@ where
|
||||
/// assert_eq!(q.magnitude_squared(), 30.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn magnitude_squared(&self) -> T {
|
||||
self.norm_squared()
|
||||
}
|
||||
@ -340,6 +349,7 @@ where
|
||||
/// assert_eq!(q1.dot(&q2), 70.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn dot(&self, rhs: &Self) -> T {
|
||||
self.coords.dot(&rhs.coords)
|
||||
}
|
||||
@ -409,6 +419,7 @@ where
|
||||
/// let result = a.inner(&b);
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inner(&self, other: &Self) -> Self {
|
||||
(self * other + other * self).half()
|
||||
}
|
||||
@ -428,6 +439,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn outer(&self, other: &Self) -> Self {
|
||||
#[allow(clippy::eq_op)]
|
||||
(self * other - other * self).half()
|
||||
@ -448,6 +460,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn project(&self, other: &Self) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -470,6 +483,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn reject(&self, other: &Self) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -492,6 +506,7 @@ where
|
||||
/// assert_eq!(half_ang, f32::consts::FRAC_PI_2);
|
||||
/// assert_eq!(axis, Some(Vector3::x_axis()));
|
||||
/// ```
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn polar_decomposition(&self) -> (T, T, Option<Unit<Vector3<T>>>)
|
||||
where
|
||||
T: RealField,
|
||||
@ -519,6 +534,7 @@ where
|
||||
/// assert_relative_eq!(q.ln(), Quaternion::new(1.683647, 1.190289, 0.0, 0.0), epsilon = 1.0e-6)
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn ln(&self) -> Self {
|
||||
let n = self.norm();
|
||||
let v = self.vector();
|
||||
@ -537,6 +553,7 @@ where
|
||||
/// assert_relative_eq!(q.exp(), Quaternion::new(2.0, 5.0, 0.0, 0.0), epsilon = 1.0e-5)
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn exp(&self) -> Self {
|
||||
self.exp_eps(T::simd_default_epsilon())
|
||||
}
|
||||
@ -556,6 +573,7 @@ where
|
||||
/// assert_eq!(q.exp_eps(1.0e-6), Quaternion::identity());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn exp_eps(&self, eps: T) -> Self {
|
||||
let v = self.vector();
|
||||
let nn = v.norm_squared();
|
||||
@ -579,6 +597,7 @@ where
|
||||
/// assert_relative_eq!(q.powf(1.5), Quaternion::new( -6.2576659, 4.1549037, 6.2323556, 8.3098075), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn powf(&self, n: T) -> Self {
|
||||
(self.ln() * n).exp()
|
||||
}
|
||||
@ -674,18 +693,21 @@ where
|
||||
|
||||
/// Calculates square of a quaternion.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn squared(&self) -> Self {
|
||||
self * self
|
||||
}
|
||||
|
||||
/// Divides quaternion into two.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn half(&self) -> Self {
|
||||
self / crate::convert(2.0f64)
|
||||
}
|
||||
|
||||
/// Calculates square root.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sqrt(&self) -> Self {
|
||||
self.powf(crate::convert(0.5))
|
||||
}
|
||||
@ -694,12 +716,14 @@ where
|
||||
///
|
||||
/// A quaternion is pure if it has no real part (`self.w == 0.0`).
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_pure(&self) -> bool {
|
||||
self.w.is_zero()
|
||||
}
|
||||
|
||||
/// Convert quaternion to pure quaternion.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn pure(&self) -> Self {
|
||||
Self::from_imag(self.imag())
|
||||
}
|
||||
@ -708,6 +732,7 @@ where
|
||||
///
|
||||
/// Calculates B<sup>-1</sup> * A where A = self, B = other.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn left_div(&self, other: &Self) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -730,6 +755,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn right_div(&self, other: &Self) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -749,6 +775,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn cos(&self) -> Self {
|
||||
let z = self.imag().magnitude();
|
||||
let w = -self.w.simd_sin() * z.simd_sinhc();
|
||||
@ -766,6 +793,7 @@ where
|
||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn acos(&self) -> Self {
|
||||
let u = Self::from_imag(self.imag().normalize());
|
||||
let identity = Self::identity();
|
||||
@ -787,6 +815,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sin(&self) -> Self {
|
||||
let z = self.imag().magnitude();
|
||||
let w = self.w.simd_cos() * z.simd_sinhc();
|
||||
@ -804,6 +833,7 @@ where
|
||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn asin(&self) -> Self {
|
||||
let u = Self::from_imag(self.imag().normalize());
|
||||
let identity = Self::identity();
|
||||
@ -825,6 +855,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn tan(&self) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -843,6 +874,7 @@ where
|
||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn atan(&self) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -867,6 +899,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sinh(&self) -> Self {
|
||||
(self.exp() - (-self).exp()).half()
|
||||
}
|
||||
@ -883,6 +916,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn asinh(&self) -> Self {
|
||||
let identity = Self::identity();
|
||||
(self + (identity + self.squared()).sqrt()).ln()
|
||||
@ -900,6 +934,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn cosh(&self) -> Self {
|
||||
(self.exp() + (-self).exp()).half()
|
||||
}
|
||||
@ -916,6 +951,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn acosh(&self) -> Self {
|
||||
let identity = Self::identity();
|
||||
(self + (self + identity).sqrt() * (self - identity).sqrt()).ln()
|
||||
@ -933,6 +969,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn tanh(&self) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -952,6 +989,7 @@ where
|
||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn atanh(&self) -> Self {
|
||||
let identity = Self::identity();
|
||||
((identity + self).ln() - (identity - self).ln()).half()
|
||||
@ -1069,6 +1107,7 @@ where
|
||||
/// assert_eq!(rot.angle(), 1.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle(&self) -> T {
|
||||
let w = self.quaternion().scalar().simd_abs();
|
||||
self.quaternion().imag().norm().simd_atan2(w) * crate::convert(2.0f64)
|
||||
@ -1085,6 +1124,7 @@ where
|
||||
/// assert_eq!(*axis.quaternion(), Quaternion::new(1.0, 0.0, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn quaternion(&self) -> &Quaternion<T> {
|
||||
self.as_ref()
|
||||
}
|
||||
@ -1133,6 +1173,7 @@ where
|
||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle_to(&self, other: &Self) -> T {
|
||||
let delta = self.rotation_to(other);
|
||||
delta.angle()
|
||||
@ -1152,6 +1193,7 @@ where
|
||||
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||
other / self
|
||||
}
|
||||
@ -1168,6 +1210,7 @@ where
|
||||
/// assert_eq!(q1.lerp(&q2, 0.1), Quaternion::new(0.9, 0.1, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn lerp(&self, other: &Self, t: T) -> Quaternion<T> {
|
||||
self.as_ref().lerp(other.as_ref(), t)
|
||||
}
|
||||
@ -1184,6 +1227,7 @@ where
|
||||
/// assert_eq!(q1.nlerp(&q2, 0.1), UnitQuaternion::new_normalize(Quaternion::new(0.9, 0.1, 0.0, 0.0)));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
||||
let mut res = self.lerp(other, t);
|
||||
let _ = res.normalize_mut();
|
||||
@ -1209,6 +1253,7 @@ where
|
||||
/// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -1228,6 +1273,7 @@ where
|
||||
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
||||
/// must be to return `None`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
@ -1287,6 +1333,7 @@ where
|
||||
/// assert!(rot.axis().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
||||
where
|
||||
T: RealField,
|
||||
@ -1311,6 +1358,7 @@ where
|
||||
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scaled_axis(&self) -> Vector3<T>
|
||||
where
|
||||
T: RealField,
|
||||
@ -1339,6 +1387,7 @@ where
|
||||
/// assert!(rot.axis_angle().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
||||
where
|
||||
T: RealField,
|
||||
@ -1350,6 +1399,7 @@ where
|
||||
///
|
||||
/// Note that this function yields a `Quaternion<T>` because it loses the unit property.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn exp(&self) -> Quaternion<T> {
|
||||
self.as_ref().exp()
|
||||
}
|
||||
@ -1369,6 +1419,7 @@ where
|
||||
/// assert_relative_eq!(q.ln().vector().into_owned(), axisangle, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn ln(&self) -> Quaternion<T>
|
||||
where
|
||||
T: RealField,
|
||||
@ -1397,6 +1448,7 @@ where
|
||||
/// assert_eq!(pow.angle(), 2.4);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn powf(&self, n: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -1425,6 +1477,7 @@ where
|
||||
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_rotation_matrix(&self) -> Rotation<T, 3> {
|
||||
let i = self.as_ref()[0];
|
||||
let j = self.as_ref()[1];
|
||||
@ -1482,6 +1535,7 @@ where
|
||||
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn euler_angles(&self) -> (T, T, T)
|
||||
where
|
||||
T: RealField,
|
||||
@ -1506,6 +1560,7 @@ where
|
||||
/// assert_relative_eq!(rot.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||
self.to_rotation_matrix().to_homogeneous()
|
||||
}
|
||||
@ -1526,6 +1581,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||
self * pt
|
||||
}
|
||||
@ -1546,6 +1602,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||
self * v
|
||||
}
|
||||
@ -1566,6 +1623,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
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
|
||||
// the inverse transformation explicitly here) ?
|
||||
@ -1588,6 +1646,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -1608,6 +1667,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -1616,6 +1676,7 @@ where
|
||||
///
|
||||
/// This is faster, but approximate, way to compute `UnitQuaternion::new(axisangle) * self`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
|
||||
let half: T = crate::convert(0.5);
|
||||
let q1 = self.into_inner();
|
||||
|
@ -34,6 +34,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||
}
|
||||
|
||||
/// The reflexion axis.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis(&self) -> &Vector<T, D, S> {
|
||||
&self.axis
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
/// assert_eq!(*rot.matrix(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn matrix(&self) -> &SMatrix<T, D, D> {
|
||||
&self.matrix
|
||||
}
|
||||
@ -262,6 +263,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||
/// assert_eq!(rot.to_homogeneous(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: Zero + One,
|
||||
@ -403,6 +405,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self * pt
|
||||
}
|
||||
@ -422,6 +425,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self * v
|
||||
}
|
||||
@ -441,6 +445,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
Point::from(self.inverse_transform_vector(&pt.coords))
|
||||
}
|
||||
@ -460,6 +465,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self.matrix().tr_mul(v)
|
||||
}
|
||||
@ -479,6 +485,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
||||
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T::Element: SimdRealField,
|
||||
@ -47,6 +48,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -67,6 +69,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// * `epsilon`: the value below which the sinus of the angle separating both rotations
|
||||
/// must be to return `None`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||
where
|
||||
T: RealField,
|
||||
|
@ -186,6 +186,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||
other * self.inverse()
|
||||
}
|
||||
@ -215,6 +216,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn powf(&self, n: T) -> Self {
|
||||
Self::new(self.angle() * n)
|
||||
}
|
||||
@ -232,6 +234,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// assert_relative_eq!(rot.angle(), 1.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle(&self) -> T {
|
||||
self.matrix()[(1, 0)].simd_atan2(self.matrix()[(0, 0)])
|
||||
}
|
||||
@ -247,6 +250,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle_to(&self, other: &Self) -> T {
|
||||
self.rotation_to(other).angle()
|
||||
}
|
||||
@ -256,6 +260,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||
/// This is generally used in the context of generic programming. Using
|
||||
/// the `.angle()` method instead is more common.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scaled_axis(&self) -> SVector<T, 1> {
|
||||
Vector1::new(self.angle())
|
||||
}
|
||||
@ -640,6 +645,7 @@ where
|
||||
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||
other * self.inverse()
|
||||
}
|
||||
@ -659,6 +665,7 @@ where
|
||||
/// assert_eq!(pow.angle(), 2.4);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn powf(&self, n: T) -> Self
|
||||
where
|
||||
T: RealField,
|
||||
@ -765,6 +772,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert_relative_eq!(rot.angle(), 1.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle(&self) -> T {
|
||||
((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - T::one())
|
||||
/ crate::convert(2.0))
|
||||
@ -787,6 +795,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert!(rot.axis().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
||||
where
|
||||
T: RealField,
|
||||
@ -811,6 +820,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scaled_axis(&self) -> Vector3<T>
|
||||
where
|
||||
T: RealField,
|
||||
@ -842,6 +852,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert!(rot.axis_angle().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
||||
where
|
||||
T: RealField,
|
||||
@ -864,6 +875,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle_to(&self, other: &Self) -> T
|
||||
where
|
||||
T::Element: SimdRealField,
|
||||
@ -896,6 +908,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||
/// assert_relative_eq!(euler.1, 0.2, epsilon = 1.0e-6);
|
||||
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn euler_angles(&self) -> (T, T, T)
|
||||
where
|
||||
T: RealField,
|
||||
|
@ -122,6 +122,7 @@ where
|
||||
impl<T: Scalar, R, const D: usize> Similarity<T, R, D> {
|
||||
/// The scaling factor of this similarity transformation.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scaling(&self) -> T {
|
||||
self.scaling.inlined_clone()
|
||||
}
|
||||
@ -248,6 +249,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(19.0, 17.0, -9.0), epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self * pt
|
||||
}
|
||||
@ -269,6 +271,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self * v
|
||||
}
|
||||
@ -289,6 +292,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point3::new(-1.5, 1.5, 1.5), epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self.isometry.inverse_transform_point(pt) / self.scaling()
|
||||
}
|
||||
@ -309,6 +313,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self.isometry.inverse_transform_vector(v) / self.scaling()
|
||||
}
|
||||
@ -321,6 +326,7 @@ where
|
||||
impl<T: SimdRealField, R, const D: usize> Similarity<T, R, D> {
|
||||
/// Converts this similarity into its equivalent homogeneous transformation matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
Const<D>: DimNameAdd<U1>,
|
||||
|
@ -8,6 +8,7 @@ macro_rules! impl_swizzle {
|
||||
$(
|
||||
/// Builds a new point from components of `self`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn $name(&self) -> $Result<T>
|
||||
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||
$Result::new($(self[$i].inlined_clone()),*)
|
||||
|
@ -301,6 +301,7 @@ where
|
||||
/// assert_eq!(*t.matrix(), m);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn matrix(&self) -> &OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
||||
&self.matrix
|
||||
}
|
||||
@ -367,6 +368,7 @@ where
|
||||
/// assert_eq!(t.into_inner(), m);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
||||
self.matrix().clone_owned()
|
||||
}
|
||||
@ -498,6 +500,7 @@ where
|
||||
///
|
||||
/// This is the same as the multiplication `self * pt`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self * pt
|
||||
}
|
||||
@ -507,6 +510,7 @@ where
|
||||
///
|
||||
/// This is the same as the multiplication `self * v`.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self * v
|
||||
}
|
||||
@ -524,6 +528,7 @@ where
|
||||
/// This may be cheaper than inverting the transformation and transforming
|
||||
/// the point.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
self.clone().inverse() * pt
|
||||
}
|
||||
@ -532,6 +537,7 @@ where
|
||||
/// This may be cheaper than inverting the transformation and transforming
|
||||
/// the vector.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||
self.clone().inverse() * v
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
|
||||
/// assert_eq!(t.to_homogeneous(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||
where
|
||||
T: Zero + One,
|
||||
@ -241,6 +242,7 @@ impl<T: Scalar + ClosedAdd, const D: usize> Translation<T, D> {
|
||||
/// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.0));
|
||||
/// assert_eq!(transformed_point, Point3::new(5.0, 7.0, 9.0));
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
pt + &self.vector
|
||||
}
|
||||
@ -256,6 +258,7 @@ impl<T: Scalar + ClosedSub, const D: usize> Translation<T, D> {
|
||||
/// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 5.0, 6.0));
|
||||
/// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0));
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||
pt - &self.vector
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ where
|
||||
/// assert_eq!(rot.angle(), 1.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle(&self) -> T {
|
||||
self.im.simd_atan2(self.re)
|
||||
}
|
||||
@ -98,6 +99,7 @@ where
|
||||
/// assert_eq!(rot.sin_angle(), angle.sin());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn sin_angle(&self) -> T {
|
||||
self.im
|
||||
}
|
||||
@ -112,6 +114,7 @@ where
|
||||
/// assert_eq!(rot.cos_angle(),angle.cos());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn cos_angle(&self) -> T {
|
||||
self.re
|
||||
}
|
||||
@ -121,6 +124,7 @@ where
|
||||
/// This is generally used in the context of generic programming. Using
|
||||
/// the `.angle()` method instead is more common.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn scaled_axis(&self) -> Vector1<T> {
|
||||
Vector1::new(self.angle())
|
||||
}
|
||||
@ -131,6 +135,7 @@ where
|
||||
/// the `.angle()` method instead is more common.
|
||||
/// Returns `None` if the angle is zero.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn axis_angle(&self) -> Option<(Unit<Vector1<T>>, T)>
|
||||
where
|
||||
T: RealField,
|
||||
@ -157,6 +162,7 @@ where
|
||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn angle_to(&self, other: &Self) -> T {
|
||||
let delta = self.rotation_to(other);
|
||||
delta.angle()
|
||||
@ -254,6 +260,7 @@ where
|
||||
/// assert_eq!(rot.to_rotation_matrix(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_rotation_matrix(&self) -> Rotation2<T> {
|
||||
let r = self.re;
|
||||
let i = self.im;
|
||||
@ -274,6 +281,7 @@ where
|
||||
/// assert_eq!(rot.to_homogeneous(), expected);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn to_homogeneous(&self) -> Matrix3<T> {
|
||||
self.to_rotation_matrix().to_homogeneous()
|
||||
}
|
||||
@ -298,6 +306,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point2::new(-2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
||||
self * pt
|
||||
}
|
||||
@ -316,6 +325,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector2::new(-2.0, 1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
||||
self * v
|
||||
}
|
||||
@ -332,6 +342,7 @@ where
|
||||
/// assert_relative_eq!(transformed_point, Point2::new(2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
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
|
||||
// the inverse transformation explicitly here) ?
|
||||
@ -350,6 +361,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, Vector2::new(2.0, -1.0), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -366,6 +378,7 @@ where
|
||||
/// assert_relative_eq!(transformed_vector, -Vector2::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<T>>) -> Unit<Vector2<T>> {
|
||||
self.inverse() * v
|
||||
}
|
||||
@ -392,6 +405,7 @@ where
|
||||
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn slerp(&self, other: &Self, t: T) -> Self {
|
||||
Self::new(self.angle() * (T::one() - t) + other.angle() * t)
|
||||
}
|
||||
|
@ -148,6 +148,7 @@ where
|
||||
/// assert_eq!(*rot.complex(), Complex::new(angle.cos(), angle.sin()));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn complex(&self) -> &Complex<T> {
|
||||
self.as_ref()
|
||||
}
|
||||
@ -244,6 +245,7 @@ where
|
||||
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||
other / self
|
||||
}
|
||||
@ -262,6 +264,7 @@ where
|
||||
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn powf(&self, n: T) -> Self {
|
||||
Self::from_angle(self.angle() * n)
|
||||
}
|
||||
|
@ -153,6 +153,7 @@ where
|
||||
|
||||
/// Indicates whether this decomposition contains an upper-diagonal matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_upper_diagonal(&self) -> bool {
|
||||
self.upper_diagonal
|
||||
}
|
||||
@ -188,6 +189,7 @@ where
|
||||
|
||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn d(&self) -> OMatrix<T, DimMinimum<R, C>, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, DimMinimum<R, C>>,
|
||||
@ -207,6 +209,7 @@ where
|
||||
/// Computes the orthogonal matrix `U` of this `U * D * V` decomposition.
|
||||
// TODO: code duplication with householder::assemble_q.
|
||||
// Except that we are returning a rectangular matrix here.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn u(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||
@ -237,6 +240,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the orthogonal matrix `V_t` of this `U * D * V_t` decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn v_t(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
@ -274,6 +278,7 @@ where
|
||||
}
|
||||
|
||||
/// The diagonal part of this decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn diagonal(&self) -> OVector<T::RealField, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T::RealField, DimMinimum<R, C>>,
|
||||
@ -282,6 +287,7 @@ where
|
||||
}
|
||||
|
||||
/// The off-diagonal part of this decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<DimMinimum<R, C>, U1>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T::RealField, DimDiff<DimMinimum<R, C>, U1>>,
|
||||
|
@ -92,6 +92,7 @@ where
|
||||
|
||||
/// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
|
||||
/// uppen-triangular part filled with zeros.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn l(&self) -> OMatrix<T, D, D> {
|
||||
self.chol.lower_triangle()
|
||||
}
|
||||
@ -101,6 +102,7 @@ where
|
||||
///
|
||||
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
||||
/// part are garbage and should be ignored by further computations.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
||||
&self.chol
|
||||
}
|
||||
@ -142,6 +144,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the determinant of the decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant(&self) -> T::SimdRealField {
|
||||
let dim = self.chol.nrows();
|
||||
let mut prod_diag = T::one();
|
||||
@ -289,6 +292,7 @@ where
|
||||
|
||||
/// Updates the decomposition such that we get the decomposition of the factored matrix with its `j`th column removed.
|
||||
/// Since the matrix is square, the `j`th row will also be removed.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn remove_column(&self, j: usize) -> Cholesky<T, DimDiff<D, U1>>
|
||||
where
|
||||
D: DimSub<U1>,
|
||||
|
@ -95,6 +95,7 @@ where
|
||||
|
||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
@ -126,6 +127,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||
@ -150,6 +152,7 @@ where
|
||||
}
|
||||
/// Retrieves the column permutation of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||
&self.p
|
||||
}
|
||||
@ -284,6 +287,7 @@ where
|
||||
/// Computes the inverse of the decomposed matrix.
|
||||
///
|
||||
/// Returns `None` if the decomposed matrix is not invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||
assert!(
|
||||
self.col_piv_qr.is_square(),
|
||||
@ -302,6 +306,7 @@ where
|
||||
}
|
||||
|
||||
/// Indicates if the decomposed matrix is invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
assert!(
|
||||
self.col_piv_qr.is_square(),
|
||||
@ -318,6 +323,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the determinant of the decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant(&self) -> T {
|
||||
let dim = self.col_piv_qr.nrows();
|
||||
assert!(
|
||||
|
@ -112,6 +112,7 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
|
||||
///
|
||||
/// # Errors
|
||||
/// Inputs must satisfy `self.len() >= kernel.len() > 0`.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn convolve_same<D2, S2>(&self, kernel: Vector<T, D2, S2>) -> OVector<T, D1>
|
||||
where
|
||||
D2: Dim,
|
||||
|
@ -12,6 +12,7 @@ impl<T: ComplexField, D: DimMin<D, Output = D>, S: Storage<T, D, D>> SquareMatri
|
||||
///
|
||||
/// If the matrix has a dimension larger than 3, an LU decomposition is used.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant(&self) -> T
|
||||
where
|
||||
DefaultAllocator: Allocator<T, D, D> + Allocator<(usize, usize), D>,
|
||||
|
@ -96,6 +96,7 @@ where
|
||||
|
||||
/// The lower triangular matrix of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||
@ -109,6 +110,7 @@ where
|
||||
|
||||
/// The upper triangular matrix of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
@ -119,12 +121,14 @@ where
|
||||
|
||||
/// The row permutations of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||
&self.p
|
||||
}
|
||||
|
||||
/// The column permutations of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn q(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||
&self.q
|
||||
}
|
||||
@ -211,6 +215,7 @@ where
|
||||
/// Computes the inverse of the decomposed matrix.
|
||||
///
|
||||
/// Returns `None` if the decomposed matrix is not invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||
assert!(
|
||||
self.lu.is_square(),
|
||||
@ -228,6 +233,7 @@ where
|
||||
}
|
||||
|
||||
/// Indicates if the decomposed matrix is invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
assert!(
|
||||
self.lu.is_square(),
|
||||
@ -239,6 +245,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the determinant of the decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant(&self) -> T {
|
||||
assert!(
|
||||
self.lu.is_square(),
|
||||
|
@ -89,11 +89,13 @@ impl<T: ComplexField> GivensRotation<T> {
|
||||
}
|
||||
|
||||
/// The cos part of this roration.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn c(&self) -> T::RealField {
|
||||
self.c
|
||||
}
|
||||
|
||||
/// The sin part of this roration.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn s(&self) -> T {
|
||||
self.s
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ where
|
||||
///
|
||||
/// This is less efficient than `.unpack_h()` as it allocates a new matrix.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn h(&self) -> OMatrix<T, D, D> {
|
||||
let dim = self.hess.nrows();
|
||||
let mut res = self.hess.clone();
|
||||
@ -126,6 +127,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||
householder::assemble_q(&self.hess, self.subdiag.as_slice())
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ where
|
||||
|
||||
/// The lower triangular matrix of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||
@ -170,6 +171,7 @@ where
|
||||
|
||||
/// The upper triangular matrix of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
@ -180,6 +182,7 @@ where
|
||||
|
||||
/// The row permutations of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||
&self.p
|
||||
}
|
||||
@ -258,6 +261,7 @@ where
|
||||
/// Computes the inverse of the decomposed matrix.
|
||||
///
|
||||
/// Returns `None` if the matrix is not invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||
assert!(
|
||||
self.lu.is_square(),
|
||||
@ -292,6 +296,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the determinant of the decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant(&self) -> T {
|
||||
let dim = self.lu.nrows();
|
||||
assert!(
|
||||
@ -308,6 +313,7 @@ where
|
||||
}
|
||||
|
||||
/// Indicates if the decomposed matrix is invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
assert!(
|
||||
self.lu.is_square(),
|
||||
|
@ -140,17 +140,20 @@ where
|
||||
}
|
||||
|
||||
/// The number of non-identity permutations applied by this sequence.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
/// Returns true if the permutation sequence contains no elements.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// The determinant of the matrix corresponding to this permutation.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn determinant<T: One + ClosedNeg>(&self) -> T {
|
||||
if self.len % 2 == 0 {
|
||||
T::one()
|
||||
|
@ -70,6 +70,7 @@ where
|
||||
|
||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||
#[inline]
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||
@ -96,6 +97,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||
@ -244,6 +246,7 @@ where
|
||||
/// Computes the inverse of the decomposed matrix.
|
||||
///
|
||||
/// Returns `None` if the decomposed matrix is not invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||
assert!(
|
||||
self.qr.is_square(),
|
||||
@ -262,6 +265,7 @@ where
|
||||
}
|
||||
|
||||
/// Indicates if the decomposed matrix is invertible.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
assert!(
|
||||
self.qr.is_square(),
|
||||
|
@ -385,6 +385,7 @@ where
|
||||
/// Computes the real eigenvalues of the decomposed matrix.
|
||||
///
|
||||
/// Return `None` if some eigenvalues are complex.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||
let mut out = unsafe {
|
||||
crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, Const::<1>)
|
||||
@ -397,6 +398,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the complex eigenvalues of the decomposed matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
||||
where
|
||||
T: RealField,
|
||||
@ -509,6 +511,7 @@ where
|
||||
+ Allocator<T, D>,
|
||||
{
|
||||
/// Computes the eigenvalues of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||
assert!(
|
||||
self.is_square(),
|
||||
@ -551,6 +554,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the eigenvalues of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
||||
// TODO: add balancing?
|
||||
where
|
||||
|
@ -502,6 +502,7 @@ where
|
||||
|
||||
/// Computes the rank of the decomposed matrix, i.e., the number of singular values greater
|
||||
/// than `eps`.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rank(&self, eps: T::RealField) -> usize {
|
||||
assert!(
|
||||
eps >= T::RealField::zero(),
|
||||
@ -615,6 +616,7 @@ where
|
||||
+ Allocator<T::RealField, DimDiff<DimMinimum<R, C>, U1>>,
|
||||
{
|
||||
/// Computes the singular values of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn singular_values(&self) -> OVector<T::RealField, DimMinimum<R, C>> {
|
||||
SVD::new(self.clone_owned(), false, false).singular_values
|
||||
}
|
||||
@ -622,6 +624,7 @@ where
|
||||
/// Computes the rank of this matrix.
|
||||
///
|
||||
/// All singular values below `eps` are considered equal to 0.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn rank(&self, eps: T::RealField) -> usize {
|
||||
let svd = SVD::new(self.clone_owned(), false, false);
|
||||
svd.rank(eps)
|
||||
|
@ -268,6 +268,7 @@ where
|
||||
/// Rebuild the original matrix.
|
||||
///
|
||||
/// This is useful if some of the eigenvalues have been manually modified.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
||||
let mut u_t = self.eigenvectors.clone();
|
||||
for i in 0..self.eigenvalues.len() {
|
||||
@ -311,6 +312,7 @@ where
|
||||
/// Computes the eigenvalues of this symmetric matrix.
|
||||
///
|
||||
/// Only the lower-triangular part of the matrix is read.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn symmetric_eigenvalues(&self) -> OVector<T::RealField, D> {
|
||||
SymmetricEigen::do_decompose(
|
||||
self.clone_owned(),
|
||||
|
@ -131,6 +131,7 @@ where
|
||||
}
|
||||
|
||||
/// The diagonal components of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn diagonal(&self) -> OVector<T::RealField, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<T::RealField, D>,
|
||||
@ -139,6 +140,7 @@ where
|
||||
}
|
||||
|
||||
/// The off-diagonal components of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<D, U1>>
|
||||
where
|
||||
DefaultAllocator: Allocator<T::RealField, DimDiff<D, U1>>,
|
||||
@ -147,6 +149,7 @@ where
|
||||
}
|
||||
|
||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||
householder::assemble_q(&self.tri, self.off_diagonal.as_slice())
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ where
|
||||
}
|
||||
|
||||
/// Returns the diagonal elements as a matrix
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn d_matrix(&self) -> OMatrix<T, D, D> {
|
||||
OMatrix::from_diagonal(&self.d)
|
||||
}
|
||||
|
@ -119,16 +119,19 @@ where
|
||||
DefaultAllocator: Allocator<usize, C>,
|
||||
{
|
||||
/// The value buffer of this storage.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn values(&self) -> &[T] {
|
||||
&self.vals
|
||||
}
|
||||
|
||||
/// The column shifts buffer.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn p(&self) -> &[usize] {
|
||||
self.p.as_slice()
|
||||
}
|
||||
|
||||
/// The row index buffers.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn i(&self) -> &[usize] {
|
||||
&self.i
|
||||
}
|
||||
@ -356,27 +359,32 @@ impl<T: Scalar, R: Dim, C: Dim, S: CsStorage<T, R, C>> CsMatrix<T, R, C, S> {
|
||||
}
|
||||
|
||||
/// The size of the data buffer.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
/// The number of rows of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn nrows(&self) -> usize {
|
||||
self.data.shape().0.value()
|
||||
}
|
||||
|
||||
/// The number of rows of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn ncols(&self) -> usize {
|
||||
self.data.shape().1.value()
|
||||
}
|
||||
|
||||
/// The shape of this matrix.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn shape(&self) -> (usize, usize) {
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
(nrows.value(), ncols.value())
|
||||
}
|
||||
|
||||
/// Whether this matrix is square or not.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_square(&self) -> bool {
|
||||
let (nrows, ncols) = self.data.shape();
|
||||
nrows.value() == ncols.value()
|
||||
@ -391,6 +399,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: CsStorage<T, R, C>> CsMatrix<T, R, C, S> {
|
||||
/// If at any time this `is_sorted` method returns `false`, then, something went wrong
|
||||
/// and an issue should be open on the nalgebra repository with details on how to reproduce
|
||||
/// this.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn is_sorted(&self) -> bool {
|
||||
for j in 0..self.ncols() {
|
||||
let mut curr = None;
|
||||
|
@ -67,6 +67,7 @@ where
|
||||
}
|
||||
|
||||
/// The lower-triangular matrix of the cholesky decomposition.
|
||||
#[must_use = "This function does not mutate self. You should use the return value."]
|
||||
pub fn l(&self) -> Option<&CsMatrix<T, D, D>> {
|
||||
if self.ok {
|
||||
Some(&self.l)
|
||||
|
Loading…
Reference in New Issue
Block a user