Library: RandomDraw - introduce policy template
to define this as a generic library component, any reference to the actual data source moust be extracted from the body of the implementation and supplied later at usage site. In the actual case at hand the source for randomness would be the node hash, and that is absolutely an internal implementation detail.
This commit is contained in:
parent
605c1b4a17
commit
651e28bac9
3 changed files with 123 additions and 59 deletions
|
|
@ -97,36 +97,53 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
namespace random_draw { // Policy definitions
|
||||
|
||||
/**
|
||||
* Default policy for RandomDraw: generate limted-range random numbers.
|
||||
* @tparam max result values will be `uint` in the range `[0 ... max]`
|
||||
*/
|
||||
template<uint max>
|
||||
struct LimitedRandomGenerate
|
||||
: function<Limited<uint, max>(void)>
|
||||
{
|
||||
static double defaultSrc() { return rand()/double(RAND_MAX); }
|
||||
};
|
||||
|
||||
}//(End)Policy definitions
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @tparam POL configuration policy baseclass
|
||||
*/
|
||||
template<typename T, T max>
|
||||
template<class POL>
|
||||
class RandomDraw
|
||||
: public function<Limited<T,max>(size_t)>
|
||||
: public POL
|
||||
{
|
||||
using Lim = Limited<T,max>;
|
||||
using Fun = function<Lim(size_t)>;
|
||||
using Fun = typename _Fun<POL>::Functor;
|
||||
using Tar = typename _Fun<POL>::Ret;
|
||||
|
||||
T maxResult_{Lim::maxVal()}; ///< maximum parameter val actually to produce < max
|
||||
Tar maxResult_{Tar::maxVal()}; ///< maximum parameter val actually to produce < max
|
||||
double probability_{0}; ///< probability that value is in [1 .. m]
|
||||
|
||||
|
||||
/** @internal quantise into limited result value */
|
||||
Lim
|
||||
Tar
|
||||
limited (double val)
|
||||
{
|
||||
if (probability_ == 0.0 or val == 0.0)
|
||||
return Lim{0};
|
||||
return Tar{0};
|
||||
double q = (1.0 - probability_);
|
||||
val -= q; // [0 .. [q .. 1[
|
||||
val /= probability_; // [0 .. 1[
|
||||
val *= maxResult_; // [0 .. m[
|
||||
val += 1; // [1 .. m]
|
||||
val += CAP_EPSILON; // round down yet absorb dust
|
||||
return Lim{val};
|
||||
return Tar{val};
|
||||
}
|
||||
|
||||
static size_t constexpr QUANTISER = 1 << 8;
|
||||
|
|
@ -143,7 +160,7 @@ namespace lib {
|
|||
public:
|
||||
/** Drawing is _disabled_ by default, always yielding "zero" */
|
||||
RandomDraw()
|
||||
: Fun{[this](size_t hash){ return limited (asRand (hash)); }}
|
||||
: Fun{adaptOut(POL::defaultSrc)}
|
||||
{ }
|
||||
|
||||
/**
|
||||
|
|
@ -189,53 +206,19 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @internal helper to expose the signature `size_t(size_t)`
|
||||
* by wrapping a given lambda or functor.
|
||||
*/
|
||||
template<class SIG, typename SEL=void>
|
||||
struct Adaptor
|
||||
{
|
||||
static_assert (not sizeof(SIG), "Unable to adapt given functor.");
|
||||
};
|
||||
|
||||
template<typename RES>
|
||||
struct Adaptor<RES(size_t)>
|
||||
{
|
||||
template<typename FUN>
|
||||
static decltype(auto)
|
||||
build (FUN&& fun)
|
||||
{
|
||||
return std::forward<FUN>(fun);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RES>
|
||||
struct Adaptor<RES(void)>
|
||||
{
|
||||
template<typename FUN>
|
||||
static auto
|
||||
build (FUN&& fun)
|
||||
{
|
||||
return [functor=std::forward<FUN>(fun)]
|
||||
(size_t)
|
||||
{
|
||||
return functor();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
template<class FUN>
|
||||
decltype(auto)
|
||||
adaptIn (FUN&& fun)
|
||||
{
|
||||
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
|
||||
static_assert (lib::meta::_Fun<FUN>::ARITY <= 1, "Function with zero or one argument expected.");
|
||||
|
||||
using Sig = typename lib::meta::_Fun<FUN>::Sig;
|
||||
using Sig = typename lib::meta::_Fun<FUN>::Sig;
|
||||
using Adaptor = typename POL::template Adaptor<Sig>;
|
||||
|
||||
return Adaptor<Sig>::build (forward<FUN> (fun));
|
||||
return Adaptor::build (forward<FUN> (fun));
|
||||
}
|
||||
|
||||
template<class FUN>
|
||||
|
|
@ -243,11 +226,10 @@ namespace lib {
|
|||
adaptOut (FUN&& fun)
|
||||
{
|
||||
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
|
||||
static_assert (lib::meta::_Fun<FUN>::ARITY ==1, "Function with exactly one argument required.");
|
||||
|
||||
using Res = typename lib::meta::_Fun<FUN>::Ret;
|
||||
|
||||
if constexpr (std::is_same_v<Res, Lim>)
|
||||
if constexpr (std::is_same_v<Res, Tar>)
|
||||
return std::forward<FUN>(fun);
|
||||
else
|
||||
if constexpr (std::is_same_v<Res, size_t>)
|
||||
|
|
@ -279,8 +261,6 @@ namespace lib {
|
|||
NOTREACHED("Handle based on return type");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,52 @@ namespace test{
|
|||
namespace {
|
||||
// const Literal THE_END = "all dead and hero got the girl";
|
||||
|
||||
struct SymmetricFive
|
||||
: function<Limited<int, 5,-5>(size_t)>
|
||||
{
|
||||
static size_t defaultSrc (size_t hash) { return hash; }
|
||||
|
||||
/**
|
||||
* @internal helper to expose the signature `size_t(size_t)`
|
||||
* by wrapping a given lambda or functor.
|
||||
*/
|
||||
template<class SIG>
|
||||
struct Adaptor
|
||||
{
|
||||
static_assert (not sizeof(SIG), "Unable to adapt given functor.");
|
||||
};
|
||||
|
||||
template<typename RES>
|
||||
struct Adaptor<RES(size_t)>
|
||||
{
|
||||
template<typename FUN>
|
||||
static decltype(auto)
|
||||
build (FUN&& fun)
|
||||
{
|
||||
return std::forward<FUN>(fun);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RES>
|
||||
struct Adaptor<RES(void)>
|
||||
{
|
||||
template<typename FUN>
|
||||
static auto
|
||||
build (FUN&& fun)
|
||||
{
|
||||
return [functor=std::forward<FUN>(fun)]
|
||||
(size_t)
|
||||
{
|
||||
return functor();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
using Draw = lib::RandomDraw<uint, 10>;
|
||||
|
||||
using Draw = RandomDraw<SymmetricFive>;
|
||||
|
||||
|
||||
|
||||
|
|
@ -74,6 +117,7 @@ namespace test{
|
|||
{
|
||||
simpleUse();
|
||||
|
||||
verify_policy();
|
||||
verify_numerics();
|
||||
verify_buildProfile();
|
||||
verify_dynamicChange();
|
||||
|
|
@ -88,12 +132,30 @@ namespace test{
|
|||
simpleUse()
|
||||
{
|
||||
auto draw = Draw().probability(0.5);
|
||||
CHECK (draw(0) == 0);
|
||||
CHECK (draw(127) == 0);
|
||||
CHECK (draw(128) == 1);
|
||||
CHECK (draw(141) == 2);
|
||||
CHECK (draw(255) ==10);
|
||||
CHECK (draw(256) == 0);
|
||||
SHOW_EXPR (int(draw(0) ));
|
||||
SHOW_EXPR (int(draw(127)));
|
||||
SHOW_EXPR (int(draw(128)));
|
||||
SHOW_EXPR (int(draw(141)));
|
||||
SHOW_EXPR (int(draw(255)));
|
||||
SHOW_EXPR (int(draw(256)));
|
||||
// CHECK (draw(0) == 0);
|
||||
// CHECK (draw(127) == 0);
|
||||
// CHECK (draw(128) == 1);
|
||||
// CHECK (draw(141) == 2);
|
||||
// CHECK (draw(255) ==10);
|
||||
// CHECK (draw(256) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test TODO verify configuration through policy template
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
*/
|
||||
void
|
||||
verify_policy()
|
||||
{
|
||||
// auto d1 = RandomDraw<random_draw::LimitedRandomGenerate<5>>().probability(1.0);
|
||||
//SHOW_EXPR (uint(d1()))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -96626,7 +96626,29 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1700491829216" ID="ID_1294373641" MODIFIED="1700502015751" TEXT="den Spec-Subtyp in RandomDraw integrieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1700491953800" ID="ID_75649548" MODIFIED="1700491984631" TEXT="Policy-Template einführen"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700491953800" ID="ID_75649548" MODIFIED="1700515755282" TEXT="Policy-Template einführen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<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">
|
||||
<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?">
|
||||
<icon BUILTIN="help"/>
|
||||
</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 CREATED="1700515591564" ID="ID_9942626" MODIFIED="1700515612341" TEXT="»beliebige Funktion« kann nicht als Lambda geschrieben werden"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1700515624424" ID="ID_124826134" MODIFIED="1700515633951" TEXT="hatte ich da nicht schon mal was...?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1700491985219" ID="ID_460437503" MODIFIED="1700491990343" TEXT="Adaptierung restrukturieren"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700491877926" ID="ID_1958310493" MODIFIED="1700502021655" TEXT="Test zur Dokumentation">
|
||||
|
|
|
|||
Loading…
Reference in a new issue