Library: RandomDraw - rework mapping rule to support origin
The first step was to allow setting a minimum value, which in theory could also be negative (at no point is the code actually limited to unsigned values; this is rather the default in practice). But reconsidering this extensions, then you'd also want the "neutral value" to be handled properly. Within context, this means that the *probability* controls when values other than the neutral value are produced; especially with p = 1.0 the neutral value shall not be produced at all
This commit is contained in:
parent
75dd4210f2
commit
5b9a463b38
3 changed files with 209 additions and 49 deletions
|
|
@ -22,25 +22,54 @@
|
|||
|
||||
/** @file random-draw.hpp
|
||||
** Build a component to select limited values randomly.
|
||||
** Prototyping to find a suitable DSL to configure drawing of random numbers and mapping results.
|
||||
** The underlying implementation shall be extracted from (and later used by) TestChainLoad; the
|
||||
** random numbers will be derived from node hash values and must be mapped to yield parameters
|
||||
** limited to a very small value range. While numerically simple, this turns out to be rather
|
||||
** error-prone, hence the desire to put a DSL in front. The challenge however arises from
|
||||
** the additional requirement to support various usage patters, all with minimal specs.
|
||||
** Generally speaking, RandomDraw uses some suitable source of randomness to "draw" a result
|
||||
** value with a limited target domain. The intended usage scenario is to parametrise some
|
||||
** configuration or computation »randomly«, with well defined probabilities and value ranges.
|
||||
** A DSL is provide to simplify the common configuration and value mapping scenarios.
|
||||
** @paragraph The underlying implementation was extracted 11/2023 from (and later used by)
|
||||
** TestChainLoad; there, random numbers are derived from node hash values and must be mapped
|
||||
** to yield control parameters governing the topology of a DAG datastructure. Notably, a
|
||||
** draw is performed on each step to decide if the graph should fork. While numerically
|
||||
** simple, this turned out to be rather error-prone, and resulting code is dense and
|
||||
** difficult to understand, hence the desire to put a library component in front.
|
||||
**
|
||||
** The following code lays out the ground structure, while treating Spec as a distinct
|
||||
** type, which is then mixed into Draw. This logical separation basically was led me to the
|
||||
** final solution: Draw both _is_ a function and _embodies_ the implementation of this function.
|
||||
** This somewhat surprising layout is what enables use as a DSL builder, because it allows both
|
||||
** to have the _builder use_ and the _converter use_ in the same class, even allowing to _define_
|
||||
** a Draw by giving a function which _produces_ a (dynamically parametrised) Draw.
|
||||
** # Implementation structure
|
||||
** RandomDraw inherits from a _policy template_, which in turn is-a std::function. The signature
|
||||
** of this function defines the input to work on; its output is assumed to be some variation of
|
||||
** a [»limited value«](\ref Limited). Notably, results are assumed to conform to an ordered
|
||||
** interval of integral values. The [core functionality](\ref drawLimited) is to use the value
|
||||
** from the random source (a `size_t` hash), break it down by some _modulus_ to create an arbitrary
|
||||
** selection and then map this _drawn value_ into the target value range. This mapping however allows
|
||||
** to discard some of the _possible drawn values_ — which equates to define a probability of producing
|
||||
** a result different than "zero" (the neutral value of the result range). Moreover, the actual value
|
||||
** mapping can be limited and configured even more within the confines of the target type.
|
||||
**
|
||||
** In this prototype, all of the functor adaptation is also part of the Draw template; for the
|
||||
** real implementation this will have to be supplied at usage site through a traits template,
|
||||
** otherwise it would not be possible to integrate seamlessly with custom data sources (as
|
||||
** happens in the intended use case, where actually a Node is the data source)
|
||||
** Additional flexibility can be gained by _binding a functor_ thereby defining further mapping and
|
||||
** transformations. A wide array of function signatures can be accepted, as long as it is possible
|
||||
** somehow to _adapt_ those functions to conform to the overall scheme as defined by the Policy base.
|
||||
** Such a mapping function can be given directly at construction, or it can be set up later through
|
||||
** the configuration DSL. As a special twist, it is even possible to bind a function exposing a
|
||||
** reference to some RandomDraw instance (which can be the host object itself). Since such a
|
||||
** function can likewise accept the input randomness source, this setup opens the ability
|
||||
** for dynamic parametrisation of the result probabilities.
|
||||
**
|
||||
** ## Policy template
|
||||
** For practical use, the RandomDraw template must be instantiate with a custom provided
|
||||
** policy template. This configuration allows to attach to locally defined types and facilities.
|
||||
** The policy template is assumed to conform to the following requirements
|
||||
** - its base type is std::function, with a result value similar to \ref Limited
|
||||
** - more specifically, the result type must be number-like and expose extension points
|
||||
** to determine the `minVal()`, `maxVal()` and `zeroVal()`
|
||||
** - moreover, the policy must define a function `defaultSrc(args...)`; this function must
|
||||
** accept input arguments in accordance to the function signature of the Policy (i.e. it
|
||||
** must read "the randomness source") and produce a result that can be adapted and fed
|
||||
** into the regular processing chain (the same as for any mapping function)
|
||||
** - optionally, this policy may also define a template `Adaptor<Sig>`, possibly with
|
||||
** specialisations for various function signatures. These adaptors are used to
|
||||
** conform any mapping function and thus allow to simplify or widen the
|
||||
** possibly configurations at usage site.
|
||||
** @todo 11/2023 This is a first draft and was extracted from an actual usage scenario.
|
||||
** It remains to be seen if the scheme as defined is of any further use henceforth.
|
||||
** @see RandomDraw_test
|
||||
** @see TestChainLoad_test
|
||||
** @see SchedulerStress_test
|
||||
|
|
@ -53,6 +82,7 @@
|
|||
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/util-quant.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
|
@ -74,11 +104,15 @@ namespace lib {
|
|||
* @tparam max maximum allowed param value (inclusive)
|
||||
* @tparam max minimum allowed param value (inclusive) - defaults to "zero".
|
||||
*/
|
||||
template<typename T, T max, T min =T(0)>
|
||||
template<typename T, T max, T min =T(0), T zero =min>
|
||||
struct Limited
|
||||
{
|
||||
static constexpr T minVal() { return min; }
|
||||
static_assert (min < max);
|
||||
static_assert (min <= zero and zero < max);
|
||||
|
||||
static constexpr T maxVal() { return max; }
|
||||
static constexpr T minVal() { return min; }
|
||||
static constexpr T zeroVal(){ return zero;}
|
||||
|
||||
T val;
|
||||
|
||||
|
|
@ -98,6 +132,7 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
|
||||
namespace random_draw { // Policy definitions
|
||||
|
||||
/**
|
||||
|
|
@ -115,7 +150,7 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
/**********************************************************//**
|
||||
* A component and builder to draw limited parameter values
|
||||
* based on some source of randomness (or hash input).
|
||||
* Effectively this is a function which "draws" on invocation.
|
||||
|
|
@ -128,7 +163,8 @@ namespace lib {
|
|||
using Fun = typename _Fun<POL>::Functor;
|
||||
using Tar = typename _Fun<POL>::Ret;
|
||||
|
||||
Tar maxResult_{Tar::maxVal()}; ///< maximum parameter val actually to produce < max
|
||||
Tar maxResult_{Tar::maxVal()}; ///< maximum result val actually to produce < max
|
||||
Tar minResult_{Tar::minVal()}; ///< minimum result val actually to produce > min
|
||||
double probability_{0}; ///< probability that value is in [1 .. m]
|
||||
|
||||
|
||||
|
|
@ -137,15 +173,34 @@ namespace lib {
|
|||
limited (double val)
|
||||
{
|
||||
if (probability_ == 0.0 or val == 0.0)
|
||||
return Tar{0};
|
||||
return Tar::zeroVal();
|
||||
//
|
||||
REQUIRE (Tar::minVal() <= minResult_);
|
||||
REQUIRE (Tar::maxVal() >= maxResult_);
|
||||
REQUIRE (minResult_ < maxResult_);
|
||||
REQUIRE (0.0 <= probability_);
|
||||
REQUIRE (probability_ <= 1.0);
|
||||
auto org = util::max (Tar::zeroVal(), minResult_);
|
||||
double q = (1.0 - probability_);
|
||||
auto org = Tar::minVal();
|
||||
val -= q; // [0 .. [q .. 1[
|
||||
val /= probability_; // [0 .. 1[
|
||||
val *= maxResult_ - org; // [0 .. m[
|
||||
val += org+1; // [1 .. m]
|
||||
val += CAP_EPSILON; // round down yet absorb dust
|
||||
return Tar{val};
|
||||
if (org == minResult_)
|
||||
{ // simple standard case
|
||||
val *= maxResult_ - org; // [0 .. m[
|
||||
val += org+1; // [1 .. m]
|
||||
val += CAP_EPSILON; // round down yet absorb dust
|
||||
return Tar{val};
|
||||
}
|
||||
else// Origin is somewhere within value range
|
||||
{// ==> wrap "negative" part above max
|
||||
// to map 0.0 ⟼ org (≙neutral)
|
||||
val *= maxResult_ - minResult_;
|
||||
val += org+1; // max inclusive but <0 ⟼ org
|
||||
if (val > maxResult_) // wrap the "negatives"
|
||||
val -= maxResult_+1 - minResult_;
|
||||
val += CAP_EPSILON;
|
||||
return Tar{val};
|
||||
}
|
||||
}
|
||||
|
||||
static size_t constexpr QUANTISER = 1 << 8;
|
||||
|
|
@ -167,7 +222,9 @@ namespace lib {
|
|||
|
||||
|
||||
public:
|
||||
/** Drawing is _disabled_ by default, always yielding "zero" */
|
||||
/**
|
||||
* Drawing is _disabled_ by default, always yielding "zero"
|
||||
*/
|
||||
RandomDraw()
|
||||
: Fun{adaptOut(POL::defaultSrc)}
|
||||
{ }
|
||||
|
|
@ -204,7 +261,7 @@ namespace lib {
|
|||
maxResult_ = m;
|
||||
return move (*this);
|
||||
}
|
||||
|
||||
|
||||
template<class FUN>
|
||||
RandomDraw&&
|
||||
mapping (FUN&& fun)
|
||||
|
|
@ -217,7 +274,9 @@ namespace lib {
|
|||
|
||||
|
||||
private:
|
||||
|
||||
/** @internal adapt input side of a given function to conform to the
|
||||
* global input arguments as defined in the Policy base function.
|
||||
* @return a function pre-fitted with a suitable Adapter from the Policy */
|
||||
template<class FUN>
|
||||
decltype(auto)
|
||||
adaptIn (FUN&& fun)
|
||||
|
|
@ -230,6 +289,15 @@ namespace lib {
|
|||
return Adaptor::build (forward<FUN> (fun));
|
||||
}
|
||||
|
||||
/** @internal adapt output side of a given function, allowing to handle it's results
|
||||
* - a function producing the overall result-type is installed as-is
|
||||
* - a `size_t` result is assumed be a hash and passed into #drawLimited
|
||||
* - likewise a `double` is assumed to be already a random val to be #limited
|
||||
* - special treatment is given to a function which produces reference to some
|
||||
* `RandomDraw`; this allows to produce a dynamic parametrisation, which is
|
||||
* then invoked on the same input arguments to produce the result value.
|
||||
* @return adapted function which produces a result value of type #Tar
|
||||
*/
|
||||
template<class FUN>
|
||||
decltype(auto)
|
||||
adaptOut (FUN&& fun)
|
||||
|
|
@ -244,24 +312,25 @@ namespace lib {
|
|||
else
|
||||
if constexpr (std::is_same_v<Res, size_t>)// ◁───────────────────────┨ function yields random source to draw value
|
||||
return chained (std::forward<FUN>(fun)
|
||||
,[this](size_t hash){ return drawLimited(hash); });
|
||||
,[this](size_t hash){ return drawLimited(hash); }
|
||||
);
|
||||
else
|
||||
if constexpr (std::is_same_v<Res, double>)// ◁───────────────────────┨ function yields random value to be quantised
|
||||
return chained (std::forward<FUN>(fun)
|
||||
,[this](double rand){ return limited(rand); });
|
||||
,[this](double rand){ return limited(rand); }
|
||||
);
|
||||
else
|
||||
if constexpr (std::is_same_v<Res, RandomDraw>)// ◁────────────────────┨ function yields parametrised RandomDraw to invoke
|
||||
if constexpr (std::is_same_v<Res, RandomDraw const&>)// ◁─────────────┨ function yields parametrised RandomDraw to invoke
|
||||
return [functor=std::forward<FUN>(fun), this]
|
||||
(auto&& ...inArgs)
|
||||
{ // invoke with copy
|
||||
RandomDraw parametricDraw = functor(inArgs...);
|
||||
{ // invoke with copy
|
||||
RandomDraw const& parametricDraw = functor(inArgs...);
|
||||
return parametricDraw (forward<decltype(inArgs)> (inArgs)...);
|
||||
};
|
||||
}; // forward arguments
|
||||
else
|
||||
static_assert (not sizeof(Res), "unable to adapt / handle result type");
|
||||
NOTREACHED("Handle based on return type");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ namespace test{
|
|||
|
||||
|
||||
/** @test TODO demonstrate a basic usage scenario
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
* @todo WIP 11/23 ✔ define ⟶ 🔁 implement
|
||||
*/
|
||||
void
|
||||
simpleUse()
|
||||
|
|
@ -152,7 +152,7 @@ SHOW_EXPR (int(draw(256)));
|
|||
|
||||
|
||||
/** @test TODO verify configuration through policy template
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
* @todo WIP 11/23 🔁 define ⟶ 🔁 implement
|
||||
*/
|
||||
void
|
||||
verify_policy()
|
||||
|
|
|
|||
|
|
@ -96631,17 +96631,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#435e98" CREATED="1700513461881" ID="ID_1696400503" MODIFIED="1700513889095" TEXT="definiert den Basis-Funktionstyp"/>
|
||||
<node COLOR="#435e98" CREATED="1700513505882" ID="ID_1225658406" MODIFIED="1700513889096" TEXT="definiert darüber auch implizit den Ergebnistyp"/>
|
||||
<node COLOR="#435e98" CREATED="1700513474582" ID="ID_1399385360" MODIFIED="1700513889096" TEXT="liefert spezielle Adapter für alle unterstützten Eingangs-Typen"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1700513891593" ID="ID_1527819070" MODIFIED="1700513932582" TEXT="unklar: default-Eingang">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700513891593" ID="ID_1527819070" MODIFIED="1700577854558" TEXT="unklar: default-Eingang">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1700515452147" ID="ID_1797461825" MODIFIED="1700515470815" TEXT="muß ich irgendwo einen Standard-Eingangstyp annehmen?">
|
||||
<node COLOR="#435e98" CREATED="1700515452147" ID="ID_1797461825" MODIFIED="1700577912934" TEXT="muß ich irgendwo einen Standard-Eingangstyp annehmen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1700577876306" ID="ID_1799486545" MODIFIED="1700577891756" TEXT="überraschenderweise nirgends im Implementierungs-Code"/>
|
||||
<node CREATED="1700577892392" ID="ID_269852112" MODIFIED="1700577911162" TEXT="es genügt die implizite Definition durch die Signatur der Policy"/>
|
||||
</node>
|
||||
<node CREATED="1700515476582" ID="ID_474690726" MODIFIED="1700515499125" TEXT="im Grunde würde das gesamte Schema mit beliebigen Eingangs-Signaturen funktionieren">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1700515519514" ID="ID_1957414628" MODIFIED="1700515559845" TEXT="⟹ dann müßte aber die Policy einen Default-Eingang liefern..."/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700515561328" ID="ID_408143188" MODIFIED="1700515586492" TEXT="brauche Funktions-Komposition">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#435e98" CREATED="1700515519514" ID="ID_1957414628" MODIFIED="1700577869042" TEXT="⟹ dann muß aber die Policy einen Default-Eingang liefern..."/>
|
||||
<node COLOR="#338800" CREATED="1700515561328" FOLDED="true" ID="ID_408143188" MODIFIED="1700577929389" TEXT="brauche Funktions-Komposition">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1700515591564" ID="ID_9942626" MODIFIED="1700536064914" TEXT="»beliebige Funktion« kann nicht einfach so als Lambda geschrieben werden">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
|
|
@ -96717,18 +96719,107 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700542362630" ID="ID_730331755" MODIFIED="1700542375501" TEXT="mit speziellem Test ausleuchten...">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1700542382819" ID="ID_1832228113" MODIFIED="1700542395074" TEXT="eine Policy die zwei Eingangs-Argumente nimmt"/>
|
||||
<node COLOR="#338800" CREATED="1700542382819" ID="ID_1832228113" MODIFIED="1700574242519" TEXT="eine Policy die zwei Eingangs-Argumente nimmt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700574245126" ID="ID_1720583823" MODIFIED="1700574258660" TEXT="Adaption von Manipulator-Funktionen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1700491985219" ID="ID_460437503" MODIFIED="1700491990343" TEXT="Adaptierung restrukturieren"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700577987947" ID="ID_1072243558" MODIFIED="1700578044322" TEXT="Result-Mapping fertigstellen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700578049835" ID="ID_1039524348" MODIFIED="1700578324330" TEXT="(optional) Minimal-Wert beachten">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700578067566" ID="ID_1673296895" MODIFIED="1700578327612" TEXT="(optional) neutralen Wert definieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700578338693" ID="ID_1746695653" MODIFIED="1700578488824" TEXT="Wunsch: neutralen Wert mitten im Wertebereich">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Beispiel: -2 .. 0 ..+2  ⟹ Wahrscheinlichkeit definiert für Werte ≠ 0
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700578688806" ID="ID_1002441906" MODIFIED="1700578701690" TEXT="brauche anderes Mapping-Layout">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700578703420" ID="ID_1936439930" MODIFIED="1700578736098" TEXT="erst mal als statischen-Zweig realisieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1700578747462" ID="ID_1744331355" MODIFIED="1700578808542" TEXT="Idee: [0....0[1...max|min...-1]">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700579867534" ID="ID_1525251156" MODIFIED="1700579872321" TEXT="Quantisierung verbessern">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1700579884119" ID="ID_805978365" MODIFIED="1700579898358" TEXT="Probleme mit der Wahrscheinlichkeitsverteilung">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1700580065522" ID="ID_1293962654" MODIFIED="1700580090733" TEXT="für Zufälligkeit wäre quant ≙ card ideal"/>
|
||||
<node CREATED="1700580100458" ID="ID_508177019" MODIFIED="1700580112917" TEXT="für Gleichverteilung muß quant eine 2-er-Potenz sein"/>
|
||||
<node CREATED="1700580270404" ID="ID_1058992457" MODIFIED="1700580289113" TEXT="Problem sind kleine Wahrscheinlichkeiten">
|
||||
<node CREATED="1700580327644" ID="ID_163898715" MODIFIED="1700580337478" TEXT="der verbleibende Rest leuchtet nicht mehr alle Werte aus"/>
|
||||
</node>
|
||||
<node CREATED="1700580296744" ID="ID_1912245268" MODIFIED="1700580306635" TEXT="auch unebene Teil-Wertbereiche sind problematisch"/>
|
||||
</node>
|
||||
<node CREATED="1700579942375" ID="ID_1570826487" MODIFIED="1700579973751" TEXT="Quantiser auf 2-log der Kardinalität aufbauen">
|
||||
<node CREATED="1700580399003" ID="ID_1712768640" MODIFIED="1700580402212" TEXT="statische Lösung">
|
||||
<node CREATED="1700580403024" ID="ID_340644857" MODIFIED="1700580414388" TEXT="kann dann nur auf max(Template-Param) aufsetzen"/>
|
||||
<node CREATED="1700580415496" ID="ID_241609475" MODIFIED="1700580425235" TEXT="muß mit zusätzlichem Headroom arbeiten"/>
|
||||
</node>
|
||||
<node CREATED="1700580428485" ID="ID_209321513" MODIFIED="1700580431707" TEXT="dynamische Lösung">
|
||||
<node CREATED="1700580432790" ID="ID_1779483070" MODIFIED="1700580440161" TEXT="wäre ein zusätzliches Objektfeld"/>
|
||||
<node CREATED="1700580440749" ID="ID_1688731462" MODIFIED="1700580454914" TEXT="müßte von jedem Param-Setter mit bedient werden"/>
|
||||
<node CREATED="1700580455526" ID="ID_1568213898" MODIFIED="1700580468829" TEXT="würde den (schnellen) ilogb verwenden"/>
|
||||
<node CREATED="1700580486714" ID="ID_1999552035" MODIFIED="1700580606017" TEXT="aber auch hier brauchen wir Headroom">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
grade wenn die Maximalgrenze nahe an einer Zweierpotenz liegt (Beispiel 10 Werte) dann werden einige Werte deutlich wahrscheinlicher
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1700578085130" ID="ID_1160195104" MODIFIED="1700578334393" TEXT="Konsistenz der Definitionen prüfen (statisch)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700491985219" ID="ID_460437503" MODIFIED="1700577836021" TEXT="Adaptierung restrukturieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700577811739" ID="ID_1356052727" MODIFIED="1700577841449" TEXT="Konfigurations-DSL aufbauen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700491877926" ID="ID_1958310493" MODIFIED="1700502021655" TEXT="Test zur Dokumentation">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1700491902622" ID="ID_523469259" MODIFIED="1700491929304" TEXT="soll auch den Prozeß der Spezialisierung demonstrieren"/>
|
||||
<node CREATED="1700491930155" ID="ID_1583745392" MODIFIED="1700491949372" TEXT="numerische Grenzen beleuchten"/>
|
||||
<node CREATED="1700501979956" ID="ID_571312425" MODIFIED="1700501992697" TEXT="Wirkung des Builder-API dokumentieren"/>
|
||||
<node CREATED="1700501993218" ID="ID_271630234" MODIFIED="1700502005459" TEXT="dynamische Parametrisierung demonstrieren"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700491902622" ID="ID_523469259" MODIFIED="1700577965111" TEXT="soll auch den Prozeß der Spezialisierung demonstrieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700491930155" ID="ID_1583745392" MODIFIED="1700577970844" TEXT="numerische Grenzen beleuchten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700501979956" ID="ID_571312425" MODIFIED="1700577970844" TEXT="Wirkung des Builder-API dokumentieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700501993218" ID="ID_271630234" MODIFIED="1700577970844" TEXT="dynamische Parametrisierung demonstrieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue