Hello.

Le ven. 19 juil. 2019 à 14:27, Alex Herbert <alex.d.herb...@gmail.com> a écrit :
>
> One principle reason for SharedStateDiscreteSampler
> and SharedStateContinuousSampler is to simplify the current design approach
> for samplers that use internal delegates to provide optimised algorithms.
> However this creates an inefficient outer class that is just wrapping the
> implementation.
>
> The idea was to simplify the implementation of the SharedStateSampler<R>
> interface for these Discrete/Continuous Samplers. However it has wider
> application to moving away from public constructors to factory methods. The
> SharedStateDiscreteSampler interface would allow the samplers package to
> move to a factory constructor model where samplers have no public
> constructor. This allows the factory method to choose the best
> implementation. This idea is recommended by Joshua Block in Effective Java
> (see [1]).
>
> For example:
>
> UniformRandomProvider rng = ...;
> double mean = ...;
> PoissonSampler sampler = new PoissonSampler(rng, mean);
>
> vs (with some potential names):
>
> SharedStateDiscreteSampler sampler =
> PoissonSampler.newSharedStateDiscreteSampler(rng, mean);
> SharedStateDiscreteSampler sampler = PoissonSampler.newInstance(rng, mean);
> SharedStateDiscreteSampler sampler = PoissonSampler.newSampler(rng, mean);
> SharedStateDiscreteSampler sampler = PoissonSampler.newPoissonSampler(rng,
> mean);
> SharedStateDiscreteSampler sampler = PoissonSampler.of(rng, mean);
>
> Currently there are some unreleased classes in v1.3 that use various
> construction methods with different approaches to fitting within the
> current design of returning an instance that supports DiscreteSampler and
> SharedStateSampler<R> and using specialised algorithms:
>
> AliasMethodDiscreteSampler
> MarsagliaTsangWangDiscreteSampler
> GuideTableDiscreteSampler
> GeometricSampler
>
> The PoissonSamplerCache could also benefit from this as it returns a
> DiscreteSampler even though the returned object is now also a
> SharedStateSampler<R>.
>
> I would advocate introducing these interfaces and switching to a factory
> method design for unreleased code. This has no binary compatibility issues.
>
> Current released code that would also benefit from this design are those
> with internal delegates:
>
> PoissonSampler
> AhrensDieterMarsagliaTsangGammaSampler
> LargeMeanPoissonSampler
> ChengBetaSampler (no delegate but it chooses an algorithm)
>
> An example of factory code would be
>
> double alpha;
> double theta
> SharedStateContinuousSampler sampler =
> AhrensDieterMarsagliaTsangGammaSampler.of(rng, alpha, theta);
> SharedStateContinuousSampler sampler =
> AhrensDieterMarsagliaTsangGammaSampler.newGammaSampler(rng, alpha, theta);
>
> Since the class name is so verbose in this case the 'of' method name does
> not appear out of place.
>
> Note that as the SharedStateSampler<R> interface is implemented by all
> (non-deprecated) distribution samplers a factory method could be added to
> every sampler. This would pave the way for removal of public constructors
> in a 2.0 release (whenever that happens).
>
> Overall the proposal is to:
>
> - Create SharedStateDiscreteSampler and SharedStateContinuousSampler
> - Simplify the implementation of SharedStateSampler<R>
> - Move to factory constructors for unreleased samplers
> - Add factory constructors to existing samplers to return optimised
> implementations

+1 (using "of" as the method name).

Gilles

>
> Thoughts on this are welcomed.
>
> Alex
>
> [1] https://www.baeldung.com/java-constructors-vs-static-factory-methods
>
> On Fri, 19 Jul 2019 at 10:35, Alex Herbert <alex.d.herb...@gmail.com> wrote:
>
> > This interface has been added in v1.3:
> >
> > /**
> >  * Applies to samplers that can share state between instances. Samplers
> > can be created with a
> >  * new source of randomness that sample from the same state.
> >  *
> >  * @param <R> Type of the sampler.
> >  * @since 1.3
> >  */
> > public interface SharedStateSampler<R> {
> >     /**
> >      * Create a new instance of the sampler with the same underlying state
> > using the given
> >      * uniform random provider as the source of randomness.
> >      *
> >      * @param rng Generator of uniformly distributed random numbers.
> >      * @return the sampler
> >      */
> >     R withUniformRandomProvider(UniformRandomProvider rng);
> > }
> >
> > All of the DiscreteSampler and ContinuousSampler classes have been updated
> > to implement SharedStateSampler.
> >
> > This is the equivalent of:
> >
> > /**
> >  * Sampler that generates values of type {@code int} and can create new
> > instances to sample
> >  * from the same state with a given source of randomness.
> >  *
> >  * @since 1.3
> >  */
> > public interface SharedStateDiscreteSampler
> >     extends DiscreteSampler,
> > SharedStateSampler<SharedStateDiscreteSampler> {
> >     // Marker interface
> > }
> >
> >
> > If this combined marker interface is added to the library it would
> > simplify a lot of the code for samplers which have internal delegates to
> > avoid casting. With this interface they can hold a
> > SharedStateDiscreteSampler rather than a DiscreteSampler delegate and
> > directly use it to create new delegates.
> >
> > For example PoissonSampler code which wraps a specific implementation:
> >
> > /**
> >  * @param rng Generator of uniformly distributed random numbers.
> >  * @param source Source to copy.
> >  */
> > private PoissonSampler(UniformRandomProvider rng,
> >         PoissonSampler source) {
> >     super(null);
> >
> >     if (source.poissonSamplerDelegate instanceof SmallMeanPoissonSampler) {
> >         poissonSamplerDelegate =
> >
> > ((SmallMeanPoissonSampler)source.poissonSamplerDelegate).withUniformRandomProvider(rng);
> >     } else {
> >         poissonSamplerDelegate =
> >
> > ((LargeMeanPoissonSampler)source.poissonSamplerDelegate).withUniformRandomProvider(rng);
> >     }
> > }
> >
> > Becomes:
> >
> > private PoissonSampler(UniformRandomProvider rng,
> >         PoissonSampler source) {
> >     super(null);
> >     poissonSamplerDelegate =
> > source.poissonSamplerDelegate.withUniformRandomProvider(rng);
> > }
> >
> >
> > I propose to add:
> >
> > public interface SharedStateDiscreteSampler
> >     extends DiscreteSampler,
> > SharedStateSampler<SharedStateDiscreteSampler> {
> >     // Marker interface
> > }
> >
> > public interface SharedStateContinuousSampler
> >     extends ContinuousSampler,
> > SharedStateSampler<SharedStateContinuousSampler> {
> >     // Marker interface
> > }
> >
> >
> >

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

Reply via email to