Re: [RNG] Generating for [e]nums

2017-08-04 Thread Gilles

Hi.

On Fri, 4 Aug 2017 15:29:42 -0400, Simon Spero wrote:
On Aug 4, 2017 2:11 PM, "Gary Gregory"  
wrote:


For example, I have a enum like:

public enum CardinalDirection (NORTH,SOUTH,EAST,WEST)

public CardinalDirection nextRandomDirection() {
   return rng.next(CardinalDirection.class);
}


This approach may be a bit slow if the random values are near an 
inner

loop.

In order to select a random enum value, you need to get hold of an 
array
containing all the possible values (equivalent to what gets returned 
by the

generated  "public static CardinalDirection[] values()".

This requires calling Class::getEnumConstants, which does a little
reflection, caches the result, then returns a clone of the resultant 
array.


It may be better to construct a random enum value generator object 
that

holds a copy of the values array, plus an RNG with the desired
characteristics.

A more general method would take an array of values, or a 
Supplier

function (e.g. CardinalDirection::values).

You could use a cache in the RNG, keyed by the class, but that's 
still

going to be a bit expensive in the middle of a tight loop.


What about the following?

---CUT---
import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.simple.RandomSource;

public class RandomEnum> {
private final T[] values;
private final UniformRandomProvider rand = 
RandomSource.create(RandomSource.SPLIT_MIX_64);


public RandomEnum(Class c) {
values = c.getEnumConstants();
}

public T next() {
return values[rand.nextInt(values.length)];
}
}
---CUT---


Regards,
Gilles



-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [RNG] Generating for [e]nums

2017-08-04 Thread Simon Spero
On Aug 4, 2017 2:11 PM, "Gary Gregory"  wrote:

For example, I have a enum like:

public enum CardinalDirection (NORTH,SOUTH,EAST,WEST)

public CardinalDirection nextRandomDirection() {
   return rng.next(CardinalDirection.class);
}


This approach may be a bit slow if the random values are near an inner
loop.

In order to select a random enum value, you need to get hold of an array
containing all the possible values (equivalent to what gets returned by the
generated  "public static CardinalDirection[] values()".

This requires calling Class::getEnumConstants, which does a little
reflection, caches the result, then returns a clone of the resultant array.

It may be better to construct a random enum value generator object that
holds a copy of the values array, plus an RNG with the desired
characteristics.

A more general method would take an array of values, or a Supplier
function (e.g. CardinalDirection::values).

You could use a cache in the RNG, keyed by the class, but that's still
going to be a bit expensive in the middle of a tight loop.

Simon

Simon