Start adding doc-tests for BLAS operations.
This commit is contained in:
parent
924a9cd160
commit
8e3edf102c
@ -16,6 +16,14 @@ use base::{DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector};
|
|||||||
impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
||||||
|
|
||||||
/// Computes the index of the vector component with the largest value.
|
/// Computes the index of the vector component with the largest value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
/// let vec = Vector3::new(11, -15, 13);
|
||||||
|
/// assert_eq!(vec.imax(), 2);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn imax(&self) -> usize {
|
pub fn imax(&self) -> usize {
|
||||||
assert!(!self.is_empty(), "The input vector must not be empty.");
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
@ -36,6 +44,14 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the index of the vector component with the largest absolute value.
|
/// Computes the index of the vector component with the largest absolute value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
/// let vec = Vector3::new(11, -15, 13);
|
||||||
|
/// assert_eq!(vec.iamax(), 1);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iamax(&self) -> usize {
|
pub fn iamax(&self) -> usize {
|
||||||
assert!(!self.is_empty(), "The input vector must not be empty.");
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
@ -56,6 +72,14 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the index of the vector component with the smallest value.
|
/// Computes the index of the vector component with the smallest value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
/// let vec = Vector3::new(11, -15, 13);
|
||||||
|
/// assert_eq!(vec.imin(), 1);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn imin(&self) -> usize {
|
pub fn imin(&self) -> usize {
|
||||||
assert!(!self.is_empty(), "The input vector must not be empty.");
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
@ -76,6 +100,14 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the index of the vector component with the smallest absolute value.
|
/// Computes the index of the vector component with the smallest absolute value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
/// let vec = Vector3::new(11, -15, 13);
|
||||||
|
/// assert_eq!(vec.iamin(), 0);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iamin(&self) -> usize {
|
pub fn iamin(&self) -> usize {
|
||||||
assert!(!self.is_empty(), "The input vector must not be empty.");
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
@ -98,6 +130,15 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
|
|||||||
|
|
||||||
impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
/// Computes the index of the matrix component with the largest absolute value.
|
/// Computes the index of the matrix component with the largest absolute value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix2x3;
|
||||||
|
/// let mat = Matrix2x3::new(11, -12, 13,
|
||||||
|
/// 21, 22, -23);
|
||||||
|
/// assert_eq!(mat.iamax_full(), (1, 2));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
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.");
|
||||||
@ -124,10 +165,26 @@ impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
|
|||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
/// The dot product between two matrices (seen as vectors).
|
/// The dot product between two vectors or matrices (seen as vectors).
|
||||||
///
|
///
|
||||||
/// Note that this is **not** the matrix multiplication as in, e.g., numpy. For matrix
|
/// Note that this is **not** the matrix multiplication as in, e.g., numpy. For matrix
|
||||||
/// multiplication, use one of: `.gemm`, `mul_to`, `.mul`, `*`.
|
/// multiplication, use one of: `.gemm`, `mul_to`, `.mul`, `*`.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Vector3, Matrix2x3};
|
||||||
|
///
|
||||||
|
/// let vec1 = Vector3::new(1.0, 2.0, 3.0);
|
||||||
|
/// let vec2 = Vector3::new(0.1, 0.2, 0.3);
|
||||||
|
/// assert_eq!(vec1.dot(&vec2), 1.4);
|
||||||
|
///
|
||||||
|
/// let mat1 = Matrix2x3::new(1.0, 2.0, 3.0,
|
||||||
|
/// 4.0, 5.0, 6.0);
|
||||||
|
/// let mat2 = Matrix2x3::new(0.1, 0.2, 0.3,
|
||||||
|
/// 0.4, 0.5, 0.6);
|
||||||
|
/// assert_eq!(mat1.dot(&mat2), 9.1);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
||||||
where
|
where
|
||||||
@ -228,6 +285,23 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The dot product between the transpose of `self` and `rhs`.
|
/// The dot product between the transpose of `self` and `rhs`.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Vector3, RowVector3, Matrix2x3, Matrix3x2};
|
||||||
|
///
|
||||||
|
/// let vec1 = Vector3::new(1.0, 2.0, 3.0);
|
||||||
|
/// let vec2 = RowVector3::new(0.1, 0.2, 0.3);
|
||||||
|
/// assert_eq!(vec1.tr_dot(&vec2), 1.4);
|
||||||
|
///
|
||||||
|
/// let mat1 = Matrix2x3::new(1.0, 2.0, 3.0,
|
||||||
|
/// 4.0, 5.0, 6.0);
|
||||||
|
/// let mat2 = Matrix3x2::new(0.1, 0.4,
|
||||||
|
/// 0.2, 0.5,
|
||||||
|
/// 0.3, 0.6);
|
||||||
|
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
||||||
where
|
where
|
||||||
@ -283,6 +357,17 @@ where
|
|||||||
/// Computes `self = a * x + b * self`.
|
/// Computes `self = a * x + b * self`.
|
||||||
///
|
///
|
||||||
/// If be is zero, `self` is never read from.
|
/// If be is zero, `self` is never read from.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
///
|
||||||
|
/// let mut vec1 = Vector3::new(1.0, 2.0, 3.0);
|
||||||
|
/// let vec2 = Vector3::new(0.1, 0.2, 0.3);
|
||||||
|
/// vec1.axpy(10.0, &vec2, 5.0);
|
||||||
|
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn axpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, b: N)
|
pub fn axpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, b: N)
|
||||||
where
|
where
|
||||||
|
@ -160,6 +160,13 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The total number of elements of this matrix.
|
/// The total number of elements of this matrix.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix3x4;
|
||||||
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
|
/// assert_eq!(mat.len(), 12);
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
@ -167,6 +174,13 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The shape of this matrix returned as the tuple (number of rows, number of columns).
|
/// The shape of this matrix returned as the tuple (number of rows, number of columns).
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix3x4;
|
||||||
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
|
/// assert_eq!(mat.shape(), (3, 4));
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn shape(&self) -> (usize, usize) {
|
pub fn shape(&self) -> (usize, usize) {
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
@ -174,25 +188,63 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The number of rows of this matrix.
|
/// The number of rows of this matrix.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix3x4;
|
||||||
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
|
/// assert_eq!(mat.nrows(), 3);
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn nrows(&self) -> usize {
|
pub fn nrows(&self) -> usize {
|
||||||
self.shape().0
|
self.shape().0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of columns of this matrix.
|
/// The number of columns of this matrix.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix3x4;
|
||||||
|
/// let mat = Matrix3x4::<f32>::zeros();
|
||||||
|
/// assert_eq!(mat.ncols(), 4);
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ncols(&self) -> usize {
|
pub fn ncols(&self) -> usize {
|
||||||
self.shape().1
|
self.shape().1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The strides (row stride, column stride) of this matrix.
|
/// The strides (row stride, column stride) of this matrix.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::DMatrix;
|
||||||
|
/// let mat = DMatrix::<f32>::zeros(10, 10);
|
||||||
|
/// let slice = mat.slice_with_steps((0, 0), (5, 3), (1, 2));
|
||||||
|
/// // The column strides is the number of steps (here 2) multiplied by the corresponding dimension.
|
||||||
|
/// assert_eq!(mat.strides(), (1, 10));
|
||||||
#[inline]
|
#[inline]
|
||||||
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates through this matrix coordinates.
|
/// Iterates through this matrix coordinates in column-major order.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::Matrix2x3;
|
||||||
|
/// let mat = Matrix2x3::new(11, 12, 13,
|
||||||
|
/// 21, 22, 23);
|
||||||
|
/// let mut it = mat.iter();
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 11);
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 21);
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 12);
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 22);
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 13);
|
||||||
|
/// assert_eq!(*it.next().unwrap(), 23);
|
||||||
|
/// assert!(it.next().is_none());
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter(&self) -> MatrixIter<N, R, C, S> {
|
pub fn iter(&self) -> MatrixIter<N, R, C, S> {
|
||||||
MatrixIter::new(&self.data)
|
MatrixIter::new(&self.data)
|
||||||
@ -363,7 +415,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, 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(value, row, col)`.
|
/// `f` also gets passed the row and column index, i.e. `f(value, row, col)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map_with_location<N2: Scalar, F: FnMut(usize, usize, N) -> N2>(&self, mut f: F) -> MatrixMN<N2, R, C>
|
pub fn map_with_location<N2: Scalar, F: FnMut(usize, usize, N) -> N2>(
|
||||||
|
&self,
|
||||||
|
mut f: F,
|
||||||
|
) -> MatrixMN<N2, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N2, R, C>,
|
DefaultAllocator: Allocator<N2, R, C>,
|
||||||
{
|
{
|
||||||
@ -419,7 +474,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, 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]
|
||||||
pub fn zip_zip_map<N2, N3, N4, S2, S3, F>(&self, b: &Matrix<N2, R, C, S2>, c: &Matrix<N3, R, C, S3>, mut f: F) -> MatrixMN<N4, R, C>
|
pub fn zip_zip_map<N2, N3, N4, S2, S3, F>(
|
||||||
|
&self,
|
||||||
|
b: &Matrix<N2, R, C, S2>,
|
||||||
|
c: &Matrix<N3, R, C, S3>,
|
||||||
|
mut f: F,
|
||||||
|
) -> MatrixMN<N4, R, C>
|
||||||
where
|
where
|
||||||
N2: Scalar,
|
N2: Scalar,
|
||||||
N3: Scalar,
|
N3: Scalar,
|
||||||
@ -434,7 +494,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||||||
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) };
|
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) };
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
(nrows.value(), ncols.value()) == b.shape() && (nrows.value(), ncols.value()) == c.shape(),
|
(nrows.value(), ncols.value()) == b.shape()
|
||||||
|
&& (nrows.value(), ncols.value()) == c.shape(),
|
||||||
"Matrix simultaneous traversal error: dimension mismatch."
|
"Matrix simultaneous traversal error: dimension mismatch."
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1274,20 +1335,32 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||||||
|
|
||||||
impl<N: Real, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> {
|
impl<N: Real, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> {
|
||||||
/// Computes the spherical linear interpolation between two unit vectors.
|
/// Computes the spherical linear interpolation between two unit vectors.
|
||||||
pub fn slerp<S2: Storage<N, D>>(&self, rhs: &Unit<Vector<N, D, S2>>, t: N) -> Unit<VectorN<N, D>>
|
pub fn slerp<S2: Storage<N, D>>(
|
||||||
|
&self,
|
||||||
|
rhs: &Unit<Vector<N, D, S2>>,
|
||||||
|
t: N,
|
||||||
|
) -> Unit<VectorN<N, D>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> {
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
// FIXME: the result is wrong when self and rhs are collinear with opposite direction.
|
// FIXME: the result is wrong when self and rhs are collinear with opposite direction.
|
||||||
self.try_slerp(rhs, t, N::default_epsilon()).unwrap_or(Unit::new_unchecked(self.clone_owned()))
|
self.try_slerp(rhs, t, N::default_epsilon())
|
||||||
|
.unwrap_or(Unit::new_unchecked(self.clone_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the spherical linear interpolation between two unit vectors.
|
/// Computes the spherical linear interpolation between two unit vectors.
|
||||||
///
|
///
|
||||||
/// 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).
|
||||||
pub fn try_slerp<S2: Storage<N, D>>(&self, rhs: &Unit<Vector<N, D, S2>>, t: N, epsilon: N) -> Option<Unit<VectorN<N, D>>>
|
pub fn try_slerp<S2: Storage<N, D>>(
|
||||||
|
&self,
|
||||||
|
rhs: &Unit<Vector<N, D, S2>>,
|
||||||
|
t: N,
|
||||||
|
epsilon: N,
|
||||||
|
) -> Option<Unit<VectorN<N, D>>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> {
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
let c_hang = self.dot(rhs);
|
let c_hang = self.dot(rhs);
|
||||||
|
|
||||||
// self == other
|
// self == other
|
||||||
|
Loading…
Reference in New Issue
Block a user