Library: consider how to handle randomness in tests
Using random or pseudo-random numbers as input for tests can be a very effective tool to spot unintended behaviour in corner cases, and also helps writing more principled test verifications. However, investigating failures in randomised tests can be challenging. A well-proven solution is to exploit the **determinism** of pseudo-random-numbers by documenting a randomly generated seed, that can be re-injected for investigation. Up to now, most tests rely on the old library function `rand()`, while at some places already the C++ standard framework for random number generation is used, packaged into a custom wrapper. Adding adequate support for documented seed values seems to be easy to achieve, after switching existing usages of `rand()` to a suitable drop-in replacement. After some consideration, I decided ''against'' wiring random generator instances explicitly, while allowing to do so on occasion, when necessary. Thus the planned seeding mechanism will rather re-seed a ''implicit default'' generator, which could then be used to construct explicit generator instances when required (e.g. for multithreaded tests) As a starting point, this changeset replaces the `randomise()` API call by a direct access to the ''reseeding functionality'' exposed by the C++ framework and all default generators. Since we already provide a dedicated static instance of the plattform entropy source, re-randomisation can be achieved by seeding from there. NOTE: there was extended debate in the net, questioning the viability of the `std::random_seq` -- these arguments, while valid from a theoretical point of view, seem rather moot when placed into a practical context, where even 2^32 different generation-paths(cycles) are more than enough to provide sufficient diffusion of results (unless the goal is really to engage into Monte-Carlo simulations for scientific research or large model simulations). Notable most of the more catchy reprovals raised by Melissa O'Neill have been refuted by experts of the field, even while being still propagated at various places in the net, often combined with promoting PCG-Random.
This commit is contained in:
parent
71af21ffd6
commit
92bc044e9e
4 changed files with 584 additions and 48 deletions
|
|
@ -84,8 +84,8 @@ namespace lib {
|
||||||
void
|
void
|
||||||
randomiseRandomness()
|
randomiseRandomness()
|
||||||
{
|
{
|
||||||
entropyGen.randomise(entropyNucleus);
|
entropyGen.reseed(entropyNucleus);
|
||||||
defaultGen.randomise(entropyNucleus);
|
defaultGen.reseed(entropyNucleus);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lib
|
} // namespace lib
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace lib {
|
||||||
double uni() { return uniformD_(generator_); }
|
double uni() { return uniformD_(generator_); }
|
||||||
|
|
||||||
/** inject controlled randomisation */
|
/** inject controlled randomisation */
|
||||||
void randomise(SeedNucleus&);
|
void reseed (SeedNucleus&);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -121,9 +121,9 @@ namespace lib {
|
||||||
|
|
||||||
template<class GEN>
|
template<class GEN>
|
||||||
inline void
|
inline void
|
||||||
RandomSequencer<GEN>::randomise (SeedNucleus& nucleus)
|
RandomSequencer<GEN>::reseed (SeedNucleus& nucleus)
|
||||||
{
|
{
|
||||||
generator_.discard (nucleus.getSeed() % 55555);
|
generator_.seed (nucleus.getSeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,15 @@ namespace test {
|
||||||
CHECK (r2 == src2.u64());
|
CHECK (r2 == src2.u64());
|
||||||
CHECK (r3 == src2.uni());
|
CHECK (r3 == src2.uni());
|
||||||
|
|
||||||
src1.randomise(coreOfEvil);
|
src1.reseed (coreOfEvil);
|
||||||
CHECK (src1.i32() != src2.i32());
|
CHECK (src1.u64() != src2.u64());
|
||||||
|
|
||||||
src2.randomise(coreOfEvil);
|
src2.reseed (coreOfEvil);
|
||||||
|
CHECK (src1.u64() != src2.u64());
|
||||||
|
(void) src2.u64();
|
||||||
|
CHECK (src1.u64() == src2.u64());
|
||||||
CHECK (src1.i32() == src2.i32());
|
CHECK (src1.i32() == src2.i32());
|
||||||
|
CHECK (src1.uni() == src2.uni());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14530,9 +14530,7 @@
|
||||||
<node CREATED="1529016854248" FOLDED="true" HGAP="37" ID="ID_1664191705" MODIFIED="1561827482928" TEXT="Abwägung" VSHIFT="5">
|
<node CREATED="1529016854248" FOLDED="true" HGAP="37" ID="ID_1664191705" MODIFIED="1561827482928" TEXT="Abwägung" VSHIFT="5">
|
||||||
<node CREATED="1529016871262" ID="ID_957194065" MODIFIED="1529017825322" TEXT="Variante-2 verschiebt das Problem">
|
<node CREATED="1529016871262" ID="ID_957194065" MODIFIED="1529017825322" TEXT="Variante-2 verschiebt das Problem">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...denn das eigentliche Problem ist,
|
...denn das eigentliche Problem ist,
|
||||||
|
|
@ -14548,9 +14546,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1529017693432" ID="ID_70956393" MODIFIED="1529018209759" TEXT="Variante-3 verwendet zwei Repräsentationen für die gleiche Sache">
|
<node CREATED="1529017693432" ID="ID_70956393" MODIFIED="1529018209759" TEXT="Variante-3 verwendet zwei Repräsentationen für die gleiche Sache">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
und zwar für die abstrahierte GUI-Location
|
und zwar für die abstrahierte GUI-Location
|
||||||
|
|
@ -16587,9 +16583,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1487119230659" ID="ID_651577067" MODIFIED="1518487921076">
|
<node CREATED="1487119230659" ID="ID_651577067" MODIFIED="1518487921076">
|
||||||
<richcontent TYPE="NODE"><html>
|
<richcontent TYPE="NODE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Frage: wieviel Interaction Control
|
Frage: wieviel Interaction Control
|
||||||
|
|
@ -19489,9 +19483,7 @@
|
||||||
<icon BUILTIN="info"/>
|
<icon BUILTIN="info"/>
|
||||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1664055752785" ID="ID_1076715259" MODIFIED="1664055785130">
|
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1664055752785" ID="ID_1076715259" MODIFIED="1664055785130">
|
||||||
<richcontent TYPE="NODE"><html>
|
<richcontent TYPE="NODE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Analyse: welche <i>beweglichen Teile </i>gibt es überhaupt?
|
Analyse: welche <i>beweglichen Teile </i>gibt es überhaupt?
|
||||||
|
|
@ -25506,9 +25498,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1612008922562" ID="ID_458884534" MODIFIED="1612009068409" TEXT="nur ein historisches Überbleibsel">
|
<node CREATED="1612008922562" ID="ID_458884534" MODIFIED="1612009068409" TEXT="nur ein historisches Überbleibsel">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
ich wollte mal ein viel generischeres Design schaffen, das sogar eine Art Grundgerüst für das Zusammenbauen des GUI sein könnte. In der vertieften Analyse wurde dann aber klar, daß dieses Design nicht so ohne Weiteres realisierbar ist. Daraufhin habe ich beschlossen, die Idee aufzugeben und stattdessen auf Einzelfälle zu spezialisieren. Und in einem weiteren Schritt habe ich dann die Themen "Grid" und "Canvas" voneinander getrennt
|
ich wollte mal ein viel generischeres Design schaffen, das sogar eine Art Grundgerüst für das Zusammenbauen des GUI sein könnte. In der vertieften Analyse wurde dann aber klar, daß dieses Design nicht so ohne Weiteres realisierbar ist. Daraufhin habe ich beschlossen, die Idee aufzugeben und stattdessen auf Einzelfälle zu spezialisieren. Und in einem weiteren Schritt habe ich dann die Themen "Grid" und "Canvas" voneinander getrennt
|
||||||
|
|
@ -33489,9 +33479,7 @@
|
||||||
<icon BUILTIN="stop-sign"/>
|
<icon BUILTIN="stop-sign"/>
|
||||||
<node CREATED="1564868166273" ID="ID_945377761" MODIFIED="1564868267923" TEXT="kann das problematische Verhalten reproduzieren">
|
<node CREATED="1564868166273" ID="ID_945377761" MODIFIED="1564868267923" TEXT="kann das problematische Verhalten reproduzieren">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Wenn man einen neuen Gtk::StyleContext erzeugt,
|
Wenn man einen neuen Gtk::StyleContext erzeugt,
|
||||||
|
|
@ -40004,9 +39992,7 @@
|
||||||
<node CREATED="1624112504484" ID="ID_585066990" MODIFIED="1624112524179" TEXT="deaktivieren der anderen Test-zeichen-Funktion (Grounding) beweirkt nichts"/>
|
<node CREATED="1624112504484" ID="ID_585066990" MODIFIED="1624112524179" TEXT="deaktivieren der anderen Test-zeichen-Funktion (Grounding) beweirkt nichts"/>
|
||||||
<node CREATED="1624112533168" ID="ID_1573289000" MODIFIED="1624113075023" TEXT="der berechnete Radius ist stets konsistent und variiert nicht, wenn man den Clip verschiebt">
|
<node CREATED="1624112533168" ID="ID_1573289000" MODIFIED="1624113075023" TEXT="der berechnete Radius ist stets konsistent und variiert nicht, wenn man den Clip verschiebt">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
ein cout in genau diesem Testcode gibt stets nur alternierend den Allocation-Wert für den Ruler-Canvas (konstant 5px) und dann den Main-Canvas (variiert mit Fensterhöhe) aus
|
ein cout in genau diesem Testcode gibt stets nur alternierend den Allocation-Wert für den Ruler-Canvas (konstant 5px) und dann den Main-Canvas (variiert mit Fensterhöhe) aus
|
||||||
|
|
@ -46632,9 +46618,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1448078778916" ID="ID_1657108949" MODIFIED="1576282358015" TEXT="Fehler löschen">
|
<node CREATED="1448078778916" ID="ID_1657108949" MODIFIED="1576282358015" TEXT="Fehler löschen">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
mark "clearErr"
|
mark "clearErr"
|
||||||
|
|
@ -47207,9 +47191,7 @@
|
||||||
<node CREATED="1455668897947" FOLDED="true" HGAP="211" ID="ID_1897861223" MODIFIED="1576200713578" TEXT="Konsequenzen" VSHIFT="23">
|
<node CREATED="1455668897947" FOLDED="true" HGAP="211" ID="ID_1897861223" MODIFIED="1576200713578" TEXT="Konsequenzen" VSHIFT="23">
|
||||||
<node CREATED="1455668923175" ID="ID_1183550957" MODIFIED="1575133324169" TEXT="brauche passendes UI-Bus API">
|
<node CREATED="1455668923175" ID="ID_1183550957" MODIFIED="1575133324169" TEXT="brauche passendes UI-Bus API">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
....so harmlos hat alles angefangen
|
....so harmlos hat alles angefangen
|
||||||
|
|
@ -47738,9 +47720,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1470778603801" ID="ID_1808045935" MODIFIED="1575133326567" TEXT="needed to implement the `del` verb">
|
<node CREATED="1470778603801" ID="ID_1808045935" MODIFIED="1575133326567" TEXT="needed to implement the `del` verb">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
since skipSrc performs both the `del` and the `skip` verb, it can not perform the match itself...
|
since skipSrc performs both the `del` and the `skip` verb, it can not perform the match itself...
|
||||||
|
|
@ -47952,9 +47932,7 @@
|
||||||
<node CREATED="1455928427432" ID="ID_1189452497" MODIFIED="1455928435275" TEXT="push mutator on stack"/>
|
<node CREATED="1455928427432" ID="ID_1189452497" MODIFIED="1455928435275" TEXT="push mutator on stack"/>
|
||||||
<node CREATED="1457190622236" ID="ID_1347446227" MODIFIED="1461946862429">
|
<node CREATED="1457190622236" ID="ID_1347446227" MODIFIED="1461946862429">
|
||||||
<richcontent TYPE="NODE"><html>
|
<richcontent TYPE="NODE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
invoke <b>mutateChild</b>
|
invoke <b>mutateChild</b>
|
||||||
|
|
@ -48183,9 +48161,7 @@
|
||||||
<node CREATED="1456186634006" ID="ID_310265994" MODIFIED="1512926191948" TEXT="Profil des Mutators">
|
<node CREATED="1456186634006" ID="ID_310265994" MODIFIED="1512926191948" TEXT="Profil des Mutators">
|
||||||
<node CREATED="1456186654411" ID="ID_1341247857" MODIFIED="1575133328189" TEXT="Erzeugen geht schnell">
|
<node CREATED="1456186654411" ID="ID_1341247857" MODIFIED="1575133328189" TEXT="Erzeugen geht schnell">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
nur Zuweisung einiger Referenzen
|
nur Zuweisung einiger Referenzen
|
||||||
|
|
@ -57147,6 +57123,293 @@
|
||||||
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_677674501" MODIFIED="1729979344958" TEXT="useFrameTable"/>
|
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_677674501" MODIFIED="1729979344958" TEXT="useFrameTable"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730904143330" ID="ID_25783469" MODIFIED="1730904275397" TEXT="#1378 controlled random seed for tests">
|
||||||
|
<linktarget COLOR="#c4145f" DESTINATION="ID_25783469" ENDARROW="Default" ENDINCLINATION="6546;452;" ID="Arrow_ID_1019579428" SOURCE="ID_1500320757" STARTARROW="None" STARTINCLINATION="1769;146;"/>
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
<node CREATED="1730931170413" HGAP="34" ID="ID_480480032" MODIFIED="1731119671920" TEXT="diverse Zweifel <random> betreffend" VSHIFT="44">
|
||||||
|
<arrowlink COLOR="#968bb0" DESTINATION="ID_607929754" ENDARROW="Default" ENDINCLINATION="-1401;152;" ID="Arrow_ID_682771755" STARTARROW="None" STARTINCLINATION="-1300;91;"/>
|
||||||
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
|
<node CREATED="1730931709389" ID="ID_470384484" MODIFIED="1730931818828" TEXT="Mersenne-Twister ist schwergewichtig">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...für den Zweck hier; wir brauchen durchaus mengenweise Zufallszahlen mit guten statistischen Eigenschaften, aber wir brauchen weder unglaublich lange Zyklenzahlen, noch bauchen wir einen extrem großen Konfigurationsraum
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<node CREATED="1731114749603" ID="ID_1333921517" MODIFIED="1731114769121" TEXT="man könnte stattdessen einen Jenkins-PRNG nehmen"/>
|
||||||
|
<node CREATED="1731114769721" ID="ID_415822546" MODIFIED="1731114790753" TEXT="oder xoroshiro oder vergleichbare moderne Algorithmen"/>
|
||||||
|
<node CREATED="1731114793582" ID="ID_1481410578" MODIFIED="1731114948438" TEXT="Maßstab: muß PractRand-Test bestehen und allgemein akzeptiert sein">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1730931890948" HGAP="67" ID="ID_408643074" MODIFIED="1731118671023" TEXT="sollte / kann man die seed-seq unterstützen?" VSHIFT="5">
|
||||||
|
<arrowlink COLOR="#3e50ba" DESTINATION="ID_276440200" ENDARROW="Default" ENDINCLINATION="26;-49;" ID="Arrow_ID_715484019" STARTARROW="None" STARTINCLINATION="-29;40;"/>
|
||||||
|
<icon BUILTIN="help"/>
|
||||||
|
<icon BUILTIN="hourglass"/>
|
||||||
|
<node CREATED="1730931907482" ID="ID_417270187" MODIFIED="1730932170717" TEXT="der aktuelle Entwuf verwendet einen uint64_t als seed">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...und mein Interface SeedNucleus ist nur darauf ausgelegt (auf den kleinsten gemeinsamen Nenner)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730931956979" ID="ID_1736173821" MODIFIED="1730932147229" TEXT="seed-seq ist ein spezielles Ding für den C++-Standard">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...und zu allem Überfluß gibt es auch noch eine recht fragwürdige standard-Implementierung, std::seed_seq, welche die gegebenen Zahlen in einen Vector auf den Heap speichert.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730931976544" ID="ID_449303857" MODIFIED="1730932077893" TEXT="aber: jeder PRNG verlangt eigentlich nach einem passenden Seed-Mechanismus">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
meist wird Seeden aus einer einzigen Zahl unterstützt, aber viele Algorithmen brauchen eigentlich mehr <i>initial state</i> und hierfür ist mehr Seed-Input nützlich; wenn man also eine größere Entropiequelle hätte, könnte man eine bessere Diffusion erreichen
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730932173054" ID="ID_1175501386" MODIFIED="1730932275229" TEXT="dieses Problem läuft auf einen double-Dispatch hinaus">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...sofern man tatsächlich ein abstrahiertes Interface für das Seeding haben möchte (d.h. im usage-Kontext ist nicht explizit klar, was für eine Quelle tatsächlich verwendet wird)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731115073844" HGAP="115" ID="ID_276440200" MODIFIED="1731118661070" TEXT="Diskussion" VSHIFT="9">
|
||||||
|
<linktarget COLOR="#3e50ba" DESTINATION="ID_276440200" ENDARROW="Default" ENDINCLINATION="26;-49;" ID="Arrow_ID_715484019" SOURCE="ID_408643074" STARTARROW="None" STARTINCLINATION="-29;40;"/>
|
||||||
|
<node CREATED="1731115107291" ID="ID_864947379" MODIFIED="1731117162631" TEXT="der Zweck für std::seed_seq und mein SeedNucleus überschneiden sich (nur) teilweise">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced" size="5">std::seed_seq </font>
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
soll vor allem die Schwächen des Mersenne-Twister überbrücken, welcher einen sehr großen <i>initial state</i> benötigt, und für einige Eingabe-Sequenzen gefährlich degenerieren kann; diese Idee wurde dann verallgemeinert...
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
unabhängig davon wurde aber die zweite Variante erlaubt, nämlich den Random-Generator mit einer einzigen Zahl zu seeden...
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Melissa O'Neil (sie spätere Autorin von PCG-Random) hat den Algorithmus für seed_seq dahingehend kritisiert, daß dieser eiene große Menge Entropie nicht optimal nutzt. Dem wurde von verschiedener Seite widersprochen; desweiteren ist fraglich, für welche Art Anwendungen diese Frage überhaupt relevant ist; denn auch nur mit einem einzigen Seed-Value erzeugt der Mersenne-Twiseter 2^32 verschiedene, extrem hochqualitative Sequenzen — es geht nur um die Frage, ob er auch 2^(624·32) verschiedene Sequenzen erzeugen <i>könnte.</i>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
das Interface für <random> ist <b>generisch</b>: es gibt ein <i>Konzept</i> für Seed-seq, und ein <i>Konzept</i> Generator, und die beiden werden dann jeweils für den Einzelfall konkret kombiniert
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced" size="5">SeedNucleus </font>
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
ist auf die besondere Situation ausgerichtet, daß ein <i>nicht näher bekannter </i>Generator irgendwann zur Laufzeit eine <i>nicht näher bekannte Seed-Quelle</i> bekommen soll
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
es soll also <b>zur Laufzeit<i> </i></b>aber damit auch <b>dynamisch</b> umgeschaltet werden zwischen einem festen Seed und deterministischem Verhalten und pseudo- oder echter Randomisierung
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
hier ist also die <i>potentielle reproduzierbarkeit</i> eine zentrale Hinsicht, wohingegen davon ausgegangen wird, daß durch <i>interaktiven Gebrauch </i>ohnehin eine unerschöpfliche Entropie-Quelle gegeben ist
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731117195402" ID="ID_1258145243" MODIFIED="1731118502486" TEXT="theoretisch könnte das Interface SeedNucleus zur Basis einer Seed-seq gemacht werden">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...und zwar würde es genügen, statt eines Seed-Value einen Iterator zurückzuliefern; dieses Proxy-Objekt müßte dann allerdings im Typ entsprechend fixiert sein (also z.B. ein uint32_t*). Dann bliebe allerdings auch noch die Frage offen, ob auch der im C++-Standard festgelegte Algorithmus implementiert werden muß, d.h. ob intern aus dem Aufruf des SeedNucleus wieder eine konforme Seed-seq erzeugt werden soll. <i>Das wäre durchaus machbar </i>(er ist genau spezifiziert und leicht zu implementieren) — würde aber wieder die gleichen Probleme aufwerfen, die auch für <font face="Monospaced">std::seed_seq</font> gelten:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
der Algorithmus muß die Länge der gelieferten Seed-Seq und die Länge der Quell-Sequenz kennen ⟹ beide Infos könnte man aus Pointer-Arrithmetik gewinnen (und das bereitzustellende C++ Interface für die Seed-seq läßt auch gar keinen anderen Ausweg zu)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
alle Unsicherheiten und Einwände bezüglich der Qualität der Seed-seq. bleiben bestehen (das wäre aber immer noch besser als nur ein einziger Seed-Wert)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
es bleibt offen, ob dieses Schema auch für andere (modernere) PRNG-Algorithmen vorteilhaft ist
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731118532378" ID="ID_1249119445" MODIFIED="1731118574223">
|
||||||
|
<richcontent TYPE="NODE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
<u>damit wird klar</u>: das aktuelle SeedNucleus-Interface is <i>zunächst gut genug</i> (KISS)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731119513557" ID="ID_855133847" MODIFIED="1731119527125" TEXT="Framework muß SeedNucleus bereitstellen"/>
|
||||||
|
<node CREATED="1731119593065" ID="ID_611482095" MODIFIED="1731119612642" TEXT="idealerweise hoch integriert (incl Seed-Aufzeichnung)"/>
|
||||||
|
<node CREATED="1731118896406" ID="ID_1421362358" MODIFIED="1731118913959" TEXT="muß den eingespeisten Seed speichern/dokumentieren können">
|
||||||
|
<node CREATED="1731119024672" ID="ID_1486830658" MODIFIED="1731119227210" TEXT="das ist kniffelig: es widerspricht der Offenheit der Interfaces">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
der SeedNucleus soll ja eben grade opaque sein, also möchte ich da keine zusätzliche Operation zum State-Speichern hinzunehmen; und für die std::seed_seq ergibt sich das Problem, daß die Länge nicht bekannt ist; man bekäme also u.U eine unbeschränkt lange Sequenz von Zahlen als Seed-Zustand
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731119229401" ID="ID_49565117" MODIFIED="1731119356668" TEXT="aber ein Dekorator würde sich hier anbieten">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
ein SeedNucleus, der einen quell-Nucleus einpackt und den/die ausgelesenen Wert(e) dokumentiert
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
und natürlich dann als Gegenstück ein Seed-Nucleus der einen festen Wert ausliefert (trivial), oder ggfs. sogar eine Weiche, die entweder die Quelle verwendet, oder einen gegeben Override
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731118832589" ID="ID_732098473" MODIFIED="1731119409643" TEXT="brauche eine reseed()-Operation um einen Seed wiederherzustellen">
|
||||||
|
<node CREATED="1731118937690" ID="ID_876325939" MODIFIED="1731118961825" TEXT="der C++ - Standard bietet de-facto diese Operation auf allen enthaltenen Engines"/>
|
||||||
|
<node CREATED="1731118962605" ID="ID_1749223447" MODIFIED="1731118982278" TEXT="notfalls könnte man aber auch ein in-place Destroy / re-Construct machen"/>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731119637225" ID="ID_955411605" MODIFIED="1731119733338" TEXT="reseed()-Operation auf unser RandomSequencer-Interface übernehmen">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731187281299" ID="ID_1511041306" MODIFIED="1731187308599" TEXT="dafür fällt die randomise()-Operation weg">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
<node CREATED="1731187320199" ID="ID_622096601" MODIFIED="1731187577587" TEXT="der Hauptzweck fällt weg">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
eigentlich hatte ich das nur als Vorsichtsmaßnahme eingefürt, da wir noch kein Framework für Zufallszahlen in Tests hatten; die Tests liefen seither stets mit einem festen Seed los, aber es sollte eben eine »Hintertür« geben, mit der man in bestimmte Tests echte Zufälligkeit injizieren klnnte
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731187426374" ID="ID_1937305565" MODIFIED="1731187480844" TEXT="bzw. kann durch reseed() aus der Entropiequelle realisiert werden"/>
|
||||||
|
<node CREATED="1731187581651" ID="ID_684894821" MODIFIED="1731187950869" TEXT="sollte das discard() gebraucht werden, kann man es ja leicht auf das API herausführen">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...das wäre nur notwendig, wenn mal eine ganze Familie von Generatoren (z.B. in parallelen Tests) zum Einsatz kommt, und zudem der unterliegende PRNG eine schlechte Diffusion hat. Normalerweise aber erzeugen wir solche Generatoren (gemäß diesem Plan) nun stets aus dem Seed eines Vater-Generators, und wir verwenden qualitativ hochwertige PRNGs, und das sollte eigentlich zur Dekorrelation genügen
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731119762690" ID="ID_1637478235" MODIFIED="1731119834979" TEXT="Entwurf: lib::test::Test::useRandom()">
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
<node CREATED="1731119858173" ID="ID_1447736454" MODIFIED="1731119870919" TEXT="verwendet einen eingebetteten SeedNucleus"/>
|
||||||
|
<node COLOR="#5b280f" CREATED="1731120003113" ID="ID_1177767927" MODIFIED="1731176382320" TEXT="jeder Aufruf erzeugt ein neues RandomSequencer-Objekt">
|
||||||
|
<icon BUILTIN="button_cancel"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731119876579" ID="ID_1129580767" MODIFIED="1731119987245" TEXT="sorgt dafür, daß der gezogene Seed dokumentiert wird">
|
||||||
|
<node COLOR="#435e98" CREATED="1731120117194" ID="ID_1685729849" MODIFIED="1731120697456" TEXT="Problem: wo?">
|
||||||
|
<icon BUILTIN="help"/>
|
||||||
|
<node CREATED="1731120134129" ID="ID_633936698" MODIFIED="1731120148682" TEXT="STDOUT und STDERR können mit Test-Definitionen interferieren"/>
|
||||||
|
<node CREATED="1731120153767" ID="ID_760903903" MODIFIED="1731120181309" TEXT="der Output vom Testrunner ist normalerweise im Test-Log nicht sichtbar"/>
|
||||||
|
<node CREATED="1731120248436" ID="ID_473259633" MODIFIED="1731120275108" TEXT="bisher ist der Testrunner selber ohne Seiteneffekte"/>
|
||||||
|
<node CREATED="1731120293131" ID="ID_685863529" MODIFIED="1731120310311" TEXT="müßte also entweder ein Logfile einführen oder im Fehlerfall ausgeben">
|
||||||
|
<node CREATED="1731120519654" ID="ID_236130865" MODIFIED="1731120546192" TEXT="Cehteh's test.sh erfüllt das bereits">
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731120547220" ID="ID_1582896343" MODIFIED="1731120597014" TEXT="es schreibt den kompletten STDOUT nur im Fehlerfall ins Log"/>
|
||||||
|
<node CREATED="1731120597722" ID="ID_1682502018" MODIFIED="1731120650108" TEXT="es filtert die ITRACE\|INFO\|NOTICE\|WARNING\|ERR -Präfixe"/>
|
||||||
|
<node CREATED="1731120684335" ID="ID_1251466681" MODIFIED="1731120694337" TEXT="Fazit: Ausgabe per NOTICE">
|
||||||
|
<icon BUILTIN="forward"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731120702508" ID="ID_1798637658" MODIFIED="1731120716944" TEXT="es wird also bei jedem Ziehen eines Seed ein NOTICE-Log geschrieben">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731120731502" ID="ID_1120851239" MODIFIED="1731120769966" TEXT="neue Kommandozeilen-Parameter: --seed <zahl>">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731176387690" ID="ID_94726091" MODIFIED="1731176394537" TEXT="Überlegungen zum API">
|
||||||
|
<node CREATED="1731176395547" ID="ID_37424726" MODIFIED="1731176788372" TEXT="in den meisten Fällen will man grade nicht ein separates Generator-Objekt">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...und zwar weil das einfach umständlich ist, die Aufrufe sind länger, man muß es durchreichen und ggfs ist dann doch noch irgendwo bei den sonstigen Utilities ein versteckter Aufruf des default-Generators. Es gibt auch nur selten einen Mehrwert, verschiedene Generatoren zu verwenden; das wäre nur notwendig wenn ein komplexer Prozeß durchgeführt wird, der in Teilen nicht völlig ablaufstabil ist, z.B. weil in mehreren Threads unabhängig voneinander Zufallszahlen gezogen werden.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731176410657" ID="ID_633466859" MODIFIED="1731176429803" TEXT="sondern es soll ein Seed für den globalen default-Generator gezogen werden"/>
|
||||||
|
<node CREATED="1731176432311" ID="ID_1316146764" MODIFIED="1731176574679" TEXT="ein eigenständiges Generator-Objekt könnte man im Einzelfall eigens erzeugen"/>
|
||||||
|
<node CREATED="1731176808100" ID="ID_515962490" MODIFIED="1731176815919" TEXT="demnach ⟹">
|
||||||
|
<node CREATED="1731176816814" ID="ID_1980459271" MODIFIED="1731177262259" TEXT="seedRand() zieht einen Seed">
|
||||||
|
<node CREATED="1731186698753" ID="ID_127278587" MODIFIED="1731186713681" TEXT="der Seed stammt aus einem dem Test übergebenen SeedNucleus"/>
|
||||||
|
<node CREATED="1731176842048" ID="ID_1519596014" MODIFIED="1731176862001" TEXT="mit diesem wird der default-Generator reseeded"/>
|
||||||
|
<node CREATED="1731176862637" ID="ID_1163242877" MODIFIED="1731176885007" TEXT="und er wird sofort auch ins Log dokument"/>
|
||||||
|
<node CREATED="1731176893512" ID="ID_1023102076" MODIFIED="1731176919929" TEXT="falls --seed gegeben, wird jeder Aufruf hier identisch den gegebenen Seed einspielen"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731177263762" ID="ID_1481572854" MODIFIED="1731177282680" TEXT="makeRandGen() erzeugt einen sub-Generator">
|
||||||
|
<node CREATED="1731177285016" ID="ID_306167360" MODIFIED="1731177302182" TEXT="dieser zieht eine Zufallszahl als Seed aus dem globalen Generator"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731177591628" ID="ID_1624911975" MODIFIED="1731177628806" TEXT="ein seedRand()-Aufruf muß davor stehen und darf nur einmal pro Testfall auftreten">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
<node CREATED="1731177631334" ID="ID_1783058296" MODIFIED="1731177642233" TEXT="d.h. ich baue keine Magie und kein Caching ein"/>
|
||||||
|
<node CREATED="1731177648796" ID="ID_1045172770" MODIFIED="1731186652255">
|
||||||
|
<richcontent TYPE="NODE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
der Test-Autor ist selber dafür verantwortlich,<br />die Zufallszahlen-Generierung zu verstehen...
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731186827432" ID="ID_1343084270" MODIFIED="1731186876763" TEXT="nested Helper-Klassen für Distributionen">
|
||||||
|
<node CREATED="1731186885784" ID="ID_1137186891" MODIFIED="1731186909601" TEXT="sie bekommen optional einen Generator als ctor-Argument"/>
|
||||||
|
<node CREATED="1731186910274" ID="ID_1712434077" MODIFIED="1731186920709" TEXT="oder hängen sich ansonsten an den default-Generator"/>
|
||||||
|
<node CREATED="1731186949918" ID="ID_1074918802" MODIFIED="1731187011177" TEXT="man könnte das später in ein Generatoren-Framework ausbauen">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
etwa analog zu dem Framework, welches mein Kollege Oleg Galimov bei der Baaderbank mitgebracht hat (es ist OpenSource, in Java geschrieben)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -91576,6 +91839,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827961401" ID="ID_927640003" MODIFIED="1730827975594" TEXT="die Test-Ontology als Singleton zugänglich machen">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827961401" ID="ID_927640003" MODIFIED="1730827975594" TEXT="die Test-Ontology als Singleton zugänglich machen">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730900496156" ID="ID_744198194" MODIFIED="1730900506692" TEXT="erweiterte Verifikationen für den TestFrame">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
<node CREATED="1730900509282" ID="ID_683548249" MODIFIED="1730900578353">
|
||||||
|
<richcontent TYPE="NODE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
läuft darauf hinaus,
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
nun den Umbau anzugehen
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<arrowlink COLOR="#6f2328" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="366;-47;" ID="Arrow_ID_1067356199" STARTARROW="None" STARTINCLINATION="5;52;"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827998905" ID="ID_1794368282" MODIFIED="1730828011958" TEXT="Adapter-λ bereitstellen">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827998905" ID="ID_1794368282" MODIFIED="1730828011958" TEXT="Adapter-λ bereitstellen">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -91620,10 +91901,43 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786359782" ID="ID_525505656" MODIFIED="1728786374933" TEXT="Spec und Seed generieren und verarbeiten">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786359782" ID="ID_525505656" MODIFIED="1728786374933" TEXT="Spec und Seed generieren und verarbeiten">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1730835558270" TEXT="Umbau TestFrame">
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1730900564912" TEXT="Umbau TestFrame">
|
||||||
<arrowlink COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
|
<arrowlink COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
|
||||||
<linktarget COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" SOURCE="ID_936086670" STARTARROW="None" STARTINCLINATION="-36;80;"/>
|
<linktarget COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" SOURCE="ID_936086670" STARTARROW="None" STARTINCLINATION="-36;80;"/>
|
||||||
|
<linktarget COLOR="#6f2328" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="366;-47;" ID="Arrow_ID_1067356199" SOURCE="ID_683548249" STARTARROW="None" STARTINCLINATION="5;52;"/>
|
||||||
<icon BUILTIN="pencil"/>
|
<icon BUILTIN="pencil"/>
|
||||||
|
<node CREATED="1730900637026" ID="ID_1500320757" MODIFIED="1730904275397" TEXT="brauche Einfluß auf den PRNG">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...im Hinblick auf Reproduzierbarkeit sollte die Voraussetzung geschaffen werden, einen Testfall au einem einzigen Seed zu speisen (auch wenn das weitere Framework für derart reproduzierbare Testfälle noch nicht gegeben ist)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<arrowlink COLOR="#c4145f" DESTINATION="ID_25783469" ENDARROW="Default" ENDINCLINATION="6546;452;" ID="Arrow_ID_1019579428" STARTARROW="None" STARTINCLINATION="1769;146;"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730900645921" ID="ID_1469990348" MODIFIED="1730901263434" TEXT="brauche Umstellung des Headers">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
der Header sollte optional sein (und hinter den Daten liegen), aber die Gegenwart eines Headers sollte explizit erkennbar sein
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730900658104" ID="ID_1382506504" MODIFIED="1730900815598" TEXT="brauche Daten-Prüfsumme auch nach Manipulation">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
bisher haben wir nur nach einem Standard generierte Serien von Zufallsdaten, das heißt, wir könnten eine Speicher-Korruption erkennen, oder eben daß diese Daten geändert wurden; was aber fehlt die die Möglichkeit, <i>nach einer solchen Änderung</i> den neuen Stand wieder durch eine Prüfsumme zu qualifizieren (wodurch man ein <i>erwartetes Ergebnis</i> feststellen könnte)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -137843,6 +138157,107 @@ std::cout << tmpl.render({"what", "World"}) << s
|
||||||
<node CREATED="1710186359368" ID="ID_765629285" MODIFIED="1710186365813" TEXT="Info">
|
<node CREATED="1710186359368" ID="ID_765629285" MODIFIED="1710186365813" TEXT="Info">
|
||||||
<icon BUILTIN="info"/>
|
<icon BUILTIN="info"/>
|
||||||
<node CREATED="1710186277136" ID="ID_336649935" LINK="https://en.cppreference.com/w/cpp/numeric/random" MODIFIED="1710186690629" TEXT="Standard-Lib: (pseudo)-random number generation"/>
|
<node CREATED="1710186277136" ID="ID_336649935" LINK="https://en.cppreference.com/w/cpp/numeric/random" MODIFIED="1710186690629" TEXT="Standard-Lib: (pseudo)-random number generation"/>
|
||||||
|
<node CREATED="1730916530347" FOLDED="true" ID="ID_607929754" MODIFIED="1731115515196" TEXT="Probleme / Diskussion">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
 
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<linktarget COLOR="#968bb0" DESTINATION="ID_607929754" ENDARROW="Default" ENDINCLINATION="-1401;152;" ID="Arrow_ID_682771755" SOURCE="ID_480480032" STARTARROW="None" STARTINCLINATION="-1300;91;"/>
|
||||||
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
|
<node CREATED="1730916541434" ID="ID_1186515484" MODIFIED="1730916550532" TEXT="nicht klar wie man »korrekt« seeded">
|
||||||
|
<node CREATED="1730916551768" ID="ID_1877378489" LINK="https://www.pcg-random.org/posts/cpp-seeding-surprises.html" MODIFIED="1730917591055" TEXT="oft zitierter Blog-Artikel der dies problematisiert">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p http-equiv="content-type" content="text/html; charset=utf-8" class="byline author vcard">
|
||||||
|
Melissa .E. O'Neill
|
||||||
|
</p>
|
||||||
|
<p class="dateline">
|
||||||
|
<a href="https://www.pcg-random.org/posts/cpp-seeding-surprises.html#" rel="bookmark"><time class="published dt-published" datetime="2015-04-16T01:22:00-07:00" itemprop="datePublished" title="2015-04-16 01:22">
|
||||||
|
2015-04-16</time></a>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<node CREATED="1730927161676" ID="ID_1870117805" MODIFIED="1730927175433" TEXT="die Autorin von PCG">
|
||||||
|
<arrowlink COLOR="#a9b4c1" DESTINATION="ID_595255954" ENDARROW="Default" ENDINCLINATION="228;0;" ID="Arrow_ID_1247304219" STARTARROW="None" STARTINCLINATION="228;25;"/>
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730916627654" ID="ID_307539744" LINK="https://simplecxx.github.io/2021/11/27/debunking-all-myths-about-mt19937.html" MODIFIED="1730916723282" TEXT="Widerspruch hierzu">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
»Simple C++« Dimitrij Mijoski  2021-11<br /><br />
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730921869936" ID="ID_897784412" MODIFIED="1730921874684" TEXT="Streitpunkte">
|
||||||
|
<node CREATED="1730921876360" ID="ID_1711092381" MODIFIED="1730922258576" TEXT="Wahrscheinlichkeit bestimmte (feste) Zahlen zu ziehen">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Letztlich werde ich aus der Diskussion zu diesem Aspekt nicht klug. Zumindest aber sind nicht alle möglichen Ergebniszahlen sofort zu Beginn gleich wahrscheinlich; es wird auch immer wieder ein Zusammenhang impliziert mit dem Umfang des <i>internal state</i>, der beim Mersenne-Twister extrem groß ist (624 int). Festzuhalten bleibt, daß ein PRNG eine gweisse <b>predictability</b> haben kann, und das heißt, man sollte sich niemals auf das Auftreten / nicht-auftreten bestimmter Zahlen verlassen. Die Eigenschaften zeigen sich erst im statistischen Durchschnitt. Will man eine echte Zufallszahl, muß man eine echte Zufallszahl nehmen
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730922284177" ID="ID_1548923616" MODIFIED="1730922467479" TEXT="Der Zustandsraum für mögliche Sequenzen ist durch den Seed begrenzt">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...das heißt, nur wenn man tatsächlich mit 624 ints seeded, erreicht man alle möglichen Sequenzen. Wobei aber bereits zwei ints (2^64) für die meisten praktischen Probleme mehr als genug sein sollte; problematisch wird das nur bei Simulationen und Lösungssuche durch Monte-Carlo.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730922568811" ID="ID_1106941071" MODIFIED="1730922708295" TEXT="std::seed_seq muß eine Heap-Allokation machen">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...darauf wird nirgends hingeweisen, und es gibt ein Interface, um einen Allokator einzuführen. Kritisiert wird auch generell das Interface für std::seed_seq — die Stichhaltigkeit dieser Kritik kann ich nicht beurteilen (anders als daß es nicht „einfach“ ist)
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<icon BUILTIN="clanbomber"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730922731765" ID="ID_648439878" MODIFIED="1730923152857" TEXT="die Standard-Implementierungen bieten keine gute Auswahl">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Es läuft darauf hinaus, den Mersenne-Twister in Form von std::mt19937 als »default« zu verwenden. Und der ist langsam, braucht viel Speicher und ist kompliziert zu seeden. Außerdem sind die gebotenen Distributions-Funktionen allesamt nicht portabel (sondern implementation-defined). Leider werden dann in der Diskussion (Reddit, Stackoverflow) diverse Favoriten genannt, für die es dann stets auch wieder (ohne tiefere Expertise schwer nachprüfbare) Einwände gibt. Die einzige Alternative, gegen die niemand wirklich etwas einzuwenden hatte (außer daß es angeblich modernere / schnellere / coolere Alternativen gäbe) ist der allseits bekannte Jenkins jsf32
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1730923153709" ID="ID_1131418575" LINK="https://www.reddit.com/r/cpp/comments/ecrnjl/can_we_do_better_than_the_mersenne_twister/" MODIFIED="1730924006139" TEXT=""can we do better than mersenne?"">
|
||||||
|
<node CREATED="1730924010003" ID="ID_406338445" LINK="https://burtleburtle.net/bob/rand/smallprng.html" MODIFIED="1730924059005" TEXT="Jenkins"/>
|
||||||
|
<node CREATED="1730924013155" ID="ID_1112820214" LINK="https://pracrand.sourceforge.net/RNG_engines.txt" MODIFIED="1730924281091" TEXT="PractRand"/>
|
||||||
|
<node CREATED="1730926918445" ID="ID_595255954" LINK="https://www.pcg-random.org/" MODIFIED="1730927175433" TEXT="PCG-Random">
|
||||||
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_595255954" ENDARROW="Default" ENDINCLINATION="228;0;" ID="Arrow_ID_1247304219" SOURCE="ID_1870117805" STARTARROW="None" STARTINCLINATION="228;25;"/>
|
||||||
|
<node CREATED="1730929577122" HGAP="24" ID="ID_1482800255" MODIFIED="1730929596392" TEXT="ist ein Hobby-Projekt von ihr" VSHIFT="18"/>
|
||||||
|
<node CREATED="1730929582849" ID="ID_340137516" MODIFIED="1730929590956" TEXT="besteht den PractRand-Test"/>
|
||||||
|
<node CREATED="1730940355738" ID="ID_472584641" LINK="https://pcg.di.unimi.it/pcg.php" MODIFIED="1730940454177" TEXT="fachliche Kontroverse zwischen Melissa O'Neill und Sebastiano Vigna"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1710186369715" ID="ID_1826063920" MODIFIED="1710186378766" TEXT="Begriffe/Typen">
|
<node CREATED="1710186369715" ID="ID_1826063920" MODIFIED="1710186378766" TEXT="Begriffe/Typen">
|
||||||
<node CREATED="1710186389857" ID="ID_1473096769" MODIFIED="1710186401416" TEXT="Generator (uniform random bit generator)">
|
<node CREATED="1710186389857" ID="ID_1473096769" MODIFIED="1710186401416" TEXT="Generator (uniform random bit generator)">
|
||||||
|
|
@ -137874,6 +138289,9 @@ std::cout << tmpl.render({"what", "World"}) << s
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1710197680765" ID="ID_235148142" MODIFIED="1710197697107" TEXT="damit sind Portabilitäts- und Implementierungsfehler minimiert"/>
|
<node CREATED="1710197680765" ID="ID_235148142" MODIFIED="1710197697107" TEXT="damit sind Portabilitäts- und Implementierungsfehler minimiert"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1730916497663" ID="ID_1307499120" MODIFIED="1730916516773" TEXT="Problem: Distributionen sind nicht portabel">
|
||||||
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
|
</node>
|
||||||
<node CREATED="1710197778929" ID="ID_34841952" MODIFIED="1710197787371" TEXT="Engine »linear-congruential«">
|
<node CREATED="1710197778929" ID="ID_34841952" MODIFIED="1710197787371" TEXT="Engine »linear-congruential«">
|
||||||
<node CREATED="1710197788537" ID="ID_1612784281" MODIFIED="1710197799179" TEXT=" nur mäßig schnell"/>
|
<node CREATED="1710197788537" ID="ID_1612784281" MODIFIED="1710197799179" TEXT=" nur mäßig schnell"/>
|
||||||
<node CREATED="1710197799755" ID="ID_518732759" MODIFIED="1710197814433" TEXT="relativ kurze Zyklen (limitiert durch Storage)"/>
|
<node CREATED="1710197799755" ID="ID_518732759" MODIFIED="1710197814433" TEXT="relativ kurze Zyklen (limitiert durch Storage)"/>
|
||||||
|
|
@ -140278,8 +140696,20 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1437693678626" HGAP="117" ID="ID_1536988357" MODIFIED="1557498707241" POSITION="left" TEXT="Doku" VSHIFT="-47">
|
<node BACKGROUND_COLOR="#d7cec4" CREATED="1437693678626" HGAP="136" ID="ID_1536988357" MODIFIED="1731199643025" POSITION="left" STYLE="bubble" VSHIFT="-39">
|
||||||
<node CREATED="1437693687650" ID="ID_1484874437" MODIFIED="1557498707241" TEXT="Sound-Systeme">
|
<richcontent TYPE="NODE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Dokumentation zu<br/>
|
||||||
|
Themenbereichen
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<edge COLOR="#61617d" STYLE="sharp_bezier"/>
|
||||||
|
<font NAME="SansSerif" SIZE="16"/>
|
||||||
|
<icon BUILTIN="list"/>
|
||||||
|
<node CREATED="1437693687650" ID="ID_1484874437" MODIFIED="1557498707241" STYLE="fork" TEXT="Sound-Systeme">
|
||||||
<node CREATED="1437693693617" ID="ID_955932218" LINK="https://wiki.debian.org/Sound" MODIFIED="1576282357932" TEXT="siehe die Debian-Übersichtsseite">
|
<node CREATED="1437693693617" ID="ID_955932218" LINK="https://wiki.debian.org/Sound" MODIFIED="1576282357932" TEXT="siehe die Debian-Übersichtsseite">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head/>
|
<head/>
|
||||||
|
|
@ -142814,7 +143244,109 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo
|
||||||
<icon BUILTIN="bell"/>
|
<icon BUILTIN="bell"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1446480582168" FOLDED="true" HGAP="46" ID="ID_554745278" MODIFIED="1581813780309" TEXT="Release" VSHIFT="-5">
|
<node CREATED="1731199725257" HGAP="106" ID="ID_1040358172" MODIFIED="1731199778693" TEXT="Code-Basis" VSHIFT="23">
|
||||||
|
<icon BUILTIN="go"/>
|
||||||
|
<node CREATED="1731199757351" ID="ID_77153778" MODIFIED="1731199764674" TEXT="Struktur"/>
|
||||||
|
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731199766411" ID="ID_85428678" MODIFIED="1731201905778" TEXT="Aufgaben">
|
||||||
|
<icon BUILTIN="bell"/>
|
||||||
|
<node CREATED="1731199789772" ID="ID_1736261073" MODIFIED="1731199796691" TEXT="Copyrights">
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731199802350" FOLDED="true" ID="ID_1389575446" MODIFIED="1731201900295" TEXT="Datei-Präambel straffen und vereinheitlichen">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
<node CREATED="1731199829027" ID="ID_1047831531" MODIFIED="1731199833428" TEXT="was ist notwendig?">
|
||||||
|
<node CREATED="1731199897754" ID="ID_1977560064" MODIFIED="1731201897705" TEXT="eigentlich genügt eine Lizenz-Datei im Source-Root">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Wenn eine Codebasis als Sammlung von Quellen veröffentlicht wird, <b>muß</b>  der Lizenzhinweis prominent sichtbar direkt beim Zugang zur Quelle gegeben sein. <i>Die Veröffentlichung ist rechtlich bindend.</i> Wenn die Veröffentlichung in Form eines Quellbaumes erfolgt, dann muß das Lizenz-Statement direkt in der Wurzel liegen. Es deckt damit automatisch alle anderen Resourcen in dieser Distribution mit ab, auch wenn in diesen Ressourcen nichts weiter steht. Darin liegt aber eine latente Gefahr: wenn eine Resource ohne direkt angehefteten Lizenz-Marker in ein anderes Projekt kopiert wird, fällt sie unter dessen allgemeine Lizenzbestimmung. Fehlt jedwede allgemeine Lizenzbestimmung, dann tritt das jeweilige Copyright-Gesetz des Landes in Kraft, und das bedeutet praktisch überall auf der Welt: der Original-Autor hat die exclusiven Veröffentlichungsrechte. Auf rechtlicher Ebene gilt stets, was sich feststellen und belegen läßt, nicht was jemand beabsichtigt hat oder haben könnte.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731199941276" ID="ID_1766701003" MODIFIED="1731200158808" TEXT="Präambel in jeder Datei wird empfohlen">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
...und zwar für den Fall, daß jemand eine in-sich geschlossene Quelldatei aus dem Projekt heraus kopiert; alle Hinweise direkt in der Datei erhöhen die Wahrscheinlichkeit, daß die Lizenzinformation nicht verlorengeht. Hinweise über Haftungsausschluß und wo man die Lizenz bekommt sind nur eine Empfehlung und haben keine rechtliche Wirkung. Diese ensteht durch die Veröffentlichung, und dazu genügt ein Statement im Root des Quellbaumes. Diese Einschätzung geht sogar aus den Hinweisen im Appendix der GPL selber hervor. Auch auf den Seiten der FSF wird zwar stark nahegelegt, den kopletten Präambel-Text einzufügen, aber es handelt sich daber ohne jeden Zweifel nur um eine Empfehlung
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731199834786" ID="ID_1475726687" MODIFIED="1731200681377" TEXT="ein Copyright-Claim mit initialem Jahr">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Wenn dieser Claim in jeder Quelldatei eigens gepflegt wird, erhöht das die Sicherheit der Verbindung von Copyright und Lizensierung. Allerdings auch nur, wenn dieser Claim korrekt ist. Es genügt, den Zeitpunkt der allerersten signifikanten Schöpfung und Veröffentlichung aufzuführen, denn alle weiteren Beiträge sind dann bereits durch die GPL gedeckt. Empfohlen wird, spätere signifikante Beiträge gesondert mit Jahreszahl aufzuführen. Jahresbereiche sind nur sinnvoll, wenn in jedem der eingeschlossenen Jahre tatsächlich etwas beigetragen wurde.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731199847273" ID="ID_555409518" MODIFIED="1731200959379" TEXT="ein Statement zur Lizenz">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Notwendig wäre das nicht, aber hilfreich, wenn die Datei herausgelöst wird. Es genügt ein Hinweis auf die exakte Form der Lizenz. Man kenn "this Program" durch den expliziten Namen ersetzen. Man kann dazu noch auf die COPYING-Datei verweisen. Alle weiteren Infos, z.B. ein Haftungsausschluß sind nur empfohlen und ändern nicht die rechtliche Wirkung der Lizenz, unter der veröffentlicht wurde
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1731200854085" ID="ID_1145620984" MODIFIED="1731200878179" TEXT="Vorschlag">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">/* </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  INDEX-ITER.hpp  -  iterator with indexed random-access to referred container </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  Copyright (C) </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">    2024,            Hermann Vosseler <Ichthyostega@web.de> </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  **Lumiera** is free software; you can redistribute it and/or modify it </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  under the terms of the GNU General Public License as published by the </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  Free Software Foundation; either version 2 of the License, or (at your </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">  option) any later version. See the file COPYING for further details. </font>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<font face="Monospaced">*/ </font>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<icon BUILTIN="edit"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1446480582168" FOLDED="true" HGAP="67" ID="ID_554745278" MODIFIED="1581813780309" TEXT="Release" VSHIFT="39">
|
||||||
<icon BUILTIN="hourglass"/>
|
<icon BUILTIN="hourglass"/>
|
||||||
<node CREATED="1446480601381" ID="ID_1870415321" MODIFIED="1581813706345" TEXT="release prep: clean-up obsolete information">
|
<node CREATED="1446480601381" ID="ID_1870415321" MODIFIED="1581813706345" TEXT="release prep: clean-up obsolete information">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue