From 0b36c53c19bb8f767245601edb851520d02f7465 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 08:40:06 +0900 Subject: [PATCH 1/8] FIX: Fix errata in pdf & cdf of WeightedUniform --- src/statistics/dist.rs | 46 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/statistics/dist.rs b/src/statistics/dist.rs index c79fee04..94106866 100644 --- a/src/statistics/dist.rs +++ b/src/statistics/dist.rs @@ -126,6 +126,20 @@ //! //! ### Binomial Distribution //! +//! ### Student's t Distribution +//! +//! ### Weighted Uniform Distribution +//! +//! * Definition +//! $$\text{WUnif}(x | \{w_i\}, \{I_i\}) = \frac{1}{\sum_{j=1}^n w_j \mu(I_i)} \sum_{i=1}^n w_i +//! \mathbb{1}_{I_i}(x)$$ +//! * $\{w_i\}$: Weights +//! * $\{I_i\}$: Intervals +//! * $\mu(I_i)$: Measure of $I_i$ +//! * $\mathbb{1}_{I_i}(x)$: Indicator function +//! +//! * Reference +//! * [Piecewise Rejection Sampling](https://axect.github.io/posts/006_prs/#22-weighted-uniform-distribution) extern crate rand; extern crate rand_distr; @@ -208,7 +222,9 @@ impl WeightedUniform { } } - let sum = weights.iter().sum(); + let sum = weights.iter() + .zip(intervals.iter()) + .fold(0f64, |acc, (w, (a, b))| acc + w * (b - a)); WeightedUniform { weights, @@ -272,7 +288,9 @@ impl WeightedUniform { ) .collect(); - let sum = weights.iter().sum(); + let sum = weights.iter() + .zip(intervals.iter()) + .fold(0f64, |acc, (w, (x, y))| acc + w * (y - x)); WeightedUniform { weights, @@ -304,12 +322,17 @@ impl WeightedUniform { pub fn update_weights(&mut self, weights: Vec) { assert_eq!(self.intervals.len(), weights.len()); self.weights = weights; - self.sum = self.weights.iter().sum(); + self.sum = self.weights.iter() + .zip(self.intervals.iter()) + .fold(0f64, |acc, (w, (a, b))| acc + w * (b - a)); } pub fn update_intervals(&mut self, intervals: Vec) { assert_eq!(self.weights.len()+1, intervals.len()); self.intervals = auto_zip(&intervals); + self.sum = self.weights.iter() + .zip(self.intervals.iter()) + .fold(0f64, |acc, (w, (a, b))| acc + w * (b - a)); } pub fn weight_at(&self, x: f64) -> f64 { @@ -665,14 +688,27 @@ impl RNG for WeightedUniform { fn pdf>(&self, x: S) -> f64 { let x: f64 = x.into(); + if x < self.intervals[0].0 || x > self.intervals[self.intervals.len() - 1].1 { + return 0f64; + } let idx = find_interval(self.intervals(), x); + let (a, b) = self.intervals[idx]; self.weights[idx] / self.sum } fn cdf>(&self, x: S) -> f64 { let x: f64 = x.into(); + if x < self.intervals[0].0 { + return 0f64; + } else if x > self.intervals[self.intervals.len() - 1].1 { + return 1f64; + } let idx = find_interval(self.intervals(), x); - self.weights[0 ..=idx].iter().sum::() / self.sum + self.weights[0 ..=idx].iter() + .zip(self.intervals[0 ..=idx].iter()) + .fold(0f64, |acc, (w, (a, b))| { + acc + w * (b - a) + }) / self.sum } } @@ -791,4 +827,4 @@ impl Statistics for WeightedUniform { fn cor(&self) -> Self::Array { vec![1f64] } -} \ No newline at end of file +} From 7eef46ffd979273b7f96ff5277b55c32d61919fb Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 08:56:31 +0900 Subject: [PATCH 2/8] FIX: Fix warnings in docs --- src/ml/reg.rs | 2 +- src/numerical/ode.rs | 2 +- src/numerical/utils.rs | 2 +- src/statistics/dist.rs | 8 ++++---- src/structure/matrix.rs | 10 +++++----- src/structure/vector.rs | 20 ++++++++++---------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/ml/reg.rs b/src/ml/reg.rs index 1184866e..f7ecf906 100644 --- a/src/ml/reg.rs +++ b/src/ml/reg.rs @@ -4,7 +4,7 @@ use crate::structure::polynomial::Polynomial; /// /// # Type /// -/// (Vec, Vec) -> Polynomial +/// `(Vec, Vec) -> Polynomial` /// /// # Examples /// ``` diff --git a/src/numerical/ode.rs b/src/numerical/ode.rs index c6b31efe..e1b2d463 100644 --- a/src/numerical/ode.rs +++ b/src/numerical/ode.rs @@ -49,7 +49,7 @@ //! * `ImMethod` : Implicit method //! * `BDF` : Backward Euler 1st order (To be fixed) //! * `GL4` : Gauss Legendre 4th order -//! * `Environment` : External environment (CubicSpline, Vec, Matrix or Another external table) +//! * `Environment` : External environment (`CubicSpline`, `Vec`, `Matrix` or Another external table) //! //! //! ### `State` structure diff --git a/src/numerical/utils.rs b/src/numerical/utils.rs index c8bc3379..158aafea 100644 --- a/src/numerical/utils.rs +++ b/src/numerical/utils.rs @@ -9,7 +9,7 @@ use crate::util::non_macro::{cat, zeros}; /// : Exact jacobian matrix using Automatic Differenitation /// /// # Type -/// (Vector, F) -> Matrix where F: Fn(&Vec) -> Vec +/// `(F, &Vec) -> Matrix where F: Fn(&Vec) -> Vec` /// /// # Examples /// ``` diff --git a/src/statistics/dist.rs b/src/statistics/dist.rs index 94106866..e1971fb6 100644 --- a/src/statistics/dist.rs +++ b/src/statistics/dist.rs @@ -70,7 +70,7 @@ //! ### Uniform Distribution //! //! * Definition -//! $$\text{Unif}(x | a, b) = \begin{cases} \frac{1}{b - a} & x \in [a,b]\\\ 0 & \text{otherwise} \end{cases}$$ +//! $$\text{Unif}(x | a, b) = \begin{cases} \frac{1}{b - a} & x \in \[a,b\]\\\ 0 & \text{otherwise} \end{cases}$$ //! * Representative value //! * Mean: $\frac{a + b}{2}$ //! * Var : $\frac{1}{12}(b-a)^2$ @@ -131,10 +131,10 @@ //! ### Weighted Uniform Distribution //! //! * Definition -//! $$\text{WUnif}(x | \{w_i\}, \{I_i\}) = \frac{1}{\sum_{j=1}^n w_j \mu(I_i)} \sum_{i=1}^n w_i +//! $$\text{WUnif}(x | \mathbf{W}, \mathcal{I}) = \frac{1}{\sum_{j=1}^n w_j \mu(I_j)} \sum_{i=1}^n w_i //! \mathbb{1}_{I_i}(x)$$ -//! * $\{w_i\}$: Weights -//! * $\{I_i\}$: Intervals +//! * $\mathbf{W} = (w_i)$: Weights +//! * $\mathcal{I} = \\{I_i\\}$: Intervals //! * $\mu(I_i)$: Measure of $I_i$ //! * $\mathbb{1}_{I_i}(x)$: Indicator function //! diff --git a/src/structure/matrix.rs b/src/structure/matrix.rs index 2bf51a4b..d5919b75 100644 --- a/src/structure/matrix.rs +++ b/src/structure/matrix.rs @@ -321,7 +321,7 @@ //! } //! ``` //! -//! ## Conversion to Vec +//! ## Conversion to `Vec` //! //! * Just use `row` or `col` method (I already showed at Basic method section). //! @@ -1718,21 +1718,21 @@ impl MatrixProduct for Matrix { // ============================================================================= // Common Properties of Matrix & Vec // ============================================================================= -/// Matrix to Vec +/// `Matrix` to `Vec` impl Into> for Matrix { fn into(self) -> Vec { self.data } } -/// &Matrix to &Vec +/// `&Matrix` to `&Vec` impl<'a> Into<&'a Vec> for &'a Matrix { fn into(self) -> &'a Vec { &self.data } } -/// Vec to Matrix +/// `Vec` to `Matrix` impl Into for Vec { fn into(self) -> Matrix { let l = self.len(); @@ -2374,7 +2374,7 @@ impl<'a, 'b> Mul<&'b Vec> for &'a Matrix { } } -/// Matrix multiplication for Vec vs Matrix +/// Matrix multiplication for `Vec` vs `Matrix` /// /// # Examples /// ``` diff --git a/src/structure/vector.rs b/src/structure/vector.rs index be6240d1..b0f0092b 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -39,7 +39,7 @@ //! } //! ``` //! -//! ## From ranges to Vec +//! ## From ranges to `Vec` //! //! * For `R`, there is `seq` to declare sequence. //! @@ -63,7 +63,7 @@ //! } //! ``` //! -//! ## Vec Operation +//! ## `Vec` Operation //! //! There are two ways to do vector operations. //! @@ -113,9 +113,9 @@ //! //! ## Conversion to Matrix //! -//! There are two ways to convert Vec to matrix. +//! There are two ways to convert `Vec` to `Matrix`. //! -//! * `into(self) -> Matrix` : Vec to column matrix +//! * `into(self) -> Matrix` : `Vec` to column matrix //! //! ```rust //! #[macro_use] @@ -135,7 +135,7 @@ //! //! # Functional Programming {#functional} //! -//! ## FP for Vec +//! ## FP for `Vec` //! //! * There are some functional programming tools for `Vec` //! @@ -282,7 +282,7 @@ use std::convert; impl FPVector for Vec { type Scalar = f64; - /// fmap for Vec + /// fmap for `Vec` /// /// # Examples /// ``` @@ -304,7 +304,7 @@ impl FPVector for Vec { v } - /// reduce for Vec + /// reduce for `Vec` /// /// # Examples /// ``` @@ -335,7 +335,7 @@ impl FPVector for Vec { .collect::>() } - /// Filter for Vec + /// Filter for `Vec` /// /// # Examples /// ``` @@ -359,7 +359,7 @@ impl FPVector for Vec { .collect::>() } - /// Take for Vec + /// Take for `Vec` /// /// # Examples /// ``` @@ -381,7 +381,7 @@ impl FPVector for Vec { return v; } - /// Skip for Vec + /// Skip for `Vec` /// /// # Examples /// ``` From b3d4cbce18e002eabfa43df227cffd4d241f4741 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 09:14:03 +0900 Subject: [PATCH 3/8] IMPL: Add more Vec algorithms * arg_min * max * min --- src/structure/vector.rs | 89 ++++++++++++++++++++++++++++++++++++++++- src/traits/general.rs | 3 ++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/structure/vector.rs b/src/structure/vector.rs index b0f0092b..25c57a1d 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -265,7 +265,7 @@ #[cfg(feature = "O3")] extern crate blas; #[cfg(feature = "O3")] -use blas::{daxpy, ddot, dnrm2, idamax}; +use blas::{daxpy, ddot, dnrm2, idamax, idamin}; use crate::structure::matrix::{matrix, Matrix, Row}; use crate::traits::{ @@ -583,6 +583,93 @@ impl Algorithm for Vec { } } + /// arg min + /// + /// # Examples + /// ``` + /// #[macro_use] + /// extern crate peroxide; + /// use peroxide::fuga::*; + /// + /// fn main() { + /// let v = c!(1,3,2,4,3,7); + /// assert_eq!(v.arg_min(),0); + /// + /// let v2 = c!(4,3,2,5,1,6); + /// assert_eq!(v2.arg_min(),4); + /// } + fn arg_min(&self) -> usize { + match () { + #[cfg(feature = "O3")] + () => { + let n_i32 = self.len() as i32; + let idx: usize; + unsafe { + idx = idamin(n_i32, self, 1) - 1; + } + idx + } + _ => { + self.into_iter() + .enumerate() + .fold((0usize, std::f64::MAX), |acc, (ics, &val)| { + if acc.1 > val { + (ics, val) + } else { + acc + } + }) + .0 + } + } + } + + fn max(&self) -> f64 { + match () { + #[cfg(feature = "O3")] + () => { + let n_i32 = self.len() as i32; + let idx: usize; + unsafe { + idx = idamax(n_i32, self, 1) - 1; + } + self[idx] + } + _ => { + self.into_iter().fold(std::f64::MIN, |acc, &val| { + if acc < val { + val + } else { + acc + } + }) + } + } + } + + fn min(&self) -> f64 { + match () { + #[cfg(feature = "O3")] + () => { + let n_i32 = self.len() as i32; + let idx: usize; + unsafe { + idx = idamin(n_i32, self, 1) - 1; + } + self[idx] + } + _ => { + self.into_iter().fold(std::f64::MAX, |acc, &val| { + if acc > val { + val + } else { + acc + } + }) + } + } + } + fn swap_with_perm(&mut self, p: &Vec<(usize, usize)>) { for (i, j) in p.iter() { self.swap(*i, *j); diff --git a/src/traits/general.rs b/src/traits/general.rs index 66bf4168..2737f97b 100644 --- a/src/traits/general.rs +++ b/src/traits/general.rs @@ -3,5 +3,8 @@ pub trait Algorithm { fn rank(&self) -> Vec; fn sign(&self) -> f64; fn arg_max(&self) -> usize; + fn arg_min(&self) -> usize; + fn max(&self) -> f64; + fn min(&self) -> f64; fn swap_with_perm(&mut self, p: &Vec<(usize, usize)>); } From df7cb4dde1a5722b540586b1756ca0f8eeb428f8 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 09:43:28 +0900 Subject: [PATCH 4/8] FIX: Fix mean & variance for WeightedUniform (#55) --- src/statistics/dist.rs | 4 ++-- tests/weighted_uniform.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/statistics/dist.rs b/src/statistics/dist.rs index e1971fb6..b563869c 100644 --- a/src/statistics/dist.rs +++ b/src/statistics/dist.rs @@ -805,14 +805,14 @@ impl Statistics for WeightedUniform { fn mean(&self) -> Self::Value { self.intervals().iter().zip(self.weights().iter()) - .map(|((l, r), w)| (l+r)/2f64 * w) + .map(|((l, r), w)| (r.powi(2)-l.powi(2))/2f64 * w) .sum::() / self.sum } fn var(&self) -> Self::Value { let mean = self.mean(); self.intervals().iter().zip(self.weights().iter()) - .map(|((l, r), w)| w * (l*l + l*r + r*r) / 3f64) + .map(|((l, r), w)| w * (r.powi(3) - l.powi(3)) / 3f64) .sum::() / self.sum - mean * mean } diff --git a/tests/weighted_uniform.rs b/tests/weighted_uniform.rs index 5358a15c..06b547d8 100644 --- a/tests/weighted_uniform.rs +++ b/tests/weighted_uniform.rs @@ -3,11 +3,11 @@ use peroxide::fuga::*; #[test] fn test_stats() { - let intervals = vec![0f64, 1f64, 3f64]; - let weights = vec![1f64, 2f64]; + let intervals = vec![0f64, 3f64, 6f64]; + let weights = vec![2f64, 1f64]; let unif = WeightedUniform::new(weights, intervals); - assert_eq!(unif.mean(), 1.5); - assert_eq!(unif.var(), 0.75); + assert_eq!(unif.mean(), 2.5); + assert_eq!(unif.var(), 2.75); } #[test] @@ -32,4 +32,4 @@ fn f(x: f64) -> f64 { } else { 0f64 } -} \ No newline at end of file +} From 510ff2697be0050e77fdcd5bb4497c4c1fa3e99f Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 10:24:51 +0900 Subject: [PATCH 5/8] FIX: Remove unnecessary blas implementation --- src/structure/vector.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/structure/vector.rs b/src/structure/vector.rs index 25c57a1d..a297e8cf 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -265,7 +265,7 @@ #[cfg(feature = "O3")] extern crate blas; #[cfg(feature = "O3")] -use blas::{daxpy, ddot, dnrm2, idamax, idamin}; +use blas::{daxpy, ddot, dnrm2, idamax}; use crate::structure::matrix::{matrix, Matrix, Row}; use crate::traits::{ @@ -600,15 +600,6 @@ impl Algorithm for Vec { /// } fn arg_min(&self) -> usize { match () { - #[cfg(feature = "O3")] - () => { - let n_i32 = self.len() as i32; - let idx: usize; - unsafe { - idx = idamin(n_i32, self, 1) - 1; - } - idx - } _ => { self.into_iter() .enumerate() @@ -649,15 +640,6 @@ impl Algorithm for Vec { fn min(&self) -> f64 { match () { - #[cfg(feature = "O3")] - () => { - let n_i32 = self.len() as i32; - let idx: usize; - unsafe { - idx = idamin(n_i32, self, 1) - 1; - } - self[idx] - } _ => { self.into_iter().fold(std::f64::MAX, |acc, &val| { if acc > val { From 226fd28d1f9f6958485fcf66b6371ce43c951fa6 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 10:31:26 +0900 Subject: [PATCH 6/8] UPD: Update PyO3 dependency --- Cargo.toml | 2 +- src/util/plot.rs | 195 +++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 99 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 78c0f2f5..fd218efc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ matrixmultiply = { version = "0.3", features = ["threading"] } peroxide-ad = "0.3" #num-complex = "0.3" netcdf = { version = "0.7", optional = true, default_features = false } -pyo3 = { version = "0.18", optional = true } +pyo3 = { version = "0.19", optional = true } blas = { version = "0.22", optional = true } lapack = { version = "0.19", optional = true } serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/src/util/plot.rs b/src/util/plot.rs index c3c97bb6..8ea4f7f1 100644 --- a/src/util/plot.rs +++ b/src/util/plot.rs @@ -309,114 +309,113 @@ impl Plot for Plot2D { } // Plot - let gil = Python::acquire_gil(); - let py = gil.python(); - - // Input data - let x = self.domain.clone(); - let ys = self.images.clone(); - let pairs = self.pairs.clone(); - let y_length = ys.len(); - let pair_length = pairs.len(); - let title = self.title.clone(); - let fig_size = self.fig_size; - let dpi = self.dpi; - let grid = match self.grid { - On => true, - Off => false, - }; - let xlabel = self.xlabel.clone(); - let ylabel = self.ylabel.clone(); - let legends = self.legends.clone(); - let path = self.path.clone(); - - // Global variables to plot - let globals = vec![("plt", py.import("matplotlib.pyplot")?)].into_py_dict(py); - globals.set_item("x", x)?; - globals.set_item("y", ys)?; - globals.set_item("pair", pairs)?; - globals.set_item("n", y_length)?; - globals.set_item("p", pair_length)?; - globals.set_item("fs", fig_size)?; - globals.set_item("dp", dpi)?; - globals.set_item("gr", grid)?; - globals.set_item("pa", path)?; - - // Plot Code - let mut plot_string = format!( - "\ - plt.rc(\"text\", usetex=True)\n\ - plt.rc(\"font\", family=\"serif\")\n\ - plt.figure(figsize=fs, dpi=dp)\n\ - plt.title(r\"{}\", fontsize=16)\n\ - plt.xlabel(r\"{}\", fontsize=14)\n\ - plt.ylabel(r\"{}\", fontsize=14)\n\ - if gr:\n\ - \tplt.grid()\n", - title, xlabel, ylabel - ); - - if self.markers.len() == 0 { - for i in 0..y_length { - plot_string - .push_str(&format!("plt.plot(x,y[{}],label=r\"{}\")\n", i, legends[i])[..]) - } - for i in 0..pair_length { - plot_string.push_str( - &format!( - "plt.plot(pair[{}][0],pair[{}][1],label=r\"{}\")\n", - i, - i, - legends[i + y_length] - )[..], - ) - } - } else { - for i in 0..y_length { - match self.markers[i] { - Line => plot_string - .push_str(&format!("plt.plot(x,y[{}],label=r\"{}\")\n", i, legends[i])[..]), - Point => plot_string.push_str( - &format!("plt.plot(x,y[{}],\".\",label=r\"{}\")\n", i, legends[i])[..], - ), - Circle => plot_string.push_str( - &format!("plt.plot(x,y[{}],\"o\",label=r\"{}\")\n", i, legends[i])[..], - ), + Python::with_gil(|py| { + // Input data + let x = self.domain.clone(); + let ys = self.images.clone(); + let pairs = self.pairs.clone(); + let y_length = ys.len(); + let pair_length = pairs.len(); + let title = self.title.clone(); + let fig_size = self.fig_size; + let dpi = self.dpi; + let grid = match self.grid { + On => true, + Off => false, + }; + let xlabel = self.xlabel.clone(); + let ylabel = self.ylabel.clone(); + let legends = self.legends.clone(); + let path = self.path.clone(); + + // Global variables to plot + let globals = vec![("plt", py.import("matplotlib.pyplot")?)].into_py_dict(py); + globals.set_item("x", x)?; + globals.set_item("y", ys)?; + globals.set_item("pair", pairs)?; + globals.set_item("n", y_length)?; + globals.set_item("p", pair_length)?; + globals.set_item("fs", fig_size)?; + globals.set_item("dp", dpi)?; + globals.set_item("gr", grid)?; + globals.set_item("pa", path)?; + + // Plot Code + let mut plot_string = format!( + "\ + plt.rc(\"text\", usetex=True)\n\ + plt.rc(\"font\", family=\"serif\")\n\ + plt.figure(figsize=fs, dpi=dp)\n\ + plt.title(r\"{}\", fontsize=16)\n\ + plt.xlabel(r\"{}\", fontsize=14)\n\ + plt.ylabel(r\"{}\", fontsize=14)\n\ + if gr:\n\ + \tplt.grid()\n", + title, xlabel, ylabel + ); + + if self.markers.len() == 0 { + for i in 0..y_length { + plot_string + .push_str(&format!("plt.plot(x,y[{}],label=r\"{}\")\n", i, legends[i])[..]) } - } - for i in 0..pair_length { - match self.markers[i + y_length] { - Line => plot_string.push_str( + for i in 0..pair_length { + plot_string.push_str( &format!( "plt.plot(pair[{}][0],pair[{}][1],label=r\"{}\")\n", i, i, legends[i + y_length] )[..], - ), - Point => plot_string.push_str( - &format!( - "plt.plot(pair[{}][0],pair[{}][1],\".\",label=r\"{}\")\n", - i, - i, - legends[i + y_length] - )[..], - ), - Circle => plot_string.push_str( - &format!( - "plt.plot(pair[{}][0],pair[{}][1],\"o\",label=r\"{}\")\n", - i, - i, - legends[i + y_length] - )[..], - ), + ) + } + } else { + for i in 0..y_length { + match self.markers[i] { + Line => plot_string + .push_str(&format!("plt.plot(x,y[{}],label=r\"{}\")\n", i, legends[i])[..]), + Point => plot_string.push_str( + &format!("plt.plot(x,y[{}],\".\",label=r\"{}\")\n", i, legends[i])[..], + ), + Circle => plot_string.push_str( + &format!("plt.plot(x,y[{}],\"o\",label=r\"{}\")\n", i, legends[i])[..], + ), + } + } + for i in 0..pair_length { + match self.markers[i + y_length] { + Line => plot_string.push_str( + &format!( + "plt.plot(pair[{}][0],pair[{}][1],label=r\"{}\")\n", + i, + i, + legends[i + y_length] + )[..], + ), + Point => plot_string.push_str( + &format!( + "plt.plot(pair[{}][0],pair[{}][1],\".\",label=r\"{}\")\n", + i, + i, + legends[i + y_length] + )[..], + ), + Circle => plot_string.push_str( + &format!( + "plt.plot(pair[{}][0],pair[{}][1],\"o\",label=r\"{}\")\n", + i, + i, + legends[i + y_length] + )[..], + ), + } } } - } - plot_string.push_str("plt.legend(fontsize=12)\nplt.savefig(pa)"); + plot_string.push_str("plt.legend(fontsize=12)\nplt.savefig(pa)"); - py.run(&plot_string[..], Some(&globals), None)?; - Ok(()) + py.run(&plot_string[..], Some(&globals), None)?; + Ok(()) + }) } } From 6075312d7002656af80564d9711906a3fac67f66 Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 10:41:38 +0900 Subject: [PATCH 7/8] FIX: Remove unnecessary code in WeightedUniform --- src/statistics/dist.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/statistics/dist.rs b/src/statistics/dist.rs index b563869c..fd533405 100644 --- a/src/statistics/dist.rs +++ b/src/statistics/dist.rs @@ -692,7 +692,6 @@ impl RNG for WeightedUniform { return 0f64; } let idx = find_interval(self.intervals(), x); - let (a, b) = self.intervals[idx]; self.weights[idx] / self.sum } From 40c410c23aa9bc62445e9e0c30eb2fca910b0c5a Mon Sep 17 00:00:00 2001 From: Tae Geun Kim Date: Thu, 3 Aug 2023 22:54:55 +0900 Subject: [PATCH 8/8] RLSE: Ver 0.34.1 * Modify statistics of Weighted Uniform distribution * Add more `Vec` algorithms --- Cargo.toml | 2 +- RELEASES.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fd218efc..f9495b48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "peroxide" -version = "0.34.0" +version = "0.34.1" authors = ["axect "] edition = "2018" description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax" diff --git a/RELEASES.md b/RELEASES.md index 2da1936e..b233812f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,14 @@ +# Release 0.34.1 (2023-08-03) + +## Modify Statistics of `WeightedUniform` + +* Modify `self.sum` to compatible with definition [Weighted Uniform Distribution](https://axect.github.io/posts/006_prs/#22-weighted-uniform-distribution) +* Modify `mean` & `var` to compatible with definition + +## Add more `Vec` algorithms + +* Implement `arg_min`, `max`, `min` + # Release 0.34.0 (2023-06-13) ## Change Gauss-Kronrod quadrature