Skip to content

Commit 8457373

Browse files
committed
Test order isomorphism of some measures of disorder
That property of some measures of disorder is highlighted by Valdimir Estivill-Castro in *Sorting and Measures of Disorder*.
1 parent 9026f7f commit 8457373

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

tests/probes/every_probe_common.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
* Copyright (c) 2021-2025 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
5+
#include <algorithm>
56
#include <numeric>
7+
#include <random>
68
#include <type_traits>
79
#include <vector>
810
#include <catch2/catch_template_test_macros.hpp>
911
#include <rapidcheck.h>
1012
#include <rapidcheck/catch.h>
1113
#include <cpp-sort/probes.h>
14+
#include "testing-tools/random.h"
1215

1316
//
1417
// Common tests for measures of presortedness
@@ -161,3 +164,80 @@ TEMPLATE_TEST_CASE( "test M(aX) <= |X| + M(X) for most probes M", "[probe]",
161164
return mop(sequence) <= (size - 1) + mop(sequence.begin() + 1, sequence.end());
162165
});
163166
}
167+
168+
TEMPLATE_TEST_CASE( "test prefix monoticity", "[probe]",
169+
decltype(cppsort::probe::dis),
170+
decltype(cppsort::probe::enc),
171+
decltype(cppsort::probe::exc),
172+
decltype(cppsort::probe::ham),
173+
decltype(cppsort::probe::inv),
174+
decltype(cppsort::probe::max),
175+
decltype(cppsort::probe::rem),
176+
decltype(cppsort::probe::runs),
177+
decltype(cppsort::probe::spear),
178+
decltype(cppsort::probe::sus) )
179+
{
180+
// Property formalized by Estivill-Castro in *Sorting and Measures of Disorder*
181+
// The following probes don't satisfy it: Block, Mono, Osc
182+
183+
// Note: the original paper claims that Osc also satisfies this property,
184+
// but it fails for X=⟨3, 0⟩ Y=⟨⟩ Z=⟨4, 2⟩
185+
186+
rc::prop("prefix monoticity", [](std::vector<int> sequence) {
187+
using diff_t = std::vector<int>::difference_type;
188+
using param_t = std::uniform_int_distribution<diff_t>::param_type;
189+
190+
auto size = static_cast<diff_t>(sequence.size());
191+
if (size < 3) {
192+
return true;
193+
}
194+
195+
// Split the sequence into three consequent subsequences X, Y and Z
196+
std::uniform_int_distribution<diff_t> dist;
197+
auto x_begin = sequence.begin();
198+
auto y_begin = x_begin + dist(hasard::engine(), param_t{0, size - 1});
199+
auto z_begin = x_begin + dist(hasard::engine(), param_t{y_begin - x_begin, size - 1});
200+
201+
// Ensure that all elements of Z are greater than all elements of X and Y
202+
std::nth_element(x_begin, z_begin, sequence.end());
203+
204+
std::decay_t<TestType> mop;
205+
auto disorder_x = mop(x_begin, y_begin);
206+
auto disorder_y = mop(y_begin, z_begin);
207+
auto disorder_yz = mop(y_begin, sequence.end());
208+
auto new_x_begin = std::rotate(x_begin, y_begin, z_begin);
209+
auto disorder_xz = mop(new_x_begin, sequence.end());
210+
211+
return disorder_x <= disorder_y
212+
? disorder_xz <= disorder_yz
213+
: disorder_yz <= disorder_xz;
214+
});
215+
}
216+
217+
TEMPLATE_TEST_CASE( "test M(XY) = M(X) + M(Y) if X <= Y for most probes M", "[probe]",
218+
decltype(cppsort::probe::exc),
219+
decltype(cppsort::probe::ham),
220+
decltype(cppsort::probe::inv),
221+
decltype(cppsort::probe::rem),
222+
decltype(cppsort::probe::runs),
223+
decltype(cppsort::probe::spear) )
224+
{
225+
// Property formalized by Estivill-Castro in *Sorting and Measures of Disorder*
226+
// Not all measures of presortedness satisfy it, but a lot do
227+
228+
rc::prop("M(XY) = M(X) + M(Y) if X ≤ Y", [](std::vector<int> sequence) {
229+
using diff_t = std::vector<int>::difference_type;
230+
using param_t = std::uniform_int_distribution<diff_t>::param_type;
231+
232+
// Split the sequence into two consequent subsequences X and Y
233+
auto size = static_cast<diff_t>(sequence.size());
234+
std::uniform_int_distribution<diff_t> dist;
235+
auto x_begin = sequence.begin();
236+
auto y_begin = x_begin + dist(hasard::engine(), param_t{0, size});
237+
std::cout << "nooooo: " << (y_begin - x_begin) << std::endl;
238+
std::nth_element(x_begin, y_begin, sequence.end());
239+
240+
std::decay_t<TestType> mop;
241+
return mop(sequence) == mop(x_begin, y_begin) + mop(y_begin, sequence.end());
242+
});
243+
}

0 commit comments

Comments
 (0)