From 2057433f48a949175ae5a27e8b29715b017dc54f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 11 Aug 2020 12:26:54 +0200 Subject: [PATCH] Add needed files Signed-off-by: Jakub Sztandera --- chain/messagepool/block_proba.go | 71 +++++++++++++++++++++++++++ chain/messagepool/block_proba_test.go | 8 +++ 2 files changed, 79 insertions(+) create mode 100644 chain/messagepool/block_proba.go create mode 100644 chain/messagepool/block_proba_test.go diff --git a/chain/messagepool/block_proba.go b/chain/messagepool/block_proba.go new file mode 100644 index 000000000..403507352 --- /dev/null +++ b/chain/messagepool/block_proba.go @@ -0,0 +1,71 @@ +package messagepool + +import "math" + +func noWinnersProb() []float64 { + poissPdf := func(x float64) float64 { + const Mu = 5 + lg, _ := math.Lgamma(x + 1) + result := math.Exp((math.Log(Mu) * x) - lg - Mu) + return result + } + + out := make([]float64, 0, MaxBlocks) + for i := 0; i < MaxBlocks; i++ { + out = append(out, poissPdf(float64(i))) + } + return out +} + +func binomialCoefficient(n, k float64) float64 { + if k > n { + return math.NaN() + } + r := 1.0 + for d := 1.0; d <= k; d++ { + r *= n + r /= d + n -= 1 + } + return r +} + +func (mp *MessagePool) blockProbabilities(tq float64) []float64 { + noWinners := noWinnersProb() // cache this + + p := 1 - tq + binoPdf := func(x, trials float64) float64 { + // based on https://github.com/atgjack/prob + if x > trials { + return 0 + } + if p == 0 { + if x == 0 { + return 1.0 + } + return 0.0 + } + if p == 1 { + if x == trials { + return 1.0 + } + return 0.0 + } + coef := binomialCoefficient(trials, x) + pow := math.Pow(p, x) * math.Pow(1-p, trials-x) + if math.IsInf(coef, 0) { + return 0 + } + return coef * pow + } + + out := make([]float64, 0, MaxBlocks) + for place := 0; place < MaxBlocks; place++ { + var pPlace float64 + for otherWinners, pCase := range noWinners { + pPlace += pCase * binoPdf(float64(place), float64(otherWinners+1)) + } + out = append(out, pPlace) + } + return out +} diff --git a/chain/messagepool/block_proba_test.go b/chain/messagepool/block_proba_test.go new file mode 100644 index 000000000..2cc2ecc2a --- /dev/null +++ b/chain/messagepool/block_proba_test.go @@ -0,0 +1,8 @@ +package messagepool + +import "testing" + +func TestBlockProbability(t *testing.T) { + mp := &MessagePool{} + t.Logf("%+v\n", mp.blockProbabilities(1-0.15)) +}