Skip to content
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 mutating versions of randperm & randcycle #22723

Merged
merged 4 commits into from
Jul 23, 2017
Merged

Conversation

rfourquet
Copy link
Member

This can be useful when needing to call repeatedly one of those functions without allocating excessively.

@rfourquet rfourquet added the domain:randomness Random number generation and the Random stdlib label Jul 9, 2017
@rfourquet
Copy link
Member Author

rfourquet commented Jul 9, 2017

I changed slightly the behavior: randperm(n) (idem for randcycle(n)) now always returns an array of type Array{Int}, whatever the type of n is. I found the old behavior not very sound; it's now possible to control the type of the array by using randperm! instead.

EDIT: If needed, I would propose to be able to also specify directly the type in randperm in this way: randperm([T=Int], n) = randperm!(Array{T}(n)).

base/random.jl Outdated
@@ -1799,31 +1800,49 @@ shuffle(a::AbstractArray) = shuffle(GLOBAL_RNG, a)

Construct a random permutation of length `n`. The optional `rng` argument specifies a random
number generator (see [Random Numbers](@ref)).
To randomly permute a arbitrary vector, see [`shuffle`](@ref)
To randomly permute an arbitrary vector, see [`shuffle`](@ref)
or [`shuffle!`](@ref).

# Example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# Examples
```jldoctest

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK for the newline, but do we use plural "Examples" even when there is only one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, there's a not yet merged pr that is changing all of the existing cases to be consistent

Copy link
Member

@Sacha0 Sacha0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superficially (i.e. modulo interface and always-return-Int bikeshedding) lgtm! :)

Needs a rebase and CI rerun?

@rfourquet
Copy link
Member Author

Ok, rebased (a previous CI was OK, but then used "[ci skip]" in subsequent commits to avoid overloading nanosoldier).

What is your take on the "always-return-Int bikeshedding" ? I don't have a too strong opinion about it, and will revert back (together with adding documentation) if this holds back this PR.

The integer type determing the array type makes sense in a way, when considering this Int is the upper bound of the returned array; but this is a bit too implicit for me. On the other hand, this integer can be seen simply as the length of the array, like many other functions in base, for which non-Int integers are accepted only for convenience, but without affecting the type of the result.

@tkelman
Copy link
Contributor

tkelman commented Jul 13, 2017

Can we dig through blame a bit to see when / why that behavior was originally added, see if there's any initial discussion to find? Array element type depending on the type of a length parameter is a little unusual, though I could see it being useful here.

@rfourquet
Copy link
Member Author

Can we dig through blame a bit to see when / why that behavior was originally added, see if there's any initial discussion to find?

Excellent idea, which shows that this was not made on purpose if I interpret it correctly. This comes from ae44b3a, with following comit message:

Rename: Int => Integer, Uint => Unsigned.

In preparation for using Int and Uint as the "I don't care"
integer and unsigned types on the current system, distinct
from any specified integer types, even if they're of the
same size and representation: Int ≠ Int64, Uint ≠ Uint64.

Before, randperm (and randcycle) only accepted Int, still the array was created as a = Array(typeof(n), n) (where n::Int). So the switch to Integer was part of an effort to make many functions accept more integer types for convenience.

@Sacha0
Copy link
Member

Sacha0 commented Jul 13, 2017

I lack a strong opinion; the behavior you propose seems reasonable :).

@rfourquet
Copy link
Member Author

I will merge in few days if no objection.

@rfourquet rfourquet merged commit 7287321 into master Jul 23, 2017
@rfourquet rfourquet deleted the rf/mutable-randperm branch July 23, 2017 16:37
@tkelman
Copy link
Contributor

tkelman commented Jul 23, 2017

Another API that could possibly make sense here would be giving the element or array type as the first input, but that's usually not a whole lot more concise than using the mutating versions on a newly-allocated array.

jeffwong pushed a commit to jeffwong/julia that referenced this pull request Jul 24, 2017
@rfourquet
Copy link
Member Author

Yes I mentioned this possibility in my second comment above, but it seems to me that needing a type different than Int is marginal, so didn't feel the urge to offer a slightly more concise API that the mutating version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:randomness Random number generation and the Random stdlib
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants