Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
k_partition_of_r_generator.h
Go to the documentation of this file.
1
// Copyright (C) 2022 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4
#
pragma
once
5
6
#
include
"../namespaces.h"
7
8
#
include
<
catch
/
catch
.
hpp
>
9
10
#
include
<
random
>
11
#
include
<
numeric
>
12
#
include
<
algorithm
>
13
14
namespace
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
{
15
namespace
QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
{
16
17
class
KPartitionOfRGenerator
:
public
Catch
::
Generators
::
IGenerator
<
std
::
vector
<
double
>> {
18
public
:
19
KPartitionOfRGenerator
(
double
r,
std
::size_t k)
20
: random_engine{
std
::random_device{}()},
21
interval_distribution
{0.0,
r
},
22
k{k},
23
r{r},
24
current_partition
(
k
)
25
{
26
assert
(r >= 0.0);
27
assert
(k >= 1);
28
29
static_cast
<
void
>(
next
(
)
);
30
}
31
32
std
::
vector
<
double
>
const
&
get
()
const
override
{
return
current_partition; }
33
34
bool
next
()
override
{
35
if
(k == 1) current_partition[0] = r;
36
else
{
37
// REMARK: The following wasn't formally proved
38
// but is based on intuition.
39
// It is probably erroneous but is expected to be
40
// good enough for our case.
41
42
// REMARK: We aim to provide a non skewed
43
// distribution for the elements of the partition.
44
//
45
// The reasoning for this is to ensure that our
46
// testing surface has a good chance of hitting
47
// many of the available elements between the many
48
// runs.
49
//
50
// To approximate this, a specific algorithm was chosen.
51
// The following code can be intuitively seen as doing the following:
52
//
53
// Consider an interval [0.0, r] on the real line, where r > 0.0.
54
//
55
// k - 1 > 0 elements of the interval are chosen,
56
// partitioning the interval into disjoint
57
// sub-intervals.
58
//
59
// ---------------------------------------------------------------------------------------------------------------------
60
// | | | | |
61
// 0 k_1 k_2 k_3 r
62
// | | | | |
63
// _______--------------------_______________________________________________________-----------------------------------
64
// k_1 - 0 k_2 - k_1 k_3 - k_2 r - k_3
65
// p1 p2 p3 p4
66
//
67
// The length of each sub interval is chosen as one of the elements of the partition.
68
//
69
// Trivially, the sum of the chosen elements is r.
70
//
71
// Furthermore, as long as the distribution used
72
// to choose the elements of the original interval
73
// is uniform, the probability of each partition
74
// being produced should tend to being uniform
75
// itself.
76
std
::generate(current_partition.begin(), current_partition.end() - 1, [
this
](){
return
interval_distribution(random_engine); });
77
78
current_partition.back() = r;
79
80
std
::sort(current_partition.begin(), current_partition.end());
81
std
::adjacent_difference(current_partition.begin(), current_partition.end(), current_partition.begin());
82
}
83
84
return
true
;
85
}
86
87
private
:
88
std
::mt19937 random_engine;
89
std
::uniform_real_distribution<
double
> interval_distribution;
90
91
std
::size_t k;
92
double
r;
93
94
std::vector<
double
> current_partition;
95
};
96
97
}
// end QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
98
99
/*!
100
* Returns a generator that generates collections of \a k elements
101
* whose sum is \a r.
102
*
103
* \a r must be a real number greater or euqal to zero and \a k
104
* must be a natural number greater than zero.
105
*
106
* The generated partitions tends to be uniformely distributed
107
* over the set of partitions of r.
108
*/
109
inline
Catch
::
Generators
::
GeneratorWrapper
<
std
::
vector
<
double
>>
k_partition_of_r
(
double
r,
std
::size_t k) {
110
return
Catch::Generators::GeneratorWrapper<std::vector<
double
>>(std::unique_ptr<Catch::Generators::IGenerator<std::vector<
double
>>>(
new
QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
::KPartitionOfRGenerator(r, k)));
111
}
112
113
}
// end QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE::QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE::KPartitionOfRGenerator
Definition
k_partition_of_r_generator.h:17
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE::QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE::KPartitionOfRGenerator::KPartitionOfRGenerator
KPartitionOfRGenerator(double r, std::size_t k)
Definition
k_partition_of_r_generator.h:19
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE::QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE::KPartitionOfRGenerator::next
bool next() override
Definition
k_partition_of_r_generator.h:34
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE::QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE::KPartitionOfRGenerator::get
std::vector< double > const & get() const override
Definition
k_partition_of_r_generator.h:32
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE::k_partition_of_r
Catch::Generators::GeneratorWrapper< std::vector< double > > k_partition_of_r(double r, std::size_t k)
Returns a generator that generates collections of k elements whose sum is r.
Definition
k_partition_of_r_generator.h:109
QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
#define QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
Definition
namespaces.h:8
QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
#define QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
Definition
namespaces.h:6
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
assert
#define assert
Definition
qcborcommon_p.h:29
qttools
src
qdoc
catch_generators
src
catch_generators
generators
k_partition_of_r_generator.h
Generated on
for Qt by
1.18.0