-
Notifications
You must be signed in to change notification settings - Fork 333
Add randn to create an array of standard gaussian numbers. #147
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
Add randn to create an array of standard gaussian numbers. #147
Conversation
Previous discussion in #146. @bluss said
Thanks for submitting this PR! You've started the wheels of the machine and they are now spinning, I'll get back to this.
|
In my humble opinion:
So overall, in my opinion, the main questions about this PR are: do we like the function signatures: |
arr.into_shape(dim).unwrap() | ||
} | ||
|
||
pub fn randn(dim: D) -> ArrayBase<Vec<A>, D> |
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.
Because this might be generally useful: Instead of ArrayBase<Vec<A>, D>
this could just be OwnedArray<A, D>
which is the equivalent type alias.
But the impl block is written for all ArrayBase
with owned storage, and the type parameter S
is unused. So I think the intention is to write ArrayBase<S, D>
as the return type here instead. This makes it work for both OwnedArray and RcArray.
Changing the return type to I am not sure exactly what constrains the implementation to a Vec, but that seems to be the situation. This seems like a good time for me to read up on the main structs, traits, and type aliases at play, is there any best place to start? |
Yes you need to change the code a bit too to make it match the return type. |
There isn't that much docs, only the ArrayBase thing that explains the type aliases https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html and https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html#ownedarray-and-rcarray |
probably only need to change OwnedArray in the body to ArrayBase or even just |
Self didn't work (beyond me exactly why), but generalized to ArrayBase. The exact relation between ArrayBase and its variants was not clear to me before, now I see ArrayBase is parameterized over how it accesses/owns its data, and OwnedArray, RcArray are just names for particular variants. |
Now it looks nice, it follows the pattern of the other constructors. |
A natural consequence of you helping know what the heck I'm doing, thanks :) BTW, having read that documentation, I have some ideas on improving it. Briefly:
Coming back to this PR, my only doubt about it is inheriting the short but cryptic [1] https://bluss.github.io/rust-ndarray/master/ndarray/index.html |
Thanks for the thoughts. It is explained very briefly here https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html also that the rand_gaussian sounds ok to me. I don't think we have a policy for naming. If you want to get started using this soon, I'd define these constructor methods in a trait that extends ArrayBase and use it in your own code. With traits it's very easy to extend your own or someone else's data structures this way. I don't think modularity is optional in rust; it is required, we have to try to break up every project into logical parts. Rustc punishes big crates severely with long compilation times. You may be aware that the crate is the unit of compilation, and there's no way to recompile a smaller unit than that. I'm also busy with making the mere basics of the n dimensional array work ( #140). This PR makes me think ndarray should be split into ndarray-core, ndarray-rand, ndarray-linalg, and so on. |
I'm enjoying this conversation.
|
Is there a reason to restrict this to let between = distributions::Range::new(0f64, 2f64 * consts::PI);
let normal = distributions::Normal::new(0f64, 1f64);
let mut rng = rand::thread_rng();
let phi = repeat(())
.take(n)
.map(|_| between.ind_sample(&mut rng))
.collect::<Vec<_>>();
let phidot = repeat(())
.take(n)
.map(|_| normal.ind_sample(&mut rng))
.collect::<Vec<_>>(); Should you decide to go ahead and include this function, I would propose to at least generalize the function to take arbitrary distributions and allow for |
There's room for many different constructors though. |
@daniel-vainsencher PR for docs is ok, I'm not sure what you want to change? I'd suggest documenting this on the |
@SuperFluffy I agree we should also have @bluss Documentation... I'll open a separate issue for this one. |
ndarray-rand sounds to me like it would be a tiny crate, and there is overhead in maintaining multiple crates (for example, inter-crate dependencies, updating for breakage, etc). How about splitting to just ndarray-core and ndarray-misc? one can always split further later on, and wanting to add a ones constructor, should I create yet another package? Also, before we decide to take on even that cost, do you find the current compilation time for ndarray bad enough by itself that we really to split? |
I am pretty intent on the split. rand support seems like a feature that has almost no intersection with the rest of the crate, especially not the core parts. This is not a statement about the usage of ndarray, just the organization of the implementation. We are not numpy, not really at all, but if you would compare with it, numpy.random is its own module, and it is pretty big. Nothing to suggest it would be a small project. And.. if it's a crate of its own, it's all the more comfortable to grow many features in it. |
While we're comparing, numpy.random is its own module, not its own git repo or its own package (unit of distribution). Are you taking into account the effects on testing and refactoring across crate boundaries? Anyway, its your decision, and if I can contribute to it I currently don't see how. I've sent the PR under the current architecture, without a concrete future architecture, I don't see how to submit further PRs for the other utility functions I've needed to create for my own project. I hope the package architecture settles down soon. |
Most of the drawbacks you bring up don't really exist. Crates can share repo, you can use local overrides, local path dependencies, etc etc. Modules and packages appear the same in python and can be inserted anywhere in the hierarchy. |
Ok, those possibilities are news to me. So you are talking about having a That does sound much better than what I had imagined based on my On Wed, Mar 16, 2016 at 3:44 PM, bluss [email protected] wrote:
Daniel Vainsencher |
Now properly cherry-picked, I hope. Will be applying comments by @bluss from original pull request to this one in further commits.