Можно ли сделать распределение Пуассона с вероятностями, основанными на целых числах? - PullRequest
0 голосов
/ 26 февраля 2019

Работать в Солидности и Эфириуме EVM и Десятичных дробей не существует.Есть ли способ, которым я мог бы математически все еще создать распределение Пуассона, используя целые числа?он не должен быть идеальным, то есть округление или потеря некоторых цифр могут быть приемлемыми.

1 Ответ

0 голосов
/ 07 марта 2019

Позвольте мне предисловие, заявив, что то, что следует, не будет (напрямую) полезным для вас с эфирностью / твердостью.Тем не менее, он создает таблицы вероятностей, которые вы могли бы использовать для своей работы.

В итоге я был заинтригован вопросом о том, насколько точно вы можете выразить пуассоновские вероятности как рациональные, поэтому я собрал следующеескрипт на Ruby, чтобы попробовать:

def rational_poisson(lmbda)
  Hash.new.tap do |h|   # create a hash and pass it to this block as 'h'.
    # Make all components of the calculations rational to allow
    # cancellations to occur wherever possible when dividing
    e_to_minus_lambda = Math.exp(-lmbda).to_r
    factorial = 1r
    lmbda = lmbda.to_r
    power = 1r
    (0...).each do |x|
      unless x == 0
        power *= lmbda
        factorial *= x
      end
      value = (e_to_minus_lambda / factorial) * power
      # the following double inversion/conversion bounds the result
      # by the significant bits in the mantissa of a float
      approx = Rational(1, (1 / value).to_f)
      h[x] = approx
      break if x > lmbda && approx.numerator <= 1
    end
  end
end

if __FILE__ == $PROGRAM_NAME
  lmbda = (ARGV.shift || 2.0).to_f  # read in a lambda (defaults to 2.0)
  pmf = rational_poisson(lmbda)     # create the pmf for a Poisson with that lambda
  pmf.each { |key, value| puts "p(#{key}) = #{value} = #{value.to_f}" }
  puts "cumulative error = #{1.0 - pmf.values.inject(&:+)}"  # does it sum to 1?
end

Что нужно знать, когда вы просматриваете код.Добавление .to_r к значению или выражению преобразует его в рациональное, т. Е. Отношение двух целых чисел;значения с суффиксом r являются рациональными константами;(0...).each - это открытый итератор, который будет зацикливаться до тех пор, пока не будет выполнено условие break.

Этот маленький скрипт выдаст такие результаты, как:

localhost:pjs$ ruby poisson_rational.rb 1.0
p(0) = 2251799813685248/6121026514868073 = 0.36787944117144233
p(1) = 2251799813685248/6121026514868073 = 0.36787944117144233
p(2) = 1125899906842624/6121026514868073 = 0.18393972058572117
p(3) = 281474976710656/4590769886151055 = 0.061313240195240384
p(4) = 70368744177664/4590769886151055 = 0.015328310048810096
p(5) = 17592186044416/5738462357688819 = 0.003065662009762019
p(6) = 1099511627776/2151923384133307 = 0.0005109436682936699
p(7) = 274877906944/3765865922233287 = 7.299195261338141e-05
p(8) = 34359738368/3765865922233287 = 9.123994076672677e-06
p(9) = 67108864/66196861914257 = 1.0137771196302974e-06
p(10) = 33554432/330984309571285 = 1.0137771196302975e-07
p(11) = 33554432/3640827405284135 = 9.216155633002704e-09
p(12) = 4194304/5461241107926203 = 7.68012969416892e-10
p(13) = 524288/8874516800380079 = 5.907792072437631e-11
p(14) = 32768/7765202200332569 = 4.2198514803125934e-12
p(15) = 256/909984632851473 = 2.8132343202083955e-13
p(16) = 16/909984632851473 = 1.7582714501302472e-14
p(17) = 1/966858672404690 = 1.0342773236060278e-15
cumulative error = 0.0
...