forked from M-Labs/nalgebra
Merge pull request #851 from MalteT/dev
Annotate functions with #[must_use] where appropriate
This commit is contained in:
commit
543f964610
@ -80,6 +80,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> OMatrix<T, D, D> {
|
pub fn l(&self) -> OMatrix<T, D, D> {
|
||||||
let mut res = self.l.clone();
|
let mut res = self.l.clone();
|
||||||
res.fill_upper_triangle(Zero::zero(), 1);
|
res.fill_upper_triangle(Zero::zero(), 1);
|
||||||
@ -91,6 +92,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
/// 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.
|
/// part are garbage and should be ignored by further computations.
|
||||||
|
#[must_use]
|
||||||
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
||||||
&self.l
|
&self.l
|
||||||
}
|
}
|
||||||
|
@ -302,6 +302,7 @@ where
|
|||||||
|
|
||||||
/// The determinant of the decomposed matrix.
|
/// The determinant of the decomposed matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> T {
|
||||||
let mut det = T::one();
|
let mut det = T::one();
|
||||||
for e in self.eigenvalues.iter() {
|
for e in self.eigenvalues.iter() {
|
||||||
|
@ -89,6 +89,7 @@ where
|
|||||||
|
|
||||||
/// Computes the hessenberg matrix of this decomposition.
|
/// Computes the hessenberg matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn h(&self) -> OMatrix<T, D, D> {
|
pub fn h(&self) -> OMatrix<T, D, D> {
|
||||||
let mut h = self.h.clone_owned();
|
let mut h = self.h.clone_owned();
|
||||||
h.fill_lower_triangle(T::zero(), 2);
|
h.fill_lower_triangle(T::zero(), 2);
|
||||||
@ -109,6 +110,7 @@ where
|
|||||||
|
|
||||||
/// Computes the unitary matrix `Q` of this decomposition.
|
/// Computes the unitary matrix `Q` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, D, D> {
|
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||||
let n = self.h.nrows() as i32;
|
let n = self.h.nrows() as i32;
|
||||||
let mut q = self.h.clone_owned();
|
let mut q = self.h.clone_owned();
|
||||||
|
@ -85,6 +85,7 @@ where
|
|||||||
|
|
||||||
/// Gets the lower-triangular matrix part of the decomposition.
|
/// Gets the lower-triangular matrix part of the decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
||||||
let (nrows, ncols) = self.lu.data.shape();
|
let (nrows, ncols) = self.lu.data.shape();
|
||||||
let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
|
let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
|
||||||
@ -97,6 +98,7 @@ where
|
|||||||
|
|
||||||
/// Gets the upper-triangular matrix part of the decomposition.
|
/// Gets the upper-triangular matrix part of the decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
||||||
let (nrows, ncols) = self.lu.data.shape();
|
let (nrows, ncols) = self.lu.data.shape();
|
||||||
let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned();
|
let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned();
|
||||||
@ -111,6 +113,7 @@ where
|
|||||||
/// Computing the permutation matrix explicitly is costly and usually not necessary.
|
/// Computing the permutation matrix explicitly is costly and usually not necessary.
|
||||||
/// To permute rows of a matrix or vector, use the method `self.permute(...)` instead.
|
/// To permute rows of a matrix or vector, use the method `self.permute(...)` instead.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn p(&self) -> OMatrix<T, R, R> {
|
pub fn p(&self) -> OMatrix<T, R, R> {
|
||||||
let (dim, _) = self.lu.data.shape();
|
let (dim, _) = self.lu.data.shape();
|
||||||
let mut id = Matrix::identity_generic(dim, dim);
|
let mut id = Matrix::identity_generic(dim, dim);
|
||||||
@ -124,6 +127,7 @@ where
|
|||||||
|
|
||||||
/// Gets the LAPACK permutation indices.
|
/// Gets the LAPACK permutation indices.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn permutation_indices(&self) -> &OVector<i32, DimMinimum<R, C>> {
|
pub fn permutation_indices(&self) -> &OVector<i32, DimMinimum<R, C>> {
|
||||||
&self.p
|
&self.p
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ where
|
|||||||
|
|
||||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
||||||
let (nrows, ncols) = self.qr.data.shape();
|
let (nrows, ncols) = self.qr.data.shape();
|
||||||
self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle()
|
self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle()
|
||||||
@ -117,6 +118,7 @@ where
|
|||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
||||||
let (nrows, ncols) = self.qr.data.shape();
|
let (nrows, ncols) = self.qr.data.shape();
|
||||||
let min_nrows_ncols = nrows.min(ncols);
|
let min_nrows_ncols = nrows.min(ncols);
|
||||||
|
@ -138,6 +138,7 @@ where
|
|||||||
/// Computes the real eigenvalues of the decomposed matrix.
|
/// Computes the real eigenvalues of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Return `None` if some eigenvalues are complex.
|
/// Return `None` if some eigenvalues are complex.
|
||||||
|
#[must_use]
|
||||||
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||||
if self.im.iter().all(|e| e.is_zero()) {
|
if self.im.iter().all(|e| e.is_zero()) {
|
||||||
Some(self.re.clone())
|
Some(self.re.clone())
|
||||||
@ -147,6 +148,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the complex eigenvalues of the decomposed matrix.
|
/// Computes the complex eigenvalues of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
|
pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<Complex<T>, D>,
|
DefaultAllocator: Allocator<Complex<T>, D>,
|
||||||
|
@ -175,6 +175,7 @@ macro_rules! svd_impl(
|
|||||||
///
|
///
|
||||||
/// All singular value below epsilon will be set to zero instead of being inverted.
|
/// All singular value below epsilon will be set to zero instead of being inverted.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn pseudo_inverse(&self, epsilon: $t) -> OMatrix<$t, C, R> {
|
pub fn pseudo_inverse(&self, epsilon: $t) -> OMatrix<$t, C, R> {
|
||||||
let nrows = self.u.data.shape().0;
|
let nrows = self.u.data.shape().0;
|
||||||
let ncols = self.vt.data.shape().1;
|
let ncols = self.vt.data.shape().1;
|
||||||
@ -207,6 +208,7 @@ macro_rules! svd_impl(
|
|||||||
/// This is the number of singular values that are not too small (i.e. greater than
|
/// This is the number of singular values that are not too small (i.e. greater than
|
||||||
/// the given `epsilon`).
|
/// the given `epsilon`).
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rank(&self, epsilon: $t) -> usize {
|
pub fn rank(&self, epsilon: $t) -> usize {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ where
|
|||||||
|
|
||||||
/// The determinant of the decomposed matrix.
|
/// The determinant of the decomposed matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> T {
|
||||||
let mut det = T::one();
|
let mut det = T::one();
|
||||||
for e in self.eigenvalues.iter() {
|
for e in self.eigenvalues.iter() {
|
||||||
@ -150,6 +151,7 @@ where
|
|||||||
/// Rebuild the original matrix.
|
/// Rebuild the original matrix.
|
||||||
///
|
///
|
||||||
/// This is useful if some of the eigenvalues have been manually modified.
|
/// This is useful if some of the eigenvalues have been manually modified.
|
||||||
|
#[must_use]
|
||||||
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
||||||
let mut u_t = self.eigenvectors.clone();
|
let mut u_t = self.eigenvectors.clone();
|
||||||
for i in 0..self.eigenvalues.len() {
|
for i in 0..self.eigenvalues.len() {
|
||||||
|
@ -173,12 +173,14 @@ impl<T> CooMatrix<T> {
|
|||||||
|
|
||||||
/// The number of rows in the matrix.
|
/// The number of rows in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.nrows
|
self.nrows
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of columns in the matrix.
|
/// The number of columns in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.ncols
|
self.ncols
|
||||||
}
|
}
|
||||||
@ -189,21 +191,25 @@ impl<T> CooMatrix<T> {
|
|||||||
/// entries, then it may have a different number of non-zeros as reported by `nnz()` compared
|
/// entries, then it may have a different number of non-zeros as reported by `nnz()` compared
|
||||||
/// to its CSR representation.
|
/// to its CSR representation.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.values.len()
|
self.values.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The row indices of the explicitly stored entries.
|
/// The row indices of the explicitly stored entries.
|
||||||
|
#[must_use]
|
||||||
pub fn row_indices(&self) -> &[usize] {
|
pub fn row_indices(&self) -> &[usize] {
|
||||||
&self.row_indices
|
&self.row_indices
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column indices of the explicitly stored entries.
|
/// The column indices of the explicitly stored entries.
|
||||||
|
#[must_use]
|
||||||
pub fn col_indices(&self) -> &[usize] {
|
pub fn col_indices(&self) -> &[usize] {
|
||||||
&self.col_indices
|
&self.col_indices
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The values of the explicitly stored entries.
|
/// The values of the explicitly stored entries.
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
&self.values
|
&self.values
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,13 @@ impl<T> CsMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn pattern(&self) -> &SparsityPattern {
|
pub fn pattern(&self) -> &SparsityPattern {
|
||||||
&self.sparsity_pattern
|
&self.sparsity_pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
&self.values
|
&self.values
|
||||||
}
|
}
|
||||||
@ -48,6 +50,7 @@ impl<T> CsMatrix<T> {
|
|||||||
|
|
||||||
/// Returns the raw data represented as a tuple `(major_offsets, minor_indices, values)`.
|
/// Returns the raw data represented as a tuple `(major_offsets, minor_indices, values)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cs_data(&self) -> (&[usize], &[usize], &[T]) {
|
pub fn cs_data(&self) -> (&[usize], &[usize], &[T]) {
|
||||||
let pattern = self.pattern();
|
let pattern = self.pattern();
|
||||||
(
|
(
|
||||||
@ -88,6 +91,7 @@ impl<T> CsMatrix<T> {
|
|||||||
|
|
||||||
/// Internal method for simplifying access to a lane's data
|
/// Internal method for simplifying access to a lane's data
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_index_range(&self, row_index: usize) -> Option<Range<usize>> {
|
pub fn get_index_range(&self, row_index: usize) -> Option<Range<usize>> {
|
||||||
let row_begin = *self.sparsity_pattern.major_offsets().get(row_index)?;
|
let row_begin = *self.sparsity_pattern.major_offsets().get(row_index)?;
|
||||||
let row_end = *self.sparsity_pattern.major_offsets().get(row_index + 1)?;
|
let row_end = *self.sparsity_pattern.major_offsets().get(row_index + 1)?;
|
||||||
@ -111,6 +115,7 @@ impl<T> CsMatrix<T> {
|
|||||||
|
|
||||||
/// Returns an entry for the given major/minor indices, or `None` if the indices are out
|
/// Returns an entry for the given major/minor indices, or `None` if the indices are out
|
||||||
/// of bounds.
|
/// of bounds.
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, major_index: usize, minor_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, major_index: usize, minor_index: usize) -> Option<SparseEntry<T>> {
|
||||||
let row_range = self.get_index_range(major_index)?;
|
let row_range = self.get_index_range(major_index)?;
|
||||||
let (_, minor_indices, values) = self.cs_data();
|
let (_, minor_indices, values) = self.cs_data();
|
||||||
@ -139,6 +144,7 @@ impl<T> CsMatrix<T> {
|
|||||||
get_mut_entry_from_slices(minor_dim, minor_indices, values, minor_index)
|
get_mut_entry_from_slices(minor_dim, minor_indices, values, minor_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn get_lane(&self, index: usize) -> Option<CsLane<T>> {
|
pub fn get_lane(&self, index: usize) -> Option<CsLane<T>> {
|
||||||
let range = self.get_index_range(index)?;
|
let range = self.get_index_range(index)?;
|
||||||
let (_, minor_indices, values) = self.cs_data();
|
let (_, minor_indices, values) = self.cs_data();
|
||||||
@ -150,6 +156,7 @@ impl<T> CsMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_lane_mut(&mut self, index: usize) -> Option<CsLaneMut<T>> {
|
pub fn get_lane_mut(&mut self, index: usize) -> Option<CsLaneMut<T>> {
|
||||||
let range = self.get_index_range(index)?;
|
let range = self.get_index_range(index)?;
|
||||||
let minor_dim = self.pattern().minor_dim();
|
let minor_dim = self.pattern().minor_dim();
|
||||||
@ -172,6 +179,7 @@ impl<T> CsMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn filter<P>(&self, predicate: P) -> Self
|
pub fn filter<P>(&self, predicate: P) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -207,6 +215,7 @@ impl<T> CsMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the diagonal of the matrix as a sparse matrix.
|
/// Returns the diagonal of the matrix as a sparse matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal_as_matrix(&self) -> Self
|
pub fn diagonal_as_matrix(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -372,26 +381,31 @@ macro_rules! impl_cs_lane_common_methods {
|
|||||||
($name:ty) => {
|
($name:ty) => {
|
||||||
impl<'a, T> $name {
|
impl<'a, T> $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn minor_dim(&self) -> usize {
|
pub fn minor_dim(&self) -> usize {
|
||||||
self.minor_dim
|
self.minor_dim
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.minor_indices.len()
|
self.minor_indices.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn minor_indices(&self) -> &[usize] {
|
pub fn minor_indices(&self) -> &[usize] {
|
||||||
self.minor_indices
|
self.minor_indices
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
self.values
|
self.values
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, global_col_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, global_col_index: usize) -> Option<SparseEntry<T>> {
|
||||||
get_entry_from_slices(
|
get_entry_from_slices(
|
||||||
self.minor_dim,
|
self.minor_dim,
|
||||||
@ -416,6 +430,7 @@ impl<'a, T> CsLaneMut<'a, T> {
|
|||||||
(self.minor_indices, self.values)
|
(self.minor_indices, self.values)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry_mut(&mut self, global_minor_index: usize) -> Option<SparseEntryMut<T>> {
|
pub fn get_entry_mut(&mut self, global_minor_index: usize) -> Option<SparseEntryMut<T>> {
|
||||||
get_mut_entry_from_slices(
|
get_mut_entry_from_slices(
|
||||||
self.minor_dim,
|
self.minor_dim,
|
||||||
|
@ -192,12 +192,14 @@ impl<T> CscMatrix<T> {
|
|||||||
|
|
||||||
/// The number of rows in the matrix.
|
/// The number of rows in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.cs.pattern().minor_dim()
|
self.cs.pattern().minor_dim()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of columns in the matrix.
|
/// The number of columns in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.cs.pattern().major_dim()
|
self.cs.pattern().major_dim()
|
||||||
}
|
}
|
||||||
@ -208,24 +210,28 @@ impl<T> CscMatrix<T> {
|
|||||||
/// number of algebraically zero entries in the matrix. Explicitly stored entries can still
|
/// number of algebraically zero entries in the matrix. Explicitly stored entries can still
|
||||||
/// be zero. Corresponds to the number of entries in the sparsity pattern.
|
/// be zero. Corresponds to the number of entries in the sparsity pattern.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.pattern().nnz()
|
self.pattern().nnz()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column offsets defining part of the CSC format.
|
/// The column offsets defining part of the CSC format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn col_offsets(&self) -> &[usize] {
|
pub fn col_offsets(&self) -> &[usize] {
|
||||||
self.pattern().major_offsets()
|
self.pattern().major_offsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The row indices defining part of the CSC format.
|
/// The row indices defining part of the CSC format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_indices(&self) -> &[usize] {
|
pub fn row_indices(&self) -> &[usize] {
|
||||||
self.pattern().minor_indices()
|
self.pattern().minor_indices()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The non-zero values defining part of the CSC format.
|
/// The non-zero values defining part of the CSC format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
self.cs.values()
|
self.cs.values()
|
||||||
}
|
}
|
||||||
@ -298,6 +304,7 @@ impl<T> CscMatrix<T> {
|
|||||||
/// ------
|
/// ------
|
||||||
/// Panics if column index is out of bounds.
|
/// Panics if column index is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn col(&self, index: usize) -> CscCol<T> {
|
pub fn col(&self, index: usize) -> CscCol<T> {
|
||||||
self.get_col(index).expect("Row index must be in bounds")
|
self.get_col(index).expect("Row index must be in bounds")
|
||||||
}
|
}
|
||||||
@ -315,12 +322,14 @@ impl<T> CscMatrix<T> {
|
|||||||
|
|
||||||
/// Return the column at the given column index, or `None` if out of bounds.
|
/// Return the column at the given column index, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_col(&self, index: usize) -> Option<CscCol<T>> {
|
pub fn get_col(&self, index: usize) -> Option<CscCol<T>> {
|
||||||
self.cs.get_lane(index).map(|lane| CscCol { lane })
|
self.cs.get_lane(index).map(|lane| CscCol { lane })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable column access for the given column index, or `None` if out of bounds.
|
/// Mutable column access for the given column index, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_col_mut(&mut self, index: usize) -> Option<CscColMut<T>> {
|
pub fn get_col_mut(&mut self, index: usize) -> Option<CscColMut<T>> {
|
||||||
self.cs.get_lane_mut(index).map(|lane| CscColMut { lane })
|
self.cs.get_lane_mut(index).map(|lane| CscColMut { lane })
|
||||||
}
|
}
|
||||||
@ -381,6 +390,7 @@ impl<T> CscMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the underlying sparsity pattern.
|
/// Returns a reference to the underlying sparsity pattern.
|
||||||
|
#[must_use]
|
||||||
pub fn pattern(&self) -> &SparsityPattern {
|
pub fn pattern(&self) -> &SparsityPattern {
|
||||||
self.cs.pattern()
|
self.cs.pattern()
|
||||||
}
|
}
|
||||||
@ -397,6 +407,7 @@ impl<T> CscMatrix<T> {
|
|||||||
///
|
///
|
||||||
/// Each call to this function incurs the cost of a binary search among the explicitly
|
/// Each call to this function incurs the cost of a binary search among the explicitly
|
||||||
/// stored row entries for the given column.
|
/// stored row entries for the given column.
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, row_index: usize, col_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, row_index: usize, col_index: usize) -> Option<SparseEntry<T>> {
|
||||||
self.cs.get_entry(col_index, row_index)
|
self.cs.get_entry(col_index, row_index)
|
||||||
}
|
}
|
||||||
@ -422,6 +433,7 @@ impl<T> CscMatrix<T> {
|
|||||||
/// Panics
|
/// Panics
|
||||||
/// ------
|
/// ------
|
||||||
/// Panics if `row_index` or `col_index` is out of bounds.
|
/// Panics if `row_index` or `col_index` is out of bounds.
|
||||||
|
#[must_use]
|
||||||
pub fn index_entry(&self, row_index: usize, col_index: usize) -> SparseEntry<T> {
|
pub fn index_entry(&self, row_index: usize, col_index: usize) -> SparseEntry<T> {
|
||||||
self.get_entry(row_index, col_index)
|
self.get_entry(row_index, col_index)
|
||||||
.expect("Out of bounds matrix indices encountered")
|
.expect("Out of bounds matrix indices encountered")
|
||||||
@ -441,6 +453,7 @@ impl<T> CscMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a triplet of slices `(col_offsets, row_indices, values)` that make up the CSC data.
|
/// Returns a triplet of slices `(col_offsets, row_indices, values)` that make up the CSC data.
|
||||||
|
#[must_use]
|
||||||
pub fn csc_data(&self) -> (&[usize], &[usize], &[T]) {
|
pub fn csc_data(&self) -> (&[usize], &[usize], &[T]) {
|
||||||
self.cs.cs_data()
|
self.cs.cs_data()
|
||||||
}
|
}
|
||||||
@ -453,6 +466,7 @@ impl<T> CscMatrix<T> {
|
|||||||
|
|
||||||
/// Creates a sparse matrix that contains only the explicit entries decided by the
|
/// Creates a sparse matrix that contains only the explicit entries decided by the
|
||||||
/// given predicate.
|
/// given predicate.
|
||||||
|
#[must_use]
|
||||||
pub fn filter<P>(&self, predicate: P) -> Self
|
pub fn filter<P>(&self, predicate: P) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -470,6 +484,7 @@ impl<T> CscMatrix<T> {
|
|||||||
/// Returns a new matrix representing the upper triangular part of this matrix.
|
/// Returns a new matrix representing the upper triangular part of this matrix.
|
||||||
///
|
///
|
||||||
/// The result includes the diagonal of the matrix.
|
/// The result includes the diagonal of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn upper_triangle(&self) -> Self
|
pub fn upper_triangle(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -480,6 +495,7 @@ impl<T> CscMatrix<T> {
|
|||||||
/// Returns a new matrix representing the lower triangular part of this matrix.
|
/// Returns a new matrix representing the lower triangular part of this matrix.
|
||||||
///
|
///
|
||||||
/// The result includes the diagonal of the matrix.
|
/// The result includes the diagonal of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn lower_triangle(&self) -> Self
|
pub fn lower_triangle(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -488,6 +504,7 @@ impl<T> CscMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the diagonal of the matrix as a sparse matrix.
|
/// Returns the diagonal of the matrix as a sparse matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal_as_csc(&self) -> Self
|
pub fn diagonal_as_csc(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -498,6 +515,7 @@ impl<T> CscMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the transpose of the matrix.
|
/// Compute the transpose of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn transpose(&self) -> CscMatrix<T>
|
pub fn transpose(&self) -> CscMatrix<T>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
@ -617,24 +635,28 @@ macro_rules! impl_csc_col_common_methods {
|
|||||||
impl<'a, T> $name {
|
impl<'a, T> $name {
|
||||||
/// The number of global rows in the column.
|
/// The number of global rows in the column.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.lane.minor_dim()
|
self.lane.minor_dim()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of non-zeros in this column.
|
/// The number of non-zeros in this column.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.lane.nnz()
|
self.lane.nnz()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The row indices corresponding to explicitly stored entries in this column.
|
/// The row indices corresponding to explicitly stored entries in this column.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_indices(&self) -> &[usize] {
|
pub fn row_indices(&self) -> &[usize] {
|
||||||
self.lane.minor_indices()
|
self.lane.minor_indices()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The values corresponding to explicitly stored entries in this column.
|
/// The values corresponding to explicitly stored entries in this column.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
self.lane.values()
|
self.lane.values()
|
||||||
}
|
}
|
||||||
@ -643,6 +665,7 @@ macro_rules! impl_csc_col_common_methods {
|
|||||||
///
|
///
|
||||||
/// Each call to this function incurs the cost of a binary search among the explicitly
|
/// Each call to this function incurs the cost of a binary search among the explicitly
|
||||||
/// stored row entries.
|
/// stored row entries.
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, global_row_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, global_row_index: usize) -> Option<SparseEntry<T>> {
|
||||||
self.lane.get_entry(global_row_index)
|
self.lane.get_entry(global_row_index)
|
||||||
}
|
}
|
||||||
@ -669,6 +692,7 @@ impl<'a, T> CscColMut<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable entry for the given global row index.
|
/// Returns a mutable entry for the given global row index.
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry_mut(&mut self, global_row_index: usize) -> Option<SparseEntryMut<T>> {
|
pub fn get_entry_mut(&mut self, global_row_index: usize) -> Option<SparseEntryMut<T>> {
|
||||||
self.lane.get_entry_mut(global_row_index)
|
self.lane.get_entry_mut(global_row_index)
|
||||||
}
|
}
|
||||||
|
@ -192,12 +192,14 @@ impl<T> CsrMatrix<T> {
|
|||||||
|
|
||||||
/// The number of rows in the matrix.
|
/// The number of rows in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.cs.pattern().major_dim()
|
self.cs.pattern().major_dim()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of columns in the matrix.
|
/// The number of columns in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.cs.pattern().minor_dim()
|
self.cs.pattern().minor_dim()
|
||||||
}
|
}
|
||||||
@ -208,12 +210,14 @@ impl<T> CsrMatrix<T> {
|
|||||||
/// number of algebraically zero entries in the matrix. Explicitly stored entries can still
|
/// number of algebraically zero entries in the matrix. Explicitly stored entries can still
|
||||||
/// be zero. Corresponds to the number of entries in the sparsity pattern.
|
/// be zero. Corresponds to the number of entries in the sparsity pattern.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.cs.pattern().nnz()
|
self.cs.pattern().nnz()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The row offsets defining part of the CSR format.
|
/// The row offsets defining part of the CSR format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_offsets(&self) -> &[usize] {
|
pub fn row_offsets(&self) -> &[usize] {
|
||||||
let (offsets, _, _) = self.cs.cs_data();
|
let (offsets, _, _) = self.cs.cs_data();
|
||||||
offsets
|
offsets
|
||||||
@ -221,6 +225,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
|
|
||||||
/// The column indices defining part of the CSR format.
|
/// The column indices defining part of the CSR format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn col_indices(&self) -> &[usize] {
|
pub fn col_indices(&self) -> &[usize] {
|
||||||
let (_, indices, _) = self.cs.cs_data();
|
let (_, indices, _) = self.cs.cs_data();
|
||||||
indices
|
indices
|
||||||
@ -228,6 +233,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
|
|
||||||
/// The non-zero values defining part of the CSR format.
|
/// The non-zero values defining part of the CSR format.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
self.cs.values()
|
self.cs.values()
|
||||||
}
|
}
|
||||||
@ -300,6 +306,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
/// ------
|
/// ------
|
||||||
/// Panics if row index is out of bounds.
|
/// Panics if row index is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row(&self, index: usize) -> CsrRow<T> {
|
pub fn row(&self, index: usize) -> CsrRow<T> {
|
||||||
self.get_row(index).expect("Row index must be in bounds")
|
self.get_row(index).expect("Row index must be in bounds")
|
||||||
}
|
}
|
||||||
@ -317,12 +324,14 @@ impl<T> CsrMatrix<T> {
|
|||||||
|
|
||||||
/// Return the row at the given row index, or `None` if out of bounds.
|
/// Return the row at the given row index, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_row(&self, index: usize) -> Option<CsrRow<T>> {
|
pub fn get_row(&self, index: usize) -> Option<CsrRow<T>> {
|
||||||
self.cs.get_lane(index).map(|lane| CsrRow { lane })
|
self.cs.get_lane(index).map(|lane| CsrRow { lane })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable row access for the given row index, or `None` if out of bounds.
|
/// Mutable row access for the given row index, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_row_mut(&mut self, index: usize) -> Option<CsrRowMut<T>> {
|
pub fn get_row_mut(&mut self, index: usize) -> Option<CsrRowMut<T>> {
|
||||||
self.cs.get_lane_mut(index).map(|lane| CsrRowMut { lane })
|
self.cs.get_lane_mut(index).map(|lane| CsrRowMut { lane })
|
||||||
}
|
}
|
||||||
@ -383,6 +392,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the underlying sparsity pattern.
|
/// Returns a reference to the underlying sparsity pattern.
|
||||||
|
#[must_use]
|
||||||
pub fn pattern(&self) -> &SparsityPattern {
|
pub fn pattern(&self) -> &SparsityPattern {
|
||||||
self.cs.pattern()
|
self.cs.pattern()
|
||||||
}
|
}
|
||||||
@ -399,6 +409,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
///
|
///
|
||||||
/// Each call to this function incurs the cost of a binary search among the explicitly
|
/// Each call to this function incurs the cost of a binary search among the explicitly
|
||||||
/// stored column entries for the given row.
|
/// stored column entries for the given row.
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, row_index: usize, col_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, row_index: usize, col_index: usize) -> Option<SparseEntry<T>> {
|
||||||
self.cs.get_entry(row_index, col_index)
|
self.cs.get_entry(row_index, col_index)
|
||||||
}
|
}
|
||||||
@ -424,6 +435,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
/// Panics
|
/// Panics
|
||||||
/// ------
|
/// ------
|
||||||
/// Panics if `row_index` or `col_index` is out of bounds.
|
/// Panics if `row_index` or `col_index` is out of bounds.
|
||||||
|
#[must_use]
|
||||||
pub fn index_entry(&self, row_index: usize, col_index: usize) -> SparseEntry<T> {
|
pub fn index_entry(&self, row_index: usize, col_index: usize) -> SparseEntry<T> {
|
||||||
self.get_entry(row_index, col_index)
|
self.get_entry(row_index, col_index)
|
||||||
.expect("Out of bounds matrix indices encountered")
|
.expect("Out of bounds matrix indices encountered")
|
||||||
@ -443,6 +455,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a triplet of slices `(row_offsets, col_indices, values)` that make up the CSR data.
|
/// Returns a triplet of slices `(row_offsets, col_indices, values)` that make up the CSR data.
|
||||||
|
#[must_use]
|
||||||
pub fn csr_data(&self) -> (&[usize], &[usize], &[T]) {
|
pub fn csr_data(&self) -> (&[usize], &[usize], &[T]) {
|
||||||
self.cs.cs_data()
|
self.cs.cs_data()
|
||||||
}
|
}
|
||||||
@ -455,6 +468,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
|
|
||||||
/// Creates a sparse matrix that contains only the explicit entries decided by the
|
/// Creates a sparse matrix that contains only the explicit entries decided by the
|
||||||
/// given predicate.
|
/// given predicate.
|
||||||
|
#[must_use]
|
||||||
pub fn filter<P>(&self, predicate: P) -> Self
|
pub fn filter<P>(&self, predicate: P) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -470,6 +484,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
/// Returns a new matrix representing the upper triangular part of this matrix.
|
/// Returns a new matrix representing the upper triangular part of this matrix.
|
||||||
///
|
///
|
||||||
/// The result includes the diagonal of the matrix.
|
/// The result includes the diagonal of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn upper_triangle(&self) -> Self
|
pub fn upper_triangle(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -480,6 +495,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
/// Returns a new matrix representing the lower triangular part of this matrix.
|
/// Returns a new matrix representing the lower triangular part of this matrix.
|
||||||
///
|
///
|
||||||
/// The result includes the diagonal of the matrix.
|
/// The result includes the diagonal of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn lower_triangle(&self) -> Self
|
pub fn lower_triangle(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -488,6 +504,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the diagonal of the matrix as a sparse matrix.
|
/// Returns the diagonal of the matrix as a sparse matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal_as_csr(&self) -> Self
|
pub fn diagonal_as_csr(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -498,6 +515,7 @@ impl<T> CsrMatrix<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the transpose of the matrix.
|
/// Compute the transpose of the matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn transpose(&self) -> CsrMatrix<T>
|
pub fn transpose(&self) -> CsrMatrix<T>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
@ -617,24 +635,28 @@ macro_rules! impl_csr_row_common_methods {
|
|||||||
impl<'a, T> $name {
|
impl<'a, T> $name {
|
||||||
/// The number of global columns in the row.
|
/// The number of global columns in the row.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.lane.minor_dim()
|
self.lane.minor_dim()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of non-zeros in this row.
|
/// The number of non-zeros in this row.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.lane.nnz()
|
self.lane.nnz()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column indices corresponding to explicitly stored entries in this row.
|
/// The column indices corresponding to explicitly stored entries in this row.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn col_indices(&self) -> &[usize] {
|
pub fn col_indices(&self) -> &[usize] {
|
||||||
self.lane.minor_indices()
|
self.lane.minor_indices()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The values corresponding to explicitly stored entries in this row.
|
/// The values corresponding to explicitly stored entries in this row.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
self.lane.values()
|
self.lane.values()
|
||||||
}
|
}
|
||||||
@ -644,6 +666,7 @@ macro_rules! impl_csr_row_common_methods {
|
|||||||
/// Each call to this function incurs the cost of a binary search among the explicitly
|
/// Each call to this function incurs the cost of a binary search among the explicitly
|
||||||
/// stored column entries.
|
/// stored column entries.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry(&self, global_col_index: usize) -> Option<SparseEntry<T>> {
|
pub fn get_entry(&self, global_col_index: usize) -> Option<SparseEntry<T>> {
|
||||||
self.lane.get_entry(global_col_index)
|
self.lane.get_entry(global_col_index)
|
||||||
}
|
}
|
||||||
@ -673,6 +696,7 @@ impl<'a, T> CsrRowMut<'a, T> {
|
|||||||
|
|
||||||
/// Returns a mutable entry for the given global column index.
|
/// Returns a mutable entry for the given global column index.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_entry_mut(&mut self, global_col_index: usize) -> Option<SparseEntryMut<T>> {
|
pub fn get_entry_mut(&mut self, global_col_index: usize) -> Option<SparseEntryMut<T>> {
|
||||||
self.lane.get_entry_mut(global_col_index)
|
self.lane.get_entry_mut(global_col_index)
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ impl CscSymbolicCholesky {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The pattern of the Cholesky factor `L`.
|
/// The pattern of the Cholesky factor `L`.
|
||||||
|
#[must_use]
|
||||||
pub fn l_pattern(&self) -> &SparsityPattern {
|
pub fn l_pattern(&self) -> &SparsityPattern {
|
||||||
&self.l_pattern
|
&self.l_pattern
|
||||||
}
|
}
|
||||||
@ -171,6 +172,7 @@ impl<T: RealField> CscCholesky<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the Cholesky factor `L`.
|
/// Returns a reference to the Cholesky factor `L`.
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> &CscMatrix<T> {
|
pub fn l(&self) -> &CscMatrix<T> {
|
||||||
&self.l_factor
|
&self.l_factor
|
||||||
}
|
}
|
||||||
@ -260,6 +262,7 @@ impl<T: RealField> CscCholesky<T> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `B` is not square.
|
/// Panics if `B` is not square.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<'a>(&'a self, b: impl Into<DMatrixSlice<'a, T>>) -> DMatrix<T> {
|
pub fn solve<'a>(&'a self, b: impl Into<DMatrixSlice<'a, T>>) -> DMatrix<T> {
|
||||||
let b = b.into();
|
let b = b.into();
|
||||||
let mut output = b.clone_owned();
|
let mut output = b.clone_owned();
|
||||||
|
@ -170,6 +170,7 @@ pub struct SparseFormatError {
|
|||||||
|
|
||||||
impl SparseFormatError {
|
impl SparseFormatError {
|
||||||
/// The type of error.
|
/// The type of error.
|
||||||
|
#[must_use]
|
||||||
pub fn kind(&self) -> &SparseFormatErrorKind {
|
pub fn kind(&self) -> &SparseFormatErrorKind {
|
||||||
&self.kind
|
&self.kind
|
||||||
}
|
}
|
||||||
|
@ -140,11 +140,13 @@ pub enum Op<T> {
|
|||||||
|
|
||||||
impl<T> Op<T> {
|
impl<T> Op<T> {
|
||||||
/// Returns a reference to the inner value that the operation applies to.
|
/// Returns a reference to the inner value that the operation applies to.
|
||||||
|
#[must_use]
|
||||||
pub fn inner_ref(&self) -> &T {
|
pub fn inner_ref(&self) -> &T {
|
||||||
self.as_ref().into_inner()
|
self.as_ref().into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an `Op` applied to a reference of the inner value.
|
/// Returns an `Op` applied to a reference of the inner value.
|
||||||
|
#[must_use]
|
||||||
pub fn as_ref(&self) -> Op<&T> {
|
pub fn as_ref(&self) -> Op<&T> {
|
||||||
match self {
|
match self {
|
||||||
Op::NoOp(obj) => Op::NoOp(&obj),
|
Op::NoOp(obj) => Op::NoOp(&obj),
|
||||||
|
@ -96,11 +96,13 @@ impl OperationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The operation error kind.
|
/// The operation error kind.
|
||||||
|
#[must_use]
|
||||||
pub fn kind(&self) -> &OperationErrorKind {
|
pub fn kind(&self) -> &OperationErrorKind {
|
||||||
&self.error_kind
|
&self.error_kind
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The underlying error message.
|
/// The underlying error message.
|
||||||
|
#[must_use]
|
||||||
pub fn message(&self) -> &str {
|
pub fn message(&self) -> &str {
|
||||||
self.message.as_str()
|
self.message.as_str()
|
||||||
}
|
}
|
||||||
|
@ -60,18 +60,21 @@ impl SparsityPattern {
|
|||||||
|
|
||||||
/// The offsets for the major dimension.
|
/// The offsets for the major dimension.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn major_offsets(&self) -> &[usize] {
|
pub fn major_offsets(&self) -> &[usize] {
|
||||||
&self.major_offsets
|
&self.major_offsets
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The indices for the minor dimension.
|
/// The indices for the minor dimension.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn minor_indices(&self) -> &[usize] {
|
pub fn minor_indices(&self) -> &[usize] {
|
||||||
&self.minor_indices
|
&self.minor_indices
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of major lanes in the pattern.
|
/// The number of major lanes in the pattern.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn major_dim(&self) -> usize {
|
pub fn major_dim(&self) -> usize {
|
||||||
assert!(self.major_offsets.len() > 0);
|
assert!(self.major_offsets.len() > 0);
|
||||||
self.major_offsets.len() - 1
|
self.major_offsets.len() - 1
|
||||||
@ -79,12 +82,14 @@ impl SparsityPattern {
|
|||||||
|
|
||||||
/// The number of minor lanes in the pattern.
|
/// The number of minor lanes in the pattern.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn minor_dim(&self) -> usize {
|
pub fn minor_dim(&self) -> usize {
|
||||||
self.minor_dim
|
self.minor_dim
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of "non-zeros", i.e. explicitly stored entries in the pattern.
|
/// The number of "non-zeros", i.e. explicitly stored entries in the pattern.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nnz(&self) -> usize {
|
pub fn nnz(&self) -> usize {
|
||||||
self.minor_indices.len()
|
self.minor_indices.len()
|
||||||
}
|
}
|
||||||
@ -96,12 +101,14 @@ impl SparsityPattern {
|
|||||||
///
|
///
|
||||||
/// Panics if `major_index` is out of bounds.
|
/// Panics if `major_index` is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lane(&self, major_index: usize) -> &[usize] {
|
pub fn lane(&self, major_index: usize) -> &[usize] {
|
||||||
self.get_lane(major_index).unwrap()
|
self.get_lane(major_index).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the lane at the given index, or `None` if out of bounds.
|
/// Get the lane at the given index, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_lane(&self, major_index: usize) -> Option<&[usize]> {
|
pub fn get_lane(&self, major_index: usize) -> Option<&[usize]> {
|
||||||
let offset_begin = *self.major_offsets().get(major_index)?;
|
let offset_begin = *self.major_offsets().get(major_index)?;
|
||||||
let offset_end = *self.major_offsets().get(major_index + 1)?;
|
let offset_end = *self.major_offsets().get(major_index + 1)?;
|
||||||
@ -197,6 +204,7 @@ impl SparsityPattern {
|
|||||||
/// assert_eq!(entries, vec![(0, 0), (0, 2), (1, 1), (2, 0)]);
|
/// assert_eq!(entries, vec![(0, 0), (0, 2), (1, 1), (2, 0)]);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
#[must_use]
|
||||||
pub fn entries(&self) -> SparsityPatternIter {
|
pub fn entries(&self) -> SparsityPatternIter {
|
||||||
SparsityPatternIter::from_pattern(self)
|
SparsityPatternIter::from_pattern(self)
|
||||||
}
|
}
|
||||||
@ -228,6 +236,7 @@ impl SparsityPattern {
|
|||||||
///
|
///
|
||||||
/// This is analogous to matrix transposition, i.e. an entry `(i, j)` becomes `(j, i)` in the
|
/// This is analogous to matrix transposition, i.e. an entry `(i, j)` becomes `(j, i)` in the
|
||||||
/// new pattern.
|
/// new pattern.
|
||||||
|
#[must_use]
|
||||||
pub fn transpose(&self) -> Self {
|
pub fn transpose(&self) -> Self {
|
||||||
// By using unit () values, we can use the same routines as for CSR/CSC matrices
|
// By using unit () values, we can use the same routines as for CSR/CSC matrices
|
||||||
let values = vec![(); self.nnz()];
|
let values = vec![(); self.nnz()];
|
||||||
|
@ -193,6 +193,7 @@ where
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
SB: Storage<T, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
@ -221,6 +222,7 @@ where
|
|||||||
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
@ -248,6 +250,7 @@ where
|
|||||||
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
SB: Storage<T, R2, C2>,
|
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))
|
/// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0))
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn abs(&self) -> OMatrix<T, R, C>
|
pub fn abs(&self) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
T: Signed,
|
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);* $(;)*) => {$(
|
($($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]
|
#[doc = $desc]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> MatrixComponentOp<T, R1, C1, R2, C2>
|
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> MatrixComponentOp<T, R1, C1, R2, C2>
|
||||||
where T: $Trait,
|
where T: $Trait,
|
||||||
R2: Dim, C2: Dim,
|
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)
|
/// assert_eq!(u.inf(&v), expected)
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
|
pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||||
where
|
where
|
||||||
T: SimdPartialOrd,
|
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)
|
/// assert_eq!(u.sup(&v), expected)
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
|
pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||||
where
|
where
|
||||||
T: SimdPartialOrd,
|
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)
|
/// assert_eq!(u.inf_sup(&v), expected)
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
|
pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
|
||||||
where
|
where
|
||||||
T: SimdPartialOrd,
|
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> {
|
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).
|
/// Extracts the upper triangular part of this matrix (including the diagonal).
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn upper_triangle(&self) -> OMatrix<T, R, C>
|
pub fn upper_triangle(&self) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
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).
|
/// Extracts the lower triangular part of this matrix (including the diagonal).
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lower_triangle(&self) -> OMatrix<T, R, C>
|
pub fn lower_triangle(&self) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
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`.
|
/// Creates a new matrix by extracting the given set of rows from `self`.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
#[must_use]
|
||||||
pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix<T, Dynamic, C>
|
pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix<T, Dynamic, C>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a usize>,
|
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`.
|
/// Creates a new matrix by extracting the given set of columns from `self`.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
#[must_use]
|
||||||
pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix<T, R, Dynamic>
|
pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix<T, R, Dynamic>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a usize>,
|
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
|
/// Produces a view of the data at the given index, or
|
||||||
/// `None` if the index is out of bounds.
|
/// `None` if the index is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output>
|
pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output>
|
||||||
where
|
where
|
||||||
I: MatrixIndex<'a, T, R, C, S>,
|
I: MatrixIndex<'a, T, R, C, S>,
|
||||||
@ -495,6 +496,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
|||||||
/// Produces a mutable view of the data at the given index, or
|
/// Produces a mutable view of the data at the given index, or
|
||||||
/// `None` if the index is out of bounds.
|
/// `None` if the index is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut>
|
pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut>
|
||||||
where
|
where
|
||||||
S: StorageMut<T, R, C>,
|
S: StorageMut<T, R, C>,
|
||||||
@ -506,6 +508,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
|
/// Produces a view of the data at the given index, or
|
||||||
/// panics if the index is out of bounds.
|
/// panics if the index is out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn index<'a, I>(&'a self, index: I) -> I::Output
|
pub fn index<'a, I>(&'a self, index: I) -> I::Output
|
||||||
where
|
where
|
||||||
I: MatrixIndex<'a, T, R, C, S>,
|
I: MatrixIndex<'a, T, R, C, S>,
|
||||||
@ -527,6 +530,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
|
/// Produces a view of the data at the given index, without doing
|
||||||
/// any bounds checking.
|
/// any bounds checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
|
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
|
||||||
where
|
where
|
||||||
I: MatrixIndex<'a, T, R, C, S>,
|
I: MatrixIndex<'a, T, R, C, S>,
|
||||||
@ -537,6 +541,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
|||||||
/// Returns a mutable view of the data at the given index, without doing
|
/// Returns a mutable view of the data at the given index, without doing
|
||||||
/// any bounds checking.
|
/// any bounds checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
|
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
|
||||||
where
|
where
|
||||||
S: StorageMut<T, R, C>,
|
S: StorageMut<T, R, C>,
|
||||||
|
@ -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);
|
/// 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));
|
/// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[must_use]
|
||||||
pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D>,
|
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());
|
/// assert_eq!(v, v2.normalize());
|
||||||
/// ```
|
/// ```
|
||||||
|
#[must_use]
|
||||||
pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -72,6 +74,7 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(v, v2);
|
/// assert_eq!(v, v2);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[must_use]
|
||||||
pub fn slerp<S2: Storage<T, D>>(
|
pub fn slerp<S2: Storage<T, D>>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Unit<Vector<T, D, S2>>,
|
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
|
/// Returns `None` if the two vectors are almost collinear and with opposite direction
|
||||||
/// (in this case, there is an infinity of possible results).
|
/// (in this case, there is an infinity of possible results).
|
||||||
|
#[must_use]
|
||||||
pub fn try_slerp<S2: Storage<T, D>>(
|
pub fn try_slerp<S2: Storage<T, D>>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Unit<Vector<T, D, S2>>,
|
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();
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
/// assert_eq!(mat.shape(), (3, 4));
|
/// assert_eq!(mat.shape(), (3, 4));
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn shape(&self) -> (usize, usize) {
|
pub fn shape(&self) -> (usize, usize) {
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
(nrows.value(), ncols.value())
|
(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();
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
/// assert_eq!(mat.nrows(), 3);
|
/// assert_eq!(mat.nrows(), 3);
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.shape().0
|
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();
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
/// assert_eq!(mat.ncols(), 4);
|
/// assert_eq!(mat.ncols(), 4);
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.shape().1
|
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.
|
/// // The column strides is the number of steps (here 2) multiplied by the corresponding dimension.
|
||||||
/// assert_eq!(mat.strides(), (1, 10));
|
/// assert_eq!(mat.strides(), (1, 10));
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn strides(&self) -> (usize, usize) {
|
pub fn strides(&self) -> (usize, usize) {
|
||||||
let (srows, scols) = self.data.strides();
|
let (srows, scols) = self.data.strides();
|
||||||
(srows.value(), scols.value())
|
(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]);
|
/// assert_eq!(m[i], m[3]);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn vector_to_matrix_index(&self, i: usize) -> (usize, usize) {
|
pub fn vector_to_matrix_index(&self, i: usize) -> (usize, usize) {
|
||||||
let (nrows, ncols) = self.shape();
|
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]);
|
/// assert_eq!(unsafe { *ptr }, m[0]);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_ptr(&self) -> *const T {
|
pub fn as_ptr(&self) -> *const T {
|
||||||
self.data.ptr()
|
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.
|
/// See `relative_eq` from the `RelativeEq` trait for more details.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn relative_eq<R2, C2, SB>(
|
pub fn relative_eq<R2, C2, SB>(
|
||||||
&self,
|
&self,
|
||||||
other: &Matrix<T, R2, C2, SB>,
|
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.
|
/// Tests whether `self` and `rhs` are exactly equal.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn eq<R2, C2, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> bool
|
pub fn eq<R2, C2, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> bool
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
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.
|
/// Clones this matrix to one that owns its data.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn clone_owned(&self) -> OMatrix<T, R, C>
|
pub fn clone_owned(&self) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
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
|
/// Clones this matrix into one that owns its data. The actual type of the result depends on
|
||||||
/// matrix storage combination rules for addition.
|
/// matrix storage combination rules for addition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn clone_owned_sum<R2, C2>(&self) -> MatrixSum<T, R, C, R2, C2>
|
pub fn clone_owned_sum<R2, C2>(&self) -> MatrixSum<T, R, C, R2, C2>
|
||||||
where
|
where
|
||||||
R2: Dim,
|
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> {
|
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.
|
/// Returns a matrix containing the result of `f` applied to each of its entries.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
|
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T2, R, C>,
|
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
|
/// - 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.
|
/// to compute the initial value. Folding then continues on all the remaining components of the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn fold_with<T2>(
|
pub fn fold_with<T2>(
|
||||||
&self,
|
&self,
|
||||||
init_f: impl FnOnce(Option<&T>) -> T2,
|
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`,
|
/// 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)`.
|
/// `f` also gets passed the row and column index, i.e. `f(row, col, value)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn map_with_location<T2: Scalar, F: FnMut(usize, usize, T) -> T2>(
|
pub fn map_with_location<T2: Scalar, F: FnMut(usize, usize, T) -> T2>(
|
||||||
&self,
|
&self,
|
||||||
mut f: F,
|
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
|
/// Returns a matrix containing the result of `f` applied to each entries of `self` and
|
||||||
/// `rhs`.
|
/// `rhs`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn zip_map<T2, N3, S2, F>(&self, rhs: &Matrix<T2, R, C, S2>, mut f: F) -> OMatrix<N3, R, C>
|
pub fn zip_map<T2, N3, S2, F>(&self, rhs: &Matrix<T2, R, C, S2>, mut f: F) -> OMatrix<N3, R, C>
|
||||||
where
|
where
|
||||||
T2: Scalar,
|
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
|
/// Returns a matrix containing the result of `f` applied to each entries of `self` and
|
||||||
/// `b`, and `c`.
|
/// `b`, and `c`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn zip_zip_map<T2, N3, N4, S2, S3, F>(
|
pub fn zip_zip_map<T2, N3, N4, S2, S3, F>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T2, R, C, S2>,
|
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`.
|
/// Folds a function `f` on each entry of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn fold<Acc>(&self, init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc {
|
pub fn fold<Acc>(&self, init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc {
|
||||||
let (nrows, ncols) = self.data.shape();
|
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`.
|
/// Folds a function `f` on each pairs of entries from `self` and `rhs`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn zip_fold<T2, R2, C2, S2, Acc>(
|
pub fn zip_fold<T2, R2, C2, S2, Acc>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Matrix<T2, R2, C2, S2>,
|
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> {
|
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.
|
/// Gets a reference to the i-th element of this column vector without bound checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
|
pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
|
||||||
debug_assert!(i < self.nrows(), "Vector index out of bounds.");
|
debug_assert!(i < self.nrows(), "Vector index out of bounds.");
|
||||||
let i = i * self.strides().0;
|
let i = i * self.strides().0;
|
||||||
@ -1248,6 +1266,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
|||||||
impl<T: Scalar, D: Dim, S: StorageMut<T, D>> Vector<T, D, S> {
|
impl<T: Scalar, D: Dim, S: StorageMut<T, D>> Vector<T, D, S> {
|
||||||
/// Gets a mutable reference to the i-th element of this column vector without bound checking.
|
/// Gets a mutable reference to the i-th element of this column vector without bound checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
|
pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
|
||||||
debug_assert!(i < self.nrows(), "Vector index out of bounds.");
|
debug_assert!(i < self.nrows(), "Vector index out of bounds.");
|
||||||
let i = i * self.strides().0;
|
let i = i * self.strides().0;
|
||||||
@ -1258,6 +1277,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> {
|
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.
|
/// Extracts a slice containing the entire matrix entries ordered column-by-columns.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_slice(&self) -> &[T] {
|
pub fn as_slice(&self) -> &[T] {
|
||||||
self.data.as_slice()
|
self.data.as_slice()
|
||||||
}
|
}
|
||||||
@ -1266,6 +1286,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: ContiguousStorage<T, R, C>> Matrix<T, R, C, S
|
|||||||
impl<T: Scalar, R: Dim, C: Dim, S: ContiguousStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
impl<T: Scalar, R: Dim, C: Dim, S: ContiguousStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// Extracts a mutable slice containing the entire matrix entries ordered column-by-columns.
|
/// Extracts a mutable slice containing the entire matrix entries ordered column-by-columns.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
self.data.as_mut_slice()
|
self.data.as_mut_slice()
|
||||||
}
|
}
|
||||||
@ -1446,6 +1467,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> {
|
impl<T: Scalar, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||||
/// The diagonal of this matrix.
|
/// The diagonal of this matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal(&self) -> OVector<T, D>
|
pub fn diagonal(&self) -> OVector<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
@ -1457,6 +1479,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
|
/// This is a more efficient version of `self.diagonal().map(f)` since this
|
||||||
/// allocates only once.
|
/// allocates only once.
|
||||||
|
#[must_use]
|
||||||
pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
|
pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T2, D>,
|
DefaultAllocator: Allocator<T2, D>,
|
||||||
@ -1481,6 +1504,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.
|
/// Computes a trace of a square matrix, i.e., the sum of its diagonal elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn trace(&self) -> T
|
pub fn trace(&self) -> T
|
||||||
where
|
where
|
||||||
T: Scalar + Zero + ClosedAdd,
|
T: Scalar + Zero + ClosedAdd,
|
||||||
@ -1504,6 +1528,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> {
|
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())`.
|
/// The symmetric part of `self`, i.e., `0.5 * (self + self.transpose())`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn symmetric_part(&self) -> OMatrix<T, D, D>
|
pub fn symmetric_part(&self) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
@ -1520,6 +1545,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())`.
|
/// The hermitian part of `self`, i.e., `0.5 * (self + self.adjoint())`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn hermitian_part(&self) -> OMatrix<T, D, D>
|
pub fn hermitian_part(&self) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
@ -1542,6 +1568,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
|
/// Yields the homogeneous matrix for this matrix, i.e., appending an additional dimension and
|
||||||
/// and setting the diagonal element to `1`.
|
/// and setting the diagonal element to `1`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>>,
|
DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>>,
|
||||||
@ -1562,6 +1589,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
|
/// Computes the coordinates in projective space of this vector, i.e., appends a `0` to its
|
||||||
/// coordinates.
|
/// coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
|
pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
||||||
@ -1589,6 +1617,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> {
|
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`.
|
/// Constructs a new vector of higher dimension by appending `element` to the end of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
|
pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
|
||||||
@ -1891,6 +1920,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`.
|
/// The perpendicular product between two 2D column vectors, i.e. `a.x * b.y - a.y * b.x`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn perp<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> T
|
pub fn perp<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
@ -1920,6 +1950,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
|
/// 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.
|
/// dynamically-sized matrices and statically-sized 3D matrices.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cross<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> MatrixCross<T, R, C, R2, C2>
|
pub fn cross<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> MatrixCross<T, R, C, R2, C2>
|
||||||
where
|
where
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
@ -1993,6 +2024,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> {
|
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)`.
|
/// Computes the matrix `M` such that for all vector `v` we have `M * v == self.cross(&v)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
|
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
|
||||||
OMatrix::<T, U3, U3>::new(
|
OMatrix::<T, U3, U3>::new(
|
||||||
T::zero(),
|
T::zero(),
|
||||||
@ -2011,6 +2043,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> {
|
impl<T: SimdComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// The smallest angle between two vectors.
|
/// The smallest angle between two vectors.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle<R2: Dim, C2: Dim, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> T::SimdRealField
|
pub fn angle<R2: Dim, C2: Dim, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
SB: Storage<T, R2, C2>,
|
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
|
/// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed
|
||||||
/// by the range `cols`.
|
/// by the range `cols`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn slice_range<RowRange, ColRange>(
|
pub fn slice_range<RowRange, ColRange>(
|
||||||
&self,
|
&self,
|
||||||
rows: RowRange,
|
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`.
|
/// Slice containing all the rows indexed by the range `rows`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rows_range<RowRange: SliceRange<R>>(
|
pub fn rows_range<RowRange: SliceRange<R>>(
|
||||||
&self,
|
&self,
|
||||||
rows: RowRange,
|
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`.
|
/// Slice containing all the columns indexed by the range `rows`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn columns_range<ColRange: SliceRange<C>>(
|
pub fn columns_range<ColRange: SliceRange<C>>(
|
||||||
&self,
|
&self,
|
||||||
cols: ColRange,
|
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);
|
/// assert_eq!(Vector3::new(-1.0, -2.0, -3.0).amax(), 3.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn amax(&self) -> T
|
pub fn amax(&self) -> T
|
||||||
where
|
where
|
||||||
T: Zero + SimdSigned + SimdPartialOrd,
|
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);
|
/// Complex::new(1.0, 3.0)).camax(), 5.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn camax(&self) -> T::SimdRealField
|
pub fn camax(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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);
|
/// assert_eq!(Vector3::new(5u32, 2, 3).max(), 5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn max(&self) -> T
|
pub fn max(&self) -> T
|
||||||
where
|
where
|
||||||
T: SimdPartialOrd + Zero,
|
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);
|
/// assert_eq!(Vector3::new(10.0, 2.0, 30.0).amin(), 2.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn amin(&self) -> T
|
pub fn amin(&self) -> T
|
||||||
where
|
where
|
||||||
T: Zero + SimdPartialOrd + SimdSigned,
|
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);
|
/// Complex::new(1.0, 3.0)).camin(), 3.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn camin(&self) -> T::SimdRealField
|
pub fn camin(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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);
|
/// assert_eq!(Vector3::new(5u32, 2, 3).min(), 2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn min(&self) -> T
|
pub fn min(&self) -> T
|
||||||
where
|
where
|
||||||
T: SimdPartialOrd + Zero,
|
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));
|
/// assert_eq!(mat.icamax_full(), (1, 0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn icamax_full(&self) -> (usize, usize)
|
pub fn icamax_full(&self) -> (usize, usize)
|
||||||
where
|
where
|
||||||
T: ComplexField,
|
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));
|
/// assert_eq!(mat.iamax_full(), (1, 2));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn iamax_full(&self) -> (usize, usize) {
|
pub fn iamax_full(&self) -> (usize, usize) {
|
||||||
assert!(!self.is_empty(), "The input matrix must not be empty.");
|
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);
|
/// assert_eq!(vec.icamax(), 2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn icamax(&self) -> usize
|
pub fn icamax(&self) -> usize
|
||||||
where
|
where
|
||||||
T: ComplexField,
|
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));
|
/// assert_eq!(vec.argmax(), (2, 13));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn argmax(&self) -> (usize, T)
|
pub fn argmax(&self) -> (usize, T)
|
||||||
where
|
where
|
||||||
T: PartialOrd,
|
T: PartialOrd,
|
||||||
@ -271,6 +281,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
|||||||
/// assert_eq!(vec.imax(), 2);
|
/// assert_eq!(vec.imax(), 2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn imax(&self) -> usize
|
pub fn imax(&self) -> usize
|
||||||
where
|
where
|
||||||
T: PartialOrd,
|
T: PartialOrd,
|
||||||
@ -288,6 +299,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
|||||||
/// assert_eq!(vec.iamax(), 1);
|
/// assert_eq!(vec.iamax(), 1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn iamax(&self) -> usize
|
pub fn iamax(&self) -> usize
|
||||||
where
|
where
|
||||||
T: PartialOrd + Signed,
|
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));
|
/// assert_eq!(vec.argmin(), (1, -15));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn argmin(&self) -> (usize, T)
|
pub fn argmin(&self) -> (usize, T)
|
||||||
where
|
where
|
||||||
T: PartialOrd,
|
T: PartialOrd,
|
||||||
@ -350,6 +363,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
|||||||
/// assert_eq!(vec.imin(), 1);
|
/// assert_eq!(vec.imin(), 1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn imin(&self) -> usize
|
pub fn imin(&self) -> usize
|
||||||
where
|
where
|
||||||
T: PartialOrd,
|
T: PartialOrd,
|
||||||
@ -367,6 +381,7 @@ impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
|
|||||||
/// assert_eq!(vec.iamin(), 0);
|
/// assert_eq!(vec.iamin(), 0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn iamin(&self) -> usize
|
pub fn iamin(&self) -> usize
|
||||||
where
|
where
|
||||||
T: PartialOrd + Signed,
|
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> {
|
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// The squared L2 norm of this vector.
|
/// The squared L2 norm of this vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn norm_squared(&self) -> T::SimdRealField
|
pub fn norm_squared(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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.
|
/// Use `.apply_norm` to apply a custom norm.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn norm(&self) -> T::SimdRealField
|
pub fn norm(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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.
|
/// Use `.apply_metric_distance` to apply a custom norm.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn metric_distance<R2, C2, S2>(&self, rhs: &Matrix<T, R2, C2, S2>) -> T::SimdRealField
|
pub fn metric_distance<R2, C2, S2>(&self, rhs: &Matrix<T, R2, C2, S2>) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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());
|
/// assert_eq!(v.apply_norm(&EuclideanNorm), v.norm());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn apply_norm(&self, norm: &impl Norm<T>) -> T::SimdRealField
|
pub fn apply_norm(&self, norm: &impl Norm<T>) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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());
|
/// assert_eq!(v1.apply_metric_distance(&v2, &EuclideanNorm), (v1 - v2).norm());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn apply_metric_distance<R2, C2, S2>(
|
pub fn apply_metric_distance<R2, C2, S2>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Matrix<T, R2, C2, S2>,
|
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()`
|
/// This function is simply implemented as a call to `norm()`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn magnitude(&self) -> T::SimdRealField
|
pub fn magnitude(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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()`
|
/// This function is simply implemented as a call to `norm_squared()`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn magnitude_squared(&self) -> T::SimdRealField
|
pub fn magnitude_squared(&self) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
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.
|
/// The Lp norm of this matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lp_norm(&self, p: i32) -> T::SimdRealField
|
pub fn lp_norm(&self, p: i32) -> T::SimdRealField
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
@ -341,6 +349,7 @@ 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`.
|
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cap_magnitude(&self, max: T::RealField) -> OMatrix<T, R, C>
|
pub fn cap_magnitude(&self, max: T::RealField) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
T: ComplexField,
|
T: ComplexField,
|
||||||
@ -357,6 +366,7 @@ 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`.
|
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn simd_cap_magnitude(&self, max: T::SimdRealField) -> OMatrix<T, R, C>
|
pub fn simd_cap_magnitude(&self, max: T::SimdRealField) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
|
@ -676,6 +676,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Equivalent to `self.transpose() * rhs`.
|
/// Equivalent to `self.transpose() * rhs`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn tr_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
pub fn tr_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
||||||
where
|
where
|
||||||
SB: Storage<T, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
@ -692,6 +693,7 @@ where
|
|||||||
|
|
||||||
/// Equivalent to `self.adjoint() * rhs`.
|
/// Equivalent to `self.adjoint() * rhs`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ad_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
pub fn ad_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
|
||||||
where
|
where
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
@ -801,6 +803,7 @@ where
|
|||||||
|
|
||||||
/// The kronecker product of two matrices (aka. tensor product of the corresponding linear
|
/// The kronecker product of two matrices (aka. tensor product of the corresponding linear
|
||||||
/// maps).
|
/// maps).
|
||||||
|
#[must_use]
|
||||||
pub fn kronecker<R2: Dim, C2: Dim, SB>(
|
pub fn kronecker<R2: Dim, C2: Dim, SB>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Matrix<T, R2, C2, SB>,
|
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);
|
/// assert_eq!(mat.len(), 12);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
nrows * ncols
|
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());
|
/// assert!(!mat.is_empty());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates if this is a square matrix.
|
/// Indicates if this is a square matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_square(&self) -> bool {
|
pub fn is_square(&self) -> bool {
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
nrows == ncols
|
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)`
|
/// 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.
|
/// for i from `0` to `min(R, C)`) are equal one; and that all other elements are zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_identity(&self, eps: T::Epsilon) -> bool
|
pub fn is_identity(&self, eps: T::Epsilon) -> bool
|
||||||
where
|
where
|
||||||
T: Zero + One + RelativeEq,
|
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
|
/// In this definition `Id` is approximately equal to the identity matrix with a relative error
|
||||||
/// equal to `eps`.
|
/// equal to `eps`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_orthogonal(&self, eps: T::Epsilon) -> bool
|
pub fn is_orthogonal(&self, eps: T::Epsilon) -> bool
|
||||||
where
|
where
|
||||||
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
|
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
|
||||||
@ -129,6 +134,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Checks that this matrix is orthogonal and has a determinant equal to 1.
|
/// Checks that this matrix is orthogonal and has a determinant equal to 1.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_special_orthogonal(&self, eps: T) -> bool
|
pub fn is_special_orthogonal(&self, eps: T) -> bool
|
||||||
where
|
where
|
||||||
D: DimMin<D, Output = D>,
|
D: DimMin<D, Output = D>,
|
||||||
@ -139,6 +145,7 @@ where
|
|||||||
|
|
||||||
/// Returns `true` if this matrix is invertible.
|
/// Returns `true` if this matrix is invertible.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_invertible(&self) -> bool {
|
pub fn is_invertible(&self) -> bool {
|
||||||
// TODO: improve this?
|
// TODO: improve this?
|
||||||
self.clone_owned().try_inverse().is_some()
|
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
|
/// Returns a row vector where each element is the result of the application of `f` on the
|
||||||
/// corresponding column of the original matrix.
|
/// corresponding column of the original matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn compress_rows(
|
pub fn compress_rows(
|
||||||
&self,
|
&self,
|
||||||
f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
|
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()`.
|
/// This is the same as `self.compress_rows(f).transpose()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn compress_rows_tr(
|
pub fn compress_rows_tr(
|
||||||
&self,
|
&self,
|
||||||
f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
|
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.
|
/// Returns a column vector resulting from the folding of `f` on each column of this matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn compress_columns(
|
pub fn compress_columns(
|
||||||
&self,
|
&self,
|
||||||
init: OVector<T, R>,
|
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);
|
/// assert_eq!(m.sum(), 21.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sum(&self) -> T
|
pub fn sum(&self) -> T
|
||||||
where
|
where
|
||||||
T: ClosedAdd + Zero,
|
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));
|
/// assert_eq!(mint.row_sum(), RowVector2::new(9,12));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_sum(&self) -> RowOVector<T, C>
|
pub fn row_sum(&self) -> RowOVector<T, C>
|
||||||
where
|
where
|
||||||
T: ClosedAdd + Zero,
|
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));
|
/// assert_eq!(mint.row_sum_tr(), Vector2::new(9,12));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_sum_tr(&self) -> OVector<T, C>
|
pub fn row_sum_tr(&self) -> OVector<T, C>
|
||||||
where
|
where
|
||||||
T: ClosedAdd + Zero,
|
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));
|
/// assert_eq!(mint.column_sum(), Vector3::new(3,7,11));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn column_sum(&self) -> OVector<T, R>
|
pub fn column_sum(&self) -> OVector<T, R>
|
||||||
where
|
where
|
||||||
T: ClosedAdd + Zero,
|
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);
|
/// assert_relative_eq!(m.variance(), 35.0 / 12.0, epsilon = 1.0e-8);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn variance(&self) -> T
|
pub fn variance(&self) -> T
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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));
|
/// assert_eq!(m.row_variance(), RowVector3::new(2.25, 2.25, 2.25));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_variance(&self) -> RowOVector<T, C>
|
pub fn row_variance(&self) -> RowOVector<T, C>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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));
|
/// assert_eq!(m.row_variance_tr(), Vector3::new(2.25, 2.25, 2.25));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_variance_tr(&self) -> OVector<T, C>
|
pub fn row_variance_tr(&self) -> OVector<T, C>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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);
|
/// assert_relative_eq!(m.column_variance(), Vector2::new(2.0 / 3.0, 2.0 / 3.0), epsilon = 1.0e-8);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn column_variance(&self) -> OVector<T, R>
|
pub fn column_variance(&self) -> OVector<T, R>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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);
|
/// assert_eq!(m.mean(), 3.5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn mean(&self) -> T
|
pub fn mean(&self) -> T
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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));
|
/// assert_eq!(m.row_mean(), RowVector3::new(2.5, 3.5, 4.5));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_mean(&self) -> RowOVector<T, C>
|
pub fn row_mean(&self) -> RowOVector<T, C>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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));
|
/// assert_eq!(m.row_mean_tr(), Vector3::new(2.5, 3.5, 4.5));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn row_mean_tr(&self) -> OVector<T, C>
|
pub fn row_mean_tr(&self) -> OVector<T, C>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
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));
|
/// assert_eq!(m.column_mean(), Vector2::new(2.0, 5.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn column_mean(&self) -> OVector<T, R>
|
pub fn column_mean(&self) -> OVector<T, R>
|
||||||
where
|
where
|
||||||
T: Field + SupersetOf<f64>,
|
T: Field + SupersetOf<f64>,
|
||||||
|
@ -8,6 +8,7 @@ macro_rules! impl_swizzle {
|
|||||||
$(
|
$(
|
||||||
/// Builds a new vector from components of `self`.
|
/// Builds a new vector from components of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn $name(&self) -> $Result<T>
|
pub fn $name(&self) -> $Result<T>
|
||||||
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||||
$Result::new($(self[$i].inlined_clone()),*)
|
$Result::new($(self[$i].inlined_clone()),*)
|
||||||
|
@ -95,6 +95,7 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
|
|||||||
|
|
||||||
/// The underlying data storage.
|
/// The underlying data storage.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_vec(&self) -> &Vec<T> {
|
pub fn as_vec(&self) -> &Vec<T> {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
@ -129,12 +130,14 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
|
|||||||
|
|
||||||
/// The number of elements on the underlying vector.
|
/// The number of elements on the underlying vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.data.len()
|
self.data.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the underlying vector contains no elements.
|
/// Returns true if the underlying vector contains no elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,7 @@ where
|
|||||||
/// ));
|
/// ));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||||
self * (T::one() - t) + other * t
|
self * (T::one() - t) + other * t
|
||||||
}
|
}
|
||||||
@ -381,6 +382,7 @@ where
|
|||||||
/// ));
|
/// ));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn dual_quaternion(&self) -> &DualQuaternion<T> {
|
pub fn dual_quaternion(&self) -> &DualQuaternion<T> {
|
||||||
self.as_ref()
|
self.as_ref()
|
||||||
}
|
}
|
||||||
@ -463,7 +465,6 @@ where
|
|||||||
/// assert_relative_eq!(inv * unit, UnitDualQuaternion::identity(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(inv * unit, UnitDualQuaternion::identity(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
|
||||||
pub fn inverse_mut(&mut self) {
|
pub fn inverse_mut(&mut self) {
|
||||||
let quat = self.as_mut_unchecked();
|
let quat = self.as_mut_unchecked();
|
||||||
quat.real = Unit::new_unchecked(quat.real).inverse().into_inner();
|
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);
|
/// assert_relative_eq!(dq_to * dq1, dq2, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn isometry_to(&self, other: &Self) -> Self {
|
pub fn isometry_to(&self, other: &Self) -> Self {
|
||||||
other / self
|
other / self
|
||||||
}
|
}
|
||||||
@ -518,6 +520,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> DualQuaternion<T> {
|
pub fn lerp(&self, other: &Self, t: T) -> DualQuaternion<T> {
|
||||||
self.as_ref().lerp(other.as_ref(), t)
|
self.as_ref().lerp(other.as_ref(), t)
|
||||||
}
|
}
|
||||||
@ -546,6 +549,7 @@ where
|
|||||||
/// ), epsilon = 1.0e-6);
|
/// ), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
||||||
let mut res = self.lerp(other, t);
|
let mut res = self.lerp(other, t);
|
||||||
let _ = res.normalize_mut();
|
let _ = res.normalize_mut();
|
||||||
@ -581,6 +585,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// assert_relative_eq!(dq.translation().vector.y, 3.0, epsilon = 1.0e-6);
|
/// assert_relative_eq!(dq.translation().vector.y, 3.0, epsilon = 1.0e-6);
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sclerp(&self, other: &Self, t: T) -> Self
|
pub fn sclerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -600,6 +605,7 @@ where
|
|||||||
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
||||||
/// must be to return `None`.
|
/// must be to return `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn try_sclerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
pub fn try_sclerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -667,6 +673,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rotation(&self) -> UnitQuaternion<T> {
|
pub fn rotation(&self) -> UnitQuaternion<T> {
|
||||||
Unit::new_unchecked(self.as_ref().real)
|
Unit::new_unchecked(self.as_ref().real)
|
||||||
}
|
}
|
||||||
@ -686,6 +693,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn translation(&self) -> Translation3<T> {
|
pub fn translation(&self) -> Translation3<T> {
|
||||||
let two = T::one() + T::one();
|
let two = T::one() + T::one();
|
||||||
Translation3::from(
|
Translation3::from(
|
||||||
@ -712,6 +720,7 @@ where
|
|||||||
/// assert_relative_eq!(iso.translation.vector, translation, epsilon = 1.0e-6);
|
/// assert_relative_eq!(iso.translation.vector, translation, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_isometry(&self) -> Isometry3<T> {
|
pub fn to_isometry(&self) -> Isometry3<T> {
|
||||||
Isometry3::from_parts(self.translation(), self.rotation())
|
Isometry3::from_parts(self.translation(), self.rotation())
|
||||||
}
|
}
|
||||||
@ -735,6 +744,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -758,6 +768,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -781,6 +792,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||||
self.inverse() * pt
|
self.inverse() * pt
|
||||||
}
|
}
|
||||||
@ -805,6 +817,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -830,6 +843,7 @@ where
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -857,6 +871,7 @@ where
|
|||||||
/// assert_relative_eq!(dq.to_homogeneous(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(dq.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||||
self.to_isometry().to_homogeneous()
|
self.to_isometry().to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,7 @@ where
|
|||||||
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
|
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
|
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
|
||||||
let inv_rot1 = self.rotation.inverse();
|
let inv_rot1 = self.rotation.inverse();
|
||||||
let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone();
|
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);
|
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, 2.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -407,6 +409,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -429,6 +432,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Point3::new(0.0, 2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Point3::new(0.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self.rotation
|
self.rotation
|
||||||
.inverse_transform_point(&(pt - &self.translation.vector))
|
.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);
|
/// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self.rotation.inverse_transform_vector(v)
|
self.rotation.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
@ -476,6 +481,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
||||||
self.rotation.inverse_transform_unit_vector(v)
|
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);
|
/// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
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);
|
/// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_matrix(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
pub fn to_matrix(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
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));
|
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
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));
|
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
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));
|
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
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));
|
/// assert_eq!(iso3.rotation.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
pub fn try_lerp_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -163,6 +167,7 @@ impl<T: SimdRealField> Isometry2<T> {
|
|||||||
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -199,6 +204,7 @@ impl<T: SimdRealField> IsometryMatrix2<T> {
|
|||||||
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
/// assert_relative_eq!(iso3.rotation.angle(), std::f32::consts::FRAC_PI_2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
pub fn lerp_slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
|
@ -188,6 +188,7 @@ impl<T: RealField> Orthographic3<T> {
|
|||||||
/// assert_relative_eq!(proj.as_matrix() * inv, Matrix4::identity());
|
/// assert_relative_eq!(proj.as_matrix() * inv, Matrix4::identity());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse(&self) -> Matrix4<T> {
|
pub fn inverse(&self) -> Matrix4<T> {
|
||||||
let mut res = self.to_homogeneous();
|
let mut res = self.to_homogeneous();
|
||||||
|
|
||||||
@ -221,6 +222,7 @@ impl<T: RealField> Orthographic3<T> {
|
|||||||
/// assert_eq!(proj.to_homogeneous(), expected);
|
/// assert_eq!(proj.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||||
self.matrix
|
self.matrix
|
||||||
}
|
}
|
||||||
@ -240,6 +242,7 @@ impl<T: RealField> Orthographic3<T> {
|
|||||||
/// assert_eq!(*proj.as_matrix(), expected);
|
/// assert_eq!(*proj.as_matrix(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_matrix(&self) -> &Matrix4<T> {
|
pub fn as_matrix(&self) -> &Matrix4<T> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
@ -253,6 +256,7 @@ impl<T: RealField> Orthographic3<T> {
|
|||||||
/// assert_eq!(proj.as_projective().to_homogeneous(), proj.to_homogeneous());
|
/// assert_eq!(proj.as_projective().to_homogeneous(), proj.to_homogeneous());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_projective(&self) -> &Projective3<T> {
|
pub fn as_projective(&self) -> &Projective3<T> {
|
||||||
unsafe { mem::transmute(self) }
|
unsafe { mem::transmute(self) }
|
||||||
}
|
}
|
||||||
@ -266,6 +270,7 @@ impl<T: RealField> Orthographic3<T> {
|
|||||||
/// assert_eq!(proj.to_projective().to_homogeneous(), proj.to_homogeneous());
|
/// assert_eq!(proj.to_projective().to_homogeneous(), proj.to_homogeneous());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_projective(&self) -> Projective3<T> {
|
pub fn to_projective(&self) -> Projective3<T> {
|
||||||
Projective3::from_matrix_unchecked(self.matrix)
|
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);
|
/// assert_relative_eq!(proj.left(), 10.0, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn left(&self) -> T {
|
pub fn left(&self) -> T {
|
||||||
(-T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
(-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);
|
/// assert_relative_eq!(proj.right(), 1.0, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn right(&self) -> T {
|
pub fn right(&self) -> T {
|
||||||
(T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
(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);
|
/// assert_relative_eq!(proj.bottom(), 20.0, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn bottom(&self) -> T {
|
pub fn bottom(&self) -> T {
|
||||||
(-T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
(-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);
|
/// assert_relative_eq!(proj.top(), 2.0, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn top(&self) -> T {
|
pub fn top(&self) -> T {
|
||||||
(T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
(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);
|
/// assert_relative_eq!(proj.znear(), 1000.0, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn znear(&self) -> T {
|
pub fn znear(&self) -> T {
|
||||||
(T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
(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);
|
/// assert_relative_eq!(proj.zfar(), 0.1, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn zfar(&self) -> T {
|
pub fn zfar(&self) -> T {
|
||||||
(-T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
(-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));
|
/// assert_relative_eq!(proj.project_point(&p8), Point3::new( 1.0, 1.0, 1.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.matrix[(0, 0)] * p[0] + self.matrix[(0, 3)],
|
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);
|
/// assert_relative_eq!(proj.unproject_point(&p8), Point3::new(10.0, 20.0, -1000.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
(p[0] - self.matrix[(0, 3)]) / self.matrix[(0, 0)],
|
(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);
|
/// assert_relative_eq!(proj.project_vector(&v3), Vector3::z() * -2.0 / 999.9);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
||||||
where
|
where
|
||||||
SB: Storage<T, U3>,
|
SB: Storage<T, U3>,
|
||||||
|
@ -104,6 +104,7 @@ impl<T: RealField> Perspective3<T> {
|
|||||||
|
|
||||||
/// Retrieves the inverse of the underlying homogeneous matrix.
|
/// Retrieves the inverse of the underlying homogeneous matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse(&self) -> Matrix4<T> {
|
pub fn inverse(&self) -> Matrix4<T> {
|
||||||
let mut res = self.to_homogeneous();
|
let mut res = self.to_homogeneous();
|
||||||
|
|
||||||
@ -123,24 +124,28 @@ impl<T: RealField> Perspective3<T> {
|
|||||||
|
|
||||||
/// Computes the corresponding homogeneous matrix.
|
/// Computes the corresponding homogeneous matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||||
self.matrix.clone_owned()
|
self.matrix.clone_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reference to the underlying homogeneous transformation matrix.
|
/// A reference to the underlying homogeneous transformation matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_matrix(&self) -> &Matrix4<T> {
|
pub fn as_matrix(&self) -> &Matrix4<T> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reference to this transformation seen as a `Projective3`.
|
/// A reference to this transformation seen as a `Projective3`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_projective(&self) -> &Projective3<T> {
|
pub fn as_projective(&self) -> &Projective3<T> {
|
||||||
unsafe { mem::transmute(self) }
|
unsafe { mem::transmute(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This transformation seen as a `Projective3`.
|
/// This transformation seen as a `Projective3`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_projective(&self) -> Projective3<T> {
|
pub fn to_projective(&self) -> Projective3<T> {
|
||||||
Projective3::from_matrix_unchecked(self.matrix)
|
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.
|
/// Gets the `width / height` aspect ratio of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn aspect(&self) -> T {
|
pub fn aspect(&self) -> T {
|
||||||
self.matrix[(1, 1)] / self.matrix[(0, 0)]
|
self.matrix[(1, 1)] / self.matrix[(0, 0)]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the y field of view of the view frustum.
|
/// Gets the y field of view of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn fovy(&self) -> T {
|
pub fn fovy(&self) -> T {
|
||||||
(T::one() / self.matrix[(1, 1)]).atan() * crate::convert(2.0)
|
(T::one() / self.matrix[(1, 1)]).atan() * crate::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the near plane offset of the view frustum.
|
/// Gets the near plane offset of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn znear(&self) -> T {
|
pub fn znear(&self) -> T {
|
||||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
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.
|
/// Gets the far plane offset of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn zfar(&self) -> T {
|
pub fn zfar(&self) -> T {
|
||||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
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.
|
// TODO: when we get specialization, specialize the Mul impl instead.
|
||||||
/// Projects a point. Faster than matrix multiplication.
|
/// Projects a point. Faster than matrix multiplication.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
let inverse_denom = -T::one() / p[2];
|
let inverse_denom = -T::one() / p[2];
|
||||||
Point3::new(
|
Point3::new(
|
||||||
@ -204,6 +214,7 @@ impl<T: RealField> Perspective3<T> {
|
|||||||
|
|
||||||
/// Un-projects a point. Faster than multiplication by the matrix inverse.
|
/// Un-projects a point. Faster than multiplication by the matrix inverse.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
let inverse_denom = self.matrix[(2, 3)] / (p[2] + self.matrix[(2, 2)]);
|
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.
|
// TODO: when we get specialization, specialize the Mul impl instead.
|
||||||
/// Projects a vector. Faster than matrix multiplication.
|
/// Projects a vector. Faster than matrix multiplication.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
pub fn project_vector<SB>(&self, p: &Vector<T, U3, SB>) -> Vector3<T>
|
||||||
where
|
where
|
||||||
SB: Storage<T, U3>,
|
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));
|
/// assert_eq!(p.map(|e| e as u32), Point3::new(1, 2, 3));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, f: F) -> Point<T2, D> {
|
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, f: F) -> Point<T2, D> {
|
||||||
self.coords.map(f).into()
|
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));
|
/// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<Const<D>, U1>>
|
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
T: One,
|
T: One,
|
||||||
@ -199,6 +201,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
|||||||
/// assert_eq!(p.len(), 3);
|
/// assert_eq!(p.len(), 3);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.coords.len()
|
self.coords.len()
|
||||||
}
|
}
|
||||||
@ -212,6 +215,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
|||||||
/// assert!(!p.is_empty());
|
/// assert!(!p.is_empty());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
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.
|
/// Gets a reference to i-th element of this point without bound-checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked(&self, i: usize) -> &T {
|
pub unsafe fn get_unchecked(&self, i: usize) -> &T {
|
||||||
self.coords.vget_unchecked(i)
|
self.coords.vget_unchecked(i)
|
||||||
}
|
}
|
||||||
@ -272,6 +277,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
|
|||||||
|
|
||||||
/// Gets a mutable reference to i-th element of this point without bound-checking.
|
/// Gets a mutable reference to i-th element of this point without bound-checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked_mut(&mut self, i: usize) -> &mut T {
|
pub unsafe fn get_unchecked_mut(&mut self, i: usize) -> &mut T {
|
||||||
self.coords.vget_unchecked_mut(i)
|
self.coords.vget_unchecked_mut(i)
|
||||||
}
|
}
|
||||||
@ -378,18 +384,21 @@ impl<T: Scalar + PartialOrd, const D: usize> PartialOrd for Point<T, D> {
|
|||||||
impl<T: Scalar + SimdPartialOrd, const D: usize> Point<T, D> {
|
impl<T: Scalar + SimdPartialOrd, const D: usize> Point<T, D> {
|
||||||
/// Computes the infimum (aka. componentwise min) of two points.
|
/// Computes the infimum (aka. componentwise min) of two points.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inf(&self, other: &Self) -> Point<T, D> {
|
pub fn inf(&self, other: &Self) -> Point<T, D> {
|
||||||
self.coords.inf(&other.coords).into()
|
self.coords.inf(&other.coords).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the supremum (aka. componentwise max) of two points.
|
/// Computes the supremum (aka. componentwise max) of two points.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sup(&self, other: &Self) -> Point<T, D> {
|
pub fn sup(&self, other: &Self) -> Point<T, D> {
|
||||||
self.coords.sup(&other.coords).into()
|
self.coords.sup(&other.coords).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the (infimum, supremum) of two points.
|
/// Computes the (infimum, supremum) of two points.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inf_sup(&self, other: &Self) -> (Point<T, D>, Point<T, D>) {
|
pub fn inf_sup(&self, other: &Self) -> (Point<T, D>, Point<T, D>) {
|
||||||
let (inf, sup) = self.coords.inf_sup(&other.coords);
|
let (inf, sup) = self.coords.inf_sup(&other.coords);
|
||||||
(inf.into(), sup.into())
|
(inf.into(), sup.into())
|
||||||
|
@ -191,6 +191,7 @@ where
|
|||||||
|
|
||||||
/// The imaginary part of this quaternion.
|
/// The imaginary part of this quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn imag(&self) -> Vector3<T> {
|
pub fn imag(&self) -> Vector3<T> {
|
||||||
self.coords.xyz()
|
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));
|
/// assert_eq!(q1.lerp(&q2, 0.1), Quaternion::new(1.9, 3.8, 5.7, 7.6));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||||
self * (T::one() - t) + other * t
|
self * (T::one() - t) + other * t
|
||||||
}
|
}
|
||||||
@ -238,6 +240,7 @@ where
|
|||||||
/// assert_eq!(q.vector()[2], 4.0);
|
/// assert_eq!(q.vector()[2], 4.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn vector(&self) -> MatrixSlice<T, U3, U1, RStride<T, U4, U1>, CStride<T, U4, U1>> {
|
pub fn vector(&self) -> MatrixSlice<T, U3, U1, RStride<T, U4, U1>, CStride<T, U4, U1>> {
|
||||||
self.coords.fixed_rows::<3>(0)
|
self.coords.fixed_rows::<3>(0)
|
||||||
}
|
}
|
||||||
@ -251,6 +254,7 @@ where
|
|||||||
/// assert_eq!(q.scalar(), 1.0);
|
/// assert_eq!(q.scalar(), 1.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scalar(&self) -> T {
|
pub fn scalar(&self) -> T {
|
||||||
self.coords[3]
|
self.coords[3]
|
||||||
}
|
}
|
||||||
@ -266,6 +270,7 @@ where
|
|||||||
/// assert_eq!(*q.as_vector(), Vector4::new(2.0, 3.0, 4.0, 1.0));
|
/// assert_eq!(*q.as_vector(), Vector4::new(2.0, 3.0, 4.0, 1.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn as_vector(&self) -> &Vector4<T> {
|
pub fn as_vector(&self) -> &Vector4<T> {
|
||||||
&self.coords
|
&self.coords
|
||||||
}
|
}
|
||||||
@ -280,6 +285,7 @@ where
|
|||||||
/// assert_relative_eq!(q.norm(), 5.47722557, epsilon = 1.0e-6);
|
/// assert_relative_eq!(q.norm(), 5.47722557, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn norm(&self) -> T {
|
pub fn norm(&self) -> T {
|
||||||
self.coords.norm()
|
self.coords.norm()
|
||||||
}
|
}
|
||||||
@ -297,6 +303,7 @@ where
|
|||||||
/// assert_relative_eq!(q.magnitude(), 5.47722557, epsilon = 1.0e-6);
|
/// assert_relative_eq!(q.magnitude(), 5.47722557, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn magnitude(&self) -> T {
|
pub fn magnitude(&self) -> T {
|
||||||
self.norm()
|
self.norm()
|
||||||
}
|
}
|
||||||
@ -310,6 +317,7 @@ where
|
|||||||
/// assert_eq!(q.magnitude_squared(), 30.0);
|
/// assert_eq!(q.magnitude_squared(), 30.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn norm_squared(&self) -> T {
|
pub fn norm_squared(&self) -> T {
|
||||||
self.coords.norm_squared()
|
self.coords.norm_squared()
|
||||||
}
|
}
|
||||||
@ -326,6 +334,7 @@ where
|
|||||||
/// assert_eq!(q.magnitude_squared(), 30.0);
|
/// assert_eq!(q.magnitude_squared(), 30.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn magnitude_squared(&self) -> T {
|
pub fn magnitude_squared(&self) -> T {
|
||||||
self.norm_squared()
|
self.norm_squared()
|
||||||
}
|
}
|
||||||
@ -340,6 +349,7 @@ where
|
|||||||
/// assert_eq!(q1.dot(&q2), 70.0);
|
/// assert_eq!(q1.dot(&q2), 70.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn dot(&self, rhs: &Self) -> T {
|
pub fn dot(&self, rhs: &Self) -> T {
|
||||||
self.coords.dot(&rhs.coords)
|
self.coords.dot(&rhs.coords)
|
||||||
}
|
}
|
||||||
@ -409,6 +419,7 @@ where
|
|||||||
/// let result = a.inner(&b);
|
/// let result = a.inner(&b);
|
||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inner(&self, other: &Self) -> Self {
|
pub fn inner(&self, other: &Self) -> Self {
|
||||||
(self * other + other * self).half()
|
(self * other + other * self).half()
|
||||||
}
|
}
|
||||||
@ -428,6 +439,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn outer(&self, other: &Self) -> Self {
|
pub fn outer(&self, other: &Self) -> Self {
|
||||||
#[allow(clippy::eq_op)]
|
#[allow(clippy::eq_op)]
|
||||||
(self * other - other * self).half()
|
(self * other - other * self).half()
|
||||||
@ -448,6 +460,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn project(&self, other: &Self) -> Option<Self>
|
pub fn project(&self, other: &Self) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -470,6 +483,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn reject(&self, other: &Self) -> Option<Self>
|
pub fn reject(&self, other: &Self) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -492,6 +506,7 @@ where
|
|||||||
/// assert_eq!(half_ang, f32::consts::FRAC_PI_2);
|
/// assert_eq!(half_ang, f32::consts::FRAC_PI_2);
|
||||||
/// assert_eq!(axis, Some(Vector3::x_axis()));
|
/// assert_eq!(axis, Some(Vector3::x_axis()));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[must_use]
|
||||||
pub fn polar_decomposition(&self) -> (T, T, Option<Unit<Vector3<T>>>)
|
pub fn polar_decomposition(&self) -> (T, T, Option<Unit<Vector3<T>>>)
|
||||||
where
|
where
|
||||||
T: RealField,
|
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)
|
/// assert_relative_eq!(q.ln(), Quaternion::new(1.683647, 1.190289, 0.0, 0.0), epsilon = 1.0e-6)
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ln(&self) -> Self {
|
pub fn ln(&self) -> Self {
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
let v = self.vector();
|
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)
|
/// assert_relative_eq!(q.exp(), Quaternion::new(2.0, 5.0, 0.0, 0.0), epsilon = 1.0e-5)
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn exp(&self) -> Self {
|
pub fn exp(&self) -> Self {
|
||||||
self.exp_eps(T::simd_default_epsilon())
|
self.exp_eps(T::simd_default_epsilon())
|
||||||
}
|
}
|
||||||
@ -556,6 +573,7 @@ where
|
|||||||
/// assert_eq!(q.exp_eps(1.0e-6), Quaternion::identity());
|
/// assert_eq!(q.exp_eps(1.0e-6), Quaternion::identity());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn exp_eps(&self, eps: T) -> Self {
|
pub fn exp_eps(&self, eps: T) -> Self {
|
||||||
let v = self.vector();
|
let v = self.vector();
|
||||||
let nn = v.norm_squared();
|
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);
|
/// assert_relative_eq!(q.powf(1.5), Quaternion::new( -6.2576659, 4.1549037, 6.2323556, 8.3098075), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn powf(&self, n: T) -> Self {
|
pub fn powf(&self, n: T) -> Self {
|
||||||
(self.ln() * n).exp()
|
(self.ln() * n).exp()
|
||||||
}
|
}
|
||||||
@ -674,18 +693,21 @@ where
|
|||||||
|
|
||||||
/// Calculates square of a quaternion.
|
/// Calculates square of a quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn squared(&self) -> Self {
|
pub fn squared(&self) -> Self {
|
||||||
self * self
|
self * self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides quaternion into two.
|
/// Divides quaternion into two.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn half(&self) -> Self {
|
pub fn half(&self) -> Self {
|
||||||
self / crate::convert(2.0f64)
|
self / crate::convert(2.0f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates square root.
|
/// Calculates square root.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sqrt(&self) -> Self {
|
pub fn sqrt(&self) -> Self {
|
||||||
self.powf(crate::convert(0.5))
|
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`).
|
/// A quaternion is pure if it has no real part (`self.w == 0.0`).
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_pure(&self) -> bool {
|
pub fn is_pure(&self) -> bool {
|
||||||
self.w.is_zero()
|
self.w.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert quaternion to pure quaternion.
|
/// Convert quaternion to pure quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn pure(&self) -> Self {
|
pub fn pure(&self) -> Self {
|
||||||
Self::from_imag(self.imag())
|
Self::from_imag(self.imag())
|
||||||
}
|
}
|
||||||
@ -708,6 +732,7 @@ where
|
|||||||
///
|
///
|
||||||
/// Calculates B<sup>-1</sup> * A where A = self, B = other.
|
/// Calculates B<sup>-1</sup> * A where A = self, B = other.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn left_div(&self, other: &Self) -> Option<Self>
|
pub fn left_div(&self, other: &Self) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -730,6 +755,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn right_div(&self, other: &Self) -> Option<Self>
|
pub fn right_div(&self, other: &Self) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -749,6 +775,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cos(&self) -> Self {
|
pub fn cos(&self) -> Self {
|
||||||
let z = self.imag().magnitude();
|
let z = self.imag().magnitude();
|
||||||
let w = -self.w.simd_sin() * z.simd_sinhc();
|
let w = -self.w.simd_sin() * z.simd_sinhc();
|
||||||
@ -766,6 +793,7 @@ where
|
|||||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn acos(&self) -> Self {
|
pub fn acos(&self) -> Self {
|
||||||
let u = Self::from_imag(self.imag().normalize());
|
let u = Self::from_imag(self.imag().normalize());
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
@ -787,6 +815,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sin(&self) -> Self {
|
pub fn sin(&self) -> Self {
|
||||||
let z = self.imag().magnitude();
|
let z = self.imag().magnitude();
|
||||||
let w = self.w.simd_cos() * z.simd_sinhc();
|
let w = self.w.simd_cos() * z.simd_sinhc();
|
||||||
@ -804,6 +833,7 @@ where
|
|||||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn asin(&self) -> Self {
|
pub fn asin(&self) -> Self {
|
||||||
let u = Self::from_imag(self.imag().normalize());
|
let u = Self::from_imag(self.imag().normalize());
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
@ -825,6 +855,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn tan(&self) -> Self
|
pub fn tan(&self) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -843,6 +874,7 @@ where
|
|||||||
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(input, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn atan(&self) -> Self
|
pub fn atan(&self) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -867,6 +899,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sinh(&self) -> Self {
|
pub fn sinh(&self) -> Self {
|
||||||
(self.exp() - (-self).exp()).half()
|
(self.exp() - (-self).exp()).half()
|
||||||
}
|
}
|
||||||
@ -883,6 +916,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn asinh(&self) -> Self {
|
pub fn asinh(&self) -> Self {
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
(self + (identity + self.squared()).sqrt()).ln()
|
(self + (identity + self.squared()).sqrt()).ln()
|
||||||
@ -900,6 +934,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cosh(&self) -> Self {
|
pub fn cosh(&self) -> Self {
|
||||||
(self.exp() + (-self).exp()).half()
|
(self.exp() + (-self).exp()).half()
|
||||||
}
|
}
|
||||||
@ -916,6 +951,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn acosh(&self) -> Self {
|
pub fn acosh(&self) -> Self {
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
(self + (self + identity).sqrt() * (self - identity).sqrt()).ln()
|
(self + (self + identity).sqrt() * (self - identity).sqrt()).ln()
|
||||||
@ -933,6 +969,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn tanh(&self) -> Self
|
pub fn tanh(&self) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -952,6 +989,7 @@ where
|
|||||||
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
/// assert_relative_eq!(expected, result, epsilon = 1.0e-7);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn atanh(&self) -> Self {
|
pub fn atanh(&self) -> Self {
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
((identity + self).ln() - (identity - self).ln()).half()
|
((identity + self).ln() - (identity - self).ln()).half()
|
||||||
@ -1069,6 +1107,7 @@ where
|
|||||||
/// assert_eq!(rot.angle(), 1.78);
|
/// assert_eq!(rot.angle(), 1.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
let w = self.quaternion().scalar().simd_abs();
|
let w = self.quaternion().scalar().simd_abs();
|
||||||
self.quaternion().imag().norm().simd_atan2(w) * crate::convert(2.0f64)
|
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));
|
/// assert_eq!(*axis.quaternion(), Quaternion::new(1.0, 0.0, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn quaternion(&self) -> &Quaternion<T> {
|
pub fn quaternion(&self) -> &Quaternion<T> {
|
||||||
self.as_ref()
|
self.as_ref()
|
||||||
}
|
}
|
||||||
@ -1133,6 +1173,7 @@ where
|
|||||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle_to(&self, other: &Self) -> T {
|
pub fn angle_to(&self, other: &Self) -> T {
|
||||||
let delta = self.rotation_to(other);
|
let delta = self.rotation_to(other);
|
||||||
delta.angle()
|
delta.angle()
|
||||||
@ -1152,6 +1193,7 @@ where
|
|||||||
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||||
other / 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));
|
/// assert_eq!(q1.lerp(&q2, 0.1), Quaternion::new(0.9, 0.1, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> Quaternion<T> {
|
pub fn lerp(&self, other: &Self, t: T) -> Quaternion<T> {
|
||||||
self.as_ref().lerp(other.as_ref(), 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)));
|
/// assert_eq!(q1.nlerp(&q2, 0.1), UnitQuaternion::new_normalize(Quaternion::new(0.9, 0.1, 0.0, 0.0)));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
pub fn nlerp(&self, other: &Self, t: T) -> Self {
|
||||||
let mut res = self.lerp(other, t);
|
let mut res = self.lerp(other, t);
|
||||||
let _ = res.normalize_mut();
|
let _ = res.normalize_mut();
|
||||||
@ -1209,6 +1253,7 @@ where
|
|||||||
/// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
/// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1228,6 +1273,7 @@ where
|
|||||||
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
/// * `epsilon`: the value below which the sinus of the angle separating both quaternion
|
||||||
/// must be to return `None`.
|
/// must be to return `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1287,6 +1333,7 @@ where
|
|||||||
/// assert!(rot.axis().is_none());
|
/// assert!(rot.axis().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1311,6 +1358,7 @@ where
|
|||||||
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scaled_axis(&self) -> Vector3<T>
|
pub fn scaled_axis(&self) -> Vector3<T>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1339,6 +1387,7 @@ where
|
|||||||
/// assert!(rot.axis_angle().is_none());
|
/// assert!(rot.axis_angle().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1350,6 +1399,7 @@ where
|
|||||||
///
|
///
|
||||||
/// Note that this function yields a `Quaternion<T>` because it loses the unit property.
|
/// Note that this function yields a `Quaternion<T>` because it loses the unit property.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn exp(&self) -> Quaternion<T> {
|
pub fn exp(&self) -> Quaternion<T> {
|
||||||
self.as_ref().exp()
|
self.as_ref().exp()
|
||||||
}
|
}
|
||||||
@ -1369,6 +1419,7 @@ where
|
|||||||
/// assert_relative_eq!(q.ln().vector().into_owned(), axisangle, epsilon = 1.0e-6);
|
/// assert_relative_eq!(q.ln().vector().into_owned(), axisangle, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn ln(&self) -> Quaternion<T>
|
pub fn ln(&self) -> Quaternion<T>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1397,6 +1448,7 @@ where
|
|||||||
/// assert_eq!(pow.angle(), 2.4);
|
/// assert_eq!(pow.angle(), 2.4);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn powf(&self, n: T) -> Self
|
pub fn powf(&self, n: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1425,6 +1477,7 @@ where
|
|||||||
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_rotation_matrix(&self) -> Rotation<T, 3> {
|
pub fn to_rotation_matrix(&self) -> Rotation<T, 3> {
|
||||||
let i = self.as_ref()[0];
|
let i = self.as_ref()[0];
|
||||||
let j = self.as_ref()[1];
|
let j = self.as_ref()[1];
|
||||||
@ -1482,6 +1535,7 @@ where
|
|||||||
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn euler_angles(&self) -> (T, T, T)
|
pub fn euler_angles(&self) -> (T, T, T)
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -1506,6 +1560,7 @@ where
|
|||||||
/// assert_relative_eq!(rot.to_homogeneous(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
pub fn to_homogeneous(&self) -> Matrix4<T> {
|
||||||
self.to_rotation_matrix().to_homogeneous()
|
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);
|
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
pub fn transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -1546,6 +1602,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
pub fn transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -1566,6 +1623,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
|
||||||
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
||||||
// the inverse transformation explicitly here) ?
|
// 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);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
pub fn inverse_transform_vector(&self, v: &Vector3<T>) -> Vector3<T> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -1608,6 +1667,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector3<T>>) -> Unit<Vector3<T>> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -1616,6 +1676,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is faster, but approximate, way to compute `UnitQuaternion::new(axisangle) * self`.
|
/// This is faster, but approximate, way to compute `UnitQuaternion::new(axisangle) * self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
|
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
|
||||||
let half: T = crate::convert(0.5);
|
let half: T = crate::convert(0.5);
|
||||||
let q1 = self.into_inner();
|
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.
|
/// The reflexion axis.
|
||||||
|
#[must_use]
|
||||||
pub fn axis(&self) -> &Vector<T, D, S> {
|
pub fn axis(&self) -> &Vector<T, D, S> {
|
||||||
&self.axis
|
&self.axis
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
|||||||
/// assert_eq!(*rot.matrix(), expected);
|
/// assert_eq!(*rot.matrix(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn matrix(&self) -> &SMatrix<T, D, D> {
|
pub fn matrix(&self) -> &SMatrix<T, D, D> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
@ -262,6 +263,7 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
|||||||
/// assert_eq!(rot.to_homogeneous(), expected);
|
/// assert_eq!(rot.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
T: Zero + One,
|
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);
|
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -422,6 +425,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -441,6 +445,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
Point::from(self.inverse_transform_vector(&pt.coords))
|
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);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self.matrix().tr_mul(v)
|
self.matrix().tr_mul(v)
|
||||||
}
|
}
|
||||||
@ -479,6 +485,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
|
||||||
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
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);
|
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T::Element: SimdRealField,
|
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));
|
/// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn slerp(&self, other: &Self, t: T) -> Self
|
pub fn slerp(&self, other: &Self, t: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -67,6 +69,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// * `epsilon`: the value below which the sinus of the angle separating both rotations
|
/// * `epsilon`: the value below which the sinus of the angle separating both rotations
|
||||||
/// must be to return `None`.
|
/// must be to return `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
|
@ -186,6 +186,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
|||||||
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||||
other * self.inverse()
|
other * self.inverse()
|
||||||
}
|
}
|
||||||
@ -215,6 +216,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
|||||||
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn powf(&self, n: T) -> Self {
|
pub fn powf(&self, n: T) -> Self {
|
||||||
Self::new(self.angle() * n)
|
Self::new(self.angle() * n)
|
||||||
}
|
}
|
||||||
@ -232,6 +234,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
|||||||
/// assert_relative_eq!(rot.angle(), 1.78);
|
/// assert_relative_eq!(rot.angle(), 1.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
self.matrix()[(1, 0)].simd_atan2(self.matrix()[(0, 0)])
|
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);
|
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle_to(&self, other: &Self) -> T {
|
pub fn angle_to(&self, other: &Self) -> T {
|
||||||
self.rotation_to(other).angle()
|
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
|
/// This is generally used in the context of generic programming. Using
|
||||||
/// the `.angle()` method instead is more common.
|
/// the `.angle()` method instead is more common.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scaled_axis(&self) -> SVector<T, 1> {
|
pub fn scaled_axis(&self) -> SVector<T, 1> {
|
||||||
Vector1::new(self.angle())
|
Vector1::new(self.angle())
|
||||||
}
|
}
|
||||||
@ -640,6 +645,7 @@ where
|
|||||||
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot_to * rot1, rot2, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||||
other * self.inverse()
|
other * self.inverse()
|
||||||
}
|
}
|
||||||
@ -659,6 +665,7 @@ where
|
|||||||
/// assert_eq!(pow.angle(), 2.4);
|
/// assert_eq!(pow.angle(), 2.4);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn powf(&self, n: T) -> Self
|
pub fn powf(&self, n: T) -> Self
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -765,6 +772,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// assert_relative_eq!(rot.angle(), 1.78);
|
/// assert_relative_eq!(rot.angle(), 1.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - T::one())
|
((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - T::one())
|
||||||
/ crate::convert(2.0))
|
/ crate::convert(2.0))
|
||||||
@ -787,6 +795,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// assert!(rot.axis().is_none());
|
/// assert!(rot.axis().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
pub fn axis(&self) -> Option<Unit<Vector3<T>>>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -811,6 +820,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot.scaled_axis(), axisangle, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scaled_axis(&self) -> Vector3<T>
|
pub fn scaled_axis(&self) -> Vector3<T>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -842,6 +852,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// assert!(rot.axis_angle().is_none());
|
/// assert!(rot.axis_angle().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
pub fn axis_angle(&self) -> Option<(Unit<Vector3<T>>, T)>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -864,6 +875,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
|||||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.0045657, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle_to(&self, other: &Self) -> T
|
pub fn angle_to(&self, other: &Self) -> T
|
||||||
where
|
where
|
||||||
T::Element: SimdRealField,
|
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.1, 0.2, epsilon = 1.0e-6);
|
||||||
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[must_use]
|
||||||
pub fn euler_angles(&self) -> (T, T, T)
|
pub fn euler_angles(&self) -> (T, T, T)
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
|
@ -122,6 +122,7 @@ where
|
|||||||
impl<T: Scalar, R, const D: usize> Similarity<T, R, D> {
|
impl<T: Scalar, R, const D: usize> Similarity<T, R, D> {
|
||||||
/// The scaling factor of this similarity transformation.
|
/// The scaling factor of this similarity transformation.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scaling(&self) -> T {
|
pub fn scaling(&self) -> T {
|
||||||
self.scaling.inlined_clone()
|
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);
|
/// assert_relative_eq!(transformed_point, Point3::new(19.0, 17.0, -9.0), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -269,6 +271,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -289,6 +292,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Point3::new(-1.5, 1.5, 1.5), epsilon = 1.0e-5);
|
/// assert_relative_eq!(transformed_point, Point3::new(-1.5, 1.5, 1.5), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self.isometry.inverse_transform_point(pt) / self.scaling()
|
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);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self.isometry.inverse_transform_vector(v) / self.scaling()
|
self.isometry.inverse_transform_vector(v) / self.scaling()
|
||||||
}
|
}
|
||||||
@ -321,6 +326,7 @@ where
|
|||||||
impl<T: SimdRealField, R, const D: usize> Similarity<T, R, D> {
|
impl<T: SimdRealField, R, const D: usize> Similarity<T, R, D> {
|
||||||
/// Converts this similarity into its equivalent homogeneous transformation matrix.
|
/// Converts this similarity into its equivalent homogeneous transformation matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
@ -8,6 +8,7 @@ macro_rules! impl_swizzle {
|
|||||||
$(
|
$(
|
||||||
/// Builds a new point from components of `self`.
|
/// Builds a new point from components of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn $name(&self) -> $Result<T>
|
pub fn $name(&self) -> $Result<T>
|
||||||
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||||
$Result::new($(self[$i].inlined_clone()),*)
|
$Result::new($(self[$i].inlined_clone()),*)
|
||||||
|
@ -301,6 +301,7 @@ where
|
|||||||
/// assert_eq!(*t.matrix(), m);
|
/// assert_eq!(*t.matrix(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn matrix(&self) -> &OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
pub fn matrix(&self) -> &OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
@ -367,6 +368,7 @@ where
|
|||||||
/// assert_eq!(t.into_inner(), m);
|
/// assert_eq!(t.into_inner(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix().clone_owned()
|
self.matrix().clone_owned()
|
||||||
}
|
}
|
||||||
@ -498,6 +500,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is the same as the multiplication `self * pt`.
|
/// This is the same as the multiplication `self * pt`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -507,6 +510,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is the same as the multiplication `self * v`.
|
/// This is the same as the multiplication `self * v`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -524,6 +528,7 @@ where
|
|||||||
/// This may be cheaper than inverting the transformation and transforming
|
/// This may be cheaper than inverting the transformation and transforming
|
||||||
/// the point.
|
/// the point.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self.clone().inverse() * pt
|
self.clone().inverse() * pt
|
||||||
}
|
}
|
||||||
@ -532,6 +537,7 @@ where
|
|||||||
/// This may be cheaper than inverting the transformation and transforming
|
/// This may be cheaper than inverting the transformation and transforming
|
||||||
/// the vector.
|
/// the vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
pub fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
|
||||||
self.clone().inverse() * v
|
self.clone().inverse() * v
|
||||||
}
|
}
|
||||||
|
@ -190,6 +190,7 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
|
|||||||
/// assert_eq!(t.to_homogeneous(), expected);
|
/// assert_eq!(t.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
pub fn to_homogeneous(&self) -> OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
T: Zero + One,
|
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));
|
/// 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));
|
/// assert_eq!(transformed_point, Point3::new(5.0, 7.0, 9.0));
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
pt + &self.vector
|
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));
|
/// 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));
|
/// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0));
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
pt - &self.vector
|
pt - &self.vector
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ where
|
|||||||
/// assert_eq!(rot.angle(), 1.78);
|
/// assert_eq!(rot.angle(), 1.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
self.im.simd_atan2(self.re)
|
self.im.simd_atan2(self.re)
|
||||||
}
|
}
|
||||||
@ -98,6 +99,7 @@ where
|
|||||||
/// assert_eq!(rot.sin_angle(), angle.sin());
|
/// assert_eq!(rot.sin_angle(), angle.sin());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn sin_angle(&self) -> T {
|
pub fn sin_angle(&self) -> T {
|
||||||
self.im
|
self.im
|
||||||
}
|
}
|
||||||
@ -112,6 +114,7 @@ where
|
|||||||
/// assert_eq!(rot.cos_angle(),angle.cos());
|
/// assert_eq!(rot.cos_angle(),angle.cos());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn cos_angle(&self) -> T {
|
pub fn cos_angle(&self) -> T {
|
||||||
self.re
|
self.re
|
||||||
}
|
}
|
||||||
@ -121,6 +124,7 @@ where
|
|||||||
/// This is generally used in the context of generic programming. Using
|
/// This is generally used in the context of generic programming. Using
|
||||||
/// the `.angle()` method instead is more common.
|
/// the `.angle()` method instead is more common.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn scaled_axis(&self) -> Vector1<T> {
|
pub fn scaled_axis(&self) -> Vector1<T> {
|
||||||
Vector1::new(self.angle())
|
Vector1::new(self.angle())
|
||||||
}
|
}
|
||||||
@ -131,6 +135,7 @@ where
|
|||||||
/// the `.angle()` method instead is more common.
|
/// the `.angle()` method instead is more common.
|
||||||
/// Returns `None` if the angle is zero.
|
/// Returns `None` if the angle is zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn axis_angle(&self) -> Option<(Unit<Vector1<T>>, T)>
|
pub fn axis_angle(&self) -> Option<(Unit<Vector1<T>>, T)>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -157,6 +162,7 @@ where
|
|||||||
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
|
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn angle_to(&self, other: &Self) -> T {
|
pub fn angle_to(&self, other: &Self) -> T {
|
||||||
let delta = self.rotation_to(other);
|
let delta = self.rotation_to(other);
|
||||||
delta.angle()
|
delta.angle()
|
||||||
@ -254,6 +260,7 @@ where
|
|||||||
/// assert_eq!(rot.to_rotation_matrix(), expected);
|
/// assert_eq!(rot.to_rotation_matrix(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_rotation_matrix(&self) -> Rotation2<T> {
|
pub fn to_rotation_matrix(&self) -> Rotation2<T> {
|
||||||
let r = self.re;
|
let r = self.re;
|
||||||
let i = self.im;
|
let i = self.im;
|
||||||
@ -274,6 +281,7 @@ where
|
|||||||
/// assert_eq!(rot.to_homogeneous(), expected);
|
/// assert_eq!(rot.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn to_homogeneous(&self) -> Matrix3<T> {
|
pub fn to_homogeneous(&self) -> Matrix3<T> {
|
||||||
self.to_rotation_matrix().to_homogeneous()
|
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);
|
/// assert_relative_eq!(transformed_point, Point2::new(-2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
pub fn transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
||||||
self * pt
|
self * pt
|
||||||
}
|
}
|
||||||
@ -316,6 +325,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, Vector2::new(-2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, Vector2::new(-2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
pub fn transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
@ -332,6 +342,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_point, Point2::new(2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Point2::new(2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> {
|
||||||
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement
|
||||||
// the inverse transformation explicitly here) ?
|
// 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);
|
/// assert_relative_eq!(transformed_vector, Vector2::new(2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
pub fn inverse_transform_vector(&self, v: &Vector2<T>) -> Vector2<T> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -366,6 +378,7 @@ where
|
|||||||
/// assert_relative_eq!(transformed_vector, -Vector2::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, -Vector2::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<T>>) -> Unit<Vector2<T>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<T>>) -> Unit<Vector2<T>> {
|
||||||
self.inverse() * v
|
self.inverse() * v
|
||||||
}
|
}
|
||||||
@ -392,6 +405,7 @@ where
|
|||||||
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
|
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn slerp(&self, other: &Self, t: T) -> Self {
|
pub fn slerp(&self, other: &Self, t: T) -> Self {
|
||||||
Self::new(self.angle() * (T::one() - t) + other.angle() * t)
|
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()));
|
/// assert_eq!(*rot.complex(), Complex::new(angle.cos(), angle.sin()));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn complex(&self) -> &Complex<T> {
|
pub fn complex(&self) -> &Complex<T> {
|
||||||
self.as_ref()
|
self.as_ref()
|
||||||
}
|
}
|
||||||
@ -244,6 +245,7 @@ where
|
|||||||
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn rotation_to(&self, other: &Self) -> Self {
|
pub fn rotation_to(&self, other: &Self) -> Self {
|
||||||
other / self
|
other / self
|
||||||
}
|
}
|
||||||
@ -262,6 +264,7 @@ where
|
|||||||
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn powf(&self, n: T) -> Self {
|
pub fn powf(&self, n: T) -> Self {
|
||||||
Self::from_angle(self.angle() * n)
|
Self::from_angle(self.angle() * n)
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ pub fn zero<T: Zero>() -> T {
|
|||||||
/// Wraps `val` into the range `[min, max]` using modular arithmetics.
|
/// Wraps `val` into the range `[min, max]` using modular arithmetics.
|
||||||
///
|
///
|
||||||
/// The range must not be empty.
|
/// The range must not be empty.
|
||||||
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn wrap<T>(mut val: T, min: T, max: T) -> T
|
pub fn wrap<T>(mut val: T, min: T, max: T) -> T
|
||||||
where
|
where
|
||||||
@ -219,6 +220,7 @@ where
|
|||||||
/// * If `min < val < max`, this returns `val`.
|
/// * If `min < val < max`, this returns `val`.
|
||||||
/// * If `val <= min`, this returns `min`.
|
/// * If `val <= min`, this returns `min`.
|
||||||
/// * If `val >= max`, this returns `max`.
|
/// * If `val >= max`, this returns `max`.
|
||||||
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
||||||
if val > min {
|
if val > min {
|
||||||
|
@ -153,6 +153,7 @@ where
|
|||||||
|
|
||||||
/// Indicates whether this decomposition contains an upper-diagonal matrix.
|
/// Indicates whether this decomposition contains an upper-diagonal matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn is_upper_diagonal(&self) -> bool {
|
pub fn is_upper_diagonal(&self) -> bool {
|
||||||
self.upper_diagonal
|
self.upper_diagonal
|
||||||
}
|
}
|
||||||
@ -188,6 +189,7 @@ where
|
|||||||
|
|
||||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn d(&self) -> OMatrix<T, DimMinimum<R, C>, DimMinimum<R, C>>
|
pub fn d(&self) -> OMatrix<T, DimMinimum<R, C>, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, DimMinimum<R, C>>,
|
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.
|
/// Computes the orthogonal matrix `U` of this `U * D * V` decomposition.
|
||||||
// TODO: code duplication with householder::assemble_q.
|
// TODO: code duplication with householder::assemble_q.
|
||||||
// Except that we are returning a rectangular matrix here.
|
// Except that we are returning a rectangular matrix here.
|
||||||
|
#[must_use]
|
||||||
pub fn u(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
pub fn u(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
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.
|
/// Computes the orthogonal matrix `V_t` of this `U * D * V_t` decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn v_t(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
pub fn v_t(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||||
@ -274,6 +278,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The diagonal part of this decomposed matrix.
|
/// The diagonal part of this decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal(&self) -> OVector<T::RealField, DimMinimum<R, C>>
|
pub fn diagonal(&self) -> OVector<T::RealField, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T::RealField, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T::RealField, DimMinimum<R, C>>,
|
||||||
@ -282,6 +287,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The off-diagonal part of this decomposed matrix.
|
/// The off-diagonal part of this decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<DimMinimum<R, C>, U1>>
|
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<DimMinimum<R, C>, U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T::RealField, DimDiff<DimMinimum<R, C>, U1>>,
|
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
|
/// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
|
||||||
/// uppen-triangular part filled with zeros.
|
/// uppen-triangular part filled with zeros.
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> OMatrix<T, D, D> {
|
pub fn l(&self) -> OMatrix<T, D, D> {
|
||||||
self.chol.lower_triangle()
|
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
|
/// 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.
|
/// part are garbage and should be ignored by further computations.
|
||||||
|
#[must_use]
|
||||||
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
||||||
&self.chol
|
&self.chol
|
||||||
}
|
}
|
||||||
@ -119,6 +121,7 @@ where
|
|||||||
|
|
||||||
/// Returns the solution of the system `self * x = b` where `self` is the decomposed matrix and
|
/// Returns the solution of the system `self * x = b` where `self` is the decomposed matrix and
|
||||||
/// `x` the unknown.
|
/// `x` the unknown.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(&self, b: &Matrix<T, R2, C2, S2>) -> OMatrix<T, R2, C2>
|
pub fn solve<R2: Dim, C2: Dim, S2>(&self, b: &Matrix<T, R2, C2, S2>) -> OMatrix<T, R2, C2>
|
||||||
where
|
where
|
||||||
S2: Storage<T, R2, C2>,
|
S2: Storage<T, R2, C2>,
|
||||||
@ -131,6 +134,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn inverse(&self) -> OMatrix<T, D, D> {
|
pub fn inverse(&self) -> OMatrix<T, D, D> {
|
||||||
let shape = self.chol.data.shape();
|
let shape = self.chol.data.shape();
|
||||||
let mut res = OMatrix::identity_generic(shape.0, shape.1);
|
let mut res = OMatrix::identity_generic(shape.0, shape.1);
|
||||||
@ -140,6 +144,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the determinant of the decomposed matrix.
|
/// Computes the determinant of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T::SimdRealField {
|
pub fn determinant(&self) -> T::SimdRealField {
|
||||||
let dim = self.chol.nrows();
|
let dim = self.chol.nrows();
|
||||||
let mut prod_diag = T::one();
|
let mut prod_diag = T::one();
|
||||||
@ -287,6 +292,7 @@ where
|
|||||||
|
|
||||||
/// Updates the decomposition such that we get the decomposition of the factored matrix with its `j`th column removed.
|
/// 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.
|
/// Since the matrix is square, the `j`th row will also be removed.
|
||||||
|
#[must_use]
|
||||||
pub fn remove_column(&self, j: usize) -> Cholesky<T, DimDiff<D, U1>>
|
pub fn remove_column(&self, j: usize) -> Cholesky<T, DimDiff<D, U1>>
|
||||||
where
|
where
|
||||||
D: DimSub<U1>,
|
D: DimSub<U1>,
|
||||||
|
@ -95,6 +95,7 @@ where
|
|||||||
|
|
||||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||||
@ -126,6 +127,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||||
@ -150,6 +152,7 @@ where
|
|||||||
}
|
}
|
||||||
/// Retrieves the column permutation of this decomposition.
|
/// Retrieves the column permutation of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||||
&self.p
|
&self.p
|
||||||
}
|
}
|
||||||
@ -201,6 +204,7 @@ where
|
|||||||
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
///
|
///
|
||||||
/// Returns `None` if `self` is not invertible.
|
/// Returns `None` if `self` is not invertible.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -283,6 +287,7 @@ where
|
|||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the decomposed matrix is not invertible.
|
/// Returns `None` if the decomposed matrix is not invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
self.col_piv_qr.is_square(),
|
self.col_piv_qr.is_square(),
|
||||||
@ -301,6 +306,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates if the decomposed matrix is invertible.
|
/// Indicates if the decomposed matrix is invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn is_invertible(&self) -> bool {
|
pub fn is_invertible(&self) -> bool {
|
||||||
assert!(
|
assert!(
|
||||||
self.col_piv_qr.is_square(),
|
self.col_piv_qr.is_square(),
|
||||||
@ -317,6 +323,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the determinant of the decomposed matrix.
|
/// Computes the determinant of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> T {
|
||||||
let dim = self.col_piv_qr.nrows();
|
let dim = self.col_piv_qr.nrows();
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -112,6 +112,7 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
|
|||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Inputs must satisfy `self.len() >= kernel.len() > 0`.
|
/// Inputs must satisfy `self.len() >= kernel.len() > 0`.
|
||||||
|
#[must_use]
|
||||||
pub fn convolve_same<D2, S2>(&self, kernel: Vector<T, D2, S2>) -> OVector<T, D1>
|
pub fn convolve_same<D2, S2>(&self, kernel: Vector<T, D2, S2>) -> OVector<T, D1>
|
||||||
where
|
where
|
||||||
D2: Dim,
|
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.
|
/// If the matrix has a dimension larger than 3, an LU decomposition is used.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T
|
pub fn determinant(&self) -> T
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D, D> + Allocator<(usize, usize), D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<(usize, usize), D>,
|
||||||
|
@ -435,6 +435,7 @@ where
|
|||||||
+ Allocator<T::RealField, D, D>,
|
+ Allocator<T::RealField, D, D>,
|
||||||
{
|
{
|
||||||
/// Computes exponential of this matrix
|
/// Computes exponential of this matrix
|
||||||
|
#[must_use]
|
||||||
pub fn exp(&self) -> Self {
|
pub fn exp(&self) -> Self {
|
||||||
// Simple case
|
// Simple case
|
||||||
if self.nrows() == 1 {
|
if self.nrows() == 1 {
|
||||||
|
@ -96,6 +96,7 @@ where
|
|||||||
|
|
||||||
/// The lower triangular matrix of this decomposition.
|
/// The lower triangular matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||||
@ -109,6 +110,7 @@ where
|
|||||||
|
|
||||||
/// The upper triangular matrix of this decomposition.
|
/// The upper triangular matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||||
@ -119,12 +121,14 @@ where
|
|||||||
|
|
||||||
/// The row permutations of this decomposition.
|
/// The row permutations of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||||
&self.p
|
&self.p
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column permutations of this decomposition.
|
/// The column permutations of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
pub fn q(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||||
&self.q
|
&self.q
|
||||||
}
|
}
|
||||||
@ -159,6 +163,7 @@ where
|
|||||||
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the decomposed matrix is not invertible.
|
/// Returns `None` if the decomposed matrix is not invertible.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -210,6 +215,7 @@ where
|
|||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the decomposed matrix is not invertible.
|
/// Returns `None` if the decomposed matrix is not invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
self.lu.is_square(),
|
self.lu.is_square(),
|
||||||
@ -227,6 +233,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates if the decomposed matrix is invertible.
|
/// Indicates if the decomposed matrix is invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn is_invertible(&self) -> bool {
|
pub fn is_invertible(&self) -> bool {
|
||||||
assert!(
|
assert!(
|
||||||
self.lu.is_square(),
|
self.lu.is_square(),
|
||||||
@ -238,6 +245,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the determinant of the decomposed matrix.
|
/// Computes the determinant of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> T {
|
||||||
assert!(
|
assert!(
|
||||||
self.lu.is_square(),
|
self.lu.is_square(),
|
||||||
|
@ -89,16 +89,19 @@ impl<T: ComplexField> GivensRotation<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The cos part of this roration.
|
/// The cos part of this roration.
|
||||||
|
#[must_use]
|
||||||
pub fn c(&self) -> T::RealField {
|
pub fn c(&self) -> T::RealField {
|
||||||
self.c
|
self.c
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The sin part of this roration.
|
/// The sin part of this roration.
|
||||||
|
#[must_use]
|
||||||
pub fn s(&self) -> T {
|
pub fn s(&self) -> T {
|
||||||
self.s
|
self.s
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of this givens rotation.
|
/// The inverse of this givens rotation.
|
||||||
|
#[must_use = "This function does not mutate self."]
|
||||||
pub fn inverse(&self) -> Self {
|
pub fn inverse(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
c: self.c,
|
c: self.c,
|
||||||
|
@ -116,6 +116,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is less efficient than `.unpack_h()` as it allocates a new matrix.
|
/// This is less efficient than `.unpack_h()` as it allocates a new matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn h(&self) -> OMatrix<T, D, D> {
|
pub fn h(&self) -> OMatrix<T, D, D> {
|
||||||
let dim = self.hess.nrows();
|
let dim = self.hess.nrows();
|
||||||
let mut res = self.hess.clone();
|
let mut res = self.hess.clone();
|
||||||
@ -126,6 +127,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, D, D> {
|
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||||
householder::assemble_q(&self.hess, self.subdiag.as_slice())
|
householder::assemble_q(&self.hess, self.subdiag.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,7 @@ where
|
|||||||
|
|
||||||
/// The lower triangular matrix of this decomposition.
|
/// The lower triangular matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||||
@ -170,6 +171,7 @@ where
|
|||||||
|
|
||||||
/// The upper triangular matrix of this decomposition.
|
/// The upper triangular matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||||
@ -180,6 +182,7 @@ where
|
|||||||
|
|
||||||
/// The row permutations of this decomposition.
|
/// The row permutations of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
pub fn p(&self) -> &PermutationSequence<DimMinimum<R, C>> {
|
||||||
&self.p
|
&self.p
|
||||||
}
|
}
|
||||||
@ -213,6 +216,7 @@ where
|
|||||||
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
///
|
///
|
||||||
/// Returns `None` if `self` is not invertible.
|
/// Returns `None` if `self` is not invertible.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -257,6 +261,7 @@ where
|
|||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the matrix is not invertible.
|
/// Returns `None` if the matrix is not invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
self.lu.is_square(),
|
self.lu.is_square(),
|
||||||
@ -291,6 +296,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the determinant of the decomposed matrix.
|
/// Computes the determinant of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> T {
|
||||||
let dim = self.lu.nrows();
|
let dim = self.lu.nrows();
|
||||||
assert!(
|
assert!(
|
||||||
@ -307,6 +313,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates if the decomposed matrix is invertible.
|
/// Indicates if the decomposed matrix is invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn is_invertible(&self) -> bool {
|
pub fn is_invertible(&self) -> bool {
|
||||||
assert!(
|
assert!(
|
||||||
self.lu.is_square(),
|
self.lu.is_square(),
|
||||||
|
@ -140,17 +140,20 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The number of non-identity permutations applied by this sequence.
|
/// The number of non-identity permutations applied by this sequence.
|
||||||
|
#[must_use]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.len
|
self.len
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the permutation sequence contains no elements.
|
/// Returns true if the permutation sequence contains no elements.
|
||||||
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The determinant of the matrix corresponding to this permutation.
|
/// The determinant of the matrix corresponding to this permutation.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn determinant<T: One + ClosedNeg>(&self) -> T {
|
pub fn determinant<T: One + ClosedNeg>(&self) -> T {
|
||||||
if self.len % 2 == 0 {
|
if self.len % 2 == 0 {
|
||||||
T::one()
|
T::one()
|
||||||
|
@ -70,6 +70,7 @@ where
|
|||||||
|
|
||||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>,
|
||||||
@ -96,6 +97,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, DimMinimum<R, C>>,
|
||||||
@ -164,6 +166,7 @@ where
|
|||||||
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
///
|
///
|
||||||
/// Returns `None` if `self` is not invertible.
|
/// Returns `None` if `self` is not invertible.
|
||||||
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -243,6 +246,7 @@ where
|
|||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the decomposed matrix is not invertible.
|
/// Returns `None` if the decomposed matrix is not invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
pub fn try_inverse(&self) -> Option<OMatrix<T, D, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
self.qr.is_square(),
|
self.qr.is_square(),
|
||||||
@ -261,6 +265,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates if the decomposed matrix is invertible.
|
/// Indicates if the decomposed matrix is invertible.
|
||||||
|
#[must_use]
|
||||||
pub fn is_invertible(&self) -> bool {
|
pub fn is_invertible(&self) -> bool {
|
||||||
assert!(
|
assert!(
|
||||||
self.qr.is_square(),
|
self.qr.is_square(),
|
||||||
|
@ -385,6 +385,7 @@ where
|
|||||||
/// Computes the real eigenvalues of the decomposed matrix.
|
/// Computes the real eigenvalues of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Return `None` if some eigenvalues are complex.
|
/// Return `None` if some eigenvalues are complex.
|
||||||
|
#[must_use]
|
||||||
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||||
let mut out = unsafe {
|
let mut out = unsafe {
|
||||||
crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, Const::<1>)
|
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.
|
/// Computes the complex eigenvalues of the decomposed matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
@ -509,6 +511,7 @@ where
|
|||||||
+ Allocator<T, D>,
|
+ Allocator<T, D>,
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues of this matrix.
|
/// Computes the eigenvalues of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
self.is_square(),
|
self.is_square(),
|
||||||
@ -551,6 +554,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the eigenvalues of this matrix.
|
/// Computes the eigenvalues of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
pub fn complex_eigenvalues(&self) -> OVector<NumComplex<T>, D>
|
||||||
// TODO: add balancing?
|
// TODO: add balancing?
|
||||||
where
|
where
|
||||||
|
@ -10,6 +10,7 @@ use crate::base::{DVectorSlice, DefaultAllocator, Matrix, OMatrix, SquareMatrix,
|
|||||||
impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||||
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use solve_lower_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -30,6 +31,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use solve_upper_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -186,6 +188,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
*/
|
*/
|
||||||
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use tr_solve_lower_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn tr_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -206,6 +209,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use tr_solve_upper_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn tr_solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -276,6 +280,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use ad_solve_lower_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ad_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn ad_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -296,6 +301,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use ad_solve_upper_triangular_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ad_solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn ad_solve_upper_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -443,6 +449,7 @@ impl<T: ComplexField, 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> {
|
impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
||||||
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use solve_lower_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -460,6 +467,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use solve_upper_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -578,6 +586,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
*/
|
*/
|
||||||
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use tr_solve_lower_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn tr_solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -595,6 +604,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.transpose() . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use tr_solve_upper_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn tr_solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -648,6 +658,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
||||||
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the lower-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use ad_solve_lower_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ad_solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn ad_solve_lower_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
@ -665,6 +676,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
|
|||||||
|
|
||||||
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
/// Computes the solution of the linear system `self.adjoint() . x = b` where `x` is the unknown and only
|
||||||
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
/// the upper-triangular part of `self` (including the diagonal) is considered not-zero.
|
||||||
|
#[must_use = "Did you mean to use ad_solve_upper_triangular_unchecked_mut()?"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ad_solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
pub fn ad_solve_upper_triangular_unchecked<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -502,6 +502,7 @@ where
|
|||||||
|
|
||||||
/// Computes the rank of the decomposed matrix, i.e., the number of singular values greater
|
/// Computes the rank of the decomposed matrix, i.e., the number of singular values greater
|
||||||
/// than `eps`.
|
/// than `eps`.
|
||||||
|
#[must_use]
|
||||||
pub fn rank(&self, eps: T::RealField) -> usize {
|
pub fn rank(&self, eps: T::RealField) -> usize {
|
||||||
assert!(
|
assert!(
|
||||||
eps >= T::RealField::zero(),
|
eps >= T::RealField::zero(),
|
||||||
@ -615,6 +616,7 @@ where
|
|||||||
+ Allocator<T::RealField, DimDiff<DimMinimum<R, C>, U1>>,
|
+ Allocator<T::RealField, DimDiff<DimMinimum<R, C>, U1>>,
|
||||||
{
|
{
|
||||||
/// Computes the singular values of this matrix.
|
/// Computes the singular values of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn singular_values(&self) -> OVector<T::RealField, DimMinimum<R, C>> {
|
pub fn singular_values(&self) -> OVector<T::RealField, DimMinimum<R, C>> {
|
||||||
SVD::new(self.clone_owned(), false, false).singular_values
|
SVD::new(self.clone_owned(), false, false).singular_values
|
||||||
}
|
}
|
||||||
@ -622,6 +624,7 @@ where
|
|||||||
/// Computes the rank of this matrix.
|
/// Computes the rank of this matrix.
|
||||||
///
|
///
|
||||||
/// All singular values below `eps` are considered equal to 0.
|
/// All singular values below `eps` are considered equal to 0.
|
||||||
|
#[must_use]
|
||||||
pub fn rank(&self, eps: T::RealField) -> usize {
|
pub fn rank(&self, eps: T::RealField) -> usize {
|
||||||
let svd = SVD::new(self.clone_owned(), false, false);
|
let svd = SVD::new(self.clone_owned(), false, false);
|
||||||
svd.rank(eps)
|
svd.rank(eps)
|
||||||
|
@ -268,6 +268,7 @@ where
|
|||||||
/// Rebuild the original matrix.
|
/// Rebuild the original matrix.
|
||||||
///
|
///
|
||||||
/// This is useful if some of the eigenvalues have been manually modified.
|
/// This is useful if some of the eigenvalues have been manually modified.
|
||||||
|
#[must_use]
|
||||||
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
||||||
let mut u_t = self.eigenvectors.clone();
|
let mut u_t = self.eigenvectors.clone();
|
||||||
for i in 0..self.eigenvalues.len() {
|
for i in 0..self.eigenvalues.len() {
|
||||||
@ -311,6 +312,7 @@ where
|
|||||||
/// Computes the eigenvalues of this symmetric matrix.
|
/// Computes the eigenvalues of this symmetric matrix.
|
||||||
///
|
///
|
||||||
/// Only the lower-triangular part of the matrix is read.
|
/// Only the lower-triangular part of the matrix is read.
|
||||||
|
#[must_use]
|
||||||
pub fn symmetric_eigenvalues(&self) -> OVector<T::RealField, D> {
|
pub fn symmetric_eigenvalues(&self) -> OVector<T::RealField, D> {
|
||||||
SymmetricEigen::do_decompose(
|
SymmetricEigen::do_decompose(
|
||||||
self.clone_owned(),
|
self.clone_owned(),
|
||||||
|
@ -131,6 +131,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The diagonal components of this decomposition.
|
/// The diagonal components of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn diagonal(&self) -> OVector<T::RealField, D>
|
pub fn diagonal(&self) -> OVector<T::RealField, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T::RealField, D>,
|
DefaultAllocator: Allocator<T::RealField, D>,
|
||||||
@ -139,6 +140,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The off-diagonal components of this decomposition.
|
/// The off-diagonal components of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<D, U1>>
|
pub fn off_diagonal(&self) -> OVector<T::RealField, DimDiff<D, U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T::RealField, DimDiff<D, U1>>,
|
DefaultAllocator: Allocator<T::RealField, DimDiff<D, U1>>,
|
||||||
@ -147,6 +149,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn q(&self) -> OMatrix<T, D, D> {
|
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||||
householder::assemble_q(&self.tri, self.off_diagonal.as_slice())
|
householder::assemble_q(&self.tri, self.off_diagonal.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the diagonal elements as a matrix
|
/// Returns the diagonal elements as a matrix
|
||||||
|
#[must_use]
|
||||||
pub fn d_matrix(&self) -> OMatrix<T, D, D> {
|
pub fn d_matrix(&self) -> OMatrix<T, D, D> {
|
||||||
OMatrix::from_diagonal(&self.d)
|
OMatrix::from_diagonal(&self.d)
|
||||||
}
|
}
|
||||||
|
@ -119,16 +119,19 @@ where
|
|||||||
DefaultAllocator: Allocator<usize, C>,
|
DefaultAllocator: Allocator<usize, C>,
|
||||||
{
|
{
|
||||||
/// The value buffer of this storage.
|
/// The value buffer of this storage.
|
||||||
|
#[must_use]
|
||||||
pub fn values(&self) -> &[T] {
|
pub fn values(&self) -> &[T] {
|
||||||
&self.vals
|
&self.vals
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column shifts buffer.
|
/// The column shifts buffer.
|
||||||
|
#[must_use]
|
||||||
pub fn p(&self) -> &[usize] {
|
pub fn p(&self) -> &[usize] {
|
||||||
self.p.as_slice()
|
self.p.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The row index buffers.
|
/// The row index buffers.
|
||||||
|
#[must_use]
|
||||||
pub fn i(&self) -> &[usize] {
|
pub fn i(&self) -> &[usize] {
|
||||||
&self.i
|
&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.
|
/// The size of the data buffer.
|
||||||
|
#[must_use]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.data.len()
|
self.data.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of rows of this matrix.
|
/// The number of rows of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.data.shape().0.value()
|
self.data.shape().0.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of rows of this matrix.
|
/// The number of rows of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.data.shape().1.value()
|
self.data.shape().1.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The shape of this matrix.
|
/// The shape of this matrix.
|
||||||
|
#[must_use]
|
||||||
pub fn shape(&self) -> (usize, usize) {
|
pub fn shape(&self) -> (usize, usize) {
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
(nrows.value(), ncols.value())
|
(nrows.value(), ncols.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this matrix is square or not.
|
/// Whether this matrix is square or not.
|
||||||
|
#[must_use]
|
||||||
pub fn is_square(&self) -> bool {
|
pub fn is_square(&self) -> bool {
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
nrows.value() == ncols.value()
|
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
|
/// 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
|
/// and an issue should be open on the nalgebra repository with details on how to reproduce
|
||||||
/// this.
|
/// this.
|
||||||
|
#[must_use]
|
||||||
pub fn is_sorted(&self) -> bool {
|
pub fn is_sorted(&self) -> bool {
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
let mut curr = None;
|
let mut curr = None;
|
||||||
@ -409,6 +418,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: CsStorage<T, R, C>> CsMatrix<T, R, C, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the transpose of this sparse matrix.
|
/// Computes the transpose of this sparse matrix.
|
||||||
|
#[must_use = "This function does not mutate the matrix. Consider using the return value or removing the function call. There's also transpose_mut() for square matrices."]
|
||||||
pub fn transpose(&self) -> CsMatrix<T, C, R>
|
pub fn transpose(&self) -> CsMatrix<T, C, R>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<usize, R>,
|
DefaultAllocator: Allocator<usize, R>,
|
||||||
|
@ -67,6 +67,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The lower-triangular matrix of the cholesky decomposition.
|
/// The lower-triangular matrix of the cholesky decomposition.
|
||||||
|
#[must_use]
|
||||||
pub fn l(&self) -> Option<&CsMatrix<T, D, D>> {
|
pub fn l(&self) -> Option<&CsMatrix<T, D, D>> {
|
||||||
if self.ok {
|
if self.ok {
|
||||||
Some(&self.l)
|
Some(&self.l)
|
||||||
|
@ -6,6 +6,7 @@ use crate::{Const, DefaultAllocator, Dim, Matrix, OMatrix, OVector, RealField};
|
|||||||
|
|
||||||
impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
|
impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
|
||||||
/// Solve a lower-triangular system with a dense right-hand-side.
|
/// Solve a lower-triangular system with a dense right-hand-side.
|
||||||
|
#[must_use = "Did you mean to use solve_lower_triangular_mut()?"]
|
||||||
pub fn solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -24,6 +25,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Solve a lower-triangular system with `self` transposed and a dense right-hand-side.
|
/// Solve a lower-triangular system with `self` transposed and a dense right-hand-side.
|
||||||
|
#[must_use = "Did you mean to use tr_solve_lower_triangular_mut()?"]
|
||||||
pub fn tr_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
pub fn tr_solve_lower_triangular<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<T, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
@ -135,6 +137,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Solve a lower-triangular system with a sparse right-hand-side.
|
/// Solve a lower-triangular system with a sparse right-hand-side.
|
||||||
|
#[must_use]
|
||||||
pub fn solve_lower_triangular_cs<D2: Dim, S2>(
|
pub fn solve_lower_triangular_cs<D2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &CsVector<T, D2, S2>,
|
b: &CsVector<T, D2, S2>,
|
||||||
|
Loading…
Reference in New Issue
Block a user