From 229541859d21d246c83b40495ea55f1e3b8405cd Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 30 Nov 2023 03:20:23 +0100 Subject: [PATCH] Chain-Load: demonstrate use of reduction rule ... special rule to generate a fixed expansion on each seed ... consecutive reductions join everything back into one chain ... can counterbalance expansions and reductions --- src/lib/random-draw.hpp | 7 ++ tests/library/random-draw-test.cpp | 13 ++++ tests/vault/gear/test-chain-load-test.cpp | 80 ++++++++++++++++++----- tests/vault/gear/test-chain-load.hpp | 17 ++++- wiki/thinkPad.ichthyo.mm | 65 ++++++++++++++---- 5 files changed, 150 insertions(+), 32 deletions(-) diff --git a/src/lib/random-draw.hpp b/src/lib/random-draw.hpp index 115beb731..a4690d2d2 100644 --- a/src/lib/random-draw.hpp +++ b/src/lib/random-draw.hpp @@ -326,6 +326,13 @@ namespace lib { return move (*this); } + RandomDraw&& + fixedVal (Tar v) + { + mapping ([v](size_t){ return v; }); + return move (*this); + } + template RandomDraw&& mapping (FUN&& fun) diff --git a/tests/library/random-draw-test.cpp b/tests/library/random-draw-test.cpp index 23e21f5c4..4ed7d37b0 100644 --- a/tests/library/random-draw-test.cpp +++ b/tests/library/random-draw-test.cpp @@ -588,6 +588,19 @@ namespace test{ "val:+0 (00|50.00%)\n" "val:+1 (-1| 0.00%)\n" "val:+2 (-1| 0.00%)\n"_expect); + + + // ═════════ + draw.fixedVal(1); + report = "+++| fixedVal(1) \n"; + report += distribution(draw); + CHECK (report == + "+++| fixedVal(1) \n" + "val:-2 (-1| 0.00%)\n" + "val:-1 (-1| 0.00%)\n" + "val:+0 (-1| 0.00%)\n" + "val:+1 (00|100.00%)\n" + "val:+2 (-1| 0.00%)\n"_expect); } diff --git a/tests/vault/gear/test-chain-load-test.cpp b/tests/vault/gear/test-chain-load-test.cpp index 4dc84b60e..9180fb024 100644 --- a/tests/vault/gear/test-chain-load-test.cpp +++ b/tests/vault/gear/test-chain-load-test.cpp @@ -302,34 +302,74 @@ namespace test { - /** @test TODO demonstrate shaping of generated topology - * - TODO - * @todo WIP 11/23 🔁 define ⟶ 🔁 implement + /** @test demonstrate impact of reduction on graph topology + * - after one fixed initial expansion, reduction causes + * all chains to be joined eventually + * - expansion and reduction can counterbalance each other, + * leading to localised »packages« of branchings and reductions + * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void verify_Reduction() { ChainLoad32 graph; - // moderate symmetrical expansion with 40% probability and maximal +2 links - graph.expansionRule(graph.rule().mapping([&](Node* n) - { - if (isStart(n)) - return graph.rule().probability(1.0).maxVal(8).mapping([](size_t){ return 1.0; }); - else - return graph.rule(); - })) + // expand immediately at start and then gradually reduce / join chains + graph.expansionRule(graph.rule_atStart(8)) .reductionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555)) .buildToplolgy() - .printTopologyDOT() - .printTopologyStatistics() +// .printTopologyDOT() +// .printTopologyStatistics() ; -// CHECK (graph.getHash() == 0xAE332109116C5100); -SHOW_EXPR(graph.getHash()) + CHECK (graph.getHash() == 0x8454196BFA40CFE1); + + auto stat = graph.computeGraphStatistics(); + CHECK (stat.levels == 9); // This connection pattern filled 9 levels + CHECK (stat.indicators[STAT_JOIN].cnt == 4); // we got 4 »Join« events (reductions= + CHECK (stat.indicators[STAT_FORK].cnt == 1); // and the single expansion/fork + CHECK (stat.indicators[STAT_FORK].cL == 0.0); // ...sitting right at the beginning + CHECK (stat.indicators[STAT_NODE].cL == "0.37890625"_expect); // Nodes are concentrated towards the beginning + + + + // expansion and reduction can counterbalance each other + graph.expansionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555)) + .reductionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555)) + .buildToplolgy() +// .printTopologyDOT() +// .printTopologyStatistics() + ; + CHECK (graph.getHash() == 0x825696EA63E579A4); + + stat = graph.computeGraphStatistics(); + CHECK (stat.levels == 12); // This example runs a bit longer + CHECK (stat.indicators[STAT_NODE].pL == "2.6666667"_expect); // in the middle threading 3-5 Nodes per Level + CHECK (stat.indicators[STAT_FORK].cnt == 5); // with 5 expansions + CHECK (stat.indicators[STAT_JOIN].cnt == 3); // and 3 reductions + CHECK (stat.indicators[STAT_FORK].cL == "0.45454545"_expect); // forks dominating earlier + CHECK (stat.indicators[STAT_JOIN].cL == "0.66666667"_expect); // while joins need forks as prerequisite + + + + // expansion bursts can be balanced with a heightened reduction intensity + graph.expansionRule(graph.rule().probability(0.3).maxVal(4).shuffle(555)) + .reductionRule(graph.rule().probability(0.9).maxVal(2).shuffle(555)) + .buildToplolgy() +// .printTopologyDOT() +// .printTopologyStatistics() + ; + CHECK (graph.getHash() == 0xA850E6A4921521AB); + + stat = graph.computeGraphStatistics(); + CHECK (stat.levels == 12); // This graph has a similar outline + CHECK (stat.indicators[STAT_NODE].pL == "2.6666667"_expect); // in the middle threading 3-5 Nodes per Level + CHECK (stat.indicators[STAT_FORK].cnt == 7); // ...yet with quite different internal structure + CHECK (stat.indicators[STAT_JOIN].cnt == 9); // + CHECK (stat.indicators[STAT_FORK].cL == "0.41558442"_expect); + CHECK (stat.indicators[STAT_JOIN].cL == "0.62626263"_expect); + CHECK (stat.indicators[STAT_FORK].pLW == "0.19583333"_expect); // while the densities of forks and joins almost match, + CHECK (stat.indicators[STAT_JOIN].pLW == "0.26527778"_expect); // a slightly higher reduction density leads to convergence eventually } -//SHOW_EXPR(graph.getHash()) -//SHOW_EXPR(stat.indicators[STAT_NODE].pL) -//SHOW_EXPR(stat.indicators[STAT_JOIN].cL) @@ -342,6 +382,10 @@ SHOW_EXPR(graph.getHash()) { } +//SHOW_EXPR(graph.getHash()) +//SHOW_EXPR(stat.indicators[STAT_NODE].pL) +//SHOW_EXPR(stat.indicators[STAT_FORK].cL) +//SHOW_EXPR(stat.indicators[STAT_JOIN].cL) diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index 4a18ad27e..c044a23ee 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -317,8 +317,6 @@ namespace test { /* ===== topology control ===== */ - static Rule rule() { return Rule(); } - TestChainLoad&& seedingRule (Rule r) { @@ -348,6 +346,21 @@ namespace test { } + /** Abbreviation for starting rules */ + static Rule rule() { return Rule(); } + + static Rule + rule_atStart (uint v) + { + return Rule().mapping([v](Node* n) + { + return isStart(n)? Rule().fixedVal(v) + : Rule(); + }); + } + + + /** * Use current configuration and seed to (re)build Node connectivity. * While working in-place, the wiring and thus the resulting hash values diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 1346f0699..78fece6e0 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -96231,14 +96231,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - - + + + + + + + + - + @@ -96265,7 +96268,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + +
+
+ + +
@@ -96274,8 +96293,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + @@ -98894,6 +98914,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + +
@@ -99052,14 +99075,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + + + + @@ -99158,9 +99184,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + + + + + + + + + +

+ stattet jede seed-Node sofort mit einem festen Branch-Faktor aus +

+ +
+
+