首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >二项式系数舍入误差

二项式系数舍入误差
EN

Stack Overflow用户
提问于 2016-09-30 12:04:11
回答 4查看 440关注 0票数 0

我必须计算表达式(x+y)**n的c二项式系数,n很大(数量级为500-1000)。我想到的第一个计算二项式系数的方法是乘法公式。所以我把它编码到我的程序中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
long double binomial(int k, int m)
{
    int i,j;
    long double num=1, den=1;
    j=m<(k-m)?m:(k-m);
    for(i=1;i<=j;i++)
    {
        num*=(k+1-i);
        den*=i;
    }
    return num/den; 
}

递归公式相比,这段代码在单个核心线程上确实非常快速,尽管后者不太容易出现舍入错误,因为它只涉及和而不涉及除法。因此,我想测试这些标志的伟大价值,并试图评估500选择250 (订单10^160)。我发现“相对误差”小于10^(-19),所以基本上是相同的数字,尽管它们有10^141的不同之处。

所以我想知道:是否有一种方法来评估计算误差的顺序?是否有比乘法公式更精确的二项式系数的快速计算方法?由于我不知道我的公式的精度,我不知道在哪里截断斯特林级数以获得更好的结果。

我谷歌了一些表的二项式系数,以便我可以复制,但我找到的最好的一个在n=100.

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-09-30 15:21:43

如果您只是使用n计算单个二项式系数C(n,k)相当大,但不大于1750年,那么使用适当的C库的最佳选择是使用tgammal标准库函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tgammal(n+1) / (tgammal(n-k+1) * tgammal(k+1))

用libm的Gnu实现进行了测试,结果一致地在几个ULP内精确值,并且通常比基于乘法和除法的解决方案更好。

如果k足够小(或大),使得二项式系数不溢出64位精度,那么可以通过交替相乘和除法得到精确的结果。

如果n太大,以至于tgammal(n+1)超过了长双(大于1754)的范围,但不超过分子溢出的范围,那么没有大号库就能得到最好的乘法解。但是,您也可以使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
expl(lgammal(n+1) - lgammal(n-k+1) - lgammal(k+1))

这不太精确,但更容易编码。(此外,如果系数的对数对您有用,则上述公式将在相当大的n和k范围内工作。不必使用expl将提高精度。)

如果您需要一个具有相同n值的二项式系数范围,那么最好的选择是迭代加法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void binoms(unsigned n, long double* res) {
  // res must have (n+3)/2 elements
  res[0] = 1;
  for (unsigned i = 2, half = 0; i <= n; ++i) {
    res[half + 1] = res[half] * 2;
    for (int k = half; k > 0; --k)
      res[k] += res[k-1];
    if (i % 2 == 0)
      ++half;
  }
}

上面只产生k为0到n/2的系数。它的舍入误差比乘法算法稍大(至少当k接近于n/2时),但是如果你需要所有的系数,并且它有更大范围的可接受的输入,它会快得多。

票数 1
EN

Stack Overflow用户

发布于 2016-09-30 12:21:17

要获得小km的确切整数结果,更好的解决方案可能是(代码稍有变化):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  unsigned long binomial(int k, int m)
  {
   int i,j; unsigned long num=1;
   j=m<(k-m)?m:(k-m);
   for(i=1;i<=j;i++)
   {
    num*=(k+1-i);
    num/=i;
   }
   return num;
  }

每次在除法num/=i之后得到一个组合数,就不会被截断。要获得更大的km的近似结果,您的解决方案可能是好的。但请注意,long double乘法已经比整数的乘法和除法(unsigned longsize_t)慢得多。如果您想精确地得到更大的数字,那么可能必须从库中编码或包含一个大整数class。如果有非常大整数n!的快速阶乘算法,你也可以搜索n。这对组合学也有帮助。当ln(n!)较大时,Stirling公式是n的一个很好的近似。这完全取决于你想要的准确程度。

票数 1
EN

Stack Overflow用户

发布于 2016-09-30 13:45:10

如果您真的想使用乘法公式,我建议采用一种基于异常的方法。

  1. 用大整数实现公式(例如长长)
  2. 尽快尝试分工合作(如卓然所建议)
  3. 添加代码以检查每个除法和乘法的正确性。
  4. 解决不正确的除法或乘法,例如
    • 尝试卓然提出的循环除法,但如果失败,则返回初始算法(在den中累加除数乘积)。
    • 将未解析的乘子、除数存储在附加的长整数中,并尝试在下一个迭代循环中求解它们。

  1. 如果您真的使用大数,那么您的结果可能不适合长整数。然后,在这种情况下,您可以切换到长双或使用您的个人LongInteger存储。

