{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Consensus.Committee.LS
(
LocalSortitionNumSeats (..)
, localSortitionNumSeats
) where
import Cardano.Ledger.BaseTypes (FixedPoint, HasZero)
import Data.Maybe (fromMaybe)
import Data.Word (Word64)
import Ouroboros.Consensus.Committee.Crypto (NormalizedVRFOutput (..))
import Ouroboros.Consensus.Committee.Types (Cumulative (..), LedgerStake (..))
import Ouroboros.Consensus.Committee.WFA
( NonPersistentCommitteeSize (..)
, TotalNonPersistentStake (..)
)
newtype LocalSortitionNumSeats = LocalSortitionNumSeats
{ LocalSortitionNumSeats -> Word64
unLocalSortitionNumSeats :: Word64
}
deriving stock (Int -> LocalSortitionNumSeats -> ShowS
[LocalSortitionNumSeats] -> ShowS
LocalSortitionNumSeats -> String
(Int -> LocalSortitionNumSeats -> ShowS)
-> (LocalSortitionNumSeats -> String)
-> ([LocalSortitionNumSeats] -> ShowS)
-> Show LocalSortitionNumSeats
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LocalSortitionNumSeats -> ShowS
showsPrec :: Int -> LocalSortitionNumSeats -> ShowS
$cshow :: LocalSortitionNumSeats -> String
show :: LocalSortitionNumSeats -> String
$cshowList :: [LocalSortitionNumSeats] -> ShowS
showList :: [LocalSortitionNumSeats] -> ShowS
Show, LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
(LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> Eq LocalSortitionNumSeats
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
== :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
$c/= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
/= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
Eq, Eq LocalSortitionNumSeats
Eq LocalSortitionNumSeats =>
(LocalSortitionNumSeats -> LocalSortitionNumSeats -> Ordering)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool)
-> (LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> Ord LocalSortitionNumSeats
LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
LocalSortitionNumSeats -> LocalSortitionNumSeats -> Ordering
LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Ordering
compare :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Ordering
$c< :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
< :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
$c<= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
<= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
$c> :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
> :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
$c>= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
>= :: LocalSortitionNumSeats -> LocalSortitionNumSeats -> Bool
$cmax :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
max :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
$cmin :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
min :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
Ord)
deriving newtype (Integer -> LocalSortitionNumSeats
LocalSortitionNumSeats -> LocalSortitionNumSeats
LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
(LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (LocalSortitionNumSeats -> LocalSortitionNumSeats)
-> (Integer -> LocalSortitionNumSeats)
-> Num LocalSortitionNumSeats
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
+ :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
$c- :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
- :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
$c* :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
* :: LocalSortitionNumSeats
-> LocalSortitionNumSeats -> LocalSortitionNumSeats
$cnegate :: LocalSortitionNumSeats -> LocalSortitionNumSeats
negate :: LocalSortitionNumSeats -> LocalSortitionNumSeats
$cabs :: LocalSortitionNumSeats -> LocalSortitionNumSeats
abs :: LocalSortitionNumSeats -> LocalSortitionNumSeats
$csignum :: LocalSortitionNumSeats -> LocalSortitionNumSeats
signum :: LocalSortitionNumSeats -> LocalSortitionNumSeats
$cfromInteger :: Integer -> LocalSortitionNumSeats
fromInteger :: Integer -> LocalSortitionNumSeats
Num, LocalSortitionNumSeats -> Bool
(LocalSortitionNumSeats -> Bool) -> HasZero LocalSortitionNumSeats
forall a. (a -> Bool) -> HasZero a
$cisZero :: LocalSortitionNumSeats -> Bool
isZero :: LocalSortitionNumSeats -> Bool
HasZero)
localSortitionNumSeats ::
NonPersistentCommitteeSize ->
TotalNonPersistentStake ->
LedgerStake ->
NormalizedVRFOutput ->
LocalSortitionNumSeats
localSortitionNumSeats :: NonPersistentCommitteeSize
-> TotalNonPersistentStake
-> LedgerStake
-> NormalizedVRFOutput
-> LocalSortitionNumSeats
localSortitionNumSeats
(NonPersistentCommitteeSize Word64
numNonPersistentVoters)
(TotalNonPersistentStake (Cumulative (LedgerStake Rational
totalNonPersistentStake)))
(LedgerStake Rational
voterStake)
(NormalizedVRFOutput Rational
normalizedVRFOutput)
| Rational
voterStake Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 = Word64 -> LocalSortitionNumSeats
LocalSortitionNumSeats Word64
0
| FixedPoint
lambda FixedPoint -> FixedPoint -> Bool
forall a. Ord a => a -> a -> Bool
<= FixedPoint
0 = Word64 -> LocalSortitionNumSeats
LocalSortitionNumSeats Word64
0
| Bool
otherwise = Word64 -> LocalSortitionNumSeats
LocalSortitionNumSeats (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
expectedSeats)
where
lambda :: FixedPoint
lambda :: FixedPoint
lambda =
Rational -> FixedPoint
forall a. Fractional a => Rational -> a
fromRational (Rational -> FixedPoint) -> Rational -> FixedPoint
forall a b. (a -> b) -> a -> b
$
Word64 -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
numNonPersistentVoters
Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
voterStake
Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
totalNonPersistentStake
orders :: [FixedPoint]
orders :: [FixedPoint]
orders =
(Rational -> FixedPoint
forall a. Fractional a => Rational -> a
fromRational Rational
normalizedVRFOutput FixedPoint -> FixedPoint -> FixedPoint
forall a. Fractional a => a -> a -> a
/ FixedPoint
lambda)
FixedPoint -> [FixedPoint] -> [FixedPoint]
forall a. a -> [a] -> [a]
: (FixedPoint -> FixedPoint -> FixedPoint)
-> [FixedPoint] -> [FixedPoint] -> [FixedPoint]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
(\FixedPoint
k FixedPoint
prev -> FixedPoint
k FixedPoint -> FixedPoint -> FixedPoint
forall a. Num a => a -> a -> a
* FixedPoint
prev FixedPoint -> FixedPoint -> FixedPoint
forall a. Fractional a => a -> a -> a
/ FixedPoint
lambda)
[FixedPoint
2 ..]
[FixedPoint]
orders
expectedSeats :: Int
expectedSeats :: Int
expectedSeats =
Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$
FixedPoint -> [FixedPoint] -> FixedPoint -> Maybe Int
forall a. RealFrac a => a -> [a] -> a -> Maybe Int
taylorExpCmpFirstNonLower
FixedPoint
3
[FixedPoint]
orders
(-FixedPoint
lambda)
data Step a
= Stop
|
Below Int a a a
taylorExpCmpFirstNonLower ::
forall a.
RealFrac a =>
a ->
[a] ->
a ->
Maybe Int
taylorExpCmpFirstNonLower :: forall a. RealFrac a => a -> [a] -> a -> Maybe Int
taylorExpCmpFirstNonLower a
boundX [a]
cmps a
x =
Int -> Int -> a -> a -> a -> Int -> [a] -> Maybe Int
goList Int
1000 Int
0 a
x a
1 a
1 Int
0 [a]
cmps
where
goList ::
Int ->
Int ->
a ->
a ->
a ->
Int ->
[a] ->
Maybe Int
goList :: Int -> Int -> a -> a -> a -> Int -> [a] -> Maybe Int
goList Int
_ Int
_ a
_ a
_ a
_ Int
_ [] = Maybe Int
forall a. Maybe a
Nothing
goList Int
maxN Int
n a
err a
acc a
divisor Int
i (a
cmp : [a]
rest) =
case Int -> Int -> a -> a -> a -> a -> Step a
decideOne Int
maxN Int
n a
err a
acc a
divisor a
cmp of
Step a
Stop ->
Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
Below Int
n' a
err' a
acc' a
divisor' ->
Int -> Int -> a -> a -> a -> Int -> [a] -> Maybe Int
goList Int
maxN Int
n' a
err' a
acc' a
divisor' (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [a]
rest
decideOne ::
Int ->
Int ->
a ->
a ->
a ->
a ->
Step a
decideOne :: Int -> Int -> a -> a -> a -> a -> Step a
decideOne Int
maxN Int
n a
err a
acc a
divisor a
cmp
| Int
maxN Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n = Step a
forall a. Step a
Stop
| a
cmp a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
acc' a -> a -> a
forall a. Num a => a -> a -> a
+ a
errorTerm = Step a
forall a. Step a
Stop
| a
cmp a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
acc' a -> a -> a
forall a. Num a => a -> a -> a
- a
errorTerm = Int -> a -> a -> a -> Step a
forall a. Int -> a -> a -> a -> Step a
Below (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
err' a
acc' a
divisor'
| Bool
otherwise = Int -> Int -> a -> a -> a -> a -> Step a
decideOne Int
maxN (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
err' a
acc' a
divisor' a
cmp
where
divisor' :: a
divisor' = a
divisor a -> a -> a
forall a. Num a => a -> a -> a
+ a
1
nextX :: a
nextX = a
err
acc' :: a
acc' = a
acc a -> a -> a
forall a. Num a => a -> a -> a
+ a
nextX
err' :: a
err' = (a
err a -> a -> a
forall a. Num a => a -> a -> a
* a
x) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
divisor'
errorTerm :: a
errorTerm = a -> a
forall a. Num a => a -> a
abs (a
err' a -> a -> a
forall a. Num a => a -> a -> a
* a
boundX)