如何从根中有效地找到多项式的系数? [复制]

Posted

技术标签:

【中文标题】如何从根中有效地找到多项式的系数? [复制]【英文标题】:How to efficiently find coefficients of a polynomial from its roots? [duplicate] 【发布时间】:2016-01-09 03:25:58 【问题描述】:

给定一个多项式的 n 根,其前导系数为 1。 我如何有效地找出这个多项式的系数?

数学上, 我知道,如果第一个系数是 1,那么一次取 k 的乘积根之和将是多项式的 k+1-th 系数。

我的代码就是基于这种方法的。

换句话说,如何以最佳方式从一次获取k 的列表中找到数字的乘积之和。

int main()


    int n, sum;
    cin >> n;
    int a[n];
    for (int i=0; i<n; i++) cin >> a[i];
    //for the second coefficient
    sum=0;
    for (int i=0; i<n; i++)
    
        sum+=a[i];
    
    cout << sum << endl;
    //for the third coefficient
    sum=0;
    for (int i=0; i<n; i++)
    
        for (int j=i+1; j<n; j++)
        
            sum+=a[i]*a[j];
        
    
    cout << sum << endl;

为了更高的系数,我考虑过标记是否将它们带入产品中,但没有编写代码,因为如果多项式的次数很大,它实际上是没有用的.

【问题讨论】:

直接计算多项式是 O(n^2) IIRC。 @n.m.您能描述一下O(n^2) 方法吗? 看看我的回答:***.com/questions/23537120/… 谢谢@MBo。无法将评论标记为答案。你能补充一个答案吗? (也许在伪代码/python/c++ 中)?我不明白该代码中的 SetLength 函数。 希望Pascal接近伪代码。 SetLength设置输出动态数组Coeff的长度,所以它的索引范围是0..N(N次幂多项式有N+1个系数)。奇数运算符评估参数的奇数/偶数 【参考方案1】:

你需要计算线性因子的乘积

(x-z1)·(x-z2)·…·(x-zn)

这可以通过重复将多项式与线性因子相乘来归纳实现

(a[0]+a[1]·x+…+a[m-1]·x^(m-1))·(x-zm)

= (-a[0]·zm) + (a[0]-a[1]·zm)·x + … + (a[m-2]-a[m-1]·zm) · x^(m-1) + a[m-1]·x^m

这可以实现为循环

a[m] = a[m-1]
for k = m-1 downto 1
    a[k] = a[k-1] - a[k]*zm
end
a[0] = -a[0]*zm

这为所有 n 个线性因子的乘法提供了总共 n²/2 次乘法和相同数量的减法。

【讨论】:

【参考方案2】:

首先在C++中a[n]是一个静态数组,所以编译器需要在编译时知道n,这里不是这样。所以代码在 C++ 中是“不正确的”。我知道它会在 gcc 或其他编译器中编译,但它违反 C++ 标准。参见C++ declare an array based on a non-constant variable? 你需要的是一个动态数组,使用newdelete 命令,或者你可以使用STL 中更安全的std::vector 类。

现在,这里的主要问题是你需要k 嵌套循环,如果你想计算k'th 系数,(我假设 1 是第 0 个系数,而不是第 1 个,只是约定)。所以,你需要实现变量号。代码中的嵌套 for 循环。我正在发布您的问题的解决方案,其中我使用了一种方法来实现变量号。的嵌套 for 循环。希望这能解决您的问题。

#include <iostream>
#include <cmath>
#include <vector>  // include vector class

using namespace std;

double coeff(int,const vector<double>& );  // function declaration to to calculate coefficients

int main()


  int N = 5; // no. of roots

  // dynamic vector containing values of roots
  vector<double> Roots(N); 
  for(int i = 0 ; i<N ; ++i)
    Roots[i] = (double)(i+1);  // just an example, you can use std::cin


  int K = 2;  // say you want to know K th coefficient of the polynomial

  double K_th_coeff = coeff(K,Roots); // function call

  cout<<K_th_coeff<<endl; // print the value

  return 0;



double coeff(int k,const vector<double>& roots)


  int size = roots.size(); // total no. of roots

  int loop_no = k; // total no. of nested loops
  vector<int> loop_counter(loop_no+1); // loop_counter's are the actual iterators through the nested loops
  // like i_1, i_2, i_3 etc., loop_counter[loop_no] is needed to maintain the condition of the loops

  for(int i=0; i<loop_no+1; ++i)
    loop_counter[i]=0;   // initialize all iterators to zero


  vector<int> MAX(loop_no+1); // MAX value for a loop, like  for(int i_1=0; i_1 < MAX[1]; i++)... 
    for(int i=0 ; i<loop_no ; ++i)
      MAX[i] = size - loop_no  + i + 1; // calculated from the algorithm

    MAX[loop_no]=2; // do'es no matter, just != 1

    int  p1=0; // required to maintain the condition of the loops

    double sum(0); // sum of all products

    while(loop_counter[loop_no]==0)
    
      // variable nested loops starts here

      int counter(0);
      // check that i_1 < i_2 < i_3 ....
      for(int i = 1 ; i < loop_no; ++i)
      
        if(loop_counter[i-1] < loop_counter[i])
          ++counter;
      


      if(counter == loop_no - 1) // true if i_1 < i_2 < i_3 ....
      
        double prod(1);
        for(int i = 0 ; i < loop_no ; ++i)  
          prod *= roots[loop_counter[i]];   // taking products

        sum += prod;  // increament
      


    // variable nested loops ends here...


    ++loop_counter[0];
    while(loop_counter[p1]==MAX[p1])
      
        loop_counter[p1]=0;
        loop_counter[++p1]++;
        if(loop_counter[p1]!=MAX[p1])
          p1=0;
      
    

    return pow(-1.0,k)*sum;   // DO NOT FORGET THE NEGATIVE SIGN


我检查了代码,它运行良好。如果您想知道如何实现变量 no.of 嵌套 for 循环,只需访问 variable nested for loops 并查看 BugMeNot2013 的答案。

【讨论】:

以上是关于如何从根中有效地找到多项式的系数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

vijos - P1739计算系数 (多项式计算 + 杨辉三角形 + 高速幂)

Spark 多项式 Logistic 回归中的意外系数

如何使用条件有效地向量化多项式计算(屋顶线模型)

重载加法运算符以添加两个多项式

求n为模n的前r个二项式系数之和的算法

如何从多项式字符串中获取系数和指数?