Skip to content

<random>: std::piecewise_linear_distribution incorrectly normalizes densities #1084

@Cory-Kramer

Description

@Cory-Kramer

Describe the bug
A std::piecewise_linear_distribution is described as accepting discrete pairs of values and densities. The densities are normalized such that the distribution becomes valid (specifically the distribution integrates to 1.0).

Command-line test case

C:\Temp>type repro.cpp

#include <array>
#include <iostream>
#include <random>

int main()
{
    std::array<double, 2> values{ 5.0, 10.0 };
    std::array<double, 2> densities{ 0.0, 1.0 };

    std::piecewise_linear_distribution<double> dist(values.begin(), values.end(), densities.begin());
    std::cout << "x:    " << dist.intervals()[0] << " to " << dist.intervals()[1] << '\n'
              << "p(x): " << dist.densities()[0] << " to " << dist.densities()[1];
}

C:\Temp>cl /EHsc /W4 /WX .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

repro.cpp
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:repro.exe
repro.obj

C:\Temp>.\repro.exe
x: 5 to 10
p(x): 0 to 2

Expected behavior
In the above example Visual Studio will (incorrectly) output

x: 5 to 10
p(x): 0 to 2

whereas Clang and GCC will (correctly) output

x: 5 to 10
p(x): 0 to 0.4

In this example you can verify the distribution simply makes a triangle of area 1.0, which since the width is 5.0 (10.0 - 5.0) the second density value must be 0.4 for the area to sum to 1.0.

STL version
Microsoft Visual Studio Enterprise 2019
Version 16.6.5

Additional context
This bug was also reported to the Visual Studio Developer Community: https://developercommunity.visualstudio.com/content/problem/1125176/stdpiecewise-linear-distribution-incorrectly-norma.html

For context here is the relevant MSVC implementation related to this bug:
https://github.com/microsoft/STL/blob/master/stl/inc/random#L4829-L4854

and Clang's implementation:
https://github.com/llvm/llvm-project/blob/master/libcxx/include/random#L6568-L6590

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions