793. discrete_distribution missing constructor

Section: 29.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 29.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 29.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".