Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ jobs:
# faer
- name: argmin-math (faer_latest)
run: cargo test -p argmin-math --no-default-features --features "faer_latest"
- name: argmin-math (faer_v0_24)
run: cargo test -p argmin-math --no-default-features --features "faer_v0_24"
- name: argmin-math (faer_v0_23)
run: cargo test -p argmin-math --no-default-features --features "faer_v0_23"
- name: argmin-math (faer_v0_22)
Expand Down
5 changes: 4 additions & 1 deletion crates/argmin-math/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ faer_0_20 = { package = "faer", version = "0.20", optional = true}
faer_0_21 = { package = "faer", version = "0.21", optional = true}
faer_0_22 = { package = "faer", version = "0.22", optional = true}
faer_0_23 = { package = "faer", version = "0.23", optional = true}
faer_0_24 = { package = "faer", version = "0.24", optional = true}
faer_traits_0_21 = {package = "faer-traits", version = "0.21", optional = true}
faer_traits_0_22 = {package = "faer-traits", version = "0.22", optional = true}
faer_traits_0_23 = {package = "faer-traits", version = "0.23", optional = true}
faer_traits_0_24 = {package = "faer-traits", version = "0.24", optional = true}

# general
num-complex_0_4 = { package = "num-complex", version = "0.4", optional = true, default-features = false, features = ["std"] }
Expand Down Expand Up @@ -84,11 +86,12 @@ ndarray_latest = ["ndarray_v0_16"]

#faer
faer_all = ["primitives"]
faer_latest = ["faer_v0_23"]
faer_latest = ["faer_v0_24"]
faer_v0_20 = ["faer_0_20", "num-complex_0_4", "faer_all"]
faer_v0_21 = ["faer_0_21", "num-complex_0_4", "faer_traits_0_21", "faer_all"]
faer_v0_22 = ["faer_0_22", "num-complex_0_4", "faer_traits_0_22", "faer_all"]
faer_v0_23 = ["faer_0_23", "num-complex_0_4", "faer_traits_0_23", "faer_all"]
faer_v0_24 = ["faer_0_24", "num-complex_0_4", "faer_traits_0_24", "faer_all"]

## With `ndarray-linalg`
ndarray_v0_16 = ["ndarray_0_16", "ndarray-linalg_0_17", "num-complex_0_4", "ndarray_all"]
Expand Down
4 changes: 1 addition & 3 deletions crates/argmin-math/src/faer_m_0_21/add.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::ArgminAdd;
use faer::{
mat::{AsMatMut, AsMatRef},
reborrow::{IntoConst, Reborrow, ReborrowMut},
unzip, zip, Mat, MatMut, MatRef,
};
use faer_traits::ComplexField;
use std::ops::{Add, AddAssign};
use faer_traits::{AddByRef, ComplexField};

/// MatRef + Scalar -> Mat
impl<E, R, C> ArgminAdd<E, Mat<E, R, C>> for MatRef<'_, E, R, C>
Expand Down
90 changes: 90 additions & 0 deletions crates/argmin-math/src/faer_m_0_21/col/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::ArgminAdd;
use faer::{
mat::{AsMatMut, AsMatRef},
unzip, zip, Col, ColRef, Mat, MatMut, MatRef,
};
use faer_traits::{AddByRef, ComplexField};

/// ColRef + Scalar -> Col
impl<E> ArgminAdd<E, Col<E>> for ColRef<'_, E>
where
E: ComplexField,
{
#[inline]
fn add(&self, other: &E) -> Col<E> {
zip!(self).map(|unzip!(this)| this.add_by_ref(other))
}
}

/// Scalar + ColRef-> Col
impl<'a, E> ArgminAdd<ColRef<'a, E>, Col<E>> for E
where
E: ComplexField,
{
#[inline]
fn add(&self, other: &ColRef<'a, E>) -> Col<E> {
// commutative with MatRef + Scalar so we can fall back on that case
<_ as ArgminAdd<_, _>>::add(other, self)
}
}