这是一个框架代码,给您一个想法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
long long binomial_l(int k, int m)
{
    int i,j;
    long long num=1, den=1;
    j=m<(k-m)?m:(k-m);
    for(i=1;i<=j;i++)
    {
        int multiplier=(k+1-i);
        int divisor=i;
        long long candidate_num=num*multiplier;
        //check multiplication
        if((candidate_num/multiplier)!=num)
        {
            //resolve exception...
        }
        else
        {
            num=candidate_num;
        }

        candidate_num=num/divisor;
        //check division
        if((candidate_num*divisor)==num)
        {
            num=candidate_num;
        }
        else
        {
            //resolve exception
            den*=divisor;
            //this multiplication should also be checked...
        }
    }
    long long candidate_result= num/den; 
    if((candidate_result*den)==num)
    {
        return candidate_result;
    }
    // you should not get here if all exceptions are resolved
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39799303

复制
相关文章
二项式系数 Binomial Coefficients
\binom nk 表示二项式系数,其中 n 称作上指标 (upper index),而称 k 为下指标 (lower index)。
yzxoi
2022/09/19
1.3K0
二项式系数 Binomial Coefficients
Binomial Coefficient(二项式系数)
In mathematics, any of the positive integers that occurs as a coefficient in the binomial theorem is a binomial coefficient. Commonly, a binomial coefficient is indexed by a pair of integers n ≥ k ≥ 0 and is written {\displaystyle {\tbinom {n}{k}}.} {\displaystyle {\tbinom {n}{k}}.} It is the coefficient of the xk term in the polynomial expansion of the binomial power (1 + x)n, and it is given by the formula.
HoneyMoose
2019/01/22
8910
LeetCode 1058. 最小化舍入误差以满足目标(排序+贪心)
给定一系列价格 [p1,p2…,pn] 和一个目标 target,将每个价格 pi 舍入为 Roundi(pi) 以使得舍入数组 [Round1(p1),Round2(p2)...,Roundn(pn)] 之和达到给定的目标值 target。每次舍入操作 Roundi(pi) 可以是向下舍 Floor(pi) 也可以是向上入 Ceil(pi)。
Michael阿明
2021/02/19
6680
算法训练 6-1 递归求二项式系数值
样例输入 一个满足题目要求的输入范例。 3 10 样例输出 与上面的样例输入对应的输出。 120 数据规模和约定   输入数据中每一个数的范围。   例:结果在int表示时不会溢出。
AI那点小事
2020/04/20
3690
算法训练 6-1 递归求二项式系数值
【组合数学】生成函数 简要介绍 ( 生成函数定义 | 牛顿二项式系数 | 常用的生成函数 | 与常数相关 | 与二项式系数相关 | 与多项式系数相关 )
1.幂级数 : 数学分析 中 重要概念 , 在 指数级的 每一项 均为 与 级数项 序号
韩曙亮
2023/03/28
6760
【组合数学】生成函数 简要介绍 ( 生成函数定义 | 牛顿二项式系数 | 常用的生成函数 | 与常数相关 | 与二项式系数相关 | 与多项式系数相关 )
第九周算法训练6-1递归求二项式系数值
本文最后更新于 1163 天前,其中的信息可能已经有所发展或是发生改变。 #include<iostream> using namespace std; int dg(int a,int b){ if(a==0||a==b){ return 1; } return dg(a,b-1)+dg(a-1,b-1); } int main(){ int a,b; cin>>a>>b; cout<<dg(a,b); return 0; } Post Views: 183
Yuyy
2022/06/28
1710
数值微分|有限差分法的误差分析
以(1)为例,分子可能会为0。但是我们不能使h太大,因为这样截断错误将变得过大。为了解决这个矛盾,我们可以采取以下措施:
fem178
2020/09/01
2.7K0
二项式定理
其实二项式定理也就一句话:$(x + y)^n = \sum_{i = 0}^n C_{n}^i x^{n - i} y^{i}$
attack
2018/09/17
9870
二项式定理
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现|附代码数据
Glmnet是一个通过惩罚最大似然关系拟合广义线性模型的软件包。正则化路径是针对正则化参数λ的值网格处的lasso或Elastic Net(弹性网络)惩罚值计算的 ( 点击文末“阅读原文”获取完整代码数据******** )。
拓端
2022/11/08
3.1K0
测量误差?什么误差?测量什么?
买了一台普源的DM3058,官网售价3980元,用来测量100nA误差范围内的电流,由于预算有限,供应商同时推荐了固纬GDM-8341万用表,分辨率可测到10nA。某宝售价2260元,与DM3058相比省下来1720元!
硬件大熊
2022/06/23
9040
测量误差?什么误差?测量什么?
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现
Glmnet是一个通过惩罚最大似然关系拟合广义线性模型的软件包。正则化路径是针对正则化参数λ的值网格处的lasso或Elastic Net(弹性网络)惩罚值计算的。该算法非常快,并且可以利用输入矩阵中的稀疏性 x。它适合线性,逻辑和多项式,泊松和Cox回归模型。可以从拟合模型中做出各种预测。它也可以拟合多元线性回归。
拓端
2021/01/13
6.3K0
误差函数
其中, 表示神经网络的输出, 表示监督数据( 采用 one-hot 编码), 表示数据的维度。
hotarugali
2022/03/03
9310
数学建模学习笔记(六)多元回归分析算法(matlab)
b:回归系数点估计 bint:回归系数区间估计 r:残差 rint:置信区间 stats:用于检验的统计量,有三个数值,相关系数r^2,F值,与F对应的概率p alpha:显著性水平(缺省时为0.05)
zstar
2022/06/14
3K0
数学建模学习笔记(六)多元回归分析算法(matlab)
Matlab 多项式的根求解
poly 函数将这些根重新转换为多项式系数。对向量执行运算时,poly 和 roots 为反函数,因此 poly(roots(p)) 返回 p(取决于舍入误差、排序和缩放)。
用户9925864
2022/07/27
8460
Matlab 多项式的根求解
数值分析笔记(3)——数值计算中的原则
又位于分母,所以会导致误差变得非常大。要避免的另一方面的原因是,会导致有效数字位数大量减少,而我们要尽量保证有效数字多。
太阳影的社区
2021/10/15
4.7K0
标准误差
标准误差是当前应用最广泛、最基本的一种随机误差的表示方法,当标准误差求得后,平均误差和极限差即可求得故国际上普遍采用标准误差作为实验结果质量的数字指标
为为为什么
2023/02/21
1.1K0
数据分享|R语言零膨胀泊松回归ZERO-INFLATED POISSON(ZIP)模型分析露营钓鱼数据实例估计IRR和OR
零膨胀泊松回归用于对超过零计数的计数数据进行建模。此外,理论表明,多余的零点是通过与计数值不同的过程生成的,并且可以独立地对多余的零点进行建模。因此,zip模型有两个部分,泊松计数模型和用于预测多余零点的 logit 模型。
拓端
2022/06/08
2.2K0
数据分享|R语言零膨胀泊松回归ZERO-INFLATED POISSON(ZIP)模型分析露营钓鱼数据实例估计IRR和OR
广义线性模型glm泊松回归的lasso、弹性网络分类预测学生考试成绩数据和交叉验证
创建一个X 包含 100 个观测值和 10 个预测变量的随机矩阵 。y 仅使用四个预测变量和少量噪声创建正态分布因变量 。
拓端
2021/12/21
1.1K0
广义线性模型glm泊松回归的lasso、弹性网络分类预测学生考试成绩数据和交叉验证
Jacobi迭代法解线性方程组
当线性方程组的规模比较大时,采用高斯消元法需要太多时间。这时就要采用迭代法求解方程组了。高斯消元法是一个O(n^3)的浮点运算的有限序列,在经过有限步计算之后理论上得到的是精确解(无舍入误差时)。而迭代法在经过有限步迭代之后一般不产生精确解,迭代法在计算过程中逐渐减小误差,当误差小于容许值时停止迭代计算。方程组的系数矩阵是严格对角占优矩阵时,迭代总是收敛的。
fem178
2019/07/08
3K0
matlab高斯消元法求解线性方程组
高斯消元法的基本原理是通过一系列行变换将线性方程组的增广矩阵转化为简化行阶梯形式,从而得到方程组的解。其核心思想是利用矩阵的行变换操作,逐步消除未知数的系数,使得方程组的求解变得更加简单。
叶茂林
2023/10/09
4560
matlab高斯消元法求解线性方程组

相似问题

二项式系数-除以零误差

13

二项式系数

519

二项式系数

20

二项式系数

31

二项式系数[Prolog]

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文