-
Notifications
You must be signed in to change notification settings - Fork 324
Issue/655: Standard deviation and variance #753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This PR implements std and var methods using the same method as used for var_axis, std_axis. The variance is computed by flattened the array into a 1D array of the .len() of original array. The return type is scalar A instead of Array<A, D:Smaller> An attempt was made to refactor var_axis to use var, but this resulted in a performance regression so original implementations are kept and we accept some code duplication. ``` pub fn var_axis(&self, axis: Axis, ddof: A) -> Array<A, D::Smaller> where A: Float + FromPrimitive, D: RemoveAxis, { let mut sum_sq = Array::<A, D::Smaller>::zeros(self.dim.remove_axis(axis)); for (lane, sum) in self.lanes(axis).into_iter().zip(sum_sq.iter_mut()) { *sum = lane.var(ddof); } sum_sq } ```
The main issue we had here was that |
I don't quite see the issue with using Zip here |
Sorry, it took me a while to get back to this - @bluss is indeed right, I was able to put it together using I opened a PR against your branch with the |
@allmywatts If you don't mind can I take over this PR and open a new one? |
@hameerabbasi hey, sorry for the late reply, yes please go ahead. |
Use `var` in var_axis
This looks ready to merge, right? |
let dof = n - ddof; | ||
let mut mean = A::from_usize(0).expect("Converting 0 to `A` must not fail."); | ||
let mut sum_sq = A::from_usize(0).expect("Converting 0 to `A` must not fail."); | ||
for (count, x) in self.iter().enumerate() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to note, iter is not an efficient way to iterate a "flattened" array, so this should potentially use unary Zip instead, for example, or ArrayBase::fold
. In the high level, this is documented in the module documentation, about array traversals.
can of course be fixed as a later change.
Super minor thing, but as long as there is a division and a checked type conversion inside the actual loop, I don't think |
/// [3., 4.], | ||
/// [5., 6.]]); | ||
/// | ||
/// let a_flat = a.view().into_shape(6).expect("This must not fail."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"This must not fail" does not add information, just use .unwrap()
. I'm just afraid that the user will conclude some kinds of into_shape()
(to 1D) always succeed, and they don't.
Superseded by #790 |
This PR implements
std
andvar
methods (see: #655) using the same method as used forvar_axis
,std_axis
.The variance is computed by flattening the array of N dimensions into a 1D array of the length
.len()
of the original array.The return type is scalar A instead of Array<A, D:Smaller>
An attempt was made to refactor
var_axis
to usevar
, but this resulted in a performance regression so original implementation is kept and we accept some code duplication. 😛Thanks @LukeMathWalker for the mentoring. 😀