use super::{VectorIntoIterator, VectorIterator, VectorIteratorMut};
use crate::{
algebra::{
abstr::{AbsDiffEq, RelativeEq},
abstr::{Field, Scalar, Sign},
linear::matrix::{General, Transpose},
},
elementary::{Exponential, Power},
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::{fmt, fmt::Display, iter::IntoIterator, ops::Neg};
#[macro_export]
macro_rules! vector
{
($( $x: expr ),*) =>
{
{
let data_array = vec![ $($x),* ];
Vector::new_row(data_array)
}
};
($( $x: expr );*) =>
{
{
let data_array = vec![ $($x),* ];
Vector::new_column(data_array)
}
};
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct Vector<T> {
pub data: General<T>,
}
impl<T> IntoIterator for Vector<T>
where
T: Field + Scalar,
{
type Item = T;
type IntoIter = VectorIntoIterator<T>;
fn into_iter(self) -> Self::IntoIter {
VectorIntoIterator::new(self.data.into_iter())
}
}
impl<T> Vector<T> {
pub fn iter(&self) -> VectorIterator<'_, T> {
VectorIterator::new(self.data.iter())
}
pub fn iter_mut(&mut self) -> VectorIteratorMut<'_, T> {
VectorIteratorMut::new(self.data.iter_mut())
}
}
impl<T> Vector<T>
where
T: Field + Scalar + Power,
{
pub fn p_norm(&self, p: &T) -> T {
debug_assert!(*p >= T::one());
let (m, n): (usize, usize) = self.dim();
let mut sum: T = T::zero();
for i in 0..(m * n) {
let b: T = self[i];
sum += b.pow(*p);
}
let norm: T = sum.pow(T::one() / *p);
norm
}
}
impl<T> Neg for Vector<T>
where
T: Field + Scalar,
{
type Output = Vector<T>;
fn neg(self) -> Self::Output {
self.apply(&|&x| -x)
}
}
impl<T> Vector<T> {
pub fn convert_to_vec(self) -> Vec<T> {
self.data.convert_to_vec()
}
}
impl<T> Vector<T>
where
T: Field + Scalar + Power + Exponential,
{
pub fn eucl_norm(&self) -> T {
let exp: T = T::from_f64(2.0);
self.p_norm(&exp)
}
}
impl<T> Vector<T>
where
T: Clone + Copy,
{
pub fn new_row(data: Vec<T>) -> Self {
Vector {
data: General::new(1, data.len(), data),
}
}
pub fn new_column(data: Vec<T>) -> Self {
Vector {
data: General::new(data.len(), 1, data),
}
}
pub fn apply(mut self: Vector<T>, f: &dyn Fn(&T) -> T) -> Self {
self.data = self.data.apply(f);
self
}
}
impl<T> Vector<T>
where
T: Scalar,
{
pub fn new_row_random(n: usize) -> Self {
Vector {
data: General::new_random(1, n),
}
}
pub fn new_column_random(m: usize) -> Self {
Vector {
data: General::new_random(m, 1),
}
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn transpose(mut self) -> Self {
self.data = self.data.transpose();
self
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn dotp(&self, rhs: &Self) -> T {
let (lhs_m, lhs_n) = self.dim();
let (rhs_m, rhs_n) = rhs.dim();
debug_assert_ne!(lhs_m, 0);
debug_assert_eq!(lhs_n, 1);
debug_assert_eq!(lhs_m, rhs_m);
debug_assert_eq!(lhs_n, rhs_n);
let temp: Vector<T> = self.clone().transpose();
let res: General<T> = &temp.data * &rhs.data;
res[[0, 0]]
}
pub fn argmax(&self) -> usize {
let (m, n) = self.dim();
let mut max_index: usize = 0;
let mut max = self[max_index];
let limit: usize = m.max(n);
debug_assert_ne!(limit, 0);
for idx in 0..limit {
let element: T = self[idx];
if element > max {
max_index = idx;
max = element;
}
}
max_index
}
pub fn argmin(&self) -> usize {
let (m, n) = self.dim();
let mut min_index: usize = 0;
let mut min: T = self[min_index];
let limit: usize = m.max(n);
debug_assert_ne!(limit, 0);
for idx in 0..limit {
let element: T = self[idx];
if element < min {
min_index = idx;
min = element;
}
}
min_index
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn dyadp(&self, rhs: &Self) -> General<T> {
let (x_m, _x_n): (usize, usize) = self.dim();
let (y_m, _y_n): (usize, usize) = rhs.dim();
let mut c: General<T> = General::zero(x_m, y_m);
for i in 0..x_m {
for j in 0..y_m {
c[[i, j]] = self[i] * rhs[j];
}
}
c
}
}
impl<T> Vector<T>
where
T: Field + Scalar + Power,
{
pub fn reflector(&self) -> Vector<T> {
let two = T::one() + T::one();
let mut x_temp: Vector<T> = self.clone();
let norm_x: T = self.p_norm(&two);
x_temp[0] += self[0].sign() * norm_x;
let x_temp_norm: T = x_temp.p_norm(&two);
x_temp[0] /= x_temp_norm;
x_temp
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn zero(m: usize) -> Self {
Vector {
data: General::zero(m, 1),
}
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn one(m: usize) -> Self {
let mut vec: Vec<T> = Vec::with_capacity(m);
for _i in 0..m {
vec.push(T::one());
}
Vector::new_column(vec)
}
}
impl<T> Vector<T> {
pub fn dim(&self) -> (usize, usize) {
self.data.dim()
}
}
impl<T> Vector<T>
where
T: Field + Scalar,
{
pub fn get_slice(&self, s: usize, e: usize) -> Vector<T> {
let (m, n): (usize, usize) = self.dim();
if m == 1 {
debug_assert!(s < n);
debug_assert!(e < n);
} else {
debug_assert!(s < m);
debug_assert!(e < m);
}
let mut slice: Vector<T> = Vector::zero(e - s + 1);
for r in s..(e + 1) {
slice[r - s] = self[r]
}
slice
}
pub fn set_slice(&mut self, rhs: &Self, s: usize) {
let (m, _n): (usize, usize) = self.dim();
let (s_m, _s_n): (usize, usize) = rhs.dim();
debug_assert!(s + s_m <= m);
for r in s..(s + s_m) {
self[r] = rhs[r - s];
}
}
}
impl<T> PartialEq<Self> for Vector<T>
where
T: Scalar,
{
fn eq(&self, other: &Self) -> bool {
if self.data == other.data {
return true;
}
false
}
}
impl<T> Display for Vector<T>
where
T: Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data.fmt(f)
}
}
impl<T> Sign for Vector<T>
where
T: Field + Scalar,
{
fn sign(&self) -> Self {
(self.clone()).apply(&|x: &T| x.sign())
}
fn abs(&self) -> Self {
(self.clone()).apply(&|x: &T| x.abs())
}
fn is_positive(&self) -> bool {
unimplemented!();
}
fn is_negative(&self) -> bool {
unimplemented!();
}
}
impl<T> AbsDiffEq for Vector<T>
where
T: Field + Scalar + AbsDiffEq<Epsilon = T>,
{
type Epsilon = T;
fn default_epsilon() -> T {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Vector<T>, epsilon: T) -> bool {
self.data.abs_diff_eq(&other.data, epsilon)
}
}
impl<T> RelativeEq for Vector<T>
where
T: Field + Scalar + AbsDiffEq<Epsilon = T> + RelativeEq,
{
fn default_max_relative() -> T {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Vector<T>,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.data.relative_eq(&other.data, epsilon, max_relative)
}
}