Add argmin and argmax.

This commit is contained in:
sebcrozet 2018-12-09 16:55:42 +01:00
parent 0d2c1be8da
commit 904000ce27
1 changed files with 55 additions and 25 deletions

View File

@ -13,18 +13,18 @@ use base::dimension::{Dim, Dynamic, U1, U2, U3, U4};
use base::storage::{Storage, StorageMut}; use base::storage::{Storage, StorageMut};
use base::{DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector}; 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, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
/// Computes the index of the vector component with the largest value. /// Computes the index and value of the vector component with the largest value.
/// ///
/// # Examples: /// # Examples:
/// ///
/// ``` /// ```
/// # use nalgebra::Vector3; /// # use nalgebra::Vector3;
/// let vec = Vector3::new(11, -15, 13); /// let vec = Vector3::new(11, -15, 13);
/// assert_eq!(vec.imax(), 2); /// assert_eq!(vec.argmax(), (2, 13));
/// ``` /// ```
#[inline] #[inline]
pub fn imax(&self) -> usize { pub fn argmax(&self) -> (usize, N) {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_max = unsafe { self.vget_unchecked(0) }; let mut the_max = unsafe { self.vget_unchecked(0) };
@ -39,7 +39,21 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
} }
} }
the_i (the_i, *the_max)
}
/// 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]
pub fn imax(&self) -> usize {
self.argmax().0
} }
/// Computes the index of the vector component with the largest absolute value. /// Computes the index of the vector component with the largest absolute value.
@ -52,7 +66,8 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
/// assert_eq!(vec.iamax(), 1); /// assert_eq!(vec.iamax(), 1);
/// ``` /// ```
#[inline] #[inline]
pub fn iamax(&self) -> usize { pub fn iamax(&self) -> usize
where N: Signed {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_max = unsafe { self.vget_unchecked(0).abs() }; let mut the_max = unsafe { self.vget_unchecked(0).abs() };
@ -70,6 +85,34 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
the_i the_i
} }
/// Computes the index and value of the vector component with the smallest value.
///
/// # Examples:
///
/// ```
/// # use nalgebra::Vector3;
/// let vec = Vector3::new(11, -15, 13);
/// assert_eq!(vec.argmin(), (1, -15));
/// ```
#[inline]
pub fn argmin(&self) -> (usize, N) {
assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_min = unsafe { self.vget_unchecked(0) };
let mut the_i = 0;
for i in 1..self.nrows() {
let val = unsafe { self.vget_unchecked(i) };
if val < the_min {
the_min = val;
the_i = i;
}
}
(the_i, *the_min)
}
/// Computes the index of the vector component with the smallest value. /// Computes the index of the vector component with the smallest value.
/// ///
/// # Examples: /// # Examples:
@ -81,21 +124,7 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
/// ``` /// ```
#[inline] #[inline]
pub fn imin(&self) -> usize { pub fn imin(&self) -> usize {
assert!(!self.is_empty(), "The input vector must not be empty."); self.argmin().0
let mut the_max = unsafe { self.vget_unchecked(0) };
let mut the_i = 0;
for i in 1..self.nrows() {
let val = unsafe { self.vget_unchecked(i) };
if val < the_max {
the_max = val;
the_i = i;
}
}
the_i
} }
/// Computes the index of the vector component with the smallest absolute value. /// Computes the index of the vector component with the smallest absolute value.
@ -108,17 +137,18 @@ impl<N: Scalar + PartialOrd + Signed, D: Dim, S: Storage<N, D>> Vector<N, D, S>
/// assert_eq!(vec.iamin(), 0); /// assert_eq!(vec.iamin(), 0);
/// ``` /// ```
#[inline] #[inline]
pub fn iamin(&self) -> usize { pub fn iamin(&self) -> usize
where N: Signed {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_max = unsafe { self.vget_unchecked(0).abs() }; let mut the_min = unsafe { self.vget_unchecked(0).abs() };
let mut the_i = 0; let mut the_i = 0;
for i in 1..self.nrows() { for i in 1..self.nrows() {
let val = unsafe { self.vget_unchecked(i).abs() }; let val = unsafe { self.vget_unchecked(i).abs() };
if val < the_max { if val < the_min {
the_max = val; the_min = val;
the_i = i; the_i = i;
} }
} }