This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 793. `discrete_distribution` missing constructor

Section: 28.5.9.6.1 [rand.dist.samp.discrete] Status: Resolved Submitter: P.J. Plauger Opened: 2008-02-09 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [rand.dist.samp.discrete].

View all issues with Resolved status.

Discussion:

`discrete_distribution` should have a constructor like:

>     template<class _Fn>
>       discrete_distribution(result_type _Count, double _Low, double _High,
>                             _Fn& _Func);

(Makes it easier to fill a histogram with function values over a range.)

[ Bellevue: ]

> How do you specify the function so that it does not return negative values? If you do it is a bad construction. This requirement is already there. Where in each bin does one evaluate the function? In the middle. Need to revisit tomorrow.

[ Sophia Antipolis: ]

> Bill is not requesting this.

> Marc Paterno: `_Fn` cannot return negative values at the points where the function is sampled. It is sampled in the middle of each bin. `_Fn` cannot return 0 everywhere it is sampled.

> Jens: lambda expressions are rvalues

> Add a library issue to provide an `initializer_list<double>` constructor for `discrete_distribution`.

> Marc Paterno: dislikes reference for `_Fn` parameter. Make it pass-by-value (to use lambda), use `std::ref` to wrap giant-state function objects.

> Daniel: See `random_shuffle`, pass-by-rvalue-reference.

> Daniel to draft wording.

[ Pre San Francisco, Daniel provided wording: ]

> The here proposed changes of the WP refer to the current state of N2691. During the Sophia Antipolis meeting two different proposals came up regarding the functor argument type, either by value or by rvalue-reference. For consistence with existing conventions (state-free algorithms and the `general_pdf_distribution` c'tor signature) the author decided to propose a function argument that is provided by value. If severe concerns exists that stateful functions would be of dominant relevance, it should be possible to replace the two occurrences of `Func` by `Func&&` in this proposal as part of an editorial process.

Proposed resolution:

Non-concept version of the proposed resolution

1. In 28.5.9.6.1 [rand.dist.samp.discrete]/1, class `discrete_distribution`, just before the member declaration

   >     explicit discrete_distribution(const param_type& parm);

   insert:

   >     template<typename Func>
   >     discrete_distribution(result_type nf, double xmin, double xmax, Func fw);

2. Between p.4 and p.5 insert a series of new paragraphs as part of the new member description::

   >     template<typename Func>
   >     discrete_distribution(result_type nf, double xmin, double xmax, Func fw);

   > Complexity: Exactly nf invocations of fw.

   > Requires:

   > 1. fw shall be callable with one argument of type double, and shall return values of a type convertible to double;
   > 2. If nf > 0, the relation `xmin` < `xmax` shall hold, and for all sample values `xk`, fw(`xk`) shall return a weight value `wk` that is non-negative, non-NaN, and non-infinity;
   > 3. The following relations shall hold: nf ≥ 0, and 0 < S = `w0`+. . .+`wn-1`.

   > Effects:

   > 1. If nf == 0, sets n = 1 and lets the sequence w have length n = 1 and consist of the single value `w0` = 1.

   > 2. Otherwise, sets n = nf, deltax = (`xmax` - `xmin`)/n and `xcent` = `xmin` + 0.5 * deltax.

   >    For each k = 0, . . . ,n-1, calculates:

   >    `xk` = `xcent` + k * deltax `wk` = fw(`xk`)

   > 3. Constructs a discrete_distribution object with probabilities:

   >    > `pk` = `wk`/S for k = 0, . . . , n-1.

Concept version of the proposed resolution

1. In 28.5.9.6.1 [rand.dist.samp.discrete]/1, class `discrete_distribution`, just before the member declaration

   >     explicit discrete_distribution(const param_type& parm);

   insert:

   >     template<Callable<auto, double> Func>
   >      requires Convertible<Func::result_type, double>
   >     discrete_distribution(result_type nf, double xmin, double xmax, Func fw);

2. Between p.4 and p.5 insert a series of new paragraphs as part of the new member description::

   >     template<Callable<auto, double> Func>
   >      requires Convertible<Func::result_type, double>
   >     discrete_distribution(result_type nf, double xmin, double xmax, Func fw);

   > Complexity: Exactly nf invocations of fw.

   > Requires:

   > 1. If nf > 0, the relation `xmin` < `xmax` shall hold, and for all sample values `xk`, fw(`xk`) shall return a weight value `wk` that is non-negative, non-NaN, and non-infinity;
   > 2. The following relations shall hold: nf ≥ 0, and 0 < S = `w0`+. . .+`wn-1`.

   > Effects:

   > 1. If nf == 0, sets n = 1 and lets the sequence w have length n = 1 and consist of the single value `w0` = 1.

   > 2. Otherwise, sets n = nf, deltax = (`xmax` - `xmin`)/n and `xcent` = `xmin` + 0.5 * deltax.

   >    For each k = 0, . . . ,n-1, calculates:

   >    `xk` = `xcent` + k * deltax `wk` = fw(`xk`)

   > 3. Constructs a discrete_distribution object with probabilities:

   >    > `pk` = `wk`/S for k = 0, . . . , n-1.

Rationale:

Addressed by N2836 "Wording Tweaks for Concept-enabled Random Number Generation in C++0X".