python中求和符号怎么打,处理Python中大二项式的求和

I need to compute this formula:

fi12W.gif

It is an approximation of this integral

CaHGl.gif

but it doesn't matter, actually I just want to compute the value of Figure 1 with PYTHON, that's what the topic concerns.

K, alpha and sigma are fixed values within a single computation, usually:

0 <= k <= 99;

alpha = 3;

sigma = 2.

Below is how I am trying to compute such summation in python:

import decimal

from scipy.special import binom

def residual_time_mean(alpha, sigma=2, k=1):

prev_prec = decimal.getcontext().prec

D = decimal.Decimal

decimal.getcontext().prec = 128

a = float(alpha)

s = float(sigma)

sum1 = 0.0

sum2 = 0.0

sumD1 = D(0.0)

sumD2 = D(0.0)

for i in range(1, k + 1):

sum1 += binom(k, i) * ((-1) ** (i + 1)) * (s / ((a - 1) * i - 1.0))

sum2 += binom(k, i) * ((-1) ** (i + 1)) * s / ((a - 1) * i - 1.0)

sumD1 += D(binom(k, i)) * (D(-1.0) ** (D(i) + D(1.0))) * (D(s) / ((D(a) - D(1.0)) * D(i) - D(1.0)))

sumD2 += D(binom(k, i)) * (D(-1.0) ** (D(i) + D(1.0))) * D(s) / ((D(a) - D(1.0)) * D(i) - D(1.0))

decimal.getcontext().prec = prev_prec

return sum1, sum2, float(sumD1), float(sumD2)

Running

for k in [0, 1, 2, 4, 8, 20, 50, 99]:

print("k={} -> {}".format(k, residual_time_mean(3, 2, k)))

the outcome is:

k=0 -> (0.0, 0.0, 0.0, 0.0)

k=1 -> (2.0, 2.0, 2.0, 2.0)

k=2 -> (3.3333333333333335, 3.3333333333333335, 3.3333333333333335, 3.3333333333333335)

k=4 -> (5.314285714285714, 5.314285714285714, 5.314285714285714, 5.314285714285714)

k=8 -> (8.184304584304588, 8.184304584304583, 8.184304584304584, 8.184304584304584)

k=20 -> (13.952692275798238, 13.952692275795965, 13.95269227579524, 13.95269227579524)

k=50 -> (23.134878809207617, 23.13390225415814, 23.134078892910786, 23.134078892910786)

k=99 -> (265412075330.96634, 179529505602.9507, 17667813427.20196, 17667813427.20196)

You can see that starting from k=8 the results are different.

Making a multiplication before a division leads results of sum1 and sum2 to diverge a lot for k=99 for instance.

sum1 += binom(k, i) * ((-1) ** (i + 1)) * (s / ((a - 1) * i - 1.0))

sum2 += binom(k, i) * ((-1) ** (i + 1)) * s / ((a - 1) * i - 1.0)

With decimal this problem doesn't occur but the result is not correct at all.

Computing the summation on WolframAlpha

for k = 99

(Here is the link for the computation on WolframAlpha). It gives 33.3159488(...) while for my python function it is 17667813427.20196. I trust WolframAlpha since it makes something like symbolic computation, indeed it also returns the real value in form of a fraction.

for other k

Approximation problems (e.g. the value computed by Wolfram is different from the one computed in python by an order of magnitude of 10^0 or more) starts occurring from k~=60.

Moreover computing the integral (Figure 2) with scipy.integrate leads to similar approximation errors.

The question:

Do you have any suggestion to handle this computation? Increasing decimal precision doesn't seem to be helpful.

解决方案

I don't understand why you involve a numpy function here, and why you are converting to float objects. Really, for this formula, if your inputs are always integers, then simply stick with int and fractions.Fraction and your answers will always be exact. It is easy enough to implement your own binom function:

In [8]: def binom(n, k):

...: return (

...: factorial(n)

...: // (factorial(k)*factorial(n-k))

...: )

...:

Note, I used integer division: //. And finally, your summation:

In [9]: from fractions import Fraction

...: def F(k, a, s):

...: result = Fraction(0, 1)

...: for i in range(1, k+1):

...: b = binom(k, i)*pow(-1, i+1)

...: x = Fraction(s, (a-1)*i - 1)

...: result += b*x

...: return result

...:

And the results:

In [10]: F(99, 3, 2)

Out[10]: Fraction(47372953498165579239913571130715220654368322523193013011418, 1421930192463933435386372127473055337225260516259631545875)

Which seems correct based on wolfram-alpha...

Note, if say, alpha can be a non-integer, you could use decimal.Decimal for arbitary-precision floating point operations:

In [17]: from decimal import Decimal

...: def F(k, a, s):

...: result = Decimal('0')

...: for i in range(1, k+1):

...: b = binom(k, i)*pow(-1, i+1)

...: x = Decimal(s) / Decimal((a-1)*i - 1)

...: result += b*x

...: return result

...:

In [18]: F(99, 3, 2)

Out[18]: Decimal('33.72169506311642881389682714')

Let's up the precision:

In [20]: import decimal

In [21]: decimal.getcontext().prec

Out[21]: 28

In [22]: decimal.getcontext().prec = 100

In [23]: F(99, 3, 2)

Out[23]: Decimal('33.31594880623309576443774363783112352607484321721989160481537847749994248174570647797323789728798446')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值