/// Col + Scalar -> Col
impl<E> ArgminAdd<E, Col<E>> for Col<E>
where
E: ComplexField,
{
#[inline]
fn add(&self, other: &E) -> Col<E> {
//@note(geo-ant) because we are taking self by reference we
// cannot mutate the matrix in place, so we can just as well
// reuse the reference code
<_ as ArgminAdd<_, _>>::add(&self.as_ref(), other)
}
}

/// Scalar + Col -> Col
impl<E> ArgminAdd<Col<E>, Col<E>> for E
where
E: ComplexField,
{
#[inline]
fn add(&self, other: &Col<E>) -> Col<E> {
// commutative with Col + Scalar so we can fall back on that case
<_ as ArgminAdd<_, _>>::add(other, self)
}
}

/// ColRef + ColRef -> Col
impl<'a, E> ArgminAdd<ColRef<'a, E>, Col<E>> for ColRef<'_, E>
where
E: ComplexField,
{
#[inline]
fn add(&self, other: &ColRef<'a, E>) -> Col<E> {
self + other
}
}

/// ColRef + Col -> Col
impl<E: ComplexField> ArgminAdd<Col<E>, Col<E>> for ColRef<'_, E> {
#[inline]
fn add(&self, other: &Col<E>) -> Col<E> {
self + other
}
}

/// Col + ColRef -> Col
impl<E: ComplexField> ArgminAdd<ColRef<'_, E>, Col<E>> for Col<E> {
#[inline]
fn add(&self, other: &ColRef<'_, E>) -> Col<E> {
self + other
}
}

/// Col + Col -> Col
impl<E: ComplexField> ArgminAdd<Col<E>, Col<E>> for Col<E> {
#[inline]
fn add(&self, other: &Col<E>) -> Col<E> {
self + other
}
}
161 changes: 161 additions & 0 deletions crates/argmin-math/src/faer_m_0_21/col/dot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
use crate::ArgminDot;
use faer::prelude::*;
use faer_traits::ComplexField;

/// contains implementations for applying matrices to column vectors.
mod matrix_column_multiplication {
use super::*;

/// MatRef . ColRef -> Col
impl<E: ComplexField> ArgminDot<ColRef<'_, E>, Col<E>> for MatRef<'_, E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> Col<E> {
self * other
}
}

/// Mat . ColRef -> Col
impl<E: ComplexField> ArgminDot<ColRef<'_, E>, Col<E>> for Mat<E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> Col<E> {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), other)
}
}

/// MatRef . ColRef -> Col
impl<E: ComplexField> ArgminDot<Col<E>, Col<E>> for MatRef<'_, E> {
#[inline]
fn dot(&self, other: &Col<E>) -> Col<E> {
<_ as ArgminDot<_, _>>::dot(self, &other.as_ref())
}
}

/// Mat . Col -> Col
impl<E: ComplexField> ArgminDot<Col<E>, Col<E>> for Mat<E> {
#[inline]
fn dot(&self, other: &Col<E>) -> Col<E> {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), &other.as_ref())
}
}
}

/// contains implementations for the scalar product of two column vectors of
/// the same length. This is v^H . u for two column vectors v,u.
mod scalar_product {
use super::*;
use faer_traits::Conjugate;

/// ColRef . ColRef -> Scalar
impl<E: ComplexField + Conjugate<Conj = E>> ArgminDot<ColRef<'_, E>, E> for ColRef<'_, E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> E {
assert_eq!(
self.nrows(),
other.nrows(),
"vectors for dot product must have same number of elements"
);
self.conjugate().transpose() * other
}
}

/// Col . ColRef -> Scalar
impl<E: ComplexField + Conjugate<Conj = E>> ArgminDot<ColRef<'_, E>, E> for Col<E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> E {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), other)
}
}

/// ColRef . Col -> Scalar
impl<E: ComplexField + Conjugate<Conj = E>> ArgminDot<Col<E>, E> for ColRef<'_, E> {
#[inline]
fn dot(&self, other: &Col<E>) -> E {
<_ as ArgminDot<_, _>>::dot(self, &other.as_ref())
}
}

