From da242b136e912a660f62eca5b2b765a2ed0490d8 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 31 Oct 2024 10:32:38 +0900 Subject: [PATCH 1/2] FIX: Fix minors --- src/complex/matrix.rs | 2 +- src/fuga/mod.rs | 4 +- src/prelude/mod.rs | 2 +- src/structure/dataframe.rs | 11 ++--- src/structure/matrix.rs | 90 ++++++++++++++++--------------------- src/structure/polynomial.rs | 2 +- 6 files changed, 48 insertions(+), 63 deletions(-) diff --git a/src/complex/matrix.rs b/src/complex/matrix.rs index a564c7bd..947643e6 100644 --- a/src/complex/matrix.rs +++ b/src/complex/matrix.rs @@ -1904,7 +1904,7 @@ impl LinearAlgebra for ComplexMatrix { PQLU { p, q, l, u } } - fn waz(&self, d_form: Form) -> Option> { + fn waz(&self, _d_form: Form) -> Option> { unimplemented!() } diff --git a/src/fuga/mod.rs b/src/fuga/mod.rs index 60dcfcb3..6dc6a88a 100644 --- a/src/fuga/mod.rs +++ b/src/fuga/mod.rs @@ -173,9 +173,12 @@ pub use crate::traits::{ }; #[cfg(feature = "complex")] +#[allow(unused_imports)] pub use crate::complex::{ C64, matrix::*, + integral::*, + vector::*, }; #[allow(unused_imports)] @@ -186,7 +189,6 @@ pub use crate::structure::{ vector::*, dataframe::*, ad::*, - //complex::C64, }; pub use crate::util::{api::*, low_level::*, non_macro::*, print::*, useful::*, wrapper::*}; diff --git a/src/prelude/mod.rs b/src/prelude/mod.rs index f1abc275..4886010a 100644 --- a/src/prelude/mod.rs +++ b/src/prelude/mod.rs @@ -177,7 +177,6 @@ pub use crate::structure::{ dataframe::{ DataFrame, DType, DTypeArray, DTypeValue, Series, Scalar, TypedScalar, TypedVector }, - //complex::C64, }; #[cfg(feature="csv")] pub use crate::structure::dataframe::WithCSV; @@ -187,6 +186,7 @@ pub use crate::structure::dataframe::WithNetCDF; #[cfg(feature = "complex")] #[allow(ambiguous_glob_reexports)] +#[allow(unused_imports)] pub use crate::complex::{ C64, matrix::*, diff --git a/src/structure/dataframe.rs b/src/structure/dataframe.rs index 51b03107..3be872d6 100644 --- a/src/structure/dataframe.rs +++ b/src/structure/dataframe.rs @@ -187,8 +187,7 @@ //! //! * `nc` feature should be required //! * `libnetcdf` dependency should be required -//! * `Char`, `Bool` are saved as `U8` type. Thus, for reading `Char` or `Bool` type nc file, -//! explicit type casting is required. +//! * `Char`, `Bool` are saved as `U8` type. Thus, for reading `Char` or `Bool` type nc file, explicit type casting is required. //! //! ``` //! #[macro_use] @@ -226,8 +225,7 @@ //! ``` //! //! * `parquet` feature should be required -//! * `Char` is saved with `String` type. Thus, for reading `Char` type parquet file, -//! the output type is `String`. +//! * `Char` is saved with `String` type. Thus, for reading `Char` type parquet file, the output type is `String`. //! * **Caution** : For different length `Bool` type column, missing values are filled with `false`. //! ``` //! #[macro_use] @@ -1398,7 +1396,7 @@ impl DataFrame { /// Push new pair of head, Series to DataFrame pub fn push(&mut self, name: &str, series: Series) { - if self.ics.len() > 0 { + if !self.ics.is_empty() { assert_eq!(self.ics.iter().find(|x| x.as_str() == name), None, "Repetitive index!"); } self.ics.push(name.to_string()); @@ -1466,8 +1464,7 @@ impl DataFrame { result.push('\n'); } result.push_str(&tab("...", lc1)); - for j in 0 .. self.data.len() { - let space = space_vec[j]; + for &space in space_vec.iter() { result.push_str(&tab("...", space)); } result.push('\n'); diff --git a/src/structure/matrix.rs b/src/structure/matrix.rs index 23feb1f7..0e6c3b65 100644 --- a/src/structure/matrix.rs +++ b/src/structure/matrix.rs @@ -462,8 +462,7 @@ //! //! ## Tips for LU, Det, Inverse //! -//! * If you save `self.lu()` rather than the direct use of `self.det()` or `self.lu()` then you -//! can get better performance (via memoization) +//! * If you save `self.lu()` rather than the direct use of `self.det()` or `self.lu()` then you can get better performance (via memoization) //! //! ```rust //! use peroxide::fuga::*; @@ -2754,12 +2753,10 @@ impl FPMatrix for Matrix { /// ```rust /// use peroxide::fuga::*; /// - /// fn main() { - /// let x = ml_matrix("1 2;3 4;5 6"); - /// let y = x.col_map(|c| c.fmap(|t| t - c.mean())); + /// let x = ml_matrix("1 2;3 4;5 6"); + /// let y = x.col_map(|c| c.fmap(|t| t - c.mean())); /// - /// assert_eq!(y, ml_matrix("-2 -2;0 0;2 2")); - /// } + /// assert_eq!(y, ml_matrix("-2 -2;0 0;2 2")); /// ``` fn col_map(&self, f: F) -> Matrix where @@ -2780,12 +2777,10 @@ impl FPMatrix for Matrix { /// ```rust /// use peroxide::fuga::*; /// - /// fn main() { - /// let x = ml_matrix("1 2 3;4 5 6"); - /// let y = x.row_map(|r| r.fmap(|t| t - r.mean())); + /// let x = ml_matrix("1 2 3;4 5 6"); + /// let y = x.row_map(|r| r.fmap(|t| t - r.mean())); /// - /// assert_eq!(y, ml_matrix("-1 0 1;-1 0 1")); - /// } + /// assert_eq!(y, ml_matrix("-1 0 1;-1 0 1")); /// ``` fn row_map(&self, f: F) -> Matrix where @@ -3035,23 +3030,21 @@ impl LinearAlgebra for Matrix { /// /// # Caution /// It returns `Option` - You should unwrap to obtain real value. - /// `PQLU` has four field - `p`, `q`, `l`, `u`. - /// `p`, `q` are permutations. - /// `l`, `u` are matrices. + /// - `PQLU` has four field - `p`, `q`, `l`, `u`. + /// - `p`, `q` are permutations. + /// - `l`, `u` are matrices. /// /// # Examples /// ``` /// use peroxide::fuga::*; /// - /// fn main() { - /// let a = matrix(vec![1,2,3,4], 2, 2, Row); - /// let pqlu = a.lu(); - /// let (p,q,l,u) = (pqlu.p, pqlu.q, pqlu.l, pqlu.u); - /// assert_eq!(p, vec![1]); // swap 0 & 1 (Row) - /// assert_eq!(q, vec![1]); // swap 0 & 1 (Col) - /// assert_eq!(l, matrix(vec![1.0,0.0,0.5,1.0],2,2,Row)); - /// assert_eq!(u, matrix(vec![4.0,3.0,0.0,-0.5],2,2,Row)); - /// } + /// let a = matrix(vec![1,2,3,4], 2, 2, Row); + /// let pqlu = a.lu(); + /// let (p,q,l,u) = (pqlu.p, pqlu.q, pqlu.l, pqlu.u); + /// assert_eq!(p, vec![1]); // swap 0 & 1 (Row) + /// assert_eq!(q, vec![1]); // swap 0 & 1 (Col) + /// assert_eq!(l, matrix(vec![1.0,0.0,0.5,1.0],2,2,Row)); + /// assert_eq!(u, matrix(vec![4.0,3.0,0.0,-0.5],2,2,Row)); /// ``` fn lu(&self) -> PQLU { assert_eq!(self.col, self.row); @@ -3155,16 +3148,14 @@ impl LinearAlgebra for Matrix { /// ``` /// use peroxide::fuga::*; /// - /// fn main() { - /// let a = ml_matrix("12 -51 4;6 167 -68; -4 24 -41"); - /// let qr = a.qr(); - /// let r = ml_matrix("-14 -21 14; 0 -175 70; 0 0 -35"); - /// #[cfg(feature="O3")] - /// { - /// assert_eq!(r, qr.r); - /// } - /// qr.r.print(); + /// let a = ml_matrix("12 -51 4;6 167 -68; -4 24 -41"); + /// let qr = a.qr(); + /// let r = ml_matrix("-14 -21 14; 0 -175 70; 0 0 -35"); + /// #[cfg(feature="O3")] + /// { + /// assert_eq!(r, qr.r); /// } + /// qr.r.print(); /// ``` #[allow(non_snake_case)] fn qr(&self) -> QR { @@ -3211,15 +3202,13 @@ impl LinearAlgebra for Matrix { /// ``` /// use peroxide::fuga::*; /// - /// fn main() { - /// let a = ml_matrix("3 2 2;2 3 -2"); - /// #[cfg(feature="O3")] - /// { - /// let svd = a.svd(); - /// assert!(eq_vec(&vec![5f64, 3f64], &svd.s, 1e-7)); - /// } - /// a.print(); + /// let a = ml_matrix("3 2 2;2 3 -2"); + /// #[cfg(feature="O3")] + /// { + /// let svd = a.svd(); + /// assert!(eq_vec(&vec![5f64, 3f64], &svd.s, 1e-7)); /// } + /// a.print(); /// ``` fn svd(&self) -> SVD { match () { @@ -3250,21 +3239,18 @@ impl LinearAlgebra for Matrix { /// /// # Examples /// ``` - /// extern crate peroxide; /// use peroxide::fuga::*; /// - /// fn main() { - /// let a = ml_matrix("1 2;2 5"); - /// #[cfg(feature = "O3")] - /// { - /// let u = a.cholesky(Upper); - /// let l = a.cholesky(Lower); + /// let a = ml_matrix("1 2;2 5"); + /// #[cfg(feature = "O3")] + /// { + /// let u = a.cholesky(Upper); + /// let l = a.cholesky(Lower); /// - /// assert_eq!(u, ml_matrix("1 2;0 1")); - /// assert_eq!(l, ml_matrix("1 0;2 1")); - /// } - /// a.print(); + /// assert_eq!(u, ml_matrix("1 2;0 1")); + /// assert_eq!(l, ml_matrix("1 0;2 1")); /// } + /// a.print(); /// ``` #[cfg(feature = "O3")] fn cholesky(&self, uplo: UPLO) -> Matrix { diff --git a/src/structure/polynomial.rs b/src/structure/polynomial.rs index 346e4625..151f3ee2 100644 --- a/src/structure/polynomial.rs +++ b/src/structure/polynomial.rs @@ -51,7 +51,7 @@ impl fmt::Display for Polynomial { let coef_0 = self.coef[1]; if coef_1 == 1. { - result.push_str("x"); + result.push('x'); } else if coef_1 == -1. { result.push_str("-x"); } else { From b2e1ceab0acecd4fbd310c1f7a9cb105b18916b0 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 31 Oct 2024 10:34:33 +0900 Subject: [PATCH 2/2] FIX: Apply cargo fmt --- examples/b_spline_test.rs | 4 +- examples/broyden_test.rs | 13 +- examples/chebyshev.rs | 2 +- examples/dataframe.rs | 4 +- examples/df_csv.rs | 4 +- examples/df_nc.rs | 12 +- examples/gradient.rs | 10 +- examples/lorenz_dp45.rs | 9 +- examples/lorenz_gl4.rs | 9 +- examples/lorenz_rk4.rs | 9 +- examples/lorenz_rkf45.rs | 9 +- examples/lorenz_tsit45.rs | 9 +- examples/matmul.rs | 6 +- examples/ode_env.rs | 13 +- examples/ode_test_gl4.rs | 9 +- examples/ode_test_rk4.rs | 9 +- examples/ode_test_rkf45.rs | 9 +- examples/optim.rs | 13 +- examples/pseudo_inv.rs | 2 +- examples/root_macro_test.rs | 2 +- examples/root_test.rs | 22 +- examples/svd.rs | 2 +- src/complex/matrix.rs | 60 +-- src/fuga/mod.rs | 56 +-- src/numerical/mod.rs | 2 +- src/numerical/newton.rs | 8 +- src/numerical/ode.rs | 347 ++++++++++++---- src/numerical/optimize.rs | 21 +- src/numerical/root.rs | 96 ++--- src/numerical/spline.rs | 82 ++-- src/numerical/utils.rs | 7 +- src/prelude/mod.rs | 45 +- src/prelude/simpler.rs | 4 +- src/special/function.rs | 10 +- src/special/mod.rs | 14 +- src/statistics/stat.rs | 21 +- src/structure/ad.rs | 269 +++++++----- src/structure/dataframe.rs | 380 +++++++++-------- src/structure/matrix.rs | 8 +- src/structure/polynomial.rs | 28 +- src/structure/sparse.rs | 8 +- src/structure/vector.rs | 19 +- src/traits/matrix.rs | 17 +- src/traits/num.rs | 4 +- src/traits/pointer.rs | 6 +- src/traits/sugar.rs | 2 +- src/util/non_macro.rs | 28 +- src/util/plot.rs | 97 +++-- src/util/print.rs | 22 +- src/util/useful.rs | 56 ++- tests/dataframe/dataframe.rs | 4 +- tests/dataframe/mod.rs | 4 +- tests/dataframe/print.rs | 2 +- tests/dataframe/series.rs | 8 +- tests/integrated.rs | 2 +- tests/numerical.rs | 4 +- tests/o3/lapack.rs | 774 +++++++++++++++++++++++++++++++---- tests/o3/mod.rs | 1 - tests/optimize.rs | 6 +- tests/ordered_stat_test.rs | 2 +- tests/polynomial.rs | 2 +- tests/root.rs | 37 +- tests/series.rs | 24 +- tests/special.rs | 2 +- tests/stat.rs | 12 +- tests/weighted_uniform.rs | 2 +- 66 files changed, 1854 insertions(+), 930 deletions(-) diff --git a/examples/b_spline_test.rs b/examples/b_spline_test.rs index 46cdda59..6ae0ae32 100644 --- a/examples/b_spline_test.rs +++ b/examples/b_spline_test.rs @@ -12,7 +12,6 @@ fn main() -> Result<(), Box> { vec![1f64, 2f64], ]; - let spline = BSpline::clamped(degree, knots, control_points.clone())?; let t = linspace(0f64, 3f64, 200); let (x, y): (Vec, Vec) = spline.eval_vec(&t).into_iter().unzip(); @@ -23,8 +22,7 @@ fn main() -> Result<(), Box> { let control_y = control_points.iter().map(|v| v[1]).collect::>(); let mut plt = Plot2D::new(); - plt - .insert_pair((x.clone(), y.clone())) + plt.insert_pair((x.clone(), y.clone())) .insert_pair((control_x.clone(), control_y.clone())) .set_plot_type(vec![(1, PlotType::Scatter)]) .set_color(vec![(0, "darkblue"), (1, "red")]) diff --git a/examples/broyden_test.rs b/examples/broyden_test.rs index 6ddf5653..b3d2c400 100644 --- a/examples/broyden_test.rs +++ b/examples/broyden_test.rs @@ -1,9 +1,13 @@ use peroxide::fuga::*; -use peroxide::numerical::root::{Pt, Intv}; +use peroxide::numerical::root::{Intv, Pt}; fn main() -> Result<(), Box> { let problem = Quadratic; - let broyden = BroydenMethod { max_iter: 100, tol: 1e-6, rtol: 1e-6 }; + let broyden = BroydenMethod { + max_iter: 100, + tol: 1e-6, + rtol: 1e-6, + }; let root = broyden.find(&problem)?; let result = problem.function(root)?; @@ -17,10 +21,7 @@ struct Quadratic; impl RootFindingProblem<2, 2, Intv<2>> for Quadratic { fn function(&self, x: Pt<2>) -> anyhow::Result> { - Ok([ - x[0] * x[0] + x[1] * x[1] - 1.0, - x[0] + x[1] - 2f64.sqrt() - ]) + Ok([x[0] * x[0] + x[1] * x[1] - 1.0, x[0] + x[1] - 2f64.sqrt()]) } fn initial_guess(&self) -> Intv<2> { diff --git a/examples/chebyshev.rs b/examples/chebyshev.rs index 2ccdbe3a..739218ee 100644 --- a/examples/chebyshev.rs +++ b/examples/chebyshev.rs @@ -4,7 +4,7 @@ use peroxide::fuga::*; fn main() { let mut c = chebyshev_polynomial(0, SpecialKind::First); c.print(); - for i in 1 .. 11 { + for i in 1..11 { c = chebyshev_polynomial(i, SpecialKind::First); c.print(); } diff --git a/examples/dataframe.rs b/examples/dataframe.rs index 386184ae..e1374be4 100644 --- a/examples/dataframe.rs +++ b/examples/dataframe.rs @@ -3,7 +3,7 @@ extern crate peroxide; use peroxide::fuga::*; fn main() { - let x = c!(1,2,3,4); + let x = c!(1, 2, 3, 4); let a = Series::new(x); a.print(); println!(""); @@ -19,7 +19,7 @@ fn main() { df.print(); println!(""); - df["1"] = Series::new(c!(5,6,7,8)); + df["1"] = Series::new(c!(5, 6, 7, 8)); df.print(); println!(""); diff --git a/examples/df_csv.rs b/examples/df_csv.rs index eedc28f5..5e051f8c 100644 --- a/examples/df_csv.rs +++ b/examples/df_csv.rs @@ -3,7 +3,7 @@ extern crate peroxide; use peroxide::fuga::*; fn main() -> Result<(), Box> { - let a = Series::new(vec![1,2,3,4]); + let a = Series::new(vec![1, 2, 3, 4]); let b = Series::new(c!(0.1, 0.2, 0.3, 0.4)); let c = Series::new(vec![true, false, true, false]); let d = Series::new(vec!['a', 'b', 'c', 'd']); @@ -13,7 +13,7 @@ fn main() -> Result<(), Box> { df.print(); - #[cfg(feature="csv")] + #[cfg(feature = "csv")] { df.write_csv("example_data/df_csv.csv")?; diff --git a/examples/df_nc.rs b/examples/df_nc.rs index f5269276..4859f8eb 100644 --- a/examples/df_nc.rs +++ b/examples/df_nc.rs @@ -2,13 +2,19 @@ extern crate peroxide; use peroxide::fuga::*; fn main() -> Result<(), Box> { - #[cfg(feature = "nc")] { + #[cfg(feature = "nc")] + { let a = Series::new(vec![1, 2, 3, 4]); let b = Series::new(vec![0.1, 0.2, 0.3, 0.4]); let c = Series::new(vec![true, false, false, true]); - let d = Series::new(vec!["a", "b", "c", "d"].into_iter().map(|x| x.to_string()).collect()); + let d = Series::new( + vec!["a", "b", "c", "d"] + .into_iter() + .map(|x| x.to_string()) + .collect(), + ); - let mut df = DataFrame::new(vec![a,b,c,d]); + let mut df = DataFrame::new(vec![a, b, c, d]); df.set_header(vec!["a", "b", "c", "d"]); println!("Write:"); df.print(); diff --git a/examples/gradient.rs b/examples/gradient.rs index d81222c9..585c1f68 100644 --- a/examples/gradient.rs +++ b/examples/gradient.rs @@ -1,12 +1,12 @@ use peroxide::fuga::*; fn main() { - f(2f64).print(); // x^3 = 8 - f_grad(2f64).print(); // 3 * x^2 = 12 - f_hess(2f64).print(); // 6 * x = 12 + f(2f64).print(); // x^3 = 8 + f_grad(2f64).print(); // 3 * x^2 = 12 + f_hess(2f64).print(); // 6 * x = 12 } -#[ad_function] // generates f_grad, f_hess +#[ad_function] // generates f_grad, f_hess fn f(x: f64) -> f64 { - x.powi(3) // x^3 + x.powi(3) // x^3 } diff --git a/examples/lorenz_dp45.rs b/examples/lorenz_dp45.rs index da1de787..ce8c8a7d 100644 --- a/examples/lorenz_dp45.rs +++ b/examples/lorenz_dp45.rs @@ -4,11 +4,7 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let dp45 = DP45::new(1e-4, 0.9, 1e-6, 1e-1, 100); let basic_ode_solver = BasicODESolver::new(dp45); - let (_, y_vec) = basic_ode_solver.solve( - &Lorenz, - (0f64, 100f64), - 1e-2, - )?; + let (_, y_vec) = basic_ode_solver.solve(&Lorenz, (0f64, 100f64), 1e-2)?; let y_mat = py_matrix(y_vec); let y0 = y_mat.col(0); let y2 = y_mat.col(2); @@ -16,8 +12,7 @@ fn main() -> Result<(), Box> { #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(y0) + plt.set_domain(y0) .insert_image(y2) .set_xlabel(r"$y_0$") .set_ylabel(r"$y_2$") diff --git a/examples/lorenz_gl4.rs b/examples/lorenz_gl4.rs index ba17bcc4..9a64b57d 100644 --- a/examples/lorenz_gl4.rs +++ b/examples/lorenz_gl4.rs @@ -4,11 +4,7 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let gl4 = GL4::new(ImplicitSolver::FixedPoint, 1e-6, 100); let basic_ode_solver = BasicODESolver::new(gl4); - let (_, y_vec) = basic_ode_solver.solve( - &Lorenz, - (0f64, 100f64), - 1e-2, - )?; + let (_, y_vec) = basic_ode_solver.solve(&Lorenz, (0f64, 100f64), 1e-2)?; let y_mat = py_matrix(y_vec); let y0 = y_mat.col(0); let y2 = y_mat.col(2); @@ -16,8 +12,7 @@ fn main() -> Result<(), Box> { #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(y0) + plt.set_domain(y0) .insert_image(y2) .set_xlabel(r"$y_0$") .set_ylabel(r"$y_2$") diff --git a/examples/lorenz_rk4.rs b/examples/lorenz_rk4.rs index 79fc3b9a..8ebc4584 100644 --- a/examples/lorenz_rk4.rs +++ b/examples/lorenz_rk4.rs @@ -3,11 +3,7 @@ use peroxide::fuga::*; #[allow(unused_variables)] fn main() -> Result<(), Box> { let basic_ode_solver = BasicODESolver::new(RK4); - let (_, y_vec) = basic_ode_solver.solve( - &Lorenz, - (0f64, 100f64), - 1e-2, - )?; + let (_, y_vec) = basic_ode_solver.solve(&Lorenz, (0f64, 100f64), 1e-2)?; let y_mat = py_matrix(y_vec); let y0 = y_mat.col(0); let y2 = y_mat.col(2); @@ -15,8 +11,7 @@ fn main() -> Result<(), Box> { #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(y0) + plt.set_domain(y0) .insert_image(y2) .set_xlabel(r"$y_0$") .set_ylabel(r"$y_2$") diff --git a/examples/lorenz_rkf45.rs b/examples/lorenz_rkf45.rs index 83e2bdac..da0453b5 100644 --- a/examples/lorenz_rkf45.rs +++ b/examples/lorenz_rkf45.rs @@ -4,11 +4,7 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let rkf45 = RKF45::new(1e-4, 0.9, 1e-6, 1e-2, 100); let basic_ode_solver = BasicODESolver::new(rkf45); - let (_, y_vec) = basic_ode_solver.solve( - &Lorenz, - (0f64, 100f64), - 1e-2, - )?; + let (_, y_vec) = basic_ode_solver.solve(&Lorenz, (0f64, 100f64), 1e-2)?; let y_mat = py_matrix(y_vec); let y0 = y_mat.col(0); let y2 = y_mat.col(2); @@ -16,8 +12,7 @@ fn main() -> Result<(), Box> { #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(y0) + plt.set_domain(y0) .insert_image(y2) .set_xlabel(r"$y_0$") .set_ylabel(r"$y_2$") diff --git a/examples/lorenz_tsit45.rs b/examples/lorenz_tsit45.rs index f923e1c5..5bc147fd 100644 --- a/examples/lorenz_tsit45.rs +++ b/examples/lorenz_tsit45.rs @@ -4,11 +4,7 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let tsit45 = TSIT45::new(1e-2, 0.9, 1e-6, 1e-1, 100); let basic_ode_solver = BasicODESolver::new(tsit45); - let (_, y_vec) = basic_ode_solver.solve( - &Lorenz, - (0f64, 100f64), - 1e-2, - )?; + let (_, y_vec) = basic_ode_solver.solve(&Lorenz, (0f64, 100f64), 1e-2)?; let y_mat = py_matrix(y_vec); let y0 = y_mat.col(0); let y2 = y_mat.col(2); @@ -16,8 +12,7 @@ fn main() -> Result<(), Box> { #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(y0) + plt.set_domain(y0) .insert_image(y2) .set_xlabel(r"$y_0$") .set_ylabel(r"$y_2$") diff --git a/examples/matmul.rs b/examples/matmul.rs index 24f0fa51..47716ec6 100644 --- a/examples/matmul.rs +++ b/examples/matmul.rs @@ -7,12 +7,12 @@ fn main() { // Create Matrix let m = rand(row, col); - + // Create another Matrix let n = rand(row, col); - + // Matmul let result = m * n; - result[(row/2, col/2)].print(); + result[(row / 2, col / 2)].print(); } diff --git a/examples/ode_env.rs b/examples/ode_env.rs index e627e8bd..e2836bb7 100644 --- a/examples/ode_env.rs +++ b/examples/ode_env.rs @@ -11,22 +11,15 @@ fn main() -> Result<(), Box> { let c = cubic_hermite_spline(&t, &y, Quadratic)?; - let test_problem = Test { - cs: c, - }; + let test_problem = Test { cs: c }; let basic_ode_solver = BasicODESolver::new(RK4); - let (t_vec, y_vec) = basic_ode_solver.solve( - &test_problem, - (0f64, 10f64), - 0.01, - )?; + let (t_vec, y_vec) = basic_ode_solver.solve(&test_problem, (0f64, 10f64), 0.01)?; let y_vec: Vec = y_vec.into_iter().flatten().collect(); #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(t_vec) + plt.set_domain(t_vec) .insert_image(y_vec) .set_xlabel(r"$t$") .set_ylabel(r"$y$") diff --git a/examples/ode_test_gl4.rs b/examples/ode_test_gl4.rs index 1d1791e5..bf31dee4 100644 --- a/examples/ode_test_gl4.rs +++ b/examples/ode_test_gl4.rs @@ -4,18 +4,13 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let gl4 = GL4::new(ImplicitSolver::FixedPoint, 1e-6, 100); let basic_ode_solver = BasicODESolver::new(gl4); - let (t_vec, y_vec) = basic_ode_solver.solve( - &Test, - (0f64, 10f64), - 0.01, - )?; + let (t_vec, y_vec) = basic_ode_solver.solve(&Test, (0f64, 10f64), 0.01)?; let y_vec: Vec = y_vec.into_iter().flatten().collect(); #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(t_vec) + plt.set_domain(t_vec) .insert_image(y_vec) .set_xlabel(r"$t$") .set_ylabel(r"$y$") diff --git a/examples/ode_test_rk4.rs b/examples/ode_test_rk4.rs index a531aa3d..6b90f5c3 100644 --- a/examples/ode_test_rk4.rs +++ b/examples/ode_test_rk4.rs @@ -3,18 +3,13 @@ use peroxide::fuga::*; #[allow(unused_variables)] fn main() -> Result<(), Box> { let basic_ode_solver = BasicODESolver::new(RK4); - let (t_vec, y_vec) = basic_ode_solver.solve( - &Test, - (0f64, 10f64), - 1e-3, - )?; + let (t_vec, y_vec) = basic_ode_solver.solve(&Test, (0f64, 10f64), 1e-3)?; let y_vec: Vec = y_vec.into_iter().flatten().collect(); #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(t_vec) + plt.set_domain(t_vec) .insert_image(y_vec) .set_xlabel(r"$t$") .set_ylabel(r"$y$") diff --git a/examples/ode_test_rkf45.rs b/examples/ode_test_rkf45.rs index 7441c3a1..04ea96c6 100644 --- a/examples/ode_test_rkf45.rs +++ b/examples/ode_test_rkf45.rs @@ -4,18 +4,13 @@ use peroxide::fuga::*; fn main() -> Result<(), Box> { let rkf = RKF45::new(1e-4, 0.9, 1e-6, 1e-1, 100); let basic_ode_solver = BasicODESolver::new(rkf); - let (t_vec, y_vec) = basic_ode_solver.solve( - &Test, - (0f64, 10f64), - 0.01, - )?; + let (t_vec, y_vec) = basic_ode_solver.solve(&Test, (0f64, 10f64), 0.01)?; let y_vec: Vec = y_vec.into_iter().flatten().collect(); #[cfg(feature = "plot")] { let mut plt = Plot2D::new(); - plt - .set_domain(t_vec) + plt.set_domain(t_vec) .insert_image(y_vec) .set_xlabel(r"$t$") .set_ylabel(r"$y$") diff --git a/examples/optim.rs b/examples/optim.rs index 066578d2..97389eaa 100644 --- a/examples/optim.rs +++ b/examples/optim.rs @@ -21,20 +21,17 @@ fn main() { // Optimizer setting let mut opt = Optimizer::new(data, quad); - let p = opt.set_init_param(n_init) + let p = opt + .set_init_param(n_init) .set_max_iter(50) .set_method(LevenbergMarquardt) .optimize(); - p.print(); // Optimized parameter - opt.get_error().print(); // Optimized RMSE + p.print(); // Optimized parameter + opt.get_error().print(); // Optimized RMSE } fn quad(x: &Vec, n: Vec) -> Option> { - Some( - x.clone().into_iter() - .map(|t| pow_temp(t, n[0])) - .collect() - ) + Some(x.clone().into_iter().map(|t| pow_temp(t, n[0])).collect()) } #[inline] diff --git a/examples/pseudo_inv.rs b/examples/pseudo_inv.rs index bf7436c8..4c29615a 100644 --- a/examples/pseudo_inv.rs +++ b/examples/pseudo_inv.rs @@ -3,7 +3,7 @@ use peroxide::fuga::*; fn main() { let a = ml_matrix("2 -1 0;4 3 -2"); - #[cfg(feature="O3")] + #[cfg(feature = "O3")] { let b = a.pseudo_inv(); assert_eq!(&a * &b, eye(2)); diff --git a/examples/root_macro_test.rs b/examples/root_macro_test.rs index 31466596..5fe4c18a 100644 --- a/examples/root_macro_test.rs +++ b/examples/root_macro_test.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate peroxide; -use peroxide::fuga::*; use anyhow::Result; +use peroxide::fuga::*; fn main() -> Result<()> { let root_bisect = bisection!(f, (0.0, 2.0), 100, 1e-6)?; diff --git a/examples/root_test.rs b/examples/root_test.rs index 06bca33e..13b223ab 100644 --- a/examples/root_test.rs +++ b/examples/root_test.rs @@ -1,12 +1,24 @@ -use peroxide::fuga::*; use anyhow::Result; +use peroxide::fuga::*; fn main() -> Result<()> { let problem = Cubic; - let bisect = BisectionMethod { max_iter: 100, tol: 1e-6 }; - let newton = NewtonMethod { max_iter: 100, tol: 1e-6 }; - let false_pos = FalsePositionMethod { max_iter: 100, tol: 1e-6 }; - let secant = SecantMethod { max_iter: 100, tol: 1e-6 }; + let bisect = BisectionMethod { + max_iter: 100, + tol: 1e-6, + }; + let newton = NewtonMethod { + max_iter: 100, + tol: 1e-6, + }; + let false_pos = FalsePositionMethod { + max_iter: 100, + tol: 1e-6, + }; + let secant = SecantMethod { + max_iter: 100, + tol: 1e-6, + }; let result_bisect = bisect.find(&problem)?; let result_newton = newton.find(&problem)?; let result_false_pos = false_pos.find(&problem)?; diff --git a/examples/svd.rs b/examples/svd.rs index ac29be96..ab98b644 100644 --- a/examples/svd.rs +++ b/examples/svd.rs @@ -3,7 +3,7 @@ use peroxide::fuga::*; fn main() { let a = ml_matrix("14 2;4 22;16 13") / 15f64; - #[cfg(feature="O3")] + #[cfg(feature = "O3")] { let svd = a.svd(); svd.u.print(); diff --git a/src/complex/matrix.rs b/src/complex/matrix.rs index 947643e6..cc489e88 100644 --- a/src/complex/matrix.rs +++ b/src/complex/matrix.rs @@ -11,16 +11,16 @@ use peroxide_num::{ExpLogOps, PowOps, TrigOps}; use rand_distr::num_traits::{One, Zero}; use crate::{ + complex::C64, structure::matrix::Shape, traits::fp::{FPMatrix, FPVector}, traits::general::Algorithm, traits::math::{InnerProduct, LinearOp, MatrixProduct, Norm, Normed, Vector}, - traits::matrix::{MatrixTrait, LinearAlgebra, Form, SolveKind, PQLU, WAZD, QR, SVD}, + traits::matrix::{Form, LinearAlgebra, MatrixTrait, SolveKind, PQLU, QR, SVD, WAZD}, traits::mutable::MutMatrix, util::low_level::{copy_vec_ptr, swap_vec_ptr}, util::non_macro::ConcatenateError, util::useful::{nearly_eq, tab}, - complex::C64, }; /// R-like complex matrix structure @@ -79,10 +79,7 @@ where T: Into, { ComplexMatrix { - data: v - .into_iter() - .map(|t| t.into()) - .collect::>(), + data: v.into_iter().map(|t| t.into()).collect::>(), row: r, col: c, shape, @@ -1115,10 +1112,7 @@ impl Neg for ComplexMatrix { fn neg(self) -> Self { cmatrix( - self.data - .into_iter() - .map(|x: C64| -x) - .collect::>(), + self.data.into_iter().map(|x: C64| -x).collect::>(), self.row, self.col, self.shape, @@ -1522,11 +1516,7 @@ impl FPMatrix for ComplexMatrix { where F: Fn(C64) -> C64, { - let result = self - .data - .iter() - .map(|x| f(*x)) - .collect::>(); + let result = self.data.iter().map(|x| f(*x)).collect::>(); cmatrix(result, self.row, self.col, self.shape) } @@ -1908,14 +1898,22 @@ impl LinearAlgebra for ComplexMatrix { unimplemented!() } - fn qr(&self) -> QR { unimplemented!() } + fn qr(&self) -> QR { + unimplemented!() + } - fn svd(&self) -> SVD { unimplemented!() } + fn svd(&self) -> SVD { + unimplemented!() + } #[cfg(feature = "O3")] - fn cholesky(&self, uplo: UPLO) -> ComplexMatrix { unimplemented!() } + fn cholesky(&self, uplo: UPLO) -> ComplexMatrix { + unimplemented!() + } - fn rref(&self) -> ComplexMatrix { unimplemented!() } + fn rref(&self) -> ComplexMatrix { + unimplemented!() + } /// Determinant /// @@ -2481,13 +2479,7 @@ pub fn cmatmul(a: &ComplexMatrix, b: &ComplexMatrix) -> ComplexMatrix { /// cgemm(C64::new(1.0, 1.0), &a, &b, C64::new(0.0, 0.0), &mut c1); /// assert_eq!(c1, mul_val); /// } -pub fn cgemm( - alpha: C64, - a: &ComplexMatrix, - b: &ComplexMatrix, - beta: C64, - c: &mut ComplexMatrix, -) { +pub fn cgemm(alpha: C64, a: &ComplexMatrix, b: &ComplexMatrix, beta: C64, c: &mut ComplexMatrix) { let m = a.row; let k = a.col; let n = b.col; @@ -2528,13 +2520,7 @@ pub fn cgemm( } /// General Matrix-Vector multiplication -pub fn cgemv( - alpha: C64, - a: &ComplexMatrix, - b: &Vec, - beta: C64, - c: &mut Vec, -) { +pub fn cgemv(alpha: C64, a: &ComplexMatrix, b: &Vec, beta: C64, c: &mut Vec) { let m = a.row; let k = a.col; let n = 1usize; @@ -2569,13 +2555,7 @@ pub fn cgemv( } /// General Vector-Matrix multiplication -pub fn complex_gevm( - alpha: C64, - a: &Vec, - b: &ComplexMatrix, - beta: C64, - c: &mut Vec, -) { +pub fn complex_gevm(alpha: C64, a: &Vec, b: &ComplexMatrix, beta: C64, c: &mut Vec) { let m = 1usize; let k = a.len(); let n = b.col; diff --git a/src/fuga/mod.rs b/src/fuga/mod.rs index 6dc6a88a..6159073b 100644 --- a/src/fuga/mod.rs +++ b/src/fuga/mod.rs @@ -149,7 +149,7 @@ #[allow(unused_imports)] pub use crate::macros::{julia_macro::*, matlab_macro::*, r_macro::*}; -pub use peroxide_ad::{ad_function, ad_closure}; +pub use peroxide_ad::{ad_closure, ad_function}; pub use peroxide_num::{ExpLogOps, PowOps, TrigOps}; @@ -157,39 +157,31 @@ pub use crate::traits::{ fp::{FPMatrix, FPVector}, general::Algorithm, math::{InnerProduct, LinearOp, MatrixProduct, Norm, Normed, Vector, VectorProduct}, - matrix::{MatrixTrait, LinearAlgebra}, + matrix::{LinearAlgebra, MatrixTrait}, mutable::{MutFP, MutMatrix}, num::Real, pointer::{MatrixPtr, Oxide, Redox, RedoxCommon}, stable::StableFn, - sugar::{Scalable, ScalableMut, VecOps, ConvToMat}, + sugar::{ConvToMat, Scalable, ScalableMut, VecOps}, }; #[cfg(feature = "parallel")] pub use crate::traits::{ - fp::{ParallelFPVector, ParallelFPMatrix}, - math::{ParallelInnerProduct, ParallelMatrixProduct, ParallelNormed, ParallelVector, ParallelVectorProduct}, + fp::{ParallelFPMatrix, ParallelFPVector}, + math::{ + ParallelInnerProduct, ParallelMatrixProduct, ParallelNormed, ParallelVector, + ParallelVectorProduct, + }, mutable::ParallelMutFP, }; #[cfg(feature = "complex")] #[allow(unused_imports)] -pub use crate::complex::{ - C64, - matrix::*, - integral::*, - vector::*, -}; +pub use crate::complex::{integral::*, matrix::*, vector::*, C64}; #[allow(unused_imports)] #[allow(ambiguous_glob_reexports)] -pub use crate::structure::{ - matrix::*, - polynomial::*, - vector::*, - dataframe::*, - ad::*, -}; +pub use crate::structure::{ad::*, dataframe::*, matrix::*, polynomial::*, vector::*}; pub use crate::util::{api::*, low_level::*, non_macro::*, print::*, useful::*, wrapper::*}; @@ -218,33 +210,21 @@ pub use paste; // Enums // ============================================================================= pub use crate::numerical::integral::Integral::{ - GaussLegendre, - NewtonCotes, - G7K15, - G10K21, - G15K31, - G20K41, - G25K51, - G30K61, - G7K15R, - G10K21R, - G15K31R, - G20K41R, - G25K51R, - G30K61R, + GaussLegendre, NewtonCotes, G10K21, G10K21R, G15K31, G15K31R, G20K41, G20K41R, G25K51, G25K51R, + G30K61, G30K61R, G7K15, G7K15R, }; +pub use crate::numerical::spline::SlopeMethod::{Akima, Quadratic}; +pub use crate::statistics::stat::Metric::*; pub use crate::statistics::stat::QType::{ Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9, }; +pub use crate::structure::ad::AD::*; +pub use crate::structure::dataframe::DType::*; +pub use crate::structure::matrix::UPLO::{Lower, Upper}; pub use crate::traits::matrix::{ Form::{Diagonal, Identity}, SolveKind::{LU, WAZ}, }; -pub use crate::structure::matrix::UPLO::{Upper, Lower}; -pub use crate::structure::dataframe::DType::*; -pub use crate::structure::ad::AD::*; -pub use crate::numerical::spline::SlopeMethod::{Akima, Quadratic}; -pub use crate::statistics::stat::Metric::*; -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] pub use arrow2::io::parquet::write::CompressionOptions; diff --git a/src/numerical/mod.rs b/src/numerical/mod.rs index e228e556..0a21bfc3 100644 --- a/src/numerical/mod.rs +++ b/src/numerical/mod.rs @@ -8,4 +8,4 @@ pub mod ode; pub mod optimize; pub mod root; pub mod spline; -pub mod utils; \ No newline at end of file +pub mod utils; diff --git a/src/numerical/newton.rs b/src/numerical/newton.rs index afef9890..e3ee8f2b 100644 --- a/src/numerical/newton.rs +++ b/src/numerical/newton.rs @@ -2,13 +2,12 @@ use crate::numerical::utils::jacobian; use crate::structure::ad::*; use crate::traits::{ math::{Norm, Normed, Vector}, - mutable::MutFP, matrix::LinearAlgebra, + mutable::MutFP, }; /// Newton-Raphson Method -pub fn newton) -> Vec + Copy>(init_cond: Vec, f: F, rtol: f64) -> Vec -{ +pub fn newton) -> Vec + Copy>(init_cond: Vec, f: F, rtol: f64) -> Vec { let mut x_next = init_cond; let mut x = x_next.clone(); update(&mut x_next, f); @@ -23,8 +22,7 @@ pub fn newton) -> Vec + Copy>(init_cond: Vec, f: F, rtol x_next } -fn update) -> Vec + Copy>(xs: &mut Vec, f: F) -{ +fn update) -> Vec + Copy>(xs: &mut Vec, f: F) { let j = jacobian(f, &xs); let pinv_j = j.pseudo_inv(); //let fx = f(NumberVector::from_f64_vec(xs.clone())).to_f64_vec(); diff --git a/src/numerical/ode.rs b/src/numerical/ode.rs index 73b89f85..4025bbe5 100644 --- a/src/numerical/ode.rs +++ b/src/numerical/ode.rs @@ -87,7 +87,7 @@ //! } //! ``` -use anyhow::{Result, bail}; +use anyhow::{bail, Result}; /// Trait for defining an ODE problem. /// @@ -117,7 +117,6 @@ pub trait ODEProblem { fn rhs(&self, t: f64, y: &[f64], dy: &mut [f64]) -> Result<()>; } - /// Trait for ODE integrators. /// /// Implement this trait to define your own ODE integrator. @@ -125,7 +124,6 @@ pub trait ODEIntegrator { fn step(&self, problem: &P, t: f64, y: &mut [f64], dt: f64) -> Result; } - /// Enum for ODE errors. /// /// # Variants @@ -165,7 +163,11 @@ pub enum ODEError { impl std::fmt::Display for ODEError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ODEError::ConstraintViolation(t, y, dy) => write!(f, "Constraint violation at t = {}, y = {:?}, dy = {:?}", t, y, dy), + ODEError::ConstraintViolation(t, y, dy) => write!( + f, + "Constraint violation at t = {}, y = {:?}, dy = {:?}", + t, y, dy + ), ODEError::ReachedMaxStepIter => write!(f, "Reached maximum number of steps per step"), } } @@ -175,7 +177,12 @@ impl std::fmt::Display for ODEError { /// /// Implement this trait to define your own ODE solver. pub trait ODESolver { - fn solve(&self, problem: &P, t_span: (f64, f64), dt: f64) -> Result<(Vec, Vec>)>; + fn solve( + &self, + problem: &P, + t_span: (f64, f64), + dt: f64, + ) -> Result<(Vec, Vec>)>; } /// A basic ODE solver using a specified integrator. @@ -222,7 +229,12 @@ impl BasicODESolver { } impl ODESolver for BasicODESolver { - fn solve(&self, problem: &P, t_span: (f64, f64), dt: f64) -> Result<(Vec, Vec>)> { + fn solve( + &self, + problem: &P, + t_span: (f64, f64), + dt: f64, + ) -> Result<(Vec, Vec>)> { let mut t = t_span.0; let mut dt = dt; let mut y = problem.initial_conditions(); @@ -248,7 +260,7 @@ impl ODESolver for BasicODESolver { /// /// ```text /// C | A -/// - - - +/// - - - /// | BU (Coefficient for update) /// | BE (Coefficient for estimate error) /// ``` @@ -295,10 +307,10 @@ impl ODEIntegrator for BU { let mut k_vec = vec![vec![0.0; n]; n_k]; let mut y_temp = y.to_vec(); - for i in 0 .. n_k { - for i in 0 .. n { + for i in 0..n_k { + for i in 0..n { let mut s = 0.0; - for j in 0 .. i { + for j in 0..i { s += Self::A[i][j] * k_vec[j][i]; } y_temp[i] = y[i] + dt * s; @@ -308,9 +320,9 @@ impl ODEIntegrator for BU { if !Self::BE.is_empty() { let mut error = 0f64; - for i in 0 .. n { + for i in 0..n { let mut s = 0.0; - for j in 0 .. n_k { + for j in 0..n_k { s += (Self::BU[j] - Self::BE[j]) * k_vec[j][i]; } error = error.max(dt * s.abs()) @@ -318,12 +330,12 @@ impl ODEIntegrator for BU { let factor = (self.tol() * dt / error).powf(0.2); let new_dt = self.safety_factor() * dt * factor; - let new_dt = new_dt.clamp(self.min_step_size(),self.max_step_size()); + let new_dt = new_dt.clamp(self.min_step_size(), self.max_step_size()); if error < self.tol() { - for i in 0 .. n { + for i in 0..n { let mut s = 0.0; - for j in 0 .. n_k { + for j in 0..n_k { s += Self::BU[j] * k_vec[j][i]; } y[i] += dt * s; @@ -337,9 +349,9 @@ impl ODEIntegrator for BU { dt = new_dt; } } else { - for i in 0 .. n { + for i in 0..n { let mut s = 0.0; - for j in 0 .. n_k { + for j in 0..n_k { s += Self::BU[j] * k_vec[j][i]; } y[i] += dt * s; @@ -363,11 +375,7 @@ pub struct RALS3; impl ButcherTableau for RALS3 { const C: &'static [f64] = &[0.0, 0.5, 0.75]; - const A: &'static [&'static [f64]] = &[ - &[], - &[0.5], - &[0.0, 0.75], - ]; + const A: &'static [&'static [f64]] = &[&[], &[0.5], &[0.0, 0.75]]; const BU: &'static [f64] = &[2.0 / 9.0, 1.0 / 3.0, 4.0 / 9.0]; const BE: &'static [f64] = &[]; } @@ -420,11 +428,37 @@ impl ButcherTableau for RK5 { &[0.2], &[0.075, 0.225], &[44.0 / 45.0, -56.0 / 15.0, 32.0 / 9.0], - &[19372.0 / 6561.0, -25360.0 / 2187.0, 64448.0 / 6561.0, -212.0 / 729.0], - &[9017.0 / 3168.0, -355.0 / 33.0, 46732.0 / 5247.0, 49.0 / 176.0, -5103.0 / 18656.0], - &[35.0 / 384.0, 0.0, 500.0 / 1113.0, 125.0 / 192.0, -2187.0 / 6784.0, 11.0 / 84.0], + &[ + 19372.0 / 6561.0, + -25360.0 / 2187.0, + 64448.0 / 6561.0, + -212.0 / 729.0, + ], + &[ + 9017.0 / 3168.0, + -355.0 / 33.0, + 46732.0 / 5247.0, + 49.0 / 176.0, + -5103.0 / 18656.0, + ], + &[ + 35.0 / 384.0, + 0.0, + 500.0 / 1113.0, + 125.0 / 192.0, + -2187.0 / 6784.0, + 11.0 / 84.0, + ], + ]; + const BU: &'static [f64] = &[ + 5179.0 / 57600.0, + 0.0, + 7571.0 / 16695.0, + 393.0 / 640.0, + -92097.0 / 339200.0, + 187.0 / 2100.0, + 1.0 / 40.0, ]; - const BU: &'static [f64] = &[5179.0 / 57600.0, 0.0, 7571.0 / 16695.0, 393.0 / 640.0, -92097.0 / 339200.0, 187.0 / 2100.0, 1.0 / 40.0]; const BE: &'static [f64] = &[]; } @@ -454,13 +488,31 @@ pub struct BS23 { impl Default for BS23 { fn default() -> Self { - Self { tol: 1e-3, safety_factor: 0.9, min_step_size: 1e-6, max_step_size: 1e-1, max_step_iter: 100 } + Self { + tol: 1e-3, + safety_factor: 0.9, + min_step_size: 1e-6, + max_step_size: 1e-1, + max_step_iter: 100, + } } } impl BS23 { - pub fn new(tol: f64, safety_factor: f64, min_step_size: f64, max_step_size: f64, max_step_iter: usize) -> Self { - Self { tol, safety_factor, min_step_size, max_step_size, max_step_iter } + pub fn new( + tol: f64, + safety_factor: f64, + min_step_size: f64, + max_step_size: f64, + max_step_iter: usize, + ) -> Self { + Self { + tol, + safety_factor, + min_step_size, + max_step_size, + max_step_iter, + } } } @@ -475,14 +527,23 @@ impl ButcherTableau for BS23 { const BU: &'static [f64] = &[2.0 / 9.0, 1.0 / 3.0, 4.0 / 9.0, 0.0]; const BE: &'static [f64] = &[7.0 / 24.0, 0.25, 1.0 / 3.0, 0.125]; - fn tol(&self) -> f64 { self.tol } - fn safety_factor(&self) -> f64 { self.safety_factor } - fn min_step_size(&self) -> f64 { self.min_step_size } - fn max_step_size(&self) -> f64 { self.max_step_size } - fn max_step_iter(&self) -> usize { self.max_step_iter } + fn tol(&self) -> f64 { + self.tol + } + fn safety_factor(&self) -> f64 { + self.safety_factor + } + fn min_step_size(&self) -> f64 { + self.min_step_size + } + fn max_step_size(&self) -> f64 { + self.max_step_size + } + fn max_step_iter(&self) -> usize { + self.max_step_iter + } } - /// Runge-Kutta-Fehlberg 4/5th order integrator. /// /// This integrator uses the Runge-Kutta-Fehlberg method, which is an adaptive step size integrator. @@ -519,7 +580,13 @@ impl Default for RKF45 { } impl RKF45 { - pub fn new(tol: f64, safety_factor: f64, min_step_size: f64, max_step_size: f64, max_step_iter: usize) -> Self { + pub fn new( + tol: f64, + safety_factor: f64, + min_step_size: f64, + max_step_size: f64, + max_step_iter: usize, + ) -> Self { Self { tol, safety_factor, @@ -538,16 +605,46 @@ impl ButcherTableau for RKF45 { &[3.0 / 32.0, 9.0 / 32.0], &[1932.0 / 2197.0, -7200.0 / 2197.0, 7296.0 / 2197.0], &[439.0 / 216.0, -8.0, 3680.0 / 513.0, -845.0 / 4104.0], - &[-8.0 / 27.0, 2.0, -3544.0 / 2565.0, 1859.0 / 4104.0, -11.0 / 40.0], + &[ + -8.0 / 27.0, + 2.0, + -3544.0 / 2565.0, + 1859.0 / 4104.0, + -11.0 / 40.0, + ], + ]; + const BU: &'static [f64] = &[ + 16.0 / 135.0, + 0.0, + 6656.0 / 12825.0, + 28561.0 / 56430.0, + -9.0 / 50.0, + 2.0 / 55.0, + ]; + const BE: &'static [f64] = &[ + 25.0 / 216.0, + 0.0, + 1408.0 / 2565.0, + 2197.0 / 4104.0, + -1.0 / 5.0, + 0.0, ]; - const BU: &'static [f64] = &[16.0 / 135.0, 0.0, 6656.0 / 12825.0, 28561.0 / 56430.0, -9.0 / 50.0, 2.0 / 55.0]; - const BE: &'static [f64] = &[25.0 / 216.0, 0.0, 1408.0 / 2565.0, 2197.0 / 4104.0, -1.0 / 5.0, 0.0]; - fn tol(&self) -> f64 { self.tol } - fn safety_factor(&self) -> f64 { self.safety_factor } - fn min_step_size(&self) -> f64 { self.min_step_size } - fn max_step_size(&self) -> f64 { self.max_step_size } - fn max_step_iter(&self) -> usize { self.max_step_iter } + fn tol(&self) -> f64 { + self.tol + } + fn safety_factor(&self) -> f64 { + self.safety_factor + } + fn min_step_size(&self) -> f64 { + self.min_step_size + } + fn max_step_size(&self) -> f64 { + self.max_step_size + } + fn max_step_iter(&self) -> usize { + self.max_step_iter + } } /// Dormand-Prince 5(4) method @@ -585,7 +682,13 @@ impl Default for DP45 { } impl DP45 { - pub fn new(tol: f64, safety_factor: f64, min_step_size: f64, max_step_size: f64, max_step_iter: usize) -> Self { + pub fn new( + tol: f64, + safety_factor: f64, + min_step_size: f64, + max_step_size: f64, + max_step_iter: usize, + ) -> Self { Self { tol, safety_factor, @@ -603,18 +706,62 @@ impl ButcherTableau for DP45 { &[0.2], &[0.075, 0.225], &[44.0 / 45.0, -56.0 / 15.0, 32.0 / 9.0], - &[19372.0 / 6561.0, -25360.0 / 2187.0, 64448.0 / 6561.0, -212.0 / 729.0], - &[9017.0 / 3168.0, -355.0 / 33.0, 46732.0 / 5247.0, 49.0 / 176.0, -5103.0 / 18656.0], - &[35.0 / 384.0, 0.0, 500.0 / 1113.0, 125.0 / 192.0, -2187.0 / 6784.0, 11.0 / 84.0], + &[ + 19372.0 / 6561.0, + -25360.0 / 2187.0, + 64448.0 / 6561.0, + -212.0 / 729.0, + ], + &[ + 9017.0 / 3168.0, + -355.0 / 33.0, + 46732.0 / 5247.0, + 49.0 / 176.0, + -5103.0 / 18656.0, + ], + &[ + 35.0 / 384.0, + 0.0, + 500.0 / 1113.0, + 125.0 / 192.0, + -2187.0 / 6784.0, + 11.0 / 84.0, + ], + ]; + const BU: &'static [f64] = &[ + 35.0 / 384.0, + 0.0, + 500.0 / 1113.0, + 125.0 / 192.0, + -2187.0 / 6784.0, + 11.0 / 84.0, + 0.0, + ]; + const BE: &'static [f64] = &[ + 5179.0 / 57600.0, + 0.0, + 7571.0 / 16695.0, + 393.0 / 640.0, + -92097.0 / 339200.0, + 187.0 / 2100.0, + 1.0 / 40.0, ]; - const BU: &'static [f64] = &[35.0 / 384.0, 0.0, 500.0 / 1113.0, 125.0 / 192.0, -2187.0 / 6784.0, 11.0 / 84.0, 0.0]; - const BE: &'static [f64] = &[5179.0 / 57600.0, 0.0, 7571.0 / 16695.0, 393.0 / 640.0, -92097.0 / 339200.0, 187.0 / 2100.0, 1.0 / 40.0]; - fn tol(&self) -> f64 { self.tol } - fn safety_factor(&self) -> f64 { self.safety_factor } - fn min_step_size(&self) -> f64 { self.min_step_size } - fn max_step_size(&self) -> f64 { self.max_step_size } - fn max_step_iter(&self) -> usize { self.max_step_iter } + fn tol(&self) -> f64 { + self.tol + } + fn safety_factor(&self) -> f64 { + self.safety_factor + } + fn min_step_size(&self) -> f64 { + self.min_step_size + } + fn max_step_size(&self) -> f64 { + self.max_step_size + } + fn max_step_iter(&self) -> usize { + self.max_step_iter + } } /// Tsitouras 5(4) method @@ -656,7 +803,13 @@ impl Default for TSIT45 { } impl TSIT45 { - pub fn new(tol: f64, safety_factor: f64, min_step_size: f64, max_step_size: f64, max_step_iter: usize) -> Self { + pub fn new( + tol: f64, + safety_factor: f64, + min_step_size: f64, + max_step_size: f64, + max_step_iter: usize, + ) -> Self { Self { tol, safety_factor, @@ -673,27 +826,70 @@ impl ButcherTableau for TSIT45 { &[], &[Self::C[1]], &[Self::C[2] - 0.335480655492357, 0.335480655492357], - &[Self::C[3] - (-6.359448489975075 + 4.362295432869581), -6.359448489975075, 4.362295432869581], - &[Self::C[4] - (-11.74888356406283 + 7.495539342889836 - 0.09249506636175525), -11.74888356406283, 7.495539342889836, -0.09249506636175525], - &[Self::C[5] - (-12.92096931784711 + 8.159367898576159 - 0.0715849732814010 - 0.02826905039406838), -12.92096931784711, 8.159367898576159, -0.0715849732814010, -0.02826905039406838], - &[Self::BU[0], Self::BU[1], Self::BU[2], Self::BU[3], Self::BU[4], Self::BU[5]], + &[ + Self::C[3] - (-6.359448489975075 + 4.362295432869581), + -6.359448489975075, + 4.362295432869581, + ], + &[ + Self::C[4] - (-11.74888356406283 + 7.495539342889836 - 0.09249506636175525), + -11.74888356406283, + 7.495539342889836, + -0.09249506636175525, + ], + &[ + Self::C[5] + - (-12.92096931784711 + 8.159367898576159 + - 0.0715849732814010 + - 0.02826905039406838), + -12.92096931784711, + 8.159367898576159, + -0.0715849732814010, + -0.02826905039406838, + ], + &[ + Self::BU[0], + Self::BU[1], + Self::BU[2], + Self::BU[3], + Self::BU[4], + Self::BU[5], + ], + ]; + const BU: &'static [f64] = &[ + 0.09646076681806523, + 0.01, + 0.4798896504144996, + 1.379008574103742, + -3.290069515436081, + 2.324710524099774, + 0.0, ]; - const BU: &'static [f64] = &[0.09646076681806523, 0.01, 0.4798896504144996, 1.379008574103742, -3.290069515436081, 2.324710524099774, 0.0]; const BE: &'static [f64] = &[ 0.001780011052226, 0.000816434459657, - - 0.007880878010262, + -0.007880878010262, 0.144711007173263, - - 0.582357165452555, + -0.582357165452555, 0.458082105929187, 1.0 / 66.0, ]; - fn tol(&self) -> f64 { self.tol } - fn safety_factor(&self) -> f64 { self.safety_factor } - fn min_step_size(&self) -> f64 { self.min_step_size } - fn max_step_size(&self) -> f64 { self.max_step_size } - fn max_step_iter(&self) -> usize { self.max_step_iter } + fn tol(&self) -> f64 { + self.tol + } + fn safety_factor(&self) -> f64 { + self.safety_factor + } + fn min_step_size(&self) -> f64 { + self.min_step_size + } + fn max_step_size(&self) -> f64 { + self.max_step_size + } + fn max_step_iter(&self) -> usize { + self.max_step_iter + } } // ┌─────────────────────────────────────────────────────────┐ @@ -776,8 +972,19 @@ impl ODEIntegrator for GL4 { let mut max_diff = 0f64; for i in 0..n { - max_diff = max_diff.max((y1[i] - y[i] - dt * (c * k1[i] + d * k2[i] - sqrt3 * (k2[i] - k1[i]) / 2.0)).abs()) - .max((y2[i] - y[i] - dt * (c * k1[i] + d * k2[i] + sqrt3 * (k2[i] - k1[i]) / 2.0)).abs()); + max_diff = max_diff + .max( + (y1[i] + - y[i] + - dt * (c * k1[i] + d * k2[i] - sqrt3 * (k2[i] - k1[i]) / 2.0)) + .abs(), + ) + .max( + (y2[i] + - y[i] + - dt * (c * k1[i] + d * k2[i] + sqrt3 * (k2[i] - k1[i]) / 2.0)) + .abs(), + ); } if max_diff < self.tol { diff --git a/src/numerical/optimize.rs b/src/numerical/optimize.rs index 5cf4f22c..dcb60005 100644 --- a/src/numerical/optimize.rs +++ b/src/numerical/optimize.rs @@ -111,9 +111,9 @@ pub use self::OptMethod::{GaussNewton, GradientDescent, LevenbergMarquardt}; use self::OptOption::{InitParam, MaxIter}; use crate::numerical::utils::jacobian; +use crate::structure::ad::{ADVec, AD}; use crate::structure::matrix::Matrix; -use crate::traits::matrix::{MatrixTrait, LinearAlgebra}; -use crate::structure::ad::{AD, ADVec}; +use crate::traits::matrix::{LinearAlgebra, MatrixTrait}; use crate::util::useful::max; use std::collections::HashMap; @@ -225,13 +225,15 @@ where /// Set initial lambda for `LevenbergMarquardt` pub fn set_lambda_init(&mut self, lambda_init: f64) -> &mut Self { - self.hyperparams.insert("lambda_init".to_string(), lambda_init); + self.hyperparams + .insert("lambda_init".to_string(), lambda_init); self } /// Set maximum lambda for `LevenbergMarquardt` pub fn set_lambda_max(&mut self, lambda_max: f64) -> &mut Self { - self.hyperparams.insert("lambda_max".to_string(), lambda_max); + self.hyperparams + .insert("lambda_max".to_string(), lambda_max); self } @@ -288,13 +290,20 @@ where let mut chi2 = ((&y - &y_hat).t() * (&y - &y_hat))[(0, 0)]; let mut nu = 2f64; let lambda_0 = *self.hyperparams.get("lambda_init").unwrap_or(&1e-3); - let lambda_max = *self.hyperparams.get("lambda_max").unwrap_or(&f64::MAX.sqrt()); + let lambda_max = *self + .hyperparams + .get("lambda_max") + .unwrap_or(&f64::MAX.sqrt()); let mut lambda = lambda_0 * max(jtj.diag()); for i in 0..max_iter { if lambda > lambda_max { - println!("Caution: At {}-th iter, lambda exceeds max value: {}", i+1, lambda); + println!( + "Caution: At {}-th iter, lambda exceeds max value: {}", + i + 1, + lambda + ); break; } diff --git a/src/numerical/root.rs b/src/numerical/root.rs index 17b67ac7..050076e0 100644 --- a/src/numerical/root.rs +++ b/src/numerical/root.rs @@ -66,26 +66,26 @@ //! extern crate peroxide; //! use peroxide::fuga::*; //! use anyhow::Result; -//! +//! //! fn main() -> Result<()> { //! let root_bisect = bisection!(f, (0.0, 2.0), 100, 1e-6)?; //! let root_newton = newton!(f, 0.0, 100, 1e-6)?; //! let root_false_pos = false_position!(f, (0.0, 2.0), 100, 1e-6)?; //! let root_secant = secant!(f, (0.0, 2.0), 100, 1e-6)?; -//! +//! //! println!("root_bisect: {}", root_bisect); //! println!("root_newton: {}", root_newton); //! println!("root_false_pos: {}", root_false_pos); //! println!("root_secant: {}", root_secant); -//! +//! //! assert!(f(root_bisect).abs() < 1e-6); //! assert!(f(root_newton).abs() < 1e-6); //! assert!(f(root_false_pos).abs() < 1e-6); //! assert!(f(root_secant).abs() < 1e-6); -//! +//! //! Ok(()) //! } -//! +//! //! #[ad_function] //! fn f(x: f64) -> f64 { //! (x - 1f64).powi(3) @@ -212,9 +212,9 @@ //! The `Cosine` struct implements the `RootFindingProblem` trait for the `f64` initial guess type. //! The initial guess is set to `0.0`, which is a point where the derivative of the cosine function is 0. //! This leads to the `NewtonMethod` returning a `RootError::ZeroDerivative` error, which is handled in the example. -use anyhow::{Result, bail}; +use anyhow::{bail, Result}; -use crate::traits::math::{Normed, Norm, LinearOp}; +use crate::traits::math::{LinearOp, Norm, Normed}; use crate::traits::sugar::{ConvToMat, VecOps}; use crate::util::non_macro::zeros; @@ -247,12 +247,15 @@ macro_rules! bisection { } let problem = BisectionProblem { f: $f }; - let bisection = BisectionMethod { max_iter: $max_iter, tol: $tol }; + let bisection = BisectionMethod { + max_iter: $max_iter, + tol: $tol, + }; match bisection.find(&problem) { Ok(root) => Ok(root[0]), Err(e) => Err(e), } - }} + }}; } /// High level macro for newton (using Automatic differentiation) @@ -284,7 +287,7 @@ macro_rules! newton { impl RootFindingProblem<1, 1, f64> for NewtonProblem { fn initial_guess(&self) -> f64 { - $x + $x } fn function(&self, x: [f64; 1]) -> Result<[f64; 1]> { @@ -300,12 +303,15 @@ macro_rules! newton { } let problem = NewtonProblem; - let newton = NewtonMethod { max_iter: $max_iter, tol: $tol }; + let newton = NewtonMethod { + max_iter: $max_iter, + tol: $tol, + }; match newton.find(&problem) { Ok(root) => Ok(root[0]), Err(e) => Err(e), } - }} + }}; } /// High level macro for false position @@ -334,12 +340,15 @@ macro_rules! false_position { } let problem = FalsePositionProblem { f: $f }; - let false_position = FalsePositionMethod { max_iter: $max_iter, tol: $tol }; + let false_position = FalsePositionMethod { + max_iter: $max_iter, + tol: $tol, + }; match false_position.find(&problem) { Ok(root) => Ok(root[0]), Err(e) => Err(e), } - }} + }}; } /// High level macro for secant @@ -368,15 +377,17 @@ macro_rules! secant { } let problem = SecantProblem { f: $f }; - let secant = SecantMethod { max_iter: $max_iter, tol: $tol }; + let secant = SecantMethod { + max_iter: $max_iter, + tol: $tol, + }; match secant.find(&problem) { Ok(root) => Ok(root[0]), Err(e) => Err(e), } - }} + }}; } - // ┌─────────────────────────────────────────────────────────┐ // Type aliases // └─────────────────────────────────────────────────────────┘ @@ -459,7 +470,7 @@ impl std::fmt::Display for RootError { RootError::NoRoot => write!(f, "There is no root in the interval"), RootError::NotConverge(a) => write!(f, "Not yet converge. Our guess is {:?}", a), RootError::ZeroDerivative(a) => write!(f, "Zero derivative in {:?}", a), - RootError::ZeroSecant(a,b) => write!(f, "Zero secant in ({:?}, {:?})", a, b), + RootError::ZeroSecant(a, b) => write!(f, "Zero secant in ({:?}, {:?})", a, b), } } } @@ -483,7 +494,7 @@ impl std::fmt::Display for RootError { macro_rules! single_function { ($problem:expr, $x:expr) => {{ $problem.function([$x])?[0] - }} + }}; } /// Macro for single derivative @@ -505,7 +516,7 @@ macro_rules! single_function { macro_rules! single_derivative { ($problem:expr, $x:expr) => {{ $problem.derivative([$x])?[0][0] - }} + }}; } // ┌─────────────────────────────────────────────────────────┐ @@ -542,10 +553,7 @@ impl RootFinder<1, 1, (f64, f64)> for BisectionMethod { self.tol } - fn find>( - &self, - problem: &P, - ) -> Result<[f64; 1]> { + fn find>(&self, problem: &P) -> Result<[f64; 1]> { let state = problem.initial_guess(); let (mut a, mut b) = state; let mut fa = single_function!(problem, a); @@ -613,10 +621,7 @@ impl RootFinder<1, 1, f64> for NewtonMethod { fn tol(&self) -> f64 { self.tol } - fn find>( - &self, - problem: &P, - ) -> Result<[f64; 1]> { + fn find>(&self, problem: &P) -> Result<[f64; 1]> { let mut x = problem.initial_guess(); for _ in 0..self.max_iter { @@ -667,10 +672,7 @@ impl RootFinder<1, 1, (f64, f64)> for SecantMethod { fn tol(&self) -> f64 { self.tol } - fn find>( - &self, - problem: &P, - ) -> Result<[f64; 1]> { + fn find>(&self, problem: &P) -> Result<[f64; 1]> { let state = problem.initial_guess(); let (mut x0, mut x1) = state; let mut f0 = single_function!(problem, x0); @@ -729,10 +731,7 @@ impl RootFinder<1, 1, (f64, f64)> for FalsePositionMethod { fn tol(&self) -> f64 { self.tol } - fn find>( - &self, - problem: &P, - ) -> Result<[f64; 1]> { + fn find>(&self, problem: &P) -> Result<[f64; 1]> { let state = problem.initial_guess(); let (mut a, mut b) = state; let mut fa = single_function!(problem, a); @@ -792,7 +791,7 @@ impl RootFinder<1, 1, (f64, f64)> for FalsePositionMethod { /// ```rust /// use peroxide::fuga::*; /// use peroxide::numerical::root::{Pt, Intv}; -/// +/// /// fn main() -> Result<(), Box> { /// let problem = CircleTangentLine; /// let broyden = BroydenMethod { max_iter: 100, tol: 1e-6, rtol: 1e-6 }; @@ -805,9 +804,9 @@ impl RootFinder<1, 1, (f64, f64)> for FalsePositionMethod { /// /// Ok(()) /// } -/// +/// /// struct CircleTangentLine; -/// +/// /// impl RootFindingProblem<2, 2, Intv<2>> for CircleTangentLine { /// fn function(&self, x: Pt<2>) -> anyhow::Result> { /// Ok([ @@ -815,7 +814,7 @@ impl RootFinder<1, 1, (f64, f64)> for FalsePositionMethod { /// x[0] + x[1] - 2f64.sqrt() /// ]) /// } -/// +/// /// fn initial_guess(&self) -> Intv<2> { /// ([0.0, 0.1], [-0.1, 0.2]) /// } @@ -836,10 +835,7 @@ impl RootFinder> for BroydenMethod fn tol(&self) -> f64 { self.tol } - fn find>>( - &self, - problem: &P, - ) -> Result> { + fn find>>(&self, problem: &P) -> Result> { // Init state let state = problem.initial_guess(); let (mut x0, mut x1) = state; @@ -857,11 +853,19 @@ impl RootFinder> for BroydenMethod if fx1.norm(Norm::L2) < self.tol { return Ok(x1); } - let dx = x1.iter().zip(x0.iter()).map(|(x1, x0)| x1 - x0).collect::>(); + let dx = x1 + .iter() + .zip(x0.iter()) + .map(|(x1, x0)| x1 - x0) + .collect::>(); if dx.norm(Norm::L2) < self.rtol { return Ok(x1); } - let df = fx1.iter().zip(fx0.iter()).map(|(fx1, fx0)| fx1 - fx0).collect::>(); + let df = fx1 + .iter() + .zip(fx0.iter()) + .map(|(fx1, fx0)| fx1 - fx0) + .collect::>(); let denom = dx.add_v(&H.apply(&df)); let right = &dx.to_row() * &H; diff --git a/src/numerical/spline.rs b/src/numerical/spline.rs index bd7c0dcd..4978769d 100644 --- a/src/numerical/spline.rs +++ b/src/numerical/spline.rs @@ -96,7 +96,7 @@ //! //! ```rust //! use peroxide::fuga::*; -//! +//! //! fn main() -> Result<(), Box> { //! let knots = vec![0f64, 1f64, 2f64, 3f64]; //! let degree = 3; @@ -108,17 +108,17 @@ //! vec![0.8, 1f64], //! vec![1f64, 2f64], //! ]; -//! +//! //! //! let spline = BSpline::clamped(degree, knots, control_points.clone())?; //! let t = linspace(0f64, 3f64, 200); //! let (x, y): (Vec, Vec) = spline.eval_vec(&t).into_iter().unzip(); -//! +//! //! # #[cfg(feature = "plot")] //! # { //! let control_x = control_points.iter().map(|v| v[0]).collect::>(); //! let control_y = control_points.iter().map(|v| v[1]).collect::>(); -//! +//! //! let mut plt = Plot2D::new(); //! plt //! .insert_pair((x.clone(), y.clone())) @@ -132,13 +132,13 @@ //! .set_path("example_data/b_spline_test.png") //! .savefig()?; //! # } -//! +//! //! let mut df = DataFrame::new(vec![]); //! df.push("t", Series::new(t)); //! df.push("x", Series::new(x)); //! df.push("y", Series::new(y)); //! df.print(); -//! +//! //! Ok(()) //! } //! ``` @@ -270,7 +270,6 @@ //! //! - Gary D. Knott, *Interpolating Splines*, Birkhäuser Boston, MA, (2000). /// - [Wikipedia - Irwin-Hall distribution](https://en.wikipedia.org/wiki/Irwin%E2%80%93Hall_distribution#Special_cases) - use self::SplineError::{NotEnoughNodes, NotEqualNodes, NotEqualSlopes, RedundantNodeX}; #[allow(unused_imports)] use crate::structure::matrix::*; @@ -282,13 +281,13 @@ use crate::traits::matrix::LinearAlgebra; #[allow(unused_imports)] use crate::util::non_macro::*; use crate::util::useful::zip_range; +use anyhow::{bail, Result}; use peroxide_num::PowOps; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::cmp::{max, min}; use std::convert::From; use std::ops::{Index, Range}; -use anyhow::{Result, bail}; pub trait Spline { fn eval(&self, t: f64) -> T; @@ -703,11 +702,7 @@ impl PolynomialSpline for CubicHermiteSpline { } impl CubicHermiteSpline { - pub fn from_nodes_with_slopes( - node_x: &[f64], - node_y: &[f64], - m: &[f64], - ) -> Result { + pub fn from_nodes_with_slopes(node_x: &[f64], node_y: &[f64], m: &[f64]) -> Result { let n = node_x.len(); if n < 3 { bail!(NotEnoughNodes); @@ -745,11 +740,7 @@ impl CubicHermiteSpline { }) } - pub fn from_nodes( - node_x: &[f64], - node_y: &[f64], - slope_method: SlopeMethod, - ) -> Result { + pub fn from_nodes(node_x: &[f64], node_y: &[f64], slope_method: SlopeMethod) -> Result { match slope_method { SlopeMethod::Akima => CubicHermiteSpline::from_nodes_with_slopes( node_x, @@ -934,7 +925,11 @@ pub struct UnitCubicBasis { impl UnitCubicBasis { pub fn new(x_min: f64, x_max: f64, scale: f64) -> Self { - Self { x_min, x_max, scale } + Self { + x_min, + x_max, + scale, + } } pub fn eval(&self, x: f64) -> f64 { @@ -967,17 +962,17 @@ impl UnitCubicBasis { /// ```rust /// use peroxide::fuga::*; /// use core::ops::Range; -/// +/// /// # #[allow(unused_variables)] /// fn main() -> anyhow::Result<()> { /// let cubic_b_spline = CubicBSplineBases::from_interval((0f64, 1f64), 5); /// let x = linspace(0f64, 1f64, 1000); /// let y = cubic_b_spline.eval_vec(&x); -/// +/// /// # #[cfg(feature = "plot")] { /// let mut plt = Plot2D::new(); /// plt.set_domain(x.clone()); -/// +/// /// for basis in &cubic_b_spline.bases { /// plt.insert_image(basis.eval_vec(&x)); /// } @@ -1014,9 +1009,14 @@ impl CubicBSplineBases { let (ranges, bases) = nodes .iter() .zip(nodes.iter().skip(4)) - .map(|(a, b)| (Range { start: *a, end: *b }, UnitCubicBasis::new(*a, *b, 1f64))) + .map(|(a, b)| { + ( + Range { start: *a, end: *b }, + UnitCubicBasis::new(*a, *b, 1f64), + ) + }) .unzip(); - + Self::new(ranges, bases) } @@ -1037,7 +1037,8 @@ impl CubicBSplineBases { } pub fn eval(&self, x: f64) -> f64 { - self.ranges.iter() + self.ranges + .iter() .enumerate() .filter(|(_, range)| range.contains(&x)) .fold(0f64, |acc, (i, _)| { @@ -1109,7 +1110,11 @@ impl BSpline { bail!("The number of knots ({}) should be equal to the number of control points ({}) + degree ({}) + 1", knots.len(), control_points.len(), degree); } - Ok(Self { degree, knots, control_points }) + Ok(Self { + degree, + knots, + control_points, + }) } /// Create new clamped B-Spline @@ -1135,7 +1140,11 @@ impl BSpline { bail!("The number of knots ({}) should be equal to the number of control points ({}) + degree ({}) + 1", knots.len(), control_points.len(), degree); } - Ok(Self { degree, knots, control_points }) + Ok(Self { + degree, + knots, + control_points, + }) } /// Obtain basis function via Cox-de Boor algorithm @@ -1146,7 +1155,9 @@ impl BSpline { // Initialize 0th degree basis functions for (j, B_j) in B.iter_mut().enumerate() { - if (self.knots[i + j] <= t && t < self.knots[i + j + 1]) || (i + j == self.knots.len() - (p + 2) && t == self.knots[i + j + 1]) { + if (self.knots[i + j] <= t && t < self.knots[i + j + 1]) + || (i + j == self.knots.len() - (p + 2) && t == self.knots[i + j + 1]) + { B_j[0] = 1f64; } else { B_j[0] = 0f64; @@ -1155,20 +1166,21 @@ impl BSpline { // Compute the basis functions for higher degree for k in 1..=p { - for j in 0..=(p-k) { - let a = if self.knots[i + j + k] == self.knots[i+j] { + for j in 0..=(p - k) { + let a = if self.knots[i + j + k] == self.knots[i + j] { 0f64 } else { - (t - self.knots[i+j]) / (self.knots[i+j+k] - self.knots[i+j]) + (t - self.knots[i + j]) / (self.knots[i + j + k] - self.knots[i + j]) }; - let b = if self.knots[i + j + k + 1] == self.knots[i+j+1] { + let b = if self.knots[i + j + k + 1] == self.knots[i + j + 1] { 0f64 } else { - (self.knots[i+j+k+1] - t) / (self.knots[i+j+k+1] - self.knots[i+j+1]) + (self.knots[i + j + k + 1] - t) + / (self.knots[i + j + k + 1] - self.knots[i + j + 1]) }; - B[j][k] = a * B[j][k-1] + b * B[j+1][k-1]; + B[j][k] = a * B[j][k - 1] + b * B[j + 1][k - 1]; } } @@ -1183,7 +1195,7 @@ impl Spline<(f64, f64)> for BSpline { let mut x = 0f64; let mut y = 0f64; - for i in 0 .. n { + for i in 0..n { let B = self.cox_de_boor(t, i); x += B * self.control_points[i][0]; y += B * self.control_points[i][1]; diff --git a/src/numerical/utils.rs b/src/numerical/utils.rs index f28ca5a9..7350ce14 100644 --- a/src/numerical/utils.rs +++ b/src/numerical/utils.rs @@ -1,7 +1,7 @@ +use crate::structure::ad::AD::*; +use crate::structure::ad::*; use crate::structure::matrix::*; use crate::traits::matrix::MatrixTrait; -use crate::structure::ad::*; -use crate::structure::ad::AD::*; use crate::util::non_macro::{cat, zeros}; /// Jacobian Matrix @@ -46,7 +46,7 @@ pub fn jacobian) -> Vec>(f: F, x: &Vec) -> Matrix { let mut J = zeros(l2, l); - for i in 0 .. l { + for i in 0..l { x_ad[i][1] = 1f64; let slopes: Vec = f(&x_ad).iter().map(|ad| ad.dx()).collect(); J.subs_col(i, &slopes); @@ -91,7 +91,6 @@ pub fn jacobian) -> Vec>(f: F, x: &Vec) -> Matrix { // JT //} - /// TriDiagonal Matrix Algorithm (TDMA) /// /// # Description diff --git a/src/prelude/mod.rs b/src/prelude/mod.rs index 4886010a..611bf2eb 100644 --- a/src/prelude/mod.rs +++ b/src/prelude/mod.rs @@ -145,7 +145,7 @@ #[allow(unused_imports)] pub use crate::macros::{julia_macro::*, matlab_macro::*, r_macro::*}; -pub use peroxide_ad::{ad_function, ad_closure}; +pub use peroxide_ad::{ad_closure, ad_function}; pub mod simpler; @@ -157,42 +157,37 @@ pub use crate::traits::{ mutable::{MutFP, MutMatrix}, num::Real, pointer::{MatrixPtr, Oxide, Redox, RedoxCommon}, - sugar::{Scalable, ScalableMut, VecOps, ConvToMat}, + sugar::{ConvToMat, Scalable, ScalableMut, VecOps}, }; -pub use peroxide_num::{ExpLogOps, TrigOps, PowOps}; +pub use peroxide_num::{ExpLogOps, PowOps, TrigOps}; pub use simpler::SimpleNorm; +#[cfg(feature = "csv")] +pub use crate::structure::dataframe::WithCSV; #[allow(unused_imports)] pub use crate::structure::{ - ad::*, ad::AD::*, + ad::*, + dataframe::{ + DType, DTypeArray, DTypeValue, DataFrame, Scalar, Series, TypedScalar, TypedVector, + }, matrix::{ combine, diag, gemm, gemv, gen_householder, inv_l, inv_u, matrix, ml_matrix, py_matrix, - r_matrix, Col, Matrix, Row, Shape, + r_matrix, Col, Matrix, Row, Shape, }, - polynomial::{Polynomial,poly,Calculus,lagrange_polynomial,legendre_polynomial}, + polynomial::{lagrange_polynomial, legendre_polynomial, poly, Calculus, Polynomial}, vector::*, - dataframe::{ - DataFrame, DType, DTypeArray, DTypeValue, Series, Scalar, TypedScalar, TypedVector - }, }; -#[cfg(feature="csv")] -pub use crate::structure::dataframe::WithCSV; -#[cfg(feature="nc")] +#[cfg(feature = "nc")] pub use crate::structure::dataframe::WithNetCDF; #[cfg(feature = "complex")] #[allow(ambiguous_glob_reexports)] #[allow(unused_imports)] -pub use crate::complex::{ - C64, - matrix::*, - vector::*, - integral::*, -}; +pub use crate::complex::{integral::*, matrix::*, vector::*, C64}; pub use simpler::{solve, SimplerLinearAlgebra}; @@ -204,8 +199,8 @@ pub use crate::statistics::{dist::*, ops::*, rand::*, stat::*}; #[allow(unused_imports)] pub use crate::special::function::{ - beta, erf, erfc, gamma, gaussian, inc_beta, inc_gamma, inv_erf, inv_erfc, inv_inc_gamma, - inv_inc_beta, ln_gamma, phi, poch, + beta, erf, erfc, gamma, gaussian, inc_beta, inc_gamma, inv_erf, inv_erfc, inv_inc_beta, + inv_inc_gamma, ln_gamma, phi, poch, }; #[allow(unused_imports)] @@ -215,19 +210,21 @@ pub use crate::numerical::{ ode::*, optimize::*, root::*, - spline::{cubic_spline, CubicSpline, CubicHermiteSpline, Spline}, + spline::{cubic_spline, CubicHermiteSpline, CubicSpline, Spline}, utils::*, }; -pub use simpler::{eigen, integrate, chebyshev_polynomial, cubic_hermite_spline, lambert_w0, lambert_wm1}; +pub use simpler::{ + chebyshev_polynomial, cubic_hermite_spline, eigen, integrate, lambert_w0, lambert_wm1, +}; #[allow(unused_imports)] pub use crate::statistics::stat::Metric::*; -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] pub use simpler::SimpleParquet; -#[cfg(feature="plot")] +#[cfg(feature = "plot")] pub use crate::util::plot::*; pub use anyhow; diff --git a/src/prelude/simpler.rs b/src/prelude/simpler.rs index 2916443b..890f7d07 100644 --- a/src/prelude/simpler.rs +++ b/src/prelude/simpler.rs @@ -11,7 +11,7 @@ use crate::structure::dataframe::{DataFrame, WithParquet}; use crate::structure::matrix::Matrix; use crate::structure::polynomial; use crate::traits::math::{Norm, Normed}; -use crate::traits::matrix::{MatrixTrait, LinearAlgebra, PQLU, WAZD, QR, Form, SolveKind}; +use crate::traits::matrix::{Form, LinearAlgebra, MatrixTrait, SolveKind, PQLU, QR, WAZD}; #[cfg(feature = "parquet")] use arrow2::io::parquet::write::CompressionOptions; #[cfg(feature = "parquet")] @@ -29,7 +29,7 @@ pub fn integrate f64 + Copy>(f: F, (a, b): (f64, f64)) -> f64 { } /// Simple Linear algebra -pub trait SimplerLinearAlgebra { +pub trait SimplerLinearAlgebra { fn back_subs(&self, b: &[f64]) -> Vec; fn forward_subs(&self, b: &[f64]) -> Vec; fn lu(&self) -> PQLU; diff --git a/src/special/function.rs b/src/special/function.rs index 29439123..77fbc1d4 100644 --- a/src/special/function.rs +++ b/src/special/function.rs @@ -122,9 +122,9 @@ pub fn phi(x: f64) -> f64 { /// /// Returns [`NAN`](f64::NAN) if the given input is smaller than -1/e (≈ -0.36787944117144233). /// -/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode +/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode /// for only 24 bits, but with faster execution time. -/// +/// /// Wrapper of the `lambert_w_0` and `sp_lambert_w_0` functions of the `puruspe` crate. /// /// # Reference @@ -141,11 +141,11 @@ pub fn lambert_w0(z: f64, mode: LambertWAccuracyMode) -> f64 { /// /// Returns [`NAN`](f64::NAN) if the given input is positive or smaller than -1/e (≈ -0.36787944117144233). /// -/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode +/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode /// for only 24 bits, but with faster execution time. -/// +/// /// Wrapper of the `lambert_w_m1` and `sp_lambert_w_m1` functions of the `puruspe` crate. -/// +/// /// # Reference /// /// [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) diff --git a/src/special/mod.rs b/src/special/mod.rs index 8cf27814..e5dc3ff0 100644 --- a/src/special/mod.rs +++ b/src/special/mod.rs @@ -1,29 +1,29 @@ //! Special functions module -//! +//! //! This module provides implementations of various special mathematical functions //! commonly used in statistical and scientific computing. It includes: -//! +//! //! - Basic special functions: //! - Gaussian (Normal) function //! - Gamma function and its logarithm //! - Pochhammer symbol (rising factorial) -//! +//! //! - Incomplete special functions: //! - Regularized incomplete gamma function and its inverse //! - Regularized incomplete beta function and its inverse -//! +//! //! - Error functions: //! - Error function (erf) and its complement (erfc) //! - Inverse error function and inverse complementary error function -//! +//! //! - Other functions: //! - Beta function //! - Phi function (CDF of the standard normal distribution) //! - Lambert W function (principal branch W₀ and secondary branch W₋₁) -//! +//! //! Many of these functions are implemented using efficient numerical approximations //! or by wrapping functions from other crates (e.g., `puruspe`). -//! +//! //! The module also includes an enum `LambertWAccuracyMode` to control the //! accuracy-speed trade-off for Lambert W function calculations. diff --git a/src/statistics/stat.rs b/src/statistics/stat.rs index 729af67c..035785ca 100644 --- a/src/statistics/stat.rs +++ b/src/statistics/stat.rs @@ -151,7 +151,7 @@ use std::fmt; use self::QType::*; //use crate::structure::dataframe::*; use crate::structure::matrix::*; -use crate::traits::matrix::{MatrixTrait, LinearAlgebra}; +use crate::traits::matrix::{LinearAlgebra, MatrixTrait}; use order_stat::kth_by; /// Statistics Trait @@ -668,7 +668,7 @@ pub fn quantile(v: &Vec, qtype: QType) -> Vec { // Confusion Matrix // ============================================================================= /// Confusion Matrix -/// +/// /// * `TP` : True Positive /// * `TN` : True Negative /// * `FP` : False Positive @@ -716,7 +716,7 @@ pub struct ConfusionMatrix { impl ConfusionMatrix { /// Create Confusion Matrix - /// + /// /// # Examples /// ``` /// use peroxide::fuga::*; @@ -753,12 +753,7 @@ impl ConfusionMatrix { } } - Self { - TP, - TN, - FP, - FN, - } + Self { TP, TN, FP, FN } } /// Condition Positive @@ -906,10 +901,10 @@ impl ConfusionMatrix { /// To Matrix pub fn to_matrix(&self) -> Matrix { let mut m = matrix(vec![0f64; 4], 2, 2, Row); - m[(0,0)] = self.TP as f64; - m[(0,1)] = self.FP as f64; - m[(1,0)] = self.FN as f64; - m[(1,1)] = self.TN as f64; + m[(0, 0)] = self.TP as f64; + m[(0, 1)] = self.FP as f64; + m[(1, 0)] = self.FN as f64; + m[(1, 1)] = self.TN as f64; m } diff --git a/src/structure/ad.rs b/src/structure/ad.rs index e850c716..19fa725b 100644 --- a/src/structure/ad.rs +++ b/src/structure/ad.rs @@ -105,17 +105,12 @@ //! ``` //! -use peroxide_num::{ExpLogOps, PowOps, TrigOps}; +use self::AD::{AD0, AD1, AD2}; use crate::statistics::ops::C; -use crate::traits::{ - stable::StableFn, - fp::FPVector, - math::Vector, - sugar::VecOps, -}; -use std::iter::{FromIterator, DoubleEndedIterator, ExactSizeIterator}; +use crate::traits::{fp::FPVector, math::Vector, stable::StableFn, sugar::VecOps}; +use peroxide_num::{ExpLogOps, PowOps, TrigOps}; +use std::iter::{DoubleEndedIterator, ExactSizeIterator, FromIterator}; use std::ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub}; -use self::AD::{AD0, AD1, AD2}; #[derive(Debug, Copy, Clone, PartialEq)] pub enum AD { @@ -197,8 +192,8 @@ impl AD { pub fn empty(&self) -> Self { match self { AD0(_) => AD0(0f64), - AD1(_,_) => AD1(0f64, 0f64), - AD2(_,_,_) => AD2(0f64, 0f64, 0f64), + AD1(_, _) => AD1(0f64, 0f64), + AD2(_, _, _) => AD2(0f64, 0f64, 0f64), } } @@ -231,10 +226,10 @@ impl AD { pub fn set_ddx(&mut self, ddx: f64) { match self { AD0(_) => panic!("Can't set ddx for AD0"), - AD1(_,_) => panic!("Can't set ddx for AD1"), - AD2(_,_,ddt) => { + AD1(_, _) => panic!("Can't set ddx for AD1"), + AD2(_, _, ddt) => { *ddt = ddx; - } + } } } @@ -314,8 +309,8 @@ impl AD { unsafe fn x_ptr(&self) -> Option<*const f64> { match self { AD0(x) => Some(x), - AD1(x,_) => Some(x), - AD2(x,_,_) => Some(x), + AD1(x, _) => Some(x), + AD2(x, _, _) => Some(x), } } @@ -323,8 +318,8 @@ impl AD { unsafe fn dx_ptr(&self) -> Option<*const f64> { match self { AD0(_) => None, - AD1(_,dx) => Some(dx), - AD2(_,dx,_) => Some(dx), + AD1(_, dx) => Some(dx), + AD2(_, dx, _) => Some(dx), } } @@ -332,32 +327,32 @@ impl AD { unsafe fn ddx_ptr(&self) -> Option<*const f64> { match self { AD0(_) => None, - AD1(_,_) => None, - AD2(_,_,ddx) => Some(ddx), + AD1(_, _) => None, + AD2(_, _, ddx) => Some(ddx), } } unsafe fn x_mut_ptr(&mut self) -> Option<*mut f64> { match self { AD0(x) => Some(&mut *x), - AD1(x,_) => Some(&mut *x), - AD2(x,_,_) => Some(&mut *x), + AD1(x, _) => Some(&mut *x), + AD2(x, _, _) => Some(&mut *x), } } unsafe fn dx_mut_ptr(&mut self) -> Option<*mut f64> { match self { AD0(_) => None, - AD1(_,dx) => Some(&mut *dx), - AD2(_,dx,_) => Some(&mut *dx), + AD1(_, dx) => Some(&mut *dx), + AD2(_, dx, _) => Some(&mut *dx), } } unsafe fn ddx_mut_ptr(&mut self) -> Option<*mut f64> { match self { AD0(_) => None, - AD1(_,_) => None, - AD2(_,_,ddx) => Some(&mut *ddx), + AD1(_, _) => None, + AD2(_, _, ddx) => Some(&mut *ddx), } } } @@ -513,7 +508,7 @@ impl<'a> Iterator for ADIterMut<'a> { let l = self.ad.len(); if self.index + self.r_index < l { unsafe { - let result= match self.index { + let result = match self.index { 0 => self.ad.x_mut_ptr(), 1 => self.ad.dx_mut_ptr(), 2 => self.ad.ddx_mut_ptr(), @@ -522,7 +517,7 @@ impl<'a> Iterator for ADIterMut<'a> { self.index += 1; match result { None => None, - Some(ad) => Some(&mut *ad) + Some(ad) => Some(&mut *ad), } } } else { @@ -622,10 +617,7 @@ impl Add for AD { let ord = self.order().max(rhs.order()); let (a, b) = (self.to_order(ord), rhs.to_order(ord)); - a.into_iter() - .zip(b) - .map(|(x, y)| x + y) - .collect() + a.into_iter().zip(b).map(|(x, y)| x + y).collect() } } @@ -636,10 +628,7 @@ impl Sub for AD { let ord = self.order().max(rhs.order()); let (a, b) = (self.to_order(ord), rhs.to_order(ord)); - a.into_iter() - .zip(b) - .map(|(x, y)| x - y) - .collect() + a.into_iter().zip(b).map(|(x, y)| x - y).collect() } } @@ -673,10 +662,16 @@ impl Div for AD { let mut z = a; z[0] = a[0] / b[0]; let y0 = 1f64 / b[0]; - for i in 1 .. z.len() { + for i in 1..z.len() { let mut s = 0f64; - for (j, (&y1, &z1)) in b.iter().skip(1).take(i).zip(z.iter().take(i).rev()).enumerate() { - s += (C(i, j+1) as f64) * y1 * z1; + for (j, (&y1, &z1)) in b + .iter() + .skip(1) + .take(i) + .zip(z.iter().take(i).rev()) + .enumerate() + { + s += (C(i, j + 1) as f64) * y1 * z1; } z[i] = y0 * (a[i] - s); } @@ -690,12 +685,15 @@ impl ExpLogOps for AD { fn exp(&self) -> Self { let mut z = self.empty(); z[0] = self[0].exp(); - for i in 1 .. z.len() { - z[i] = z.iter() + for i in 1..z.len() { + z[i] = z + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&z1, &x1))| x + (C(i-1, k) as f64) * x1 * z1); + .fold(0f64, |x, (k, (&z1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * z1 + }); } z } @@ -704,10 +702,16 @@ impl ExpLogOps for AD { let mut z = self.empty(); z[0] = self[0].ln(); let x0 = 1f64 / self[0]; - for i in 1 .. z.len() { + for i in 1..z.len() { let mut s = 0f64; - for (k, (&z1, &x1)) in z.iter().skip(1).take(i-1).zip(self.iter().skip(1).take(i-1).rev()).enumerate() { - s += (C(i-1, k+1) as f64) * z1 * x1; + for (k, (&z1, &x1)) in z + .iter() + .skip(1) + .take(i - 1) + .zip(self.iter().skip(1).take(i - 1).rev()) + .enumerate() + { + s += (C(i - 1, k + 1) as f64) * z1 * x1; } z[i] = x0 * (self[i] - s); } @@ -732,7 +736,7 @@ impl PowOps for AD { fn powi(&self, n: i32) -> Self { let mut z = *self; - for _i in 1 .. n { + for _i in 1..n { z = z * *self; } z @@ -742,10 +746,16 @@ impl PowOps for AD { let ln_x = self.ln(); let mut z = self.empty(); z[0] = self.x().powf(f); - for i in 1 .. z.len() { + for i in 1..z.len() { let mut s = 0f64; - for (j, (&z1, &ln_x1)) in z.iter().skip(1).take(i-1).zip(ln_x.iter().skip(1).take(i-1).rev()).enumerate() { - s += (C(i-1, j+1) as f64) * z1 * ln_x1; + for (j, (&z1, &ln_x1)) in z + .iter() + .skip(1) + .take(i - 1) + .zip(ln_x.iter().skip(1).take(i - 1).rev()) + .enumerate() + { + s += (C(i - 1, j + 1) as f64) * z1 * ln_x1; } z[i] = f * (z[0] * ln_x[i] + s); } @@ -757,10 +767,16 @@ impl PowOps for AD { let p = y * ln_x; let mut z = self.empty(); z[0] = self.x().powf(y.x()); - for n in 1 .. z.len() { + for n in 1..z.len() { let mut s = 0f64; - for (k, (&z1, &p1)) in z.iter().skip(1).take(n-1).zip(p.iter().skip(1).take(n-1).rev()).enumerate() { - s += (C(n-1, k+1) as f64) * z1 * p1; + for (k, (&z1, &p1)) in z + .iter() + .skip(1) + .take(n - 1) + .zip(p.iter().skip(1).take(n - 1).rev()) + .enumerate() + { + s += (C(n - 1, k + 1) as f64) * z1 * p1; } z[n] = z[0] * p[n] + s; } @@ -778,17 +794,23 @@ impl TrigOps for AD { let mut v = self.empty(); u[0] = self[0].sin(); v[0] = self[0].cos(); - for i in 1 .. u.len() { - u[i] = v.iter() + for i in 1..u.len() { + u[i] = v + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&v1, &x1))| x + (C(i-1, k) as f64) * x1 * v1); - v[i] = u.iter() + .fold(0f64, |x, (k, (&v1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * v1 + }); + v[i] = u + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&u1, &x1))| x + (C(i-1, k) as f64) * x1 * u1); + .fold(0f64, |x, (k, (&u1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * u1 + }); } (u, v) } @@ -803,17 +825,23 @@ impl TrigOps for AD { let mut v = self.empty(); u[0] = self[0].sinh(); v[0] = self[0].cosh(); - for i in 1 .. u.len() { - u[i] = v.iter() + for i in 1..u.len() { + u[i] = v + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&v1, &x1))| x + (C(i-1, k) as f64) * x1 * v1); - v[i] = u.iter() + .fold(0f64, |x, (k, (&v1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * v1 + }); + v[i] = u + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&u1, &x1))| x + (C(i-1, k) as f64) * x1 * u1); + .fold(0f64, |x, (k, (&u1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * u1 + }); } u } @@ -823,17 +851,23 @@ impl TrigOps for AD { let mut v = self.empty(); u[0] = self[0].sinh(); v[0] = self[0].cosh(); - for i in 1 .. u.len() { - u[i] = v.iter() + for i in 1..u.len() { + u[i] = v + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&v1, &x1))| x + (C(i-1, k) as f64) * x1 * v1); - v[i] = u.iter() + .fold(0f64, |x, (k, (&v1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * v1 + }); + v[i] = u + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&u1, &x1))| x + (C(i-1, k) as f64) * x1 * u1); + .fold(0f64, |x, (k, (&u1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * u1 + }); } v } @@ -843,17 +877,23 @@ impl TrigOps for AD { let mut v = self.empty(); u[0] = self[0].sinh(); v[0] = self[0].cosh(); - for i in 1 .. u.len() { - u[i] = v.iter() + for i in 1..u.len() { + u[i] = v + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&v1, &x1))| x + (C(i-1, k) as f64) * x1 * v1); - v[i] = u.iter() + .fold(0f64, |x, (k, (&v1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * v1 + }); + v[i] = u + .iter() .take(i) .zip(self.iter().skip(1).take(i).rev()) .enumerate() - .fold(0f64, |x, (k, (&u1, &x1))| x + (C(i-1, k) as f64) * x1 * u1); + .fold(0f64, |x, (k, (&u1, &x1))| { + x + (C(i - 1, k) as f64) * x1 * u1 + }); } u / v } @@ -862,12 +902,15 @@ impl TrigOps for AD { let dx = 1f64 / (1f64 - self.powi(2)).sqrt(); let mut z = self.empty(); z[0] = self[0].asin(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -876,12 +919,15 @@ impl TrigOps for AD { let dx = (-1f64) / (1f64 - self.powi(2)).sqrt(); let mut z = self.empty(); z[0] = self[0].acos(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -890,12 +936,15 @@ impl TrigOps for AD { let dx = 1f64 / (1f64 + self.powi(2)); let mut z = self.empty(); z[0] = self[0].atan(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -904,12 +953,15 @@ impl TrigOps for AD { let dx = 1f64 / (1f64 + self.powi(2)).sqrt(); let mut z = self.empty(); z[0] = self[0].asinh(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -918,12 +970,15 @@ impl TrigOps for AD { let dx = 1f64 / (self.powi(2) - 1f64).sqrt(); let mut z = self.empty(); z[0] = self[0].acosh(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -932,12 +987,15 @@ impl TrigOps for AD { let dx = 1f64 / (1f64 - self.powi(2)); let mut z = self.empty(); z[0] = self[0].atanh(); - for n in 1 .. z.len() { - z[n] = dx.iter() + for n in 1..z.len() { + z[n] = dx + .iter() .take(n) .zip(self.iter().skip(1).take(n).rev()) .enumerate() - .fold(0f64, |s, (k, (&q1, &x1))| s + (C(n-1, k) as f64) * x1 * q1); + .fold(0f64, |s, (k, (&q1, &x1))| { + s + (C(n - 1, k) as f64) * x1 * q1 + }); } z } @@ -1237,7 +1295,10 @@ impl AD> StableFn for ADFn { impl) -> Vec> StableFn> for ADFn { type Output = Vec; fn call_stable(&self, target: Vec) -> Self::Output { - ((self.f)(target.iter().map(|&t| AD::from(t)).collect())).iter().map(|&t| t.x()).collect() + ((self.f)(target.iter().map(|&t| AD::from(t)).collect())) + .iter() + .map(|&t| t.x()) + .collect() } } @@ -1251,7 +1312,10 @@ impl) -> Vec> StableFn> for ADFn { impl<'a, F: Fn(&Vec) -> Vec> StableFn<&'a Vec> for ADFn { type Output = Vec; fn call_stable(&self, target: &'a Vec) -> Self::Output { - ((self.f)(&target.iter().map(|&t| AD::from(t)).collect())).iter().map(|&t| t.x()).collect() + ((self.f)(&target.iter().map(|&t| AD::from(t)).collect())) + .iter() + .map(|&t| t.x()) + .collect() } } @@ -1300,26 +1364,33 @@ impl FPVector for Vec { fn fmap(&self, f: F) -> Self where - F: Fn(Self::Scalar) -> Self::Scalar { + F: Fn(Self::Scalar) -> Self::Scalar, + { self.iter().map(|&x| f(x)).collect() } fn reduce(&self, init: T, f: F) -> Self::Scalar where - F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar, - T: Into { - self.iter().fold(init.into(), |x, &y| f(x,y)) + F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar, + T: Into, + { + self.iter().fold(init.into(), |x, &y| f(x, y)) } fn zip_with(&self, f: F, other: &Self) -> Self where - F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar { - self.iter().zip(other.iter()).map(|(&x, &y)| f(x, y)).collect() + F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar, + { + self.iter() + .zip(other.iter()) + .map(|(&x, &y)| f(x, y)) + .collect() } fn filter(&self, f: F) -> Self where - F: Fn(Self::Scalar) -> bool { + F: Fn(Self::Scalar) -> bool, + { self.iter().filter(|&x| f(*x)).cloned().collect() } diff --git a/src/structure/dataframe.rs b/src/structure/dataframe.rs index 3be872d6..e32c3393 100644 --- a/src/structure/dataframe.rs +++ b/src/structure/dataframe.rs @@ -39,7 +39,7 @@ //! fn at_raw(&self, i: usize) -> T; //! fn push(&mut self, elem: T); //! } -//! ``` +//! ``` //! //! * `Series` methods //! @@ -58,7 +58,7 @@ //! * All integer & float types can be exchanged. //! * `Bool, Char` can be changed to `Str` or `U8` only. //! * `U8` can be changed to all types. -//! +//! //! ### 3. Example //! //! ```rust @@ -72,7 +72,7 @@ //! //! a.print(); // print for Series //! b.dtype.print(); // print for dtype of Series (=Char) -//! c.as_type(U8); // Bool => U8 +//! c.as_type(U8); // Bool => U8 //! //! assert_eq!(c.dtype, U8); //! } @@ -214,16 +214,16 @@ //! Ok(()) //! } //! ``` -//! +//! //! * `WithParquet` trait -//! +//! //! ```ignore //! pub trait WithParquet: Sized { //! fn write_parquet(&self, file_path: &str, compression: CompressionOptions) -> Result<(), Box>; //! fn read_parquet(file_path: &str) -> Result>; //! } //! ``` -//! +//! //! * `parquet` feature should be required //! * `Char` is saved with `String` type. Thus, for reading `Char` type parquet file, the output type is `String`. //! * **Caution** : For different length `Bool` type column, missing values are filled with `false`. @@ -253,56 +253,35 @@ //! } //! ``` -#[cfg(feature="csv")] +use crate::traits::math::Vector; +use crate::util::{print::LowerExpWithPlus, useful::tab}; +use std::cmp::{max, min}; +#[cfg(feature = "csv")] use std::collections::HashMap; +#[cfg(any(feature = "csv", feature = "nc", feature = "parquet"))] +use std::error::Error; use std::fmt; use std::ops::{Index, IndexMut}; -use std::cmp::{max, min}; -#[cfg(any(feature="csv", feature="nc", feature="parquet"))] -use std::error::Error; -use crate::util::{ - useful::tab, - print::LowerExpWithPlus, -}; -use crate::traits::math::Vector; -use DType::{ - USIZE,U8,U16,U32,U64, - ISIZE,I8,I16,I32,I64, - F32,F64,Bool,Char,Str -}; +use DType::{Bool, Char, Str, F32, F64, I16, I32, I64, I8, ISIZE, U16, U32, U64, U8, USIZE}; -#[cfg(feature="csv")] -use csv::{ReaderBuilder, WriterBuilder}; -#[cfg(feature="nc")] -use netcdf::{ - types::VariableType, - variable::{VariableMut, Variable}, - Numeric, -}; -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] use arrow2::{ - array::{ - PrimitiveArray, - BooleanArray, - Utf8Array, - Array - }, + array::{Array, BooleanArray, PrimitiveArray, Utf8Array}, chunk::Chunk, - datatypes::{Field, DataType, Schema}, - types::NativeType, + datatypes::{DataType, Field, Schema}, + io::parquet::read::{infer_schema, read_metadata, FileReader}, io::parquet::write::{ - WriteOptions, - CompressionOptions, - RowGroupIterator, - Version, - FileWriter, - Encoding + CompressionOptions, Encoding, FileWriter, RowGroupIterator, Version, WriteOptions, }, - io::parquet::read::{ - read_metadata, - infer_schema, - FileReader, - } + types::NativeType, +}; +#[cfg(feature = "csv")] +use csv::{ReaderBuilder, WriterBuilder}; +#[cfg(feature = "nc")] +use netcdf::{ + types::VariableType, + variable::{Variable, VariableMut}, + Numeric, }; // ============================================================================= @@ -446,7 +425,9 @@ pub struct Scalar { // Traits // ============================================================================= pub trait TypedScalar { - fn new(s: T) -> Self where Self: Sized; + fn new(s: T) -> Self + where + Self: Sized; fn unwrap(self) -> T; } @@ -459,13 +440,13 @@ pub trait TypedVector { fn push(&mut self, elem: T); fn map T>(&self, f: F) -> Self; fn mut_map(&mut self, f: F); - fn fold T>(&self, init: T, f: F) -> T; + fn fold T>(&self, init: T, f: F) -> T; fn filter bool>(&self, f: F) -> Self; fn take(&self, n: usize) -> Self; fn skip(&self, n: usize) -> Self; fn take_while bool>(&self, f: F) -> Self; fn skip_while bool>(&self, f: F) -> Self; - fn zip_with T>(&self, f: F, other: &Self) -> Self; + fn zip_with T>(&self, f: F, other: &Self) -> Self; } // ============================================================================= @@ -488,7 +469,7 @@ macro_rules! impl_typed_scalar { } } } - } + }; } macro_rules! impl_typed_vector { @@ -576,13 +557,14 @@ macro_rules! impl_typed_vector { let v: Vec<$type> = self.to_vec(); let w: Vec<$type> = other.to_vec(); Series::new( - v.into_iter().zip(w.into_iter()) + v.into_iter() + .zip(w.into_iter()) .map(|(x, y)| f(x, y)) - .collect::>() + .collect::>(), ) } } - } + }; } macro_rules! dtype_case { @@ -691,7 +673,7 @@ macro_rules! set_space { st2 } } - _ => $elem.to_string() + _ => $elem.to_string(), } }}; @@ -701,14 +683,14 @@ macro_rules! set_space { let elem: f32 = $elem.unwrap(); $space = max( $space, - min(elem.fmt_lower_exp(2).len(), elem.to_string().len()) + min(elem.fmt_lower_exp(2).len(), elem.to_string().len()), ); } F64 => { let elem: f64 = $elem.unwrap(); $space = max( $space, - min(elem.fmt_lower_exp(2).len(), elem.to_string().len()) + min(elem.fmt_lower_exp(2).len(), elem.to_string().len()), ); } _ => { @@ -722,14 +704,10 @@ macro_rules! format_float_vec { ($self:expr) => {{ let mut result = String::new(); result.push_str("["); - for i in 0 .. $self.len() { + for i in 0..$self.len() { let st1 = $self[i].fmt_lower_exp(2); let st2 = $self[i].to_string(); - let st = if st1.len() < st2.len() { - st1 - } else { - st2 - }; + let st = if st1.len() < st2.len() { st1 } else { st2 }; result.push_str(&st); if i == $self.len() - 1 { break; @@ -755,7 +733,7 @@ macro_rules! string_cast_vec { let y: Vec<$ty1> = $to_vec; let x: Vec = y.into_iter().map(|x| x.to_string()).collect(); $wrapper(x) - }} + }}; } macro_rules! type_parse_vec { @@ -813,20 +791,18 @@ macro_rules! dtype_cast_vec { ($dt1:expr, $dt2:expr, $to_vec:expr, $wrapper:expr) => {{ match $dt1 { USIZE => dtype_cast_vec_part!(usize, $dt2, $to_vec, $wrapper), - U8 => { - match $dt2 { - Bool => { - let y: Vec = $to_vec; - let x: Vec = y.into_iter().map(|x| x != 0).collect(); - $wrapper(x) - }, - Char => { - let y: Vec = $to_vec; - let x: Vec = y.into_iter().map(|x| x as char).collect(); - $wrapper(x) - }, - _ => dtype_cast_vec_part!(u8, $dt2, $to_vec, $wrapper) + U8 => match $dt2 { + Bool => { + let y: Vec = $to_vec; + let x: Vec = y.into_iter().map(|x| x != 0).collect(); + $wrapper(x) } + Char => { + let y: Vec = $to_vec; + let x: Vec = y.into_iter().map(|x| x as char).collect(); + $wrapper(x) + } + _ => dtype_cast_vec_part!(u8, $dt2, $to_vec, $wrapper), }, U16 => dtype_cast_vec_part!(u16, $dt2, $to_vec, $wrapper), U32 => dtype_cast_vec_part!(u32, $dt2, $to_vec, $wrapper), @@ -839,28 +815,24 @@ macro_rules! dtype_cast_vec { F32 => dtype_cast_vec_part!(f32, $dt2, $to_vec, $wrapper), F64 => dtype_cast_vec_part!(f64, $dt2, $to_vec, $wrapper), Str => dtype_parse_vec_part!($dt2, $to_vec, $wrapper), - Char => { - match $dt2 { - Str => string_cast_vec!(char, $to_vec, $wrapper), - U8 => { - let y: Vec = $to_vec; - let x: Vec = y.into_iter().map(|x| x as u8).collect(); - $wrapper(x) - }, - _ => panic!("Can't convert char type to {}", $dt2), + Char => match $dt2 { + Str => string_cast_vec!(char, $to_vec, $wrapper), + U8 => { + let y: Vec = $to_vec; + let x: Vec = y.into_iter().map(|x| x as u8).collect(); + $wrapper(x) } - } - Bool => { - match $dt2 { - Str => string_cast_vec!(bool, $to_vec, $wrapper), - U8 => { - let y: Vec = $to_vec; - let x: Vec = y.into_iter().map(|x| x as u8).collect(); - $wrapper(x) - }, - _ => panic!("Can't convert bool type to {}", $dt2), + _ => panic!("Can't convert char type to {}", $dt2), + }, + Bool => match $dt2 { + Str => string_cast_vec!(bool, $to_vec, $wrapper), + U8 => { + let y: Vec = $to_vec; + let x: Vec = y.into_iter().map(|x| x as u8).collect(); + $wrapper(x) } - } + _ => panic!("Can't convert bool type to {}", $dt2), + }, } }}; } @@ -873,7 +845,7 @@ fn to_string(x: T) -> String { x.to_string() } -#[cfg(feature= "nc")] +#[cfg(feature = "nc")] fn dtype_to_vtype(dt: DType) -> netcdf::types::BasicType { match dt { USIZE => netcdf::types::BasicType::Uint64, @@ -894,7 +866,7 @@ fn dtype_to_vtype(dt: DType) -> netcdf::types::BasicType { } } -#[cfg(feature= "nc")] +#[cfg(feature = "nc")] fn vtype_to_dtype(dv: netcdf::types::BasicType) -> DType { match dv { netcdf::types::BasicType::Ubyte => U8, @@ -911,20 +883,26 @@ fn vtype_to_dtype(dv: netcdf::types::BasicType) -> DType { } } -#[cfg(feature= "nc")] +#[cfg(feature = "nc")] fn nc_put_value(var: &mut VariableMut, v: Vec) -> Result<(), netcdf::error::Error> { var.put_values(&v, None, None) } -#[cfg(feature= "nc")] -fn nc_read_value(val: &Variable, v: Vec) -> Result where Series: TypedVector { +#[cfg(feature = "nc")] +fn nc_read_value( + val: &Variable, + v: Vec, +) -> Result +where + Series: TypedVector, +{ let mut v = v; v.resize_with(val.len(), Default::default); val.values_to(&mut v, None, None)?; Ok(Series::new(v.clone())) } -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] fn dtype_to_arrow(dt: DType) -> DataType { match dt { USIZE => DataType::UInt64, @@ -945,7 +923,7 @@ fn dtype_to_arrow(dt: DType) -> DataType { } } -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] fn arrow_to_dtype(dt: DataType) -> DType { match dt { DataType::Boolean => Bool, @@ -961,27 +939,29 @@ fn arrow_to_dtype(dt: DataType) -> DType { DataType::Float32 => F32, DataType::Float64 => F64, DataType::Utf8 => Str, - _ => unimplemented!() + _ => unimplemented!(), } } -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] macro_rules! dtype_case_to_arrow { ($ty:ty, $to_arr:expr, $value:expr, $chunk_vec:expr; $length:expr) => {{ let v: Vec<$ty> = $value; - let v_wrap = (0usize..$length).map(|i| { - if i < v.len() { - Some(v[i].clone()) - } else { - None - } - }).collect::>(); + let v_wrap = (0usize..$length) + .map(|i| { + if i < v.len() { + Some(v[i].clone()) + } else { + None + } + }) + .collect::>(); let arr = $to_arr(v_wrap); $chunk_vec.push(arr.boxed()) - }} + }}; } -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] macro_rules! dtype_match_to_arrow { ($dtype:expr, $value:expr, $chunk_vec:expr; $length:expr) => {{ match $dtype { @@ -1008,26 +988,38 @@ macro_rules! dtype_match_to_arrow { }}; } -#[cfg(feature= "parquet")] -fn parquet_read_value(arr: &Box, _v: Vec) -> Result where Series: TypedVector { +#[cfg(feature = "parquet")] +fn parquet_read_value( + arr: &Box, + _v: Vec, +) -> Result +where + Series: TypedVector, +{ let x = arr.as_any().downcast_ref::>().unwrap(); let x = x.values_iter().cloned().collect::>(); Ok(Series::new(x)) } -fn add_vec + Clone>(v: Vec, w: Vec) -> Series -where Series: TypedVector { +fn add_vec + Clone>(v: Vec, w: Vec) -> Series +where + Series: TypedVector, +{ Series::new(v.into_iter().zip(w).map(|(x, y)| x + y).collect::>()) } -fn sub_vec + Clone>(v: Vec, w: Vec) -> Series -where Series: TypedVector { +fn sub_vec + Clone>(v: Vec, w: Vec) -> Series +where + Series: TypedVector, +{ Series::new(v.into_iter().zip(w).map(|(x, y)| x - y).collect::>()) } -fn mul_scalar + Clone + Copy>(v: Vec, s: T) -> Series -where Series: TypedVector { +fn mul_scalar + Clone + Copy>(v: Vec, s: T) -> Series +where + Series: TypedVector, +{ Series::new(v.into_iter().map(|x| x * s).collect::>()) } @@ -1139,7 +1131,7 @@ impl Series { pub fn at(&self, i: usize) -> Scalar { dtype_match!(self.dtype, self.at_raw(i), Scalar::new) } - + /// Length for Series pub fn len(&self) -> usize { dtype_match!(self.dtype, self.as_slice().to_vec(), len; Vec) @@ -1194,7 +1186,7 @@ impl Vector for Series { assert_eq!(self.dtype, rhs.dtype, "DTypes are not same (add_vec)"); dtype_match!( N; - self.dtype, + self.dtype, self.to_vec(), |x| add_vec(x, rhs.to_vec()); Vec @@ -1372,12 +1364,9 @@ impl fmt::Display for Scalar { impl DataFrame { /// Declare new DataFrame with `Vec` pub fn new(v: Vec) -> Self { - let ics = (0usize .. v.len()).map(|x| x.to_string()).collect(); + let ics = (0usize..v.len()).map(|x| x.to_string()).collect(); - Self { - data: v, - ics, - } + Self { data: v, ics } } pub fn header(&self) -> &Vec { @@ -1397,7 +1386,11 @@ impl DataFrame { /// Push new pair of head, Series to DataFrame pub fn push(&mut self, name: &str, series: Series) { if !self.ics.is_empty() { - assert_eq!(self.ics.iter().find(|x| x.as_str() == name), None, "Repetitive index!"); + assert_eq!( + self.ics.iter().find(|x| x.as_str() == name), + None, + "Repetitive index!" + ); } self.ics.push(name.to_string()); self.data.push(series); @@ -1415,9 +1408,12 @@ impl DataFrame { } pub fn spread(&self) -> String { - let r: usize = self.data.iter().fold(0, |max_len, column| max(max_len, column.len())); + let r: usize = self + .data + .iter() + .fold(0, |max_len, column| max(max_len, column.len())); let h = self.header(); - + let mut result = String::new(); if r > 100 { @@ -1425,15 +1421,15 @@ impl DataFrame { result.push_str(&tab("", lc1)); let mut space_vec: Vec = vec![]; - for i in 0 .. self.data.len() { + for i in 0..self.data.len() { let v = &self[i]; let mut space = 0usize; - for j in 0 .. v.len().min(5) { + for j in 0..v.len().min(5) { let elem = v.at(j); set_space!(elem, space); } - if v.len() >= r-5 { - for j in v.len()-5 .. v.len() { + if v.len() >= r - 5 { + for j in v.len() - 5..v.len() { let elem = v.at(j); set_space!(elem, space); } @@ -1447,18 +1443,18 @@ impl DataFrame { space_vec.push(space); } result.push('\n'); - - for i in 0 .. 5 { + + for i in 0..5 { result.push_str(&tab(&format!("r[{}]", i), lc1)); - for j in 0 .. self.data.len() { + for j in 0..self.data.len() { let v = &self[j]; let space = space_vec[j]; if i < v.len() { let elem = v.at(i); let st = set_space!(elem); result.push_str(&tab(&st, space)); - } else { - result.push_str(&tab("", space)); + } else { + result.push_str(&tab("", space)); } } result.push('\n'); @@ -1468,9 +1464,9 @@ impl DataFrame { result.push_str(&tab("...", space)); } result.push('\n'); - for i in r-5 .. r { + for i in r - 5..r { result.push_str(&tab(&format!("r[{}]", i), lc1)); - for j in 0 .. self.data.len() { + for j in 0..self.data.len() { let v = &self[j]; let space = space_vec[j]; if i < v.len() { @@ -1481,7 +1477,7 @@ impl DataFrame { result.push_str(&tab("", space)); } } - if i == r-1 { + if i == r - 1 { break; } result.push('\n'); @@ -1492,10 +1488,10 @@ impl DataFrame { result.push_str(&tab("", 5)); let mut space_vec: Vec = vec![]; - for i in 0 .. self.data.len() { + for i in 0..self.data.len() { let v = &self[i]; let mut space = 0usize; - for j in 0 .. v.len() { + for j in 0..v.len() { let elem = v.at(j); set_space!(elem, space) } @@ -1509,9 +1505,9 @@ impl DataFrame { } result.push('\n'); - for i in 0 .. r { + for i in 0..r { result.push_str(&tab(&format!("r[{}]", i), 5)); - for j in 0 .. self.data.len() { + for j in 0..self.data.len() { let v = &self[j]; let space = space_vec[j]; if i < v.len() { @@ -1529,7 +1525,7 @@ impl DataFrame { } result } - + /// Type casting for DataFrame /// /// # Examples @@ -1553,7 +1549,11 @@ impl DataFrame { /// } /// ``` pub fn as_types(&mut self, dtypes: Vec) { - assert_eq!(self.data.len(), dtypes.len(), "Length of dtypes are not compatible with DataFrame"); + assert_eq!( + self.data.len(), + dtypes.len(), + "Length of dtypes are not compatible with DataFrame" + ); for (i, dtype) in dtypes.into_iter().enumerate() { self[i].as_type(dtype); } @@ -1634,13 +1634,13 @@ impl fmt::Display for DataFrame { // ============================================================================= /// To handle CSV file format -#[cfg(feature="csv")] +#[cfg(feature = "csv")] pub trait WithCSV: Sized { fn write_csv(&self, file_path: &str) -> Result<(), Box>; fn read_csv(file_path: &str, delimiter: char) -> Result>; } -#[cfg(feature="csv")] +#[cfg(feature = "csv")] impl WithCSV for DataFrame { /// Write csv file fn write_csv(&self, file_path: &str) -> Result<(), Box> { @@ -1650,11 +1650,9 @@ impl WithCSV for DataFrame { .iter() .fold(0, |max_len, column| max(max_len, column.len())); let c: usize = self.data.len(); - wtr.write_record( - self.header().clone() - )?; - - for i in 0 .. r { + wtr.write_record(self.header().clone())?; + + for i in 0..r { let mut record: Vec = vec!["".to_string(); c]; for (j, v) in self.data.iter().enumerate() { if i < v.len() { @@ -1696,14 +1694,14 @@ impl WithCSV for DataFrame { } /// To handle with NetCDF file format -#[cfg(feature= "nc")] +#[cfg(feature = "nc")] pub trait WithNetCDF: Sized { fn write_nc(&self, file_path: &str) -> Result<(), Box>; fn read_nc(file_path: &str) -> Result>; fn read_nc_by_header(file_path: &str, header: Vec<&str>) -> Result>; } -#[cfg(feature= "nc")] +#[cfg(feature = "nc")] impl WithNetCDF for DataFrame { /// write netcdf file fn write_nc(&self, file_path: &str) -> Result<(), Box> { @@ -1717,7 +1715,11 @@ impl WithNetCDF for DataFrame { match v.dtype { dtype if dtype.is_numeric() => { let vtype = dtype_to_vtype(dtype); - let var = &mut f.add_variable_with_type(h, &[&dim_name], &VariableType::Basic(vtype))?; + let var = &mut f.add_variable_with_type( + h, + &[&dim_name], + &VariableType::Basic(vtype), + )?; dtype_match!(N; dtype, v.to_vec(), |v| nc_put_value(var, v); Vec)?; } Str => { @@ -1751,7 +1753,7 @@ impl WithNetCDF for DataFrame { let v_slice: &[u8] = v.as_slice(); var.put_values(v_slice, None, None)?; } - _ => unreachable!() + _ => unreachable!(), } } @@ -1766,7 +1768,7 @@ impl WithNetCDF for DataFrame { let h = v.name(); if v.vartype().is_string() { let mut data: Vec = vec![Default::default(); v.len()]; - for i in 0 .. v.len() { + for i in 0..v.len() { data[i] = v.string_value(Some(&[i]))?; } df.push(&h, Series::new(data)); @@ -1775,7 +1777,6 @@ impl WithNetCDF for DataFrame { let series = dtype_match!(N; dtype, vec![], |vec| nc_read_value(&v, vec); Vec)?; df.push(&h, series); } - } Ok(df) } @@ -1815,7 +1816,7 @@ impl WithNetCDF for DataFrame { }; if v.vartype().is_string() { let mut data: Vec = vec![Default::default(); v.len()]; - for i in 0 .. v.len() { + for i in 0..v.len() { data[i] = v.string_value(Some(&[i]))?; } df.push(&h, Series::new(data)); @@ -1830,17 +1831,27 @@ impl WithNetCDF for DataFrame { } /// To handle parquet format -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] pub trait WithParquet { - fn write_parquet(&self, file_path: &str, compression: CompressionOptions) -> Result<(), Box>; - fn read_parquet(file_path: &str) -> Result> where Self: Sized; + fn write_parquet( + &self, + file_path: &str, + compression: CompressionOptions, + ) -> Result<(), Box>; + fn read_parquet(file_path: &str) -> Result> + where + Self: Sized; // fn read_parquet_by_header(file_path: &str, header: Vec<&str>) -> Result> where Self: Sized; } -#[cfg(feature="parquet")] +#[cfg(feature = "parquet")] impl WithParquet for DataFrame { /// Write DataFrame to parquet - fn write_parquet(&self, file_path: &str, compression: CompressionOptions) -> Result<(), Box> { + fn write_parquet( + &self, + file_path: &str, + compression: CompressionOptions, + ) -> Result<(), Box> { let file = std::fs::File::create(file_path)?; let mut schema_vec = vec![]; @@ -1859,7 +1870,7 @@ impl WithParquet for DataFrame { let schema = Schema::from(schema_vec); let l = arr_vec.len(); let chunk = Chunk::new(arr_vec); - let encodings = (0 .. l).map(|_| vec![Encoding::Plain]).collect::>(); + let encodings = (0..l).map(|_| vec![Encoding::Plain]).collect::>(); let options = WriteOptions { write_statistics: true, compression, @@ -1867,12 +1878,8 @@ impl WithParquet for DataFrame { data_pagesize_limit: None, }; - let row_groups = RowGroupIterator::try_new( - vec![Ok(chunk)].into_iter(), - &schema, - options, - encodings, - )?; + let row_groups = + RowGroupIterator::try_new(vec![Ok(chunk)].into_iter(), &schema, options, encodings)?; let mut writer = FileWriter::try_new(file, schema, options)?; @@ -1886,7 +1893,10 @@ impl WithParquet for DataFrame { } /// Read parquet to DataFrame - fn read_parquet(file_path: &str) -> Result> where Self: Sized { + fn read_parquet(file_path: &str) -> Result> + where + Self: Sized, + { let mut df = DataFrame::new(vec![]); let mut reader = std::fs::File::open(file_path)?; @@ -1917,15 +1927,21 @@ impl WithParquet for DataFrame { } Char => { let data = arr.as_any().downcast_ref::>().unwrap(); - let data = data.values_iter().map(|t| t.chars().next().unwrap()).collect::>(); + let data = data + .values_iter() + .map(|t| t.chars().next().unwrap()) + .collect::>(); df.push(&h, Series::new(data)) } Str => { let data = arr.as_any().downcast_ref::>().unwrap(); - let data = data.values_iter().map(|t| t.to_string()).collect::>(); + let data = data + .values_iter() + .map(|t| t.to_string()) + .collect::>(); df.push(&h, Series::new(data)) } - _ => unreachable!() + _ => unreachable!(), } } } diff --git a/src/structure/matrix.rs b/src/structure/matrix.rs index 0e6c3b65..62dfc722 100644 --- a/src/structure/matrix.rs +++ b/src/structure/matrix.rs @@ -617,16 +617,16 @@ use serde::{Deserialize, Serialize}; pub use self::Shape::{Col, Row}; use crate::numerical::eigen::{eigen, EigenMethod}; use crate::structure::dataframe::{Series, TypedVector}; +#[cfg(feature = "parallel")] +use crate::traits::math::{ParallelInnerProduct, ParallelNormed}; use crate::traits::sugar::ScalableMut; use crate::traits::{ fp::{FPMatrix, FPVector}, general::Algorithm, math::{InnerProduct, LinearOp, MatrixProduct, Norm, Normed, Vector}, + matrix::{Form, LinearAlgebra, MatrixTrait, SolveKind, PQLU, QR, SVD, WAZD}, mutable::MutMatrix, - matrix::{MatrixTrait, LinearAlgebra, PQLU, WAZD, QR, SVD, Form, SolveKind}, }; -#[cfg(feature = "parallel")] -use crate::traits::math::{ParallelInnerProduct, ParallelNormed}; use crate::util::{ low_level::{copy_vec_ptr, swap_vec_ptr}, non_macro::{cbind, eye, rbind, zeros}, @@ -1266,7 +1266,6 @@ impl MatrixTrait for Matrix { } } } - } impl Matrix { @@ -1468,7 +1467,6 @@ impl Matrix { .collect::>(); matrix(data, row, col, Row) } - } // ============================================================================= diff --git a/src/structure/polynomial.rs b/src/structure/polynomial.rs index 151f3ee2..422747be 100644 --- a/src/structure/polynomial.rs +++ b/src/structure/polynomial.rs @@ -6,8 +6,8 @@ use crate::util::useful::*; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use peroxide_num::PowOps; use crate::traits::fp::FPVector; +use peroxide_num::PowOps; use std::cmp::{max, min}; use std::fmt; use std::ops::{Add, Div, Mul, Neg, Sub}; @@ -303,7 +303,7 @@ where type Output = Self; fn add(self, other: T) -> Self { let mut new_coef = self.coef.clone(); - new_coef[self.coef.len()-1] += other.into(); + new_coef[self.coef.len() - 1] += other.into(); Self::new(new_coef) } } @@ -322,7 +322,7 @@ where type Output = Self; fn sub(self, other: T) -> Self { let mut new_coef = self.coef.clone(); - new_coef[self.coef.len()-1] -= other.into(); + new_coef[self.coef.len() - 1] -= other.into(); Self::new(new_coef) } } @@ -555,7 +555,7 @@ pub fn lagrange_polynomial(node_x: Vec, node_y: Vec) -> Polynomial { let fixed_val = node_x[i]; let prod = node_y[i]; let mut id = poly(vec![1f64]); - + for j in 0..l { if j == i { continue; @@ -594,7 +594,7 @@ pub fn legendre_polynomial(n: usize) -> Polynomial { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SpecialKind { First, - Second + Second, } /// Chebyshev Polynomial @@ -609,7 +609,7 @@ pub fn chebyshev_polynomial(n: usize, kind: SpecialKind) -> Polynomial { 0 => prev, 1 => curr, _ => { - for _i in 1 .. n { + for _i in 1..n { std::mem::swap(&mut prev, &mut curr); curr = poly(vec![2f64, 0f64]) * prev.clone() - curr; } @@ -624,17 +624,17 @@ pub fn chebyshev_polynomial(n: usize, kind: SpecialKind) -> Polynomial { /// Generate `n`-th order Hermite polynomial. The physics convention /// H_n(x) = (-1)^n e^{x^2}\frac{d^n}{dx^n}e^{-x^2} is used. pub fn hermite_polynomial(n: usize) -> Polynomial { - let mut prev = Polynomial::new(vec![1f64]); // 1 - let mut curr = Polynomial::new(vec![2f64, 0f64]); // 2x + let mut prev = Polynomial::new(vec![1f64]); // 1 + let mut curr = Polynomial::new(vec![2f64, 0f64]); // 2x match n { 0 => prev, 1 => curr, _ => { - for idx in 1 .. n { + for idx in 1..n { let k = idx as f64; std::mem::swap(&mut prev, &mut curr); - curr = poly(vec![2f64, 0f64]) * prev.clone() - 2.0*k*curr; + curr = poly(vec![2f64, 0f64]) * prev.clone() - 2.0 * k * curr; } curr } @@ -647,17 +647,17 @@ pub fn hermite_polynomial(n: usize) -> Polynomial { /// Generate `n`-th order Bessel polynomial. Definition according to /// Krall and Fink (1949). pub fn bessel_polynomial(n: usize) -> Polynomial { - let mut prev = Polynomial::new(vec![1f64]); // 1 - let mut curr = Polynomial::new(vec![1f64, 1f64]); // x + 1 + let mut prev = Polynomial::new(vec![1f64]); // 1 + let mut curr = Polynomial::new(vec![1f64, 1f64]); // x + 1 match n { 0 => prev, 1 => curr, _ => { - for idx in 1 .. n { + for idx in 1..n { let k = idx as f64; std::mem::swap(&mut prev, &mut curr); - curr = (2.0*k+1.0) * poly(vec![1f64, 0f64]) * prev.clone() + curr; + curr = (2.0 * k + 1.0) * poly(vec![1f64, 0f64]) * prev.clone() + curr; } curr } diff --git a/src/structure/sparse.rs b/src/structure/sparse.rs index c523953c..d4ec390d 100644 --- a/src/structure/sparse.rs +++ b/src/structure/sparse.rs @@ -3,13 +3,13 @@ //! * Reference : Press, William H., and William T. Vetterling. *Numerical Recipes.* Cambridge: Cambridge Univ. Press, 2007. use crate::structure::matrix::Matrix; -use crate::traits::matrix::{Form, LinearAlgebra, SolveKind, PQLU, QR, WAZD, SVD}; use crate::traits::math::LinearOp; +use crate::traits::matrix::{Form, LinearAlgebra, SolveKind, PQLU, QR, SVD, WAZD}; //use crate::traits::math::{InnerProduct, LinearOp, Norm, Normed, Vector}; +#[cfg(feature = "O3")] +use crate::fuga::UPLO; use crate::util::non_macro::zeros; use std::ops::Mul; -#[cfg(feature="O3")] -use crate::fuga::UPLO; #[derive(Debug, Clone)] pub struct SPMatrix { @@ -164,7 +164,7 @@ impl LinearAlgebra for SPMatrix { unimplemented!() } - #[cfg(feature="O3")] + #[cfg(feature = "O3")] fn cholesky(&self, _uplo: UPLO) -> Matrix { unimplemented!() } diff --git a/src/structure/vector.rs b/src/structure/vector.rs index 33ff4e79..55a26c30 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -264,18 +264,15 @@ #[cfg(feature = "O3")] extern crate blas; +#[cfg(feature = "parallel")] +use crate::rayon::iter::{ + IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, + IntoParallelRefMutIterator, ParallelIterator, +}; #[cfg(feature = "O3")] use blas::{daxpy, ddot, dnrm2, idamax}; -#[cfg(feature = "parallel")] -use crate::rayon::iter::{ParallelIterator, IntoParallelIterator, IntoParallelRefIterator, IndexedParallelIterator, IntoParallelRefMutIterator}; use crate::structure::matrix::{matrix, Matrix, Row}; -#[cfg(feature = "parallel")] -use crate::traits::{ - fp::ParallelFPVector, - math::{ParallelInnerProduct, ParallelNormed, ParallelVectorProduct}, - mutable::ParallelMutFP, -}; use crate::traits::{ fp::FPVector, general::Algorithm, @@ -283,6 +280,12 @@ use crate::traits::{ mutable::MutFP, pointer::{Oxide, Redox, RedoxCommon}, }; +#[cfg(feature = "parallel")] +use crate::traits::{ + fp::ParallelFPVector, + math::{ParallelInnerProduct, ParallelNormed, ParallelVectorProduct}, + mutable::ParallelMutFP, +}; use std::cmp::min; impl FPVector for Vec { diff --git a/src/traits/matrix.rs b/src/traits/matrix.rs index 25d2979a..ce609bb0 100644 --- a/src/traits/matrix.rs +++ b/src/traits/matrix.rs @@ -1,8 +1,10 @@ use std::ops::{Index, IndexMut}; -pub trait MatrixTrait: Sized + Index<(usize, usize), Output=Self::Scalar> + IndexMut<(usize, usize)> { +pub trait MatrixTrait: + Sized + Index<(usize, usize), Output = Self::Scalar> + IndexMut<(usize, usize)> +{ type Scalar; - fn ptr(&self) -> *const Self::Scalar; + fn ptr(&self) -> *const Self::Scalar; fn mut_ptr(&mut self) -> *mut Self::Scalar; fn as_slice(&self) -> &[Self::Scalar]; fn as_mut_slice(&mut self) -> &mut [Self::Scalar]; @@ -13,7 +15,9 @@ pub trait MatrixTrait: Sized + Index<(usize, usize), Output=Self::Scalar> + Inde fn row(&self, index: usize) -> Vec; fn diag(&self) -> Vec; fn transpose(&self) -> Self; - fn t(&self) -> Self { self.transpose() } + fn t(&self) -> Self { + self.transpose() + } fn subs_col(&mut self, idx: usize, v: &[Self::Scalar]); fn subs_row(&mut self, idx: usize, v: &[Self::Scalar]); fn from_index(f: F, size: (usize, usize)) -> Self @@ -30,7 +34,7 @@ pub trait MatrixTrait: Sized + Index<(usize, usize), Output=Self::Scalar> + Inde // For Linear Algebra // └─────────────────────────────────────────────────────────┘ /// Linear algebra trait -pub trait LinearAlgebra { +pub trait LinearAlgebra { fn back_subs(&self, b: &[M::Scalar]) -> Vec; fn forward_subs(&self, b: &[M::Scalar]) -> Vec; fn lu(&self) -> PQLU; @@ -50,7 +54,7 @@ pub trait LinearAlgebra { } #[allow(non_snake_case)] -pub fn solve>(A: &M, b: &M, sk: SolveKind) -> M { +pub fn solve>(A: &M, b: &M, sk: SolveKind) -> M { A.solve_mat(b, sk) } @@ -101,7 +105,7 @@ pub enum SolveKind { WAZ, } -impl QR { +impl QR { pub fn q(&self) -> &M { &self.q } @@ -117,4 +121,3 @@ pub struct SVD { pub u: M, pub vt: M, } - diff --git a/src/traits/num.rs b/src/traits/num.rs index 77d3fa55..6b74e3cd 100644 --- a/src/traits/num.rs +++ b/src/traits/num.rs @@ -24,9 +24,9 @@ //! } //! ``` -use std::ops::{Neg, Add, Sub, Mul, Div}; use crate::structure::ad::AD; -use peroxide_num::{PowOps, TrigOps, ExpLogOps}; +use peroxide_num::{ExpLogOps, PowOps, TrigOps}; +use std::ops::{Add, Div, Mul, Neg, Sub}; pub trait Real: PowOps diff --git a/src/traits/pointer.rs b/src/traits/pointer.rs index 7551cbb7..8cc42e4d 100644 --- a/src/traits/pointer.rs +++ b/src/traits/pointer.rs @@ -43,9 +43,9 @@ //! ``` //! //! `ox()` and `red()` come from oxidation and reduction. +use crate::structure::ad::AD; use crate::structure::matrix::{Matrix, Shape}; use crate::structure::sparse::SPMatrix; -use crate::structure::ad::AD; use crate::traits::{ fp::FPVector, math::{LinearOp, Vector}, @@ -79,7 +79,7 @@ impl RedoxCommon for Redox> { type ToRedox = Vec; fn from_vec(vec: Self::ToRedox) -> Self { Self { - data: Box::new(vec) + data: Box::new(vec), } } @@ -92,7 +92,7 @@ impl RedoxCommon for Redox> { type ToRedox = Vec; fn from_vec(vec: Self::ToRedox) -> Self { Self { - data: Box::new(vec) + data: Box::new(vec), } } diff --git a/src/traits/sugar.rs b/src/traits/sugar.rs index d9286c43..05cfc65e 100644 --- a/src/traits/sugar.rs +++ b/src/traits/sugar.rs @@ -1,6 +1,6 @@ use crate::structure::matrix::{matrix, Matrix, Shape}; -use crate::traits::matrix::MatrixTrait; use crate::traits::fp::FPVector; +use crate::traits::matrix::MatrixTrait; use crate::util::non_macro::zeros_shape; use std::ops::{Add, Div, Mul, Sub}; diff --git a/src/util/non_macro.rs b/src/util/non_macro.rs index d50bd3b9..e308a9b9 100644 --- a/src/util/non_macro.rs +++ b/src/util/non_macro.rs @@ -32,14 +32,14 @@ extern crate rand; use self::rand::prelude::*; -use rand_distr::{Uniform, Distribution}; use crate::structure::{ matrix::Shape::{Col, Row}, matrix::{matrix, Matrix, Shape}, }; use crate::traits::float::FloatWithPrecision; use crate::traits::matrix::MatrixTrait; -use anyhow::{Result, bail}; +use anyhow::{bail, Result}; +use rand_distr::{Distribution, Uniform}; #[derive(Debug, Copy, Clone)] pub enum ConcatenateError { @@ -49,7 +49,10 @@ pub enum ConcatenateError { impl std::fmt::Display for ConcatenateError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { - ConcatenateError::DifferentLength => write!(f, "To concatenate, vectors or matrices must have the same length"), + ConcatenateError::DifferentLength => write!( + f, + "To concatenate, vectors or matrices must have the same length" + ), } } } @@ -65,7 +68,7 @@ impl std::fmt::Display for ConcatenateError { /// /// let a = seq(1, 10, 2); /// assert_eq!(a, vec![1f64,3f64,5f64,7f64,9f64]); -/// +/// /// let b = seq(1, 1, 1); /// assert_eq!(b, vec![1f64]); /// ``` @@ -251,11 +254,11 @@ pub fn eye_shape(n: usize, shape: Shape) -> Matrix { } /// MATLAB like linspace -/// +/// /// # Examples /// ``` /// use peroxide::fuga::*; -/// +/// /// let a = linspace(1, 10, 10); /// assert_eq!(a, seq(1,10,1)); /// assert_eq!(a.len(), 10); @@ -339,15 +342,20 @@ pub fn rand_with_rng(r: usize, c: usize, rng: &mut R) -> Matrix { /// # Description /// /// Any range -pub fn rand_with_dist, R: Rng, D: Distribution>(r: usize, c: usize, rng: &mut R, dist: D) -> Matrix { - matrix(rng.sample_iter(dist).take(r*c).collect(), r, c, Row) +pub fn rand_with_dist, R: Rng, D: Distribution>( + r: usize, + c: usize, + rng: &mut R, + dist: D, +) -> Matrix { + matrix(rng.sample_iter(dist).take(r * c).collect(), r, c, Row) } // ┌─────────────────────────────────────────────────────────┐ // Numpy like non-macro functions // └─────────────────────────────────────────────────────────┘ /// Numpy like logspace -/// +/// /// # Examples /// ``` /// use peroxide::fuga::*; @@ -371,7 +379,7 @@ where assert!(e >= s); - let step: f64 = if length > 1 { + let step: f64 = if length > 1 { (e - s) / (length as f64 - 1f64) } else { 0f64 diff --git a/src/util/plot.rs b/src/util/plot.rs index 7363c1f6..978ea7dd 100644 --- a/src/util/plot.rs +++ b/src/util/plot.rs @@ -487,14 +487,23 @@ impl Plot for Plot2D { let ylabel = self.ylabel.clone(); let legends = self.legends.clone(); let path = self.path.clone(); - let markers = self.markers.iter().map(|(i, x)| (i, format!("{}", x))).collect::>(); - let line_style = self.line_style.iter().map(|(i, x)| (i, format!("{}", x))).collect::>(); + let markers = self + .markers + .iter() + .map(|(i, x)| (i, format!("{}", x))) + .collect::>(); + let line_style = self + .line_style + .iter() + .map(|(i, x)| (i, format!("{}", x))) + .collect::>(); let color = self.color.clone(); let alpha = self.alpha.clone(); let plot_type = self.plot_type.clone(); // Global variables to plot - let globals = vec![("plt", py.import_bound("matplotlib.pyplot")?)].into_py_dict_bound(py); + let globals = + vec![("plt", py.import_bound("matplotlib.pyplot")?)].into_py_dict_bound(py); globals.as_gil_ref().set_item("x", x)?; globals.as_gil_ref().set_item("y", ys)?; globals.as_gil_ref().set_item("pair", pairs)?; @@ -515,16 +524,14 @@ impl Plot for Plot2D { // Plot Code let mut plot_string = match self.style { - PlotStyle::Default => { - "\ + PlotStyle::Default => "\ plt.rc(\"text\", usetex=True)\n\ - plt.rc(\"font\", family=\"serif\")\n".to_string() - } - PlotStyle::Science => { - "\ + plt.rc(\"font\", family=\"serif\")\n" + .to_string(), + PlotStyle::Science => "\ import scienceplots\n\ - plt.style.use(\"science\")\n".to_string() - } + plt.style.use(\"science\")\n" + .to_string(), _ => format!( "\ import scienceplots\n\ @@ -550,11 +557,15 @@ impl Plot for Plot2D { plot_string.push_str(&format!("plt.ylabel(r\"{}\")\n", y)[..]); } match self.xscale { - PlotScale::Linear => plot_string.push_str(&"plt.xscale(\"linear\")\n".to_string()[..]), + PlotScale::Linear => { + plot_string.push_str(&"plt.xscale(\"linear\")\n".to_string()[..]) + } PlotScale::Log => plot_string.push_str(&"plt.xscale(\"log\")\n".to_string()[..]), } match self.yscale { - PlotScale::Linear => plot_string.push_str(&"plt.yscale(\"linear\")\n".to_string()[..]), + PlotScale::Linear => { + plot_string.push_str(&"plt.yscale(\"linear\")\n".to_string()[..]) + } PlotScale::Log => plot_string.push_str(&"plt.yscale(\"log\")\n".to_string()[..]), } if self.xlim.is_some() { @@ -566,17 +577,20 @@ impl Plot for Plot2D { for i in 0..y_length { let mut inner_string = format!("x,y[{}]", i); - let is_corresponding_marker = !markers.is_empty() && (markers.iter().any(|(&j, _)| j == i)); + let is_corresponding_marker = + !markers.is_empty() && (markers.iter().any(|(&j, _)| j == i)); if is_corresponding_marker { let marker = markers.iter().find(|(&j, _)| j == i).unwrap().1.as_str(); inner_string.push_str(&format!(",marker=\"{}\"", marker)[..]); } - let is_corresponding_line_style = !line_style.is_empty() && (line_style.iter().any(|(&j, _)| j == i)); + let is_corresponding_line_style = + !line_style.is_empty() && (line_style.iter().any(|(&j, _)| j == i)); if is_corresponding_line_style { let style = line_style.iter().find(|(&j, _)| j == i).unwrap().1.as_str(); inner_string.push_str(&format!(",linestyle=\"{}\"", style)[..]); } - let is_corresponding_color = !color.is_empty() && (color.iter().any(|(j, _)| j == &i)); + let is_corresponding_color = + !color.is_empty() && (color.iter().any(|(j, _)| j == &i)); if is_corresponding_color { let color = color.iter().find(|(j, _)| j == &i).unwrap().1.as_str(); inner_string.push_str(&format!(",color=\"{}\"", color)[..]); @@ -584,12 +598,14 @@ impl Plot for Plot2D { if !legends.is_empty() { inner_string.push_str(&format!(",label=r\"{}\"", legends[i])[..]); } - let is_corresponding_alpha = !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &i)); + let is_corresponding_alpha = + !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &i)); if is_corresponding_alpha { let alpha = alpha.iter().find(|(j, _)| j == &i).unwrap().1; inner_string.push_str(&format!(",alpha={}", alpha)[..]); } - let is_corresponding_plot_type = !plot_type.is_empty() && (plot_type.iter().any(|(j, _)| j == &i)); + let is_corresponding_plot_type = + !plot_type.is_empty() && (plot_type.iter().any(|(j, _)| j == &i)); if is_corresponding_plot_type { let plot_type = plot_type.iter().find(|(j, _)| j == &i).unwrap().1; match plot_type { @@ -609,32 +625,56 @@ impl Plot for Plot2D { } for i in 0..pair_length { let mut inner_string = format!("pair[{}][0],pair[{}][1]", i, i); - let is_corresponding_marker = !markers.is_empty() && (markers.iter().any(|(&j, _)| j == (i + y_length))); + let is_corresponding_marker = + !markers.is_empty() && (markers.iter().any(|(&j, _)| j == (i + y_length))); if is_corresponding_marker { - let marker = markers.iter().find(|(&j, _)| j == (i + y_length)).unwrap().1.as_str(); + let marker = markers + .iter() + .find(|(&j, _)| j == (i + y_length)) + .unwrap() + .1 + .as_str(); inner_string.push_str(&format!(",marker=\"{}\"", marker)[..]); } - let is_corresponding_line_style = !line_style.is_empty() && (line_style.iter().any(|(&j, _)| j == (i + y_length))); + let is_corresponding_line_style = !line_style.is_empty() + && (line_style.iter().any(|(&j, _)| j == (i + y_length))); if is_corresponding_line_style { - let style = line_style.iter().find(|(&j, _)| j == (i + y_length)).unwrap().1.as_str(); + let style = line_style + .iter() + .find(|(&j, _)| j == (i + y_length)) + .unwrap() + .1 + .as_str(); inner_string.push_str(&format!(",linestyle=\"{}\"", style)[..]); } - let is_corresponding_color = !color.is_empty() && (color.iter().any(|(j, _)| j == &(i + y_length))); + let is_corresponding_color = + !color.is_empty() && (color.iter().any(|(j, _)| j == &(i + y_length))); if is_corresponding_color { - let color = color.iter().find(|(j, _)| j == &(i + y_length)).unwrap().1.as_str(); + let color = color + .iter() + .find(|(j, _)| j == &(i + y_length)) + .unwrap() + .1 + .as_str(); inner_string.push_str(&format!(",color=\"{}\"", color)[..]); } if !legends.is_empty() { inner_string.push_str(&format!(",label=r\"{}\"", legends[i + y_length])[..]); } - let is_corresponding_alpha = !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &(i + y_length))); + let is_corresponding_alpha = + !alpha.is_empty() && (alpha.iter().any(|(j, _)| j == &(i + y_length))); if is_corresponding_alpha { let alpha = alpha.iter().find(|(j, _)| j == &(i + y_length)).unwrap().1; inner_string.push_str(&format!(",alpha={}", alpha)[..]); } - let is_corresponding_plot_type = !plot_type.is_empty() && (plot_type.iter().any(|(j, _)| j == &(i + y_length))); + let is_corresponding_plot_type = + !plot_type.is_empty() && (plot_type.iter().any(|(j, _)| j == &(i + y_length))); if is_corresponding_plot_type { - let plot_type = plot_type.iter().find(|(j, _)| j == &(i + y_length)).unwrap().1; + let plot_type = plot_type + .iter() + .find(|(j, _)| j == &(i + y_length)) + .unwrap() + .1; match plot_type { PlotType::Scatter => { plot_string.push_str(&format!("plt.scatter({})\n", inner_string)[..]); @@ -656,7 +696,8 @@ impl Plot for Plot2D { } if self.tight { - plot_string.push_str(&format!("plt.savefig(pa, dpi={}, bbox_inches='tight')", dpi)[..]); + plot_string + .push_str(&format!("plt.savefig(pa, dpi={}, bbox_inches='tight')", dpi)[..]); } else { plot_string.push_str(&format!("plt.savefig(pa, dpi={})", dpi)[..]); } diff --git a/src/util/print.rs b/src/util/print.rs index e9038682..68ac7d63 100644 --- a/src/util/print.rs +++ b/src/util/print.rs @@ -5,10 +5,10 @@ use crate::statistics::stat::ConfusionMatrix; #[allow(unused_imports)] use crate::structure::{ ad::AD, + dataframe::{DType, DTypeArray, DataFrame, Scalar, Series}, matrix::Matrix, multinomial::Multinomial, polynomial::Polynomial, - dataframe::{DataFrame, DTypeArray, Series, Scalar, DType}, }; use rand::distributions::uniform::SampleUniform; use std::fmt::{Debug, LowerExp, UpperExp}; @@ -189,14 +189,10 @@ macro_rules! format_float_vec { ($self:expr) => {{ let mut result = String::new(); result.push_str("["); - for i in 0 .. $self.len() { + for i in 0..$self.len() { let st1 = $self[i].fmt_lower_exp(2); let st2 = $self[i].to_string(); - let st = if st1.len() < st2.len() { - st1 - } else { - st2 - }; + let st = if st1.len() < st2.len() { st1 } else { st2 }; result.push_str(&st); if i == $self.len() - 1 { break; @@ -426,9 +422,9 @@ impl Printable for ConfusionMatrix { } /// Format float number into lower exponent notation with '+' sign -/// +/// /// # Example -/// +/// /// ```rust /// use peroxide::fuga::*; /// @@ -439,7 +435,7 @@ impl Printable for ConfusionMatrix { /// ``` pub trait LowerExpWithPlus: LowerExp { fn fmt_lower_exp(&self, precision: usize) -> String { - let mut s = format!("{:.p$e}", self, p=precision); + let mut s = format!("{:.p$e}", self, p = precision); let s_old = s.clone(); let mut e = s.split_off(s.find('e').unwrap()); if e.starts_with("e-") { @@ -455,9 +451,9 @@ impl LowerExpWithPlus for f32 {} impl LowerExpWithPlus for f64 {} /// Format float number into upper exponent notation with '+' sign -/// +/// /// # Example -/// +/// /// ```rust /// use peroxide::fuga::*; /// @@ -468,7 +464,7 @@ impl LowerExpWithPlus for f64 {} /// ``` pub trait UpperExpWithPlus: UpperExp { fn fmt_upper_exp(&self, precision: usize) -> String { - let mut s = format!("{:.p$E}", self, p=precision); + let mut s = format!("{:.p$E}", self, p = precision); let s_old = s.clone(); let mut e = s.split_off(s.find('E').unwrap()); if e.starts_with("E-") { diff --git a/src/util/useful.rs b/src/util/useful.rs index b2a5df7f..e5da4a8a 100644 --- a/src/util/useful.rs +++ b/src/util/useful.rs @@ -124,29 +124,29 @@ pub fn eq_vec(x: &[f64], y: &[f64], tol: f64) -> bool { // Vec of Tuples // ============================================================================= /// Auto-zip -/// +/// /// # Examples /// ``` /// extern crate peroxide; /// use peroxide::fuga::*; -/// +/// /// let a = vec![1, 2, 3]; /// let a_zipped = auto_zip(&a); /// assert_eq!(a_zipped, vec![(1, 2), (2, 3)]); /// ``` pub fn auto_zip(x: &Vec) -> Vec<(T, T)> { - let x_head = x[0 .. x.len() - 1].to_vec(); - let x_tail = x[1 .. x.len()].to_vec(); + let x_head = x[0..x.len() - 1].to_vec(); + let x_tail = x[1..x.len()].to_vec(); x_head.into_iter().zip(x_tail).collect() } /// Find the index of interval of x -/// +/// /// # Examples /// ``` /// extern crate peroxide; /// use peroxide::fuga::*; -/// +/// /// let x = vec![ /// (0, 5), /// (5, 7), @@ -155,7 +155,7 @@ pub fn auto_zip(x: &Vec) -> Vec<(T, T)> { /// (15, 20), /// (20, 30) /// ]; -/// +/// /// assert_eq!(find_interval(&x, 11), 3); /// ``` pub fn find_interval(sorted_intervals: &Vec<(T, T)>, x: T) -> usize { @@ -163,8 +163,14 @@ pub fn find_interval(sorted_intervals: &Vec<(T, T)>, let mut j = sorted_intervals.len() - 1; // Check range - assert!(x >= sorted_intervals[0].0, "x is smaller than the smallest interval"); - assert!(x <= sorted_intervals[sorted_intervals.len() - 1].1, "x is larger than the largest interval"); + assert!( + x >= sorted_intervals[0].0, + "x is smaller than the smallest interval" + ); + assert!( + x <= sorted_intervals[sorted_intervals.len() - 1].1, + "x is larger than the largest interval" + ); while i <= j { let mid = (i + j) / 2; @@ -180,22 +186,22 @@ pub fn find_interval(sorted_intervals: &Vec<(T, T)>, } /// Generate Range of Intervals -/// +/// /// # Examples /// ``` /// extern crate peroxide; /// use peroxide::fuga::*; /// use std::ops::Range; -/// +/// /// let x = vec![1, 2, 3, 4]; /// let r = gen_range(&x); -/// +/// /// let answer = vec![ /// Range { start: 1, end: 2 }, /// Range { start: 2, end: 3 }, /// Range { start: 3, end: 4 }, /// ]; -/// +/// /// assert_eq!(r, answer); /// ``` pub fn gen_range(x: &[T]) -> Vec> { @@ -210,31 +216,37 @@ pub fn gen_range(x: &[T]) -> Vec> { } /// Generate and Zip Range of Intervals -/// +/// /// # Examples /// ``` /// extern crate peroxide; /// use peroxide::fuga::*; /// use std::ops::Range; -/// +/// /// let x: Vec = vec![1, 2, 3, 4]; /// let y: Vec = x.iter().map(|&t| t.pow(2)).collect(); /// let r = zip_range(&x, &y); -/// +/// /// let answer = vec![ /// (Range { start: 1, end: 2 }, 1), /// (Range { start: 2, end: 3 }, 4), /// (Range { start: 3, end: 4 }, 9), /// ]; -/// +/// /// assert_eq!(r, answer); /// ``` pub fn zip_range(x: &[T], y: &[U]) -> Vec<(Range, U)> { - y[0 .. x.len() - 1].iter() + y[0..x.len() - 1] + .iter() .enumerate() - .map(|(i, yi)| (Range { - start: x[i].clone(), - end: x[i + 1].clone(), - }, yi.clone())) + .map(|(i, yi)| { + ( + Range { + start: x[i].clone(), + end: x[i + 1].clone(), + }, + yi.clone(), + ) + }) .collect() } diff --git a/tests/dataframe/dataframe.rs b/tests/dataframe/dataframe.rs index 6f9c28bf..4417dc85 100644 --- a/tests/dataframe/dataframe.rs +++ b/tests/dataframe/dataframe.rs @@ -4,8 +4,8 @@ use peroxide::fuga::*; #[test] fn test_type_cast() { let mut a = DataFrame::new(vec![]); - a.push("x", Series::new(vec![1,2,3,4])); - a.push("y", Series::new(vec![true,false,false,true])); + a.push("x", Series::new(vec![1, 2, 3, 4])); + a.push("y", Series::new(vec![true, false, false, true])); let mut b = DataFrame::new(vec![]); b.push("x", Series::new(vec![1usize, 2, 3, 4])); diff --git a/tests/dataframe/mod.rs b/tests/dataframe/mod.rs index 4f4cc067..123af7ed 100644 --- a/tests/dataframe/mod.rs +++ b/tests/dataframe/mod.rs @@ -1,3 +1,3 @@ -pub mod series; pub mod dataframe; -pub mod print; \ No newline at end of file +pub mod print; +pub mod series; diff --git a/tests/dataframe/print.rs b/tests/dataframe/print.rs index 7eb0316b..065f5681 100644 --- a/tests/dataframe/print.rs +++ b/tests/dataframe/print.rs @@ -9,4 +9,4 @@ fn test_print() { df.push("z", Series::new(seq(0, 10, 0.01))); df.print(); -} \ No newline at end of file +} diff --git a/tests/dataframe/series.rs b/tests/dataframe/series.rs index 2e92bd17..ec91c086 100644 --- a/tests/dataframe/series.rs +++ b/tests/dataframe/series.rs @@ -3,16 +3,16 @@ use peroxide::fuga::*; #[test] fn test_map() { - let a = Series::new(vec![1,2,3,4]); + let a = Series::new(vec![1, 2, 3, 4]); let b = a.map(|x: i32| x + 1); - assert_eq!(b, Series::new(vec![2,3,4,5])); + assert_eq!(b, Series::new(vec![2, 3, 4, 5])); } #[test] fn test_mut_map() { - let mut a = Series::new(vec![1,2,3,4]); + let mut a = Series::new(vec![1, 2, 3, 4]); a.mut_map(|x: &mut i32| *x += 1); - assert_eq!(a, Series::new(vec![2,3,4,5])); + assert_eq!(a, Series::new(vec![2, 3, 4, 5])); } diff --git a/tests/integrated.rs b/tests/integrated.rs index 79e67589..4e969ba8 100644 --- a/tests/integrated.rs +++ b/tests/integrated.rs @@ -3,5 +3,5 @@ extern crate peroxide; #[allow(unused_imports)] use peroxide::fuga::*; -mod o3; mod dataframe; +mod o3; diff --git a/tests/numerical.rs b/tests/numerical.rs index fd6091c2..f0aec082 100644 --- a/tests/numerical.rs +++ b/tests/numerical.rs @@ -12,7 +12,7 @@ fn f(x: f64) -> f64 { } #[test] -fn test_cubic_spline_initialization() -> Result<(), Box>{ +fn test_cubic_spline_initialization() -> Result<(), Box> { let mut vx = Vec::new(); let mut vy = Vec::new(); for i in 0..11 { @@ -34,7 +34,7 @@ fn test_cubic_spline_initialization() -> Result<(), Box>{ } #[test] -fn test_cubic_spline_extension() -> Result<(), Box>{ +fn test_cubic_spline_extension() -> Result<(), Box> { let mut vx = Vec::new(); let mut vy = Vec::new(); for i in 0..11 { diff --git a/tests/o3/lapack.rs b/tests/o3/lapack.rs index d65a9360..c50e869a 100644 --- a/tests/o3/lapack.rs +++ b/tests/o3/lapack.rs @@ -13,20 +13,128 @@ pub fn test_apply() { #[cfg(feature = "O3")] #[test] pub fn test_dpotrf() { - let a = py_matrix( - vec![ - vec![2.9821852954666 , 2.680083137271475, 2.317961273223499, 2.134665492195094, 3.026598331879419, 2.283461999828011, 3.727890627691731, 1.948290349481972, 2.509358003244204, 2.354788397327008], - vec![2.680083137271475, 4.018906407367834, 2.341820593934314, 2.830765880629095, 3.552151618608445, 2.460655598487766, 3.630225204862198, 1.796569139726129, 2.846699793116624, 2.774282835105069], - vec![2.317961273223499, 2.341820593934314, 2.038910554565652, 1.966181894408401, 2.536384937997141, 1.886915794296248, 3.136970841370761, 1.905232489093743, 2.01726450417587 , 2.238391500871792], - vec![2.134665492195094, 2.830765880629095, 1.966181894408401, 3.301422256938514, 2.794302738298506, 2.205849011689008, 2.679880725689802, 1.555759606416891, 2.475715452431455, 2.116394736527704], - vec![3.026598331879419, 3.552151618608445, 2.536384937997141, 2.794302738298506, 4.337375745514422, 3.604658556851256, 4.143687579387594, 2.385563118734139, 3.321157832605267, 2.949560656237908], - vec![2.283461999828011, 2.460655598487766, 1.886915794296248, 2.205849011689008, 3.604658556851256, 3.413575093545912, 3.168622634363222, 1.907039710137486, 2.698561362072113, 2.249353149769269], - vec![3.727890627691731, 3.630225204862198, 3.136970841370761, 2.679880725689802, 4.143687579387594, 3.168622634363222, 5.142703863442649, 2.977549597798733, 3.210043437463944, 3.385961680761656], - vec![1.948290349481972, 1.796569139726129, 1.905232489093743, 1.555759606416891, 2.385563118734139, 1.907039710137486, 2.977549597798733, 2.230209604622137, 1.742552591231192, 2.252632855204552], - vec![2.509358003244204, 2.846699793116624, 2.01726450417587 , 2.475715452431455, 3.321157832605267, 2.698561362072113, 3.210043437463944, 1.742552591231192, 3.202516498869207, 2.228297655595811], - vec![2.354788397327008, 2.774282835105069, 2.238391500871792, 2.116394736527704, 2.949560656237908, 2.249353149769269, 3.385961680761656, 2.252632855204552, 2.228297655595811, 2.784914722669765] - ] - ); + let a = py_matrix(vec![ + vec![ + 2.9821852954666, + 2.680083137271475, + 2.317961273223499, + 2.134665492195094, + 3.026598331879419, + 2.283461999828011, + 3.727890627691731, + 1.948290349481972, + 2.509358003244204, + 2.354788397327008, + ], + vec![ + 2.680083137271475, + 4.018906407367834, + 2.341820593934314, + 2.830765880629095, + 3.552151618608445, + 2.460655598487766, + 3.630225204862198, + 1.796569139726129, + 2.846699793116624, + 2.774282835105069, + ], + vec![ + 2.317961273223499, + 2.341820593934314, + 2.038910554565652, + 1.966181894408401, + 2.536384937997141, + 1.886915794296248, + 3.136970841370761, + 1.905232489093743, + 2.01726450417587, + 2.238391500871792, + ], + vec![ + 2.134665492195094, + 2.830765880629095, + 1.966181894408401, + 3.301422256938514, + 2.794302738298506, + 2.205849011689008, + 2.679880725689802, + 1.555759606416891, + 2.475715452431455, + 2.116394736527704, + ], + vec![ + 3.026598331879419, + 3.552151618608445, + 2.536384937997141, + 2.794302738298506, + 4.337375745514422, + 3.604658556851256, + 4.143687579387594, + 2.385563118734139, + 3.321157832605267, + 2.949560656237908, + ], + vec![ + 2.283461999828011, + 2.460655598487766, + 1.886915794296248, + 2.205849011689008, + 3.604658556851256, + 3.413575093545912, + 3.168622634363222, + 1.907039710137486, + 2.698561362072113, + 2.249353149769269, + ], + vec![ + 3.727890627691731, + 3.630225204862198, + 3.136970841370761, + 2.679880725689802, + 4.143687579387594, + 3.168622634363222, + 5.142703863442649, + 2.977549597798733, + 3.210043437463944, + 3.385961680761656, + ], + vec![ + 1.948290349481972, + 1.796569139726129, + 1.905232489093743, + 1.555759606416891, + 2.385563118734139, + 1.907039710137486, + 2.977549597798733, + 2.230209604622137, + 1.742552591231192, + 2.252632855204552, + ], + vec![ + 2.509358003244204, + 2.846699793116624, + 2.01726450417587, + 2.475715452431455, + 3.321157832605267, + 2.698561362072113, + 3.210043437463944, + 1.742552591231192, + 3.202516498869207, + 2.228297655595811, + ], + vec![ + 2.354788397327008, + 2.774282835105069, + 2.238391500871792, + 2.116394736527704, + 2.949560656237908, + 2.249353149769269, + 3.385961680761656, + 2.252632855204552, + 2.228297655595811, + 2.784914722669765, + ], + ]); let dpotrf_u = lapack_dpotrf(&a, UPLO::Upper).unwrap(); let dpotrf_l = lapack_dpotrf(&a, UPLO::Lower).unwrap(); @@ -34,35 +142,229 @@ pub fn test_dpotrf() { let u = dpotrf_u.get_U().unwrap(); let l = dpotrf_l.get_L().unwrap(); - let scipy_u = py_matrix( - vec![ - vec![ 1.726900488003463, 1.551961537963327, 1.34226684706273 , 1.236125362766596, 1.752618841041957, 1.322289278213136, 2.158717687318329, 1.128200705840593, 1.453099365410088, 1.363592409455782], - vec![ 0. , 1.268984551541246, 0.203843359082252, 0.718958209858647, 0.65576415850829 , 0.321921568031328, 0.220631829192057, 0.035969734306862, 0.466156555210059, 0.518556243550586], - vec![ 0. , 0. , 0.442355231459957, 0.362642811042644, 0.113550376983589, 0.104958994115387, 0.439514016124092, 0.867072131324973, -0.063762143110917, 0.683573627458849], - vec![ 0. , 0. , 0. , 1.060662825095517, 0.108612163548495, 0.284560665177766, -0.289042488015237, -0.168890722850109, 0.346460971292225, -0.179029330692296], - vec![ 0. , 0. , 0. , 0. , 0.90054762326669 , 1.14736846650923 , 0.218847271328198, 0.33819073440549 , 0.486759471799237, 0.17930981650712 ], - vec![ 0. , 0. , 0. , 0. , 0. , 0.391212348671252, 0.072001696614059, -0.069844847295321, -0.059587640909243, 0.135011494209335], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0.32274897849312 , 0.109238423598569, -0.011482954266517, -0.226830086097441], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.211084069199511, 0.154785258348754, 0.218861000711332], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.696448259994717, -0.007136319580541], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.086731850555121] - ] - ); + let scipy_u = py_matrix(vec![ + vec![ + 1.726900488003463, + 1.551961537963327, + 1.34226684706273, + 1.236125362766596, + 1.752618841041957, + 1.322289278213136, + 2.158717687318329, + 1.128200705840593, + 1.453099365410088, + 1.363592409455782, + ], + vec![ + 0., + 1.268984551541246, + 0.203843359082252, + 0.718958209858647, + 0.65576415850829, + 0.321921568031328, + 0.220631829192057, + 0.035969734306862, + 0.466156555210059, + 0.518556243550586, + ], + vec![ + 0., + 0., + 0.442355231459957, + 0.362642811042644, + 0.113550376983589, + 0.104958994115387, + 0.439514016124092, + 0.867072131324973, + -0.063762143110917, + 0.683573627458849, + ], + vec![ + 0., + 0., + 0., + 1.060662825095517, + 0.108612163548495, + 0.284560665177766, + -0.289042488015237, + -0.168890722850109, + 0.346460971292225, + -0.179029330692296, + ], + vec![ + 0., + 0., + 0., + 0., + 0.90054762326669, + 1.14736846650923, + 0.218847271328198, + 0.33819073440549, + 0.486759471799237, + 0.17930981650712, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0.391212348671252, + 0.072001696614059, + -0.069844847295321, + -0.059587640909243, + 0.135011494209335, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0.32274897849312, + 0.109238423598569, + -0.011482954266517, + -0.226830086097441, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0.211084069199511, + 0.154785258348754, + 0.218861000711332, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0.696448259994717, + -0.007136319580541, + ], + vec![0., 0., 0., 0., 0., 0., 0., 0., 0., 0.086731850555121], + ]); - let scipy_l = py_matrix( - vec![ - vec![ 1.726900488003463, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.551961537963327, 1.268984551541246, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.34226684706273 , 0.203843359082252, 0.442355231459957, 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.236125362766596, 0.718958209858647, 0.362642811042644, 1.060662825095517, 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.752618841041957, 0.65576415850829 , 0.113550376983589, 0.108612163548495, 0.90054762326669 , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.322289278213136, 0.321921568031328, 0.104958994115387, 0.284560665177766, 1.14736846650923 , 0.391212348671252, 0. , 0. , 0. , 0. ], - vec![ 2.158717687318329, 0.220631829192057, 0.439514016124092, -0.289042488015237, 0.218847271328198, 0.072001696614058, 0.32274897849312 , 0. , 0. , 0. ], - vec![ 1.128200705840593, 0.035969734306862, 0.867072131324973, -0.168890722850108, 0.33819073440549 , -0.069844847295322, 0.109238423598569, 0.211084069199512, 0. , 0. ], - vec![ 1.453099365410088, 0.466156555210059, -0.063762143110917, 0.346460971292225, 0.486759471799238, -0.059587640909244, -0.011482954266516, 0.154785258348753, 0.696448259994717, 0. ], - vec![ 1.363592409455782, 0.518556243550586, 0.683573627458849, -0.179029330692296, 0.17930981650712 , 0.135011494209336, -0.226830086097441, 0.218861000711332, -0.00713631958054 , 0.086731850555118] - ] - ); + let scipy_l = py_matrix(vec![ + vec![1.726900488003463, 0., 0., 0., 0., 0., 0., 0., 0., 0.], + vec![ + 1.551961537963327, + 1.268984551541246, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.34226684706273, + 0.203843359082252, + 0.442355231459957, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.236125362766596, + 0.718958209858647, + 0.362642811042644, + 1.060662825095517, + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.752618841041957, + 0.65576415850829, + 0.113550376983589, + 0.108612163548495, + 0.90054762326669, + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.322289278213136, + 0.321921568031328, + 0.104958994115387, + 0.284560665177766, + 1.14736846650923, + 0.391212348671252, + 0., + 0., + 0., + 0., + ], + vec![ + 2.158717687318329, + 0.220631829192057, + 0.439514016124092, + -0.289042488015237, + 0.218847271328198, + 0.072001696614058, + 0.32274897849312, + 0., + 0., + 0., + ], + vec![ + 1.128200705840593, + 0.035969734306862, + 0.867072131324973, + -0.168890722850108, + 0.33819073440549, + -0.069844847295322, + 0.109238423598569, + 0.211084069199512, + 0., + 0., + ], + vec![ + 1.453099365410088, + 0.466156555210059, + -0.063762143110917, + 0.346460971292225, + 0.486759471799238, + -0.059587640909244, + -0.011482954266516, + 0.154785258348753, + 0.696448259994717, + 0., + ], + vec![ + 1.363592409455782, + 0.518556243550586, + 0.683573627458849, + -0.179029330692296, + 0.17930981650712, + 0.135011494209336, + -0.226830086097441, + 0.218861000711332, + -0.00713631958054, + 0.086731850555118, + ], + ]); assert_eq!(u, scipy_u); assert_eq!(l, scipy_l); @@ -71,53 +373,355 @@ pub fn test_dpotrf() { #[cfg(feature = "O3")] #[test] pub fn test_cholesky() { - let a = py_matrix( - vec![ - vec![2.9821852954666 , 2.680083137271475, 2.317961273223499, 2.134665492195094, 3.026598331879419, 2.283461999828011, 3.727890627691731, 1.948290349481972, 2.509358003244204, 2.354788397327008], - vec![2.680083137271475, 4.018906407367834, 2.341820593934314, 2.830765880629095, 3.552151618608445, 2.460655598487766, 3.630225204862198, 1.796569139726129, 2.846699793116624, 2.774282835105069], - vec![2.317961273223499, 2.341820593934314, 2.038910554565652, 1.966181894408401, 2.536384937997141, 1.886915794296248, 3.136970841370761, 1.905232489093743, 2.01726450417587 , 2.238391500871792], - vec![2.134665492195094, 2.830765880629095, 1.966181894408401, 3.301422256938514, 2.794302738298506, 2.205849011689008, 2.679880725689802, 1.555759606416891, 2.475715452431455, 2.116394736527704], - vec![3.026598331879419, 3.552151618608445, 2.536384937997141, 2.794302738298506, 4.337375745514422, 3.604658556851256, 4.143687579387594, 2.385563118734139, 3.321157832605267, 2.949560656237908], - vec![2.283461999828011, 2.460655598487766, 1.886915794296248, 2.205849011689008, 3.604658556851256, 3.413575093545912, 3.168622634363222, 1.907039710137486, 2.698561362072113, 2.249353149769269], - vec![3.727890627691731, 3.630225204862198, 3.136970841370761, 2.679880725689802, 4.143687579387594, 3.168622634363222, 5.142703863442649, 2.977549597798733, 3.210043437463944, 3.385961680761656], - vec![1.948290349481972, 1.796569139726129, 1.905232489093743, 1.555759606416891, 2.385563118734139, 1.907039710137486, 2.977549597798733, 2.230209604622137, 1.742552591231192, 2.252632855204552], - vec![2.509358003244204, 2.846699793116624, 2.01726450417587 , 2.475715452431455, 3.321157832605267, 2.698561362072113, 3.210043437463944, 1.742552591231192, 3.202516498869207, 2.228297655595811], - vec![2.354788397327008, 2.774282835105069, 2.238391500871792, 2.116394736527704, 2.949560656237908, 2.249353149769269, 3.385961680761656, 2.252632855204552, 2.228297655595811, 2.784914722669765] - ] - ); + let a = py_matrix(vec![ + vec![ + 2.9821852954666, + 2.680083137271475, + 2.317961273223499, + 2.134665492195094, + 3.026598331879419, + 2.283461999828011, + 3.727890627691731, + 1.948290349481972, + 2.509358003244204, + 2.354788397327008, + ], + vec![ + 2.680083137271475, + 4.018906407367834, + 2.341820593934314, + 2.830765880629095, + 3.552151618608445, + 2.460655598487766, + 3.630225204862198, + 1.796569139726129, + 2.846699793116624, + 2.774282835105069, + ], + vec![ + 2.317961273223499, + 2.341820593934314, + 2.038910554565652, + 1.966181894408401, + 2.536384937997141, + 1.886915794296248, + 3.136970841370761, + 1.905232489093743, + 2.01726450417587, + 2.238391500871792, + ], + vec![ + 2.134665492195094, + 2.830765880629095, + 1.966181894408401, + 3.301422256938514, + 2.794302738298506, + 2.205849011689008, + 2.679880725689802, + 1.555759606416891, + 2.475715452431455, + 2.116394736527704, + ], + vec![ + 3.026598331879419, + 3.552151618608445, + 2.536384937997141, + 2.794302738298506, + 4.337375745514422, + 3.604658556851256, + 4.143687579387594, + 2.385563118734139, + 3.321157832605267, + 2.949560656237908, + ], + vec![ + 2.283461999828011, + 2.460655598487766, + 1.886915794296248, + 2.205849011689008, + 3.604658556851256, + 3.413575093545912, + 3.168622634363222, + 1.907039710137486, + 2.698561362072113, + 2.249353149769269, + ], + vec![ + 3.727890627691731, + 3.630225204862198, + 3.136970841370761, + 2.679880725689802, + 4.143687579387594, + 3.168622634363222, + 5.142703863442649, + 2.977549597798733, + 3.210043437463944, + 3.385961680761656, + ], + vec![ + 1.948290349481972, + 1.796569139726129, + 1.905232489093743, + 1.555759606416891, + 2.385563118734139, + 1.907039710137486, + 2.977549597798733, + 2.230209604622137, + 1.742552591231192, + 2.252632855204552, + ], + vec![ + 2.509358003244204, + 2.846699793116624, + 2.01726450417587, + 2.475715452431455, + 3.321157832605267, + 2.698561362072113, + 3.210043437463944, + 1.742552591231192, + 3.202516498869207, + 2.228297655595811, + ], + vec![ + 2.354788397327008, + 2.774282835105069, + 2.238391500871792, + 2.116394736527704, + 2.949560656237908, + 2.249353149769269, + 3.385961680761656, + 2.252632855204552, + 2.228297655595811, + 2.784914722669765, + ], + ]); let u = a.cholesky(UPLO::Upper); let l = a.cholesky(UPLO::Lower); - let scipy_u = py_matrix( - vec![ - vec![ 1.726900488003463, 1.551961537963327, 1.34226684706273 , 1.236125362766596, 1.752618841041957, 1.322289278213136, 2.158717687318329, 1.128200705840593, 1.453099365410088, 1.363592409455782], - vec![ 0. , 1.268984551541246, 0.203843359082252, 0.718958209858647, 0.65576415850829 , 0.321921568031328, 0.220631829192057, 0.035969734306862, 0.466156555210059, 0.518556243550586], - vec![ 0. , 0. , 0.442355231459957, 0.362642811042644, 0.113550376983589, 0.104958994115387, 0.439514016124092, 0.867072131324973, -0.063762143110917, 0.683573627458849], - vec![ 0. , 0. , 0. , 1.060662825095517, 0.108612163548495, 0.284560665177766, -0.289042488015237, -0.168890722850109, 0.346460971292225, -0.179029330692296], - vec![ 0. , 0. , 0. , 0. , 0.90054762326669 , 1.14736846650923 , 0.218847271328198, 0.33819073440549 , 0.486759471799237, 0.17930981650712 ], - vec![ 0. , 0. , 0. , 0. , 0. , 0.391212348671252, 0.072001696614059, -0.069844847295321, -0.059587640909243, 0.135011494209335], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0.32274897849312 , 0.109238423598569, -0.011482954266517, -0.226830086097441], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.211084069199511, 0.154785258348754, 0.218861000711332], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.696448259994717, -0.007136319580541], - vec![ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.086731850555121] - ] - ); + let scipy_u = py_matrix(vec![ + vec![ + 1.726900488003463, + 1.551961537963327, + 1.34226684706273, + 1.236125362766596, + 1.752618841041957, + 1.322289278213136, + 2.158717687318329, + 1.128200705840593, + 1.453099365410088, + 1.363592409455782, + ], + vec![ + 0., + 1.268984551541246, + 0.203843359082252, + 0.718958209858647, + 0.65576415850829, + 0.321921568031328, + 0.220631829192057, + 0.035969734306862, + 0.466156555210059, + 0.518556243550586, + ], + vec![ + 0., + 0., + 0.442355231459957, + 0.362642811042644, + 0.113550376983589, + 0.104958994115387, + 0.439514016124092, + 0.867072131324973, + -0.063762143110917, + 0.683573627458849, + ], + vec![ + 0., + 0., + 0., + 1.060662825095517, + 0.108612163548495, + 0.284560665177766, + -0.289042488015237, + -0.168890722850109, + 0.346460971292225, + -0.179029330692296, + ], + vec![ + 0., + 0., + 0., + 0., + 0.90054762326669, + 1.14736846650923, + 0.218847271328198, + 0.33819073440549, + 0.486759471799237, + 0.17930981650712, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0.391212348671252, + 0.072001696614059, + -0.069844847295321, + -0.059587640909243, + 0.135011494209335, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0.32274897849312, + 0.109238423598569, + -0.011482954266517, + -0.226830086097441, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0.211084069199511, + 0.154785258348754, + 0.218861000711332, + ], + vec![ + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0.696448259994717, + -0.007136319580541, + ], + vec![0., 0., 0., 0., 0., 0., 0., 0., 0., 0.086731850555121], + ]); - let scipy_l = py_matrix( - vec![ - vec![ 1.726900488003463, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.551961537963327, 1.268984551541246, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.34226684706273 , 0.203843359082252, 0.442355231459957, 0. , 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.236125362766596, 0.718958209858647, 0.362642811042644, 1.060662825095517, 0. , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.752618841041957, 0.65576415850829 , 0.113550376983589, 0.108612163548495, 0.90054762326669 , 0. , 0. , 0. , 0. , 0. ], - vec![ 1.322289278213136, 0.321921568031328, 0.104958994115387, 0.284560665177766, 1.14736846650923 , 0.391212348671252, 0. , 0. , 0. , 0. ], - vec![ 2.158717687318329, 0.220631829192057, 0.439514016124092, -0.289042488015237, 0.218847271328198, 0.072001696614058, 0.32274897849312 , 0. , 0. , 0. ], - vec![ 1.128200705840593, 0.035969734306862, 0.867072131324973, -0.168890722850108, 0.33819073440549 , -0.069844847295322, 0.109238423598569, 0.211084069199512, 0. , 0. ], - vec![ 1.453099365410088, 0.466156555210059, -0.063762143110917, 0.346460971292225, 0.486759471799238, -0.059587640909244, -0.011482954266516, 0.154785258348753, 0.696448259994717, 0. ], - vec![ 1.363592409455782, 0.518556243550586, 0.683573627458849, -0.179029330692296, 0.17930981650712 , 0.135011494209336, -0.226830086097441, 0.218861000711332, -0.00713631958054 , 0.086731850555118] - ] - ); + let scipy_l = py_matrix(vec![ + vec![1.726900488003463, 0., 0., 0., 0., 0., 0., 0., 0., 0.], + vec![ + 1.551961537963327, + 1.268984551541246, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.34226684706273, + 0.203843359082252, + 0.442355231459957, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.236125362766596, + 0.718958209858647, + 0.362642811042644, + 1.060662825095517, + 0., + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.752618841041957, + 0.65576415850829, + 0.113550376983589, + 0.108612163548495, + 0.90054762326669, + 0., + 0., + 0., + 0., + 0., + ], + vec![ + 1.322289278213136, + 0.321921568031328, + 0.104958994115387, + 0.284560665177766, + 1.14736846650923, + 0.391212348671252, + 0., + 0., + 0., + 0., + ], + vec![ + 2.158717687318329, + 0.220631829192057, + 0.439514016124092, + -0.289042488015237, + 0.218847271328198, + 0.072001696614058, + 0.32274897849312, + 0., + 0., + 0., + ], + vec![ + 1.128200705840593, + 0.035969734306862, + 0.867072131324973, + -0.168890722850108, + 0.33819073440549, + -0.069844847295322, + 0.109238423598569, + 0.211084069199512, + 0., + 0., + ], + vec![ + 1.453099365410088, + 0.466156555210059, + -0.063762143110917, + 0.346460971292225, + 0.486759471799238, + -0.059587640909244, + -0.011482954266516, + 0.154785258348753, + 0.696448259994717, + 0., + ], + vec![ + 1.363592409455782, + 0.518556243550586, + 0.683573627458849, + -0.179029330692296, + 0.17930981650712, + 0.135011494209336, + -0.226830086097441, + 0.218861000711332, + -0.00713631958054, + 0.086731850555118, + ], + ]); assert_eq!(u, scipy_u); assert_eq!(l, scipy_l); @@ -139,4 +743,4 @@ pub fn test_cholesky_panic_2() { // Not Positive Definite let a = ml_matrix("1 2;2 1"); a.cholesky(UPLO::Upper).print(); -} \ No newline at end of file +} diff --git a/tests/o3/mod.rs b/tests/o3/mod.rs index 8d7696fe..49a9389b 100644 --- a/tests/o3/mod.rs +++ b/tests/o3/mod.rs @@ -1,4 +1,3 @@ //! BLAS tests pub mod lapack; - diff --git a/tests/optimize.rs b/tests/optimize.rs index b7a257e4..951ecd89 100644 --- a/tests/optimize.rs +++ b/tests/optimize.rs @@ -43,10 +43,10 @@ fn test_GD() { } fn f(x: &Vec, p: Vec) -> Option> { - Some ( + Some( x.iter() .map(|t| AD1(*t, 0f64)) .map(|t| p[0] * t.powi(2) + p[1] * t + p[2]) - .collect() + .collect(), ) -} \ No newline at end of file +} diff --git a/tests/ordered_stat_test.rs b/tests/ordered_stat_test.rs index 54001e2b..051e1a44 100644 --- a/tests/ordered_stat_test.rs +++ b/tests/ordered_stat_test.rs @@ -74,6 +74,6 @@ fn quantile_length_test() { let data = vec![0f64; 7592]; let q1 = quantile(&data, QType::Type1); let q2 = quantile(&data, QType::Type2); - + assert!(q1.iter().zip(q2.iter()).all(|(x, y)| *x == *y)); } diff --git a/tests/polynomial.rs b/tests/polynomial.rs index 121183b9..f8a589a1 100644 --- a/tests/polynomial.rs +++ b/tests/polynomial.rs @@ -20,4 +20,4 @@ fn test_translate_x() { for i in -10..10 { assert_eq!(a.eval(i), b.eval(i - 6)); } -} \ No newline at end of file +} diff --git a/tests/root.rs b/tests/root.rs index b0d8128f..8584efdd 100644 --- a/tests/root.rs +++ b/tests/root.rs @@ -1,12 +1,21 @@ -use peroxide::fuga::*; use anyhow::Result; +use peroxide::fuga::*; #[test] fn test_cubic_root() -> Result<()> { let problem = Cubic; - let bisect = BisectionMethod { max_iter: 100, tol: 1e-6 }; - let newton = NewtonMethod { max_iter: 100, tol: 1e-6 }; - let false_pos = FalsePositionMethod { max_iter: 100, tol: 1e-6 }; + let bisect = BisectionMethod { + max_iter: 100, + tol: 1e-6, + }; + let newton = NewtonMethod { + max_iter: 100, + tol: 1e-6, + }; + let false_pos = FalsePositionMethod { + max_iter: 100, + tol: 1e-6, + }; let root_bisect = bisect.find(&problem)?; let root_newton = newton.find(&problem)?; let root_false_pos = false_pos.find(&problem)?; @@ -54,9 +63,18 @@ impl RootFindingProblem<1, 1, f64> for Cubic { #[test] fn test_sine_root() -> Result<()> { let problem = Sine; - let bisect = BisectionMethod { max_iter: 100, tol: 1e-6 }; - let newton = NewtonMethod { max_iter: 100, tol: 1e-6 }; - let false_pos = FalsePositionMethod { max_iter: 100, tol: 1e-6 }; + let bisect = BisectionMethod { + max_iter: 100, + tol: 1e-6, + }; + let newton = NewtonMethod { + max_iter: 100, + tol: 1e-6, + }; + let false_pos = FalsePositionMethod { + max_iter: 100, + tol: 1e-6, + }; let root_bisect = bisect.find(&problem)?; let root_newton = newton.find(&problem)?; let root_false_pos = false_pos.find(&problem)?; @@ -104,7 +122,10 @@ impl RootFindingProblem<1, 1, f64> for Sine { #[test] fn test_cosine_root() -> Result<()> { let problem = Cosine; - let newton = NewtonMethod { max_iter: 100, tol: 1e-6 }; + let newton = NewtonMethod { + max_iter: 100, + tol: 1e-6, + }; let root_newton = match newton.find(&problem) { Ok(x) => x, Err(e) => { diff --git a/tests/series.rs b/tests/series.rs index 9573c07e..1ac71403 100644 --- a/tests/series.rs +++ b/tests/series.rs @@ -5,14 +5,14 @@ use peroxide::fuga::*; #[test] fn series_map_test() { // Int - let a: Vec = vec![1,2,3,4,5]; + let a: Vec = vec![1, 2, 3, 4, 5]; let b: Vec = a.iter().map(|x| 2 * *x + 1).collect(); let s_a = Series::new(a); let s_b = Series::new(b); assert_eq!(s_b, s_a.map(|t: i32| 2 * t + 1)); // F64 - let a: Vec = vec![1.0,2.0,3.0,4.0,5.0]; + let a: Vec = vec![1.0, 2.0, 3.0, 4.0, 5.0]; let b: Vec = a.iter().map(|x| 2f64 * *x + 1f64).collect(); let s_a = Series::new(a); let s_b = Series::new(b); @@ -22,13 +22,13 @@ fn series_map_test() { #[test] fn series_fold_test() { // Int - let a: Vec = vec![1,2,3,4,5]; + let a: Vec = vec![1, 2, 3, 4, 5]; let b = a.iter().fold(0, |x, y| x + *y); let s_a = Series::new(a); assert_eq!(b, s_a.fold(0i32, |x, y| x + y)); // F64 - let a: Vec = c!(1,2,3,4,5); + let a: Vec = c!(1, 2, 3, 4, 5); let b = a.iter().fold(0f64, |x, y| x + *y); let s_a = Series::new(a); assert_eq!(b, s_a.fold(0f64, |x, y| x + y)); @@ -37,15 +37,19 @@ fn series_fold_test() { #[test] fn series_filter_test() { // Int - let a: Vec = vec![1,2,3,4,5]; + let a: Vec = vec![1, 2, 3, 4, 5]; let b: Vec = a.clone().into_iter().filter(|x| *x % 2 == 0).collect(); let s_a = Series::new(a); let s_b = Series::new(b); assert_eq!(s_b, s_a.filter(|x: &i32| *x % 2 == 0)); // F64 - let a: Vec = c!(1,2,3,4,5); - let b: Vec = a.clone().into_iter().filter(|x| *x % 2f64 == 0f64).collect(); + let a: Vec = c!(1, 2, 3, 4, 5); + let b: Vec = a + .clone() + .into_iter() + .filter(|x| *x % 2f64 == 0f64) + .collect(); let s_a = Series::new(a); let s_b = Series::new(b); assert_eq!(s_b, s_a.filter(|x: &f64| *x % 2f64 == 0f64)); @@ -54,9 +58,9 @@ fn series_filter_test() { #[test] fn series_zip_with_test() { // Int - let a: Vec = vec![1,2,3,4,5]; - let b: Vec = vec![5,4,3,2,1]; - let c: Vec = a.iter().zip(b.iter()).map(|(x,y)| x + y).collect(); + let a: Vec = vec![1, 2, 3, 4, 5]; + let b: Vec = vec![5, 4, 3, 2, 1]; + let c: Vec = a.iter().zip(b.iter()).map(|(x, y)| x + y).collect(); let s_a = Series::new(a); let s_b = Series::new(b); let s_c = Series::new(c); diff --git a/tests/special.rs b/tests/special.rs index 3954b4bf..acec5c6c 100644 --- a/tests/special.rs +++ b/tests/special.rs @@ -1,4 +1,4 @@ -use peroxide::fuga::{*, LambertWAccuracyMode::*}; +use peroxide::fuga::{LambertWAccuracyMode::*, *}; #[test] fn lambert_w_test() { diff --git a/tests/stat.rs b/tests/stat.rs index ebad29b7..73c37275 100644 --- a/tests/stat.rs +++ b/tests/stat.rs @@ -4,27 +4,27 @@ use peroxide::fuga::*; #[test] fn test_mean() { let a: Vec = vec![1.0, 2.0, 3.0, 4.0, 5.0]; - assert_eq!(a.mean() ,3.0); + assert_eq!(a.mean(), 3.0); } #[test] fn test_mean_stable() { let a: Vec = vec![1.0; 10000000]; let diff = 10000.0; - let b = a.iter().map(|x| x+diff).collect::>(); - assert_eq!(a.mean(), b.mean()-diff); + let b = a.iter().map(|x| x + diff).collect::>(); + assert_eq!(a.mean(), b.mean() - diff); } #[test] fn test_variance() { - let a = vec![1.0,2.0,3.0,4.0,5.0]; + let a = vec![1.0, 2.0, 3.0, 4.0, 5.0]; assert_eq!(a.var(), 2.5); } #[test] fn test_variance_stable() { - let a = vec![1.0,2.0,3.0,4.0,5.0]; + let a = vec![1.0, 2.0, 3.0, 4.0, 5.0]; let diff = 1000000000.0; - let b = a.iter().map(|x| x+diff).collect::>(); + let b = a.iter().map(|x| x + diff).collect::>(); assert_eq!(a.var(), b.var()); } diff --git a/tests/weighted_uniform.rs b/tests/weighted_uniform.rs index b5f8c176..e7204995 100644 --- a/tests/weighted_uniform.rs +++ b/tests/weighted_uniform.rs @@ -31,6 +31,6 @@ fn f(x: f64) -> f64 { if x.abs() < 1f64 { 1f64 - x.abs() } else { - 0f64 + 0f64 } }