C language notes: polynomial evaluation problem

Original link: http://c.biancheng.net/c/

Polynomial Profile

In mathematics, the algebraic sum of monomials composed of a plurality of polynomials called (if subtraction: Save a number equal to the opposite of its plus). Polynomial each monomial is called polynomial terms, the highest number of individual items in these formulas, is the degree of the polynomial. Wherein the polynomial term, no letter is called a constant term.

Problem scenarios and implementation code

Problem description: Suppose a polynomial of degree n
Here Insert Picture Description
where n is the degree of the polynomial (i.e., the highest number of terms in the polynomial times), AI stored index coefficients of terms i, x is a polynomial argument (type double), has and n known values of ai and x, polynomial f (x) values
analysis:
definition of double type array a [n + 1], store the polynomial coefficients ai, modular programming, defined functions Polyf (double a [], the end result int n, double x) polynomial of the code are defined the following four solutions were discussed the merits of different algorithms.
It is assumed polynomial f (x) = 1 + 2x + 3x ^ 2, following analysis based on the polynomial

/*
假设求多项式f(x)=1+2x+3x^2 
*/
#include <stdio.h>
#include <math.h>
#define N 3
const double x=1.1;//x的实际值 
//数组a存放多项式系数,n为递多项式的次数,x为字母代数 
double Polyf1(double a[],int n,double x);//调用库函数pow() 
double Polyf2(double a[],int n,double x);//用循环语句求x^i 
double Polyf3(double a[],int n,double x);//由迭代x^i=x^(i-1)*x,省略内层循环 
double Polyf4(double a[],int n,double x);//采用秦九韶算法 
int main(void)
{
 double a[N]={1,2,3};
 printf("Polyf1():1+2x+3x^2(x=1.1)=%lf\n",Polyf1(a,2,x));
 printf("Polyf2():1+2x+3x^2(x=1.1)=%lf\n",Polyf2(a,2,x));
 printf("Polyf3():1+2x+3x^2(x=1.1)=%lf\n",Polyf3(a,2,x));
 printf("Polyf4():1+2x+3x^2(x=1.1)=%lf\n",Polyf4(a,2,x));
 return 0;
}
double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}
double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
//  term=pow(x,i);
  p+=a[i]*term;
 }
 return p;
}
double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}
double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}

operation result:
Here Insert Picture Description

Analysis of four kinds of solutions

method 1:

double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}

Analysis Method 1: This method is called double pow (double x, double i) in a header file math.h, find the i-th power of x, and finally multiplied by the coefficient a [i] is obtained for each individual polynomial, of course, you can also write your own loop algorithm instead of calling library functions, so with the second method

Method 2:

double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
  p+=a[i]*term;
 }
 return p;
}

Analysis Methods 1 and 2: Method 1 due to the library function call, the efficiency of the method is slightly slower than the point 2, are both performed a 1 + 2 + ... + n 3 multiplications i.e., n = 2 additions, but If n is set too high, the operating efficiency will be low

Method 3:

double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}

Method 3 and Method 2 Analysis:
Since the method 2 (when when i = 2), when calculating x ^ 2, first calculation 1 * x, then the x * (1 * x), in fact, may be i = 1 when, retains its value, and then (when i = 2 when) directly using the calculated results when 1 i = 1 * x, multiplied by an x, necessary to calculate 1 * x. Jiyu calculating x ^ i, available x ^ i = x ^ (i -1) * x iterations determined. To retain the modified point i.e. the end of the calculation term variable value, then the inner loop may be omitted. The method of the third function were done 2n, i.e. 4 multiplications, n = 2 additions, when n is large, since x ^ i may result from a previous iteration is calculated, the method improves efficiency than an order of magnitude.

Method 4:

double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}

Analysis Method 4:
using Horner's method, Horner's method is a monohydric n times evaluator polynomial problems once the conversion of n-type algorithm.
The f (x) = 1 + 2x + 3x ^ 2 = 1+ (2 + 3x) x

Speed ​​test function

The required header file: "time.h"

Required function: clock

Prototype:

clock_t clock( void );

CPU clock ticks between when the function returns "call clock () function in the program" from "On the program process" to (clock tick)

In time.h file, CLOCKS_PER_SEC also defines a constant, which indicates how many clock for a second timing unit will be defined as follows:

#define CLOCKS_PER_SEC ((clock_t)1000)  //一秒=1000毫秒

time clock function returns the process to run, but the run time unit than seconds, but the CPU clock cycle running count.

So to get consumed time (seconds), the CPU clock is divided by frequency, i.e. CLOCKS_PER_SEC. To give a value in seconds.

/*
假设求多项式f(x)=1+2x+3x^2 
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#define N 3
#define K 1e6
clock_t start, end;
double dur;
const double x=1.1;//x的实际值 
double a[N]={1,2,3};
//数组a存放多项式系数,n为递多项式的次数,x为字母代数 
double Polyf1(double a[],int n,double x);//调用库函数pow() 
double Polyf2(double a[],int n,double x);//用循环语句求x^i 
double Polyf3(double a[],int n,double x);//由迭代x^i=x^(i-1)*x,省略内层循环 
double Polyf4(double a[],int n,double x);//采用秦九韶算法 
void Ftick(double (*fp)(double *,int ,double));//测试函数的执行时间 
int main(void)
{
 printf("Polyf1():1+2x+3x^2(x=1.1)=%lf\n",Polyf1(a,2,x));
 printf("Polyf2():1+2x+3x^2(x=1.1)=%lf\n",Polyf2(a,2,x));
 printf("Polyf3():1+2x+3x^2(x=1.1)=%lf\n",Polyf3(a,2,x));
 printf("Polyf4():1+2x+3x^2(x=1.1)=%lf\n",Polyf4(a,2,x));
 Ftick(Polyf1);
 Ftick(Polyf2);
 Ftick(Polyf3);
 Ftick(Polyf4);
 return 0;
}
double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}
double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
//  term=pow(x,i);
  p+=a[i]*term;
 }
 return p;
}
double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}
double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}
void Ftick(double (*fp)(double *,int ,double))
{
 double sum;             //fp的返回值
 start=clock();           //记录下面代码开始执行时的时钟打点数
 for(int i = 1;i <= K;i++)     //为了能测出时间,让函数fp执行K次  
     sum = fp(a, N, x);
 end = clock();            //记录上面代码结束时的时钟打点数
 dur=(double)(end - start) / CLK_TCK / K;    //计算函数fp执行一次的时间(秒) 
 printf("f(x) = %f, time=%6.2e\n", sum, dur);   //输出sum及dur  
}

The results:
Here Insert Picture Description
you can find the last time the algorithm execution method shortest!

Reference: "C language from entry to project combat" ----------- Wang Yiping, eds

Guess you like

Origin blog.csdn.net/weixin_42124234/article/details/101630967