/// Col . Col -> Scalar
impl<E: ComplexField + Conjugate<Conj = E>> ArgminDot<Col<E>, E> for Col<E> {
#[inline]
fn dot(&self, other: &Col<E>) -> E {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), &other.as_ref())
}
}
}

mod outer_col_product {
use super::*;

/// ColRef . ColRef -> Mat
impl<E: ComplexField> ArgminDot<ColRef<'_, E>, Mat<E>> for ColRef<'_, E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> Mat<E> {
Mat::from_fn(self.nrows(), other.nrows(), |i, j| &self[i] * &other[j])
}
}

/// Col . ColRef -> Mat
impl<E: ComplexField> ArgminDot<ColRef<'_, E>, Mat<E>> for Col<E> {
#[inline]
fn dot(&self, other: &ColRef<'_, E>) -> Mat<E> {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), other)
}
}

/// ColRef . Col -> Mat
impl<E: ComplexField> ArgminDot<Col<E>, Mat<E>> for ColRef<'_, E> {
#[inline]
fn dot(&self, other: &Col<E>) -> Mat<E> {
<_ as ArgminDot<_, _>>::dot(self, &other.as_ref())
}
}

/// Col . Col -> Mat
impl<E: ComplexField> ArgminDot<Col<E>, Mat<E>> for Col<E> {
#[inline]
fn dot(&self, other: &Col<E>) -> Mat<E> {
<_ as ArgminDot<_, _>>::dot(&self.as_ref(), &other.as_ref())
}
}
}

//@note(clouds) implemented for compatibility with the nalgebra implementations
// see geo's comment in the faer_m_0_21 module (super)
mod multiply_col_with_scalar {
use super::*;
use crate::ArgminMul;
use faer_traits::ComplexField;
use std::ops::Mul;

// ColRef . Scalar -> Col
impl<E: ComplexField> ArgminDot<E, Col<E>> for ColRef<'_, E> {
#[inline]
fn dot(&self, other: &E) -> Col<E> {
<Self as ArgminMul<E, _>>::mul(self, other)
}
}

// Col . Scalar -> Col
impl<E: ComplexField> ArgminDot<E, Col<E>> for Col<E> {
#[inline]
fn dot(&self, other: &E) -> Col<E> {
<_ as ArgminDot<E, _>>::dot(&self.as_ref(), other)
}
}

// Scalar . ColRef -> Col
impl<'a, E: ComplexField> ArgminDot<ColRef<'a, E>, Col<E>> for E {
#[inline]
fn dot(&self, other: &ColRef<'a, E>) -> Col<E> {
<E as ArgminMul<ColRef<'a, E>, _>>::mul(self, other)
}
}

// Scalar . Col -> Col
impl<E: ComplexField> ArgminDot<Col<E>, Col<E>> for E {
#[inline]
fn dot(&self, other: &Col<E>) -> Col<E> {
<E as ArgminDot<_, _>>::dot(self, &other.as_ref())
}
}
}
15 changes: 15 additions & 0 deletions crates/argmin-math/src/faer_m_0_21/col/l2_norm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::ArgminL2Norm;
use faer::{Col, ColRef};
use faer_traits::ComplexField;

impl<E: ComplexField> ArgminL2Norm<E::Real> for ColRef<'_, E> {
fn l2_norm(&self) -> E::Real {
self.norm_l2()
}
}

impl<E: ComplexField> ArgminL2Norm<E::Real> for Col<E> {
fn l2_norm(&self) -> E::Real {
self.norm_l2()
}
}
11 changes: 11 additions & 0 deletions crates/argmin-math/src/faer_m_0_21/col/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod add;
mod dot;
mod l2_norm;
mod mul;
mod sub;

pub use add::*;
pub use dot::*;
pub use l2_norm::*;
pub use mul::*;
pub use sub::*;
Loading