在 GMP-GNU 中评估(100一世)一种一世( 1 -一个)( 100 -我)(100i)ai(1−a)(100−i)

计算科学 软件
2021-12-07 00:51:44

我要计算

\binom{100}{i}a^i(1-a)^{(100-i)}用于使用 GMP-GNU(100i)ai(1a)(100i)的不同ia=0.001

如何才能做到这一点?

3个回答

我希望这就是你要找的。这是一个打印出“1”的程序:

/* gcc -lgmp foo.c -o foo */
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

int main(int argc, char **argv) {
  int t, i, n=100;
  mpz_t fac_num, fac_den;
  mpq_t a, q, tq, sum;

  mpz_init(fac_num); mpz_init(fac_den); 
  mpq_init(a); mpq_init(q); mpq_init(tq); 
  mpq_init(sum);

  mpq_set_ui(sum, 0, 1);

  for (i=0; i<=n; i++) {

    mpq_set_ui(a, 1, 1000);
    mpq_set_ui(q, 999, 1000);
    mpq_set_ui(tq, 1, 1);

    mpz_set_ui(fac_num, 1);
    mpz_set_ui(fac_den, 1);
    for (t=0; t<i; t++) {
      mpz_mul_ui(fac_num, fac_num, n-t);
      mpz_mul_ui(fac_den, fac_den, t+1);
      mpq_mul(tq, tq, a);
    }

    for (; t<n; t++) 
      mpq_mul(tq, tq, q);

    mpq_set_ui(q, 1, 1);
    mpq_set_num(q, fac_num);
    mpq_set_den(q, fac_den);
    mpq_mul(q, q, tq);

    mpq_add(sum, sum, q);

  }

  mpq_canonicalize(sum);

  gmp_printf("%Qd\n", sum);

  mpz_clear(fac_num); mpz_clear(fac_den); 
  mpq_clear(a); mpq_clear(q); mpq_clear(tq);
  mpq_clear(sum);

}

可能有更有效的方法来做阶乘,你可以通过平方来做幂,但我把这些留给读者。

我也会去评估你的表达式 log(binom(100,i)) + i*log(a)+(100-i)*log(1-a) 的对数,然后取结果的指数.

你能告诉我们为什么需要多精度算术吗?您对最终结果所需的准确度是多少?我认为你可以通过良好的级数逼近走得很远,当然当 a 接近于零时......

根据您需要的准确度,考虑只对结果进行近似。

至少对于 {100 over i} 部分,您应该能够使用 Sterling 公式 (http://en.wikipedia.org/wiki/Sterling's_approximation) 等技术获得良好的近似值。余数可以相对容易地计算。