argmin/core/math/
mod.rs

1// Copyright 2018-2020 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! # Math
9//!
10//! Mathematics related traits which some solvers require. This provides an abstraction over
11//! different types of parameter vectors. The idea is, that it does not matter whether you would
12//! like to use simple `Vec`s, `ndarray`, `nalgebra` or custom defined types: As long as the traits
13//! required by the solver are implemented, you should be fine. In this module several of these
14//! traits are defined and implemented. These will be extended as needed. They are also already
15//! implemented for basic `Vec`s, and will in the future also be implemented for types defined by
16//! `ndarray` and `nalgebra`.
17//!
18//! # TODO
19//!
20//! * Implement tests for Complex<T> impls
21
22mod add;
23#[cfg(feature = "ndarrayl")]
24mod add_ndarray;
25mod add_vec;
26mod conj;
27#[cfg(feature = "ndarrayl")]
28mod conj_ndarray;
29mod conj_vec;
30mod div;
31#[cfg(feature = "ndarrayl")]
32mod div_ndarray;
33mod div_vec;
34mod dot;
35#[cfg(feature = "ndarrayl")]
36mod dot_ndarray;
37mod dot_vec;
38#[cfg(feature = "ndarrayl")]
39mod eye_ndarray;
40mod eye_vec;
41#[cfg(feature = "ndarrayl")]
42mod inv_ndarray;
43mod mul;
44#[cfg(feature = "ndarrayl")]
45mod mul_ndarray;
46mod mul_vec;
47mod norm;
48#[cfg(feature = "ndarrayl")]
49mod norm_ndarray;
50mod norm_vec;
51mod scaledadd;
52#[cfg(feature = "ndarrayl")]
53mod scaledadd_ndarray;
54mod scaledadd_vec;
55mod scaledsub;
56#[cfg(feature = "ndarrayl")]
57mod scaledsub_ndarray;
58mod scaledsub_vec;
59mod sub;
60#[cfg(feature = "ndarrayl")]
61mod sub_ndarray;
62mod sub_vec;
63mod transpose;
64#[cfg(feature = "ndarrayl")]
65mod transpose_ndarray;
66mod transpose_vec;
67mod weighteddot;
68mod zero;
69#[cfg(feature = "ndarrayl")]
70mod zero_ndarray;
71mod zero_vec;
72// #[cfg(feature = "ndarrayl")]
73// mod random_ndarray; // TODO
74mod random_vec;
75// #[cfg(feature = "ndarrayl")]
76// mod minmax_ndarray; // TODO
77mod minmax_vec;
78pub use crate::core::math::add::*;
79#[cfg(feature = "ndarrayl")]
80pub use crate::core::math::add_ndarray::*;
81pub use crate::core::math::add_vec::*;
82pub use crate::core::math::conj::*;
83#[cfg(feature = "ndarrayl")]
84pub use crate::core::math::conj_ndarray::*;
85pub use crate::core::math::conj_vec::*;
86#[cfg(feature = "ndarrayl")]
87pub use crate::core::math::div_ndarray::*;
88pub use crate::core::math::dot::*;
89#[cfg(feature = "ndarrayl")]
90pub use crate::core::math::dot_ndarray::*;
91pub use crate::core::math::dot_vec::*;
92#[cfg(feature = "ndarrayl")]
93pub use crate::core::math::eye_ndarray::*;
94pub use crate::core::math::eye_vec::*;
95#[cfg(feature = "ndarrayl")]
96pub use crate::core::math::inv_ndarray::*;
97pub use crate::core::math::mul::*;
98#[cfg(feature = "ndarrayl")]
99pub use crate::core::math::mul_ndarray::*;
100pub use crate::core::math::mul_vec::*;
101pub use crate::core::math::norm::*;
102#[cfg(feature = "ndarrayl")]
103pub use crate::core::math::norm_ndarray::*;
104pub use crate::core::math::norm_vec::*;
105pub use crate::core::math::scaledadd::*;
106#[cfg(feature = "ndarrayl")]
107pub use crate::core::math::scaledadd_ndarray::*;
108pub use crate::core::math::scaledadd_vec::*;
109pub use crate::core::math::scaledsub::*;
110#[cfg(feature = "ndarrayl")]
111pub use crate::core::math::scaledsub_ndarray::*;
112pub use crate::core::math::scaledsub_vec::*;
113pub use crate::core::math::sub::*;
114#[cfg(feature = "ndarrayl")]
115pub use crate::core::math::sub_ndarray::*;
116pub use crate::core::math::sub_vec::*;
117pub use crate::core::math::transpose::*;
118#[cfg(feature = "ndarrayl")]
119pub use crate::core::math::transpose_ndarray::*;
120pub use crate::core::math::transpose_vec::*;
121pub use crate::core::math::weighteddot::*;
122pub use crate::core::math::zero::*;
123#[cfg(feature = "ndarrayl")]
124pub use crate::core::math::zero_ndarray::*;
125pub use crate::core::math::zero_vec::*;
126// #[cfg(feature = "ndarrayl")] // TODO
127// pub use crate::core::math::random_ndarray::*;
128pub use crate::core::math::random_vec::*;
129// #[cfg(feature = "ndarrayl")] // TODO
130// pub use crate::core::math::minmax_ndarray::*;
131pub use crate::core::math::minmax_vec::*;
132
133use crate::core::Error;
134
135/// Dot/scalar product of `T` and `self`
136pub trait ArgminDot<T, U> {
137    /// Dot/scalar product of `T` and `self`
138    fn dot(&self, other: &T) -> U;
139}
140
141/// Dot/scalar product of `T` and `self` weighted by W (p^TWv)
142pub trait ArgminWeightedDot<T, U, V> {
143    /// Dot/scalar product of `T` and `self`
144    fn weighted_dot(&self, w: &V, vec: &T) -> U;
145}
146
147/// Return param vector of all zeros (for now, this is a hack. It should be done better)
148pub trait ArgminZero {
149    /// Return zero(s)
150    fn zero() -> Self;
151}
152
153/// Return the conjugate
154pub trait ArgminConj {
155    /// Return conjugate
156    fn conj(&self) -> Self;
157}
158
159/// Zero for dynamically sized objects
160pub trait ArgminZeroLike {
161    /// Return zero(s)
162    fn zero_like(&self) -> Self;
163}
164
165/// Identity matrix
166pub trait ArgminEye {
167    /// Identity matrix of size `n`
168    fn eye(n: usize) -> Self;
169    /// Identity matrix of same size as `self`
170    fn eye_like(&self) -> Self;
171}
172
173/// Add a `T` to `self`
174pub trait ArgminAdd<T, U> {
175    /// Add a `T` to `self`
176    fn add(&self, other: &T) -> U;
177}
178
179/// Subtract a `T` from `self`
180pub trait ArgminSub<T, U> {
181    /// Subtract a `T` from `self`
182    fn sub(&self, other: &T) -> U;
183}
184
185/// (Pointwise) Multiply a `T` with `self`
186pub trait ArgminMul<T, U> {
187    /// (Pointwise) Multiply a `T` with `self`
188    fn mul(&self, other: &T) -> U;
189}
190
191/// (Pointwise) Divide a `T` by `self`
192pub trait ArgminDiv<T, U> {
193    /// (Pointwise) Divide a `T` by `self`
194    fn div(&self, other: &T) -> U;
195}
196
197/// Add a `T` scaled by an `U` to `self`
198pub trait ArgminScaledAdd<T, U, V> {
199    /// Add a `T` scaled by an `U` to `self`
200    fn scaled_add(&self, factor: &U, vec: &T) -> V;
201}
202
203/// Subtract a `T` scaled by an `U` from `self`
204pub trait ArgminScaledSub<T, U, V> {
205    /// Subtract a `T` scaled by an `U` from `self`
206    fn scaled_sub(&self, factor: &U, vec: &T) -> V;
207}
208
209/// Compute the l2-norm (`U`) of `self`
210pub trait ArgminNorm<U> {
211    /// Compute the l2-norm (`U`) of `self`
212    fn norm(&self) -> U;
213}
214
215// Suboptimal: self is moved. ndarray however offers array views...
216/// Transposing a type
217pub trait ArgminTranspose {
218    /// Transpose
219    fn t(self) -> Self;
220}
221
222/// Compute the inverse (`T`) of `self`
223pub trait ArgminInv<T> {
224    /// Compute the inverse
225    fn inv(&self) -> Result<T, Error>;
226}
227
228/// Create a random number
229pub trait ArgminRandom {
230    /// Get a random element between min and max,
231    fn rand_from_range(min: &Self, max: &Self) -> Self;
232}
233
234/// Minimum and Maximum of type `T`
235pub trait ArgminMinMax {
236    /// Select piecewise minimum
237    fn min(x: &Self, y: &Self) -> Self;
238    /// Select piecewise maximum
239    fn max(x: &Self, y: &Self) -> Self;
240}