peroxide/prelude/
simpler.rs

1use crate::numerical::{
2    eigen,
3    eigen::{Eigen, EigenMethod::Jacobi},
4    integral,
5    integral::Integral::G7K15R,
6    spline,
7    spline::{CubicHermiteSpline, SlopeMethod::Quadratic},
8};
9#[cfg(feature = "parquet")]
10use crate::structure::dataframe::{DataFrame, WithParquet};
11use crate::structure::matrix::Matrix;
12use crate::structure::polynomial;
13use crate::traits::math::{Norm, Normed};
14#[allow(unused_imports)]
15use crate::traits::matrix::{Form, LinearAlgebra, MatrixTrait, SolveKind, PQLU, QR, UPLO, WAZD};
16#[cfg(feature = "parquet")]
17use parquet::basic::Compression;
18#[cfg(feature = "parquet")]
19use std::error::Error;
20
21/// Simple Norm
22pub trait SimpleNorm: Normed {
23    fn norm(&self) -> Self::Scalar;
24    fn normalize(&self) -> Self;
25}
26
27/// Simple integrate
28pub fn integrate<F: Fn(f64) -> f64 + Copy>(f: F, (a, b): (f64, f64)) -> f64 {
29    integral::integrate(f, (a, b), G7K15R(1e-4, 20))
30}
31
32/// Simple Linear algebra
33pub trait SimplerLinearAlgebra<M: MatrixTrait> {
34    fn back_subs(&self, b: &[f64]) -> Vec<f64>;
35    fn forward_subs(&self, b: &[f64]) -> Vec<f64>;
36    fn lu(&self) -> PQLU<M>;
37    fn waz_diag(&self) -> Option<WAZD<M>>;
38    fn waz(&self) -> Option<WAZD<M>>;
39    fn qr(&self) -> QR<M>;
40    #[cfg(feature = "O3")]
41    fn cholesky(&self) -> M;
42    fn rref(&self) -> M;
43    fn det(&self) -> f64;
44    fn block(&self) -> (M, M, M, M);
45    fn inv(&self) -> M;
46    fn pseudo_inv(&self) -> M;
47    fn solve(&self, b: &[f64]) -> Vec<f64>;
48    fn solve_mat(&self, m: &M) -> M;
49    fn is_symmetric(&self) -> bool;
50}
51
52/// Simple Eigenpair
53pub fn eigen(m: &Matrix) -> Eigen {
54    eigen::eigen(m, Jacobi)
55}
56
57/// Simple L2 norm
58impl SimpleNorm for Vec<f64> {
59    fn norm(&self) -> Self::Scalar {
60        Normed::norm(self, Norm::L2)
61    }
62
63    fn normalize(&self) -> Self {
64        Normed::normalize(self, Norm::L2)
65    }
66}
67
68/// Simple Frobenius norm
69impl SimpleNorm for Matrix {
70    fn norm(&self) -> Self::Scalar {
71        Normed::norm(self, Norm::F)
72    }
73
74    fn normalize(&self) -> Self {
75        unimplemented!()
76    }
77}
78
79impl SimplerLinearAlgebra<Matrix> for Matrix {
80    fn back_subs(&self, b: &[f64]) -> Vec<f64> {
81        LinearAlgebra::back_subs(self, b)
82    }
83
84    fn forward_subs(&self, b: &[f64]) -> Vec<f64> {
85        LinearAlgebra::forward_subs(self, b)
86    }
87
88    fn lu(&self) -> PQLU<Matrix> {
89        LinearAlgebra::lu(self)
90    }
91
92    fn waz_diag(&self) -> Option<WAZD<Matrix>> {
93        LinearAlgebra::waz(self, Form::Diagonal)
94    }
95
96    fn waz(&self) -> Option<WAZD<Matrix>> {
97        LinearAlgebra::waz(self, Form::Identity)
98    }
99
100    fn qr(&self) -> QR<Matrix> {
101        LinearAlgebra::qr(self)
102    }
103
104    #[cfg(feature = "O3")]
105    fn cholesky(&self) -> Matrix {
106        LinearAlgebra::cholesky(self, UPLO::Lower)
107    }
108
109    fn rref(&self) -> Matrix {
110        LinearAlgebra::rref(self)
111    }
112
113    fn det(&self) -> f64 {
114        LinearAlgebra::det(self)
115    }
116
117    fn block(&self) -> (Matrix, Matrix, Matrix, Matrix) {
118        LinearAlgebra::block(self)
119    }
120
121    fn inv(&self) -> Matrix {
122        LinearAlgebra::inv(self)
123    }
124
125    fn pseudo_inv(&self) -> Matrix {
126        LinearAlgebra::pseudo_inv(self)
127    }
128
129    fn solve(&self, b: &[f64]) -> Vec<f64> {
130        LinearAlgebra::solve(self, b, SolveKind::LU)
131    }
132
133    fn solve_mat(&self, m: &Matrix) -> Matrix {
134        LinearAlgebra::solve_mat(self, m, SolveKind::LU)
135    }
136
137    fn is_symmetric(&self) -> bool {
138        LinearAlgebra::is_symmetric(self)
139    }
140}
141
142/// Simple solve
143#[allow(non_snake_case)]
144pub fn solve(A: &Matrix, m: &Matrix) -> Matrix {
145    crate::traits::matrix::solve(A, m, SolveKind::LU)
146}
147
148/// Simple Chebyshev Polynomial (First Kind)
149pub fn chebyshev_polynomial(n: usize) -> polynomial::Polynomial {
150    polynomial::chebyshev_polynomial(n, polynomial::SpecialKind::First)
151}
152
153pub fn cubic_hermite_spline(node_x: &[f64], node_y: &[f64]) -> anyhow::Result<CubicHermiteSpline> {
154    spline::cubic_hermite_spline(node_x, node_y, Quadratic)
155}
156
157use crate::special::function::{
158    lambert_w0 as lambert_w0_flex, lambert_wm1 as lambert_wm1_flex, LambertWAccuracyMode,
159};
160
161/// The principal branch of the Lambert W function, W_0(`z`).
162///
163/// Returns [`NAN`](f64::NAN) if the given input is smaller than -1/e (≈ -0.36787944117144233).
164///
165/// Accurate to 50 bits.
166///
167/// Wrapper of `lambert_w_0` function of `lambert_w` crate.
168///
169/// # Reference
170///
171/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
172pub fn lambert_w0(z: f64) -> f64 {
173    lambert_w0_flex(z, LambertWAccuracyMode::Precise)
174}
175
176/// The secondary branch of the Lambert W function, W_-1(`z`).
177///
178/// Returns [`NAN`](f64::NAN) if the given input is positive or smaller than -1/e (≈ -0.36787944117144233).
179///
180/// Accurate to 50 bits.
181///
182/// Wrapper of `lambert_w_m1` function of `lambert_w` crate.
183///
184/// # Reference
185///
186/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
187pub fn lambert_wm1(z: f64) -> f64 {
188    lambert_wm1_flex(z, LambertWAccuracyMode::Precise)
189}
190
191/// Simple handle parquet
192#[cfg(feature = "parquet")]
193pub trait SimpleParquet: Sized {
194    fn write_parquet(&self, path: &str) -> Result<(), Box<dyn Error>>;
195    fn read_parquet(path: &str) -> Result<Self, Box<dyn Error>>;
196}
197
198#[cfg(feature = "parquet")]
199impl SimpleParquet for DataFrame {
200    fn write_parquet(&self, path: &str) -> Result<(), Box<dyn Error>> {
201        WithParquet::write_parquet(self, path, Compression::SNAPPY)
202    }
203
204    fn read_parquet(path: &str) -> Result<Self, Box<dyn Error>> {
205        WithParquet::read_parquet(path)
206    }
207}