Struct russell_lab::vector::NumVector
source · pub struct NumVector<T>{ /* private fields */ }
Expand description
Implements a vector with numeric components for linear algebra
§Remarks
- NumVector implements the Index and IntoIterator traits (mutable or not), thus, we can access components by indices or loop over the components
- NumVector has also methods to access the underlying data (mutable or not);
e.g., using
as_data()
andas_mut_data()
. - For faster computations, we recommend using the set of functions that
operate on Vectors and Matrices; e.g.,
vec_add
,vec_inner
,vec_outer
,vec_copy
,mat_vec_mul
, and others.
§Examples
use russell_lab::{vec_add, NumVector, StrError};
fn main() -> Result<(), StrError> {
// create vector
let mut u = NumVector::<f64>::from(&[4.0, 9.0, 16.0, 25.0]);
assert_eq!(
format!("{}", u),
"┌ ┐\n\
│ 4 │\n\
│ 9 │\n\
│ 16 │\n\
│ 25 │\n\
└ ┘"
);
// create vector filled with zeros
let n = u.dim();
let v = NumVector::<f64>::filled(n, 10.0);
assert_eq!(
format!("{}", v),
"┌ ┐\n\
│ 10 │\n\
│ 10 │\n\
│ 10 │\n\
│ 10 │\n\
└ ┘"
);
// create a copy and change its components
let mut w = u.clone();
w.map(|x| f64::sqrt(x));
w[0] *= -1.0;
w[1] *= -1.0;
w[2] *= -1.0;
w[3] *= -1.0;
assert_eq!(
format!("{}", w),
"┌ ┐\n\
│ -2 │\n\
│ -3 │\n\
│ -4 │\n\
│ -5 │\n\
└ ┘"
);
// change the components
for x in &mut u {
*x = f64::sqrt(*x);
}
// add vectors
let mut z = NumVector::<f64>::new(n);
vec_add(&mut z, 1.0, &u, 1.0, &w)?;
println!("{}", z);
assert_eq!(
format!("{}", z),
"┌ ┐\n\
│ 0 │\n\
│ 0 │\n\
│ 0 │\n\
│ 0 │\n\
└ ┘"
);
Ok(())
}
Implementations§
source§impl<T> NumVector<T>
impl<T> NumVector<T>
sourcepub fn new(dim: usize) -> Self
pub fn new(dim: usize) -> Self
Creates a new (zeroed) vector
§Examples
let u = NumVector::<f64>::new(3);
let correct = "┌ ┐\n\
│ 0 │\n\
│ 0 │\n\
│ 0 │\n\
└ ┘";
assert_eq!(format!("{}", u), correct);
sourcepub fn filled(dim: usize, value: T) -> Self
pub fn filled(dim: usize, value: T) -> Self
Creates new vector completely filled with the same value
§Examples
let u = NumVector::<f64>::filled(3, 4.0);
let correct = "┌ ┐\n\
│ 4 │\n\
│ 4 │\n\
│ 4 │\n\
└ ┘";
assert_eq!(format!("{}", u), correct);
sourcepub fn from<'a, S, U>(array: &'a S) -> Self
pub fn from<'a, S, U>(array: &'a S) -> Self
Creates a vector from data
§Examples
// heap-allocated 1D array (vector)
let u_data = vec![1.0, 2.0, 3.0];
let u = NumVector::<f64>::from(&u_data);
assert_eq!(
format!("{}", &u),
"┌ ┐\n\
│ 1 │\n\
│ 2 │\n\
│ 3 │\n\
└ ┘"
);
// heap-allocated 1D array (slice)
let v_data: &[f64] = &[10.0, 20.0, 30.0];
let v = NumVector::<f64>::from(&v_data);
assert_eq!(
format!("{}", &v),
"┌ ┐\n\
│ 10 │\n\
│ 20 │\n\
│ 30 │\n\
└ ┘"
);
// stack-allocated (fixed-size) 2D array
let w_data = [100.0, 200.0, 300.0];
let w = NumVector::<f64>::from(&w_data);
assert_eq!(
format!("{}", &w),
"┌ ┐\n\
│ 100 │\n\
│ 200 │\n\
│ 300 │\n\
└ ┘"
);
sourcepub fn initialized<F>(dim: usize, function: F) -> Self
pub fn initialized<F>(dim: usize, function: F) -> Self
Returns a new vector that is initialized from a callback function (map)
The function maps the index to the value, e.g., |i| (i as f64)
§Examples
let u = NumVector::<f64>::initialized(3, |i| (1 + 2 * i) as f64);
assert_eq!(
format!("{}", u),
"┌ ┐\n\
│ 1 │\n\
│ 3 │\n\
│ 5 │\n\
└ ┘"
);
sourcepub fn linspace(start: T, stop: T, count: usize) -> Result<Self, StrError>
pub fn linspace(start: T, stop: T, count: usize) -> Result<Self, StrError>
Returns evenly spaced numbers over a specified closed interval
§Panics
This function may panic if count
cannot be cast as the number type of start
and stop
.
§Examples
use russell_lab::{NumVector, StrError};
fn main() -> Result<(), StrError> {
let x = NumVector::<f64>::linspace(2.0, 3.0, 5)?;
let correct = "┌ ┐\n\
│ 2 │\n\
│ 2.25 │\n\
│ 2.5 │\n\
│ 2.75 │\n\
│ 3 │\n\
└ ┘";
assert_eq!(format!("{}", x), correct);
let indices = NumVector::<usize>::linspace(0, 10, 4)?;
assert_eq!(*indices.as_data(), [0, 3, 6, 9]);
Ok(())
}
sourcepub fn mapped_linspace<F>(
start: T,
stop: T,
count: usize,
function: F
) -> Result<Self, StrError>where
F: FnMut(T) -> T,
pub fn mapped_linspace<F>(
start: T,
stop: T,
count: usize,
function: F
) -> Result<Self, StrError>where
F: FnMut(T) -> T,
Returns a mapped linear-space; evenly spaced numbers modified by a function
§Panics
This function may panic if count
cannot be cast as the number type of start
and stop
.
§Examples
use russell_lab::{NumVector, StrError};
fn main() -> Result<(), StrError> {
let x = NumVector::<f64>::mapped_linspace(0.0, 4.0, 5, |v| v * v)?;
assert_eq!(
format!("{}", x),
"┌ ┐\n\
│ 0 │\n\
│ 1 │\n\
│ 4 │\n\
│ 9 │\n\
│ 16 │\n\
└ ┘",
);
Ok(())
}
sourcepub fn dim(&self) -> usize
pub fn dim(&self) -> usize
Returns the dimension (size) of this vector
§Examples
let u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
assert_eq!(u.dim(), 3);
sourcepub fn fill(&mut self, value: T)
pub fn fill(&mut self, value: T)
Fills this vector with a given value
u[i] := value
§Examples
let mut u = NumVector::<f64>::new(3);
u.fill(8.8);
let correct = "┌ ┐\n\
│ 8.8 │\n\
│ 8.8 │\n\
│ 8.8 │\n\
└ ┘";
assert_eq!(format!("{}", u), correct);
sourcepub fn as_data(&self) -> &Vec<T>
pub fn as_data(&self) -> &Vec<T>
Returns an access to the underlying data
§Examples
let u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
assert_eq!(u.as_data(), &[1.0, 2.0, 3.0]);
sourcepub fn as_mut_data(&mut self) -> &mut Vec<T>
pub fn as_mut_data(&mut self) -> &mut Vec<T>
Returns a mutable access to the underlying data
§Examples
let mut u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
let data = u.as_mut_data();
data[1] = 2.2;
assert_eq!(data, &[1.0, 2.2, 3.0]);
sourcepub fn map<F>(&mut self, function: F)where
F: Fn(T) -> T,
pub fn map<F>(&mut self, function: F)where
F: Fn(T) -> T,
Applies a function over all components of this vector
u := map(function(ui))
§Examples
let mut u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
u.map(|x| x * x);
let correct = "┌ ┐\n\
│ 1 │\n\
│ 4 │\n\
│ 9 │\n\
└ ┘";
assert_eq!(format!("{}", u), correct);
sourcepub fn map_with_index<F>(&mut self, function: F)
pub fn map_with_index<F>(&mut self, function: F)
Applies a function (with index) over all components of this vector
u := map(function(i, ui))
§Examples
let mut u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
u.map_with_index(|i, x| x * x + (i as f64));
let correct = "┌ ┐\n\
│ 1 │\n\
│ 5 │\n\
│ 11 │\n\
└ ┘";
assert_eq!(format!("{}", u), correct);
sourcepub fn get_mapped<F>(&self, function: F) -> Selfwhere
F: FnMut(T) -> T,
pub fn get_mapped<F>(&self, function: F) -> Selfwhere
F: FnMut(T) -> T,
Returns a mapped version of this vector
§Examples
let mut u = NumVector::<f64>::from(&[1.0, 2.0, 3.0]);
let v = u.get_mapped(|v| 4.0 - v);
u.set(1, 100.0);
assert_eq!(
format!("{}", u),
"┌ ┐\n\
│ 1 │\n\
│ 100 │\n\
│ 3 │\n\
└ ┘",
);
assert_eq!(
format!("{}", v),
"┌ ┐\n\
│ 3 │\n\
│ 2 │\n\
│ 1 │\n\
└ ┘",
);
Trait Implementations§
source§impl<'de, T> Deserialize<'de> for NumVector<T>
impl<'de, T> Deserialize<'de> for NumVector<T>
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl<T> Index<usize> for NumVector<T>
impl<T> Index<usize> for NumVector<T>
source§impl<T> IndexMut<usize> for NumVector<T>
impl<T> IndexMut<usize> for NumVector<T>
Allows to change NumVector components using indices
§Examples
use russell_lab::NumVector;
let mut u = NumVector::<f64>::from(&[-3.0, 1.2, 2.0]);
u[0] -= 10.0;
u[1] += 10.0;
u[2] += 20.0;
assert_eq!(u[0], -13.0);
assert_eq!(u[1], 11.2);
assert_eq!(u[2], 22.0);
§Panics
The index function may panic if the index is out-of-bounds.
source§impl<'a, T> IntoIterator for &'a NumVector<T>
impl<'a, T> IntoIterator for &'a NumVector<T>
Allows to iterate over NumVector components (borrow version)
§Examples
use russell_lab::NumVector;
let u = NumVector::<f64>::from(&[10.0, 20.0, 30.0]);
let mut x = 10.0;
for v in &u {
assert_eq!(*v, x);
x += 10.0;
}
source§impl<'a, T> IntoIterator for &'a mut NumVector<T>
impl<'a, T> IntoIterator for &'a mut NumVector<T>
Allows to iterate over NumVector components (mutable version)
§Examples
use russell_lab::NumVector;
let mut u = NumVector::<f64>::from(&[10.0, 20.0, 30.0]);
let mut x = 100.0;
for v in &mut u {
*v *= 10.0;
assert_eq!(*v, x);
x += 100.0;
}
source§impl<T> IntoIterator for NumVector<T>
impl<T> IntoIterator for NumVector<T>
Allows to iterate over NumVector components (move version)
§Examples
use russell_lab::NumVector;
let u = NumVector::<f64>::from(&[10.0, 20.0, 30.0]);
for (i, v) in u.into_iter().enumerate() {
assert_eq!(v, (10 * (i + 1)) as f64);
}