数值分析课程的上机作业:
/*
*******************************************************************************
* Algorithm
* Abstract:
* 本程序使用 Newton 迭代法计算多项式函数的近似根,并可确定收敛域。
* 可以定制的参数有:多项式函数的次数及各项系数、允许误差、初值、确定收敛域时的步进值、需求的近似根数目。
* 参数可以选择由终端输入或由文件输入,计算结果将显示于终端,并写入输出文件。
* 通过对 root_finding 函数的简单修改,可以实现对所给初值仅计算近似根或是一并寻找收敛域的选择。
* 选择计算近似根并寻找收敛域时,请注意该精确根的收敛域是否为无穷区间。
* Notes :
* 由于时间与精力有限,只实现了当初值大于精确值时寻找收敛域的算法,初值小于精确值时的算法未实现。
* 计算近似根时,最后一次迭代结果与前一次迭代结果将一并显示以供比较。
* 寻找收敛域时,每增加一个步进值,所得结果均将显示。
* 寻找收敛域时,若计算无休止进行,则说明该精确根的收敛域为无穷区间。
* Reference:
*
* Author:
* Qiu Jun 2007-06-04
* Revision History:
* Qiu Jun 2007-06-04 Initiated Version
*******************************************************************************
*/
/*
*******************************************************************************
* ANSI C Source Code
* File Name:
* 2_20.c
* Abstract:
* 习题 2 第 20 题(上机题):Newton 迭代法计算多项式函数近似根
* Reference:
*
* Author:
* Qiu Jun 2007-06-04
* Revision History:
* Qiu Jun 2007-06-04 Initiated Version
*******************************************************************************
*/
/*
*******************************************************************************
* Include Files
*******************************************************************************
*/
#include <stdio.h>
#include <math.h>
/*
*******************************************************************************
* Constants and Define Declarations
*******************************************************************************
*/
#define max_items 10 // 允许的多项式项数
#define max_times 100 // 允许的最大迭代次数
/*
*******************************************************************************
* Global Object Definition
*******************************************************************************
*/
int n; // 多项式阶数
int root_amount; // 需求的近似根数目
double e; // 允许误差
double step; // 寻找 delta 的每次步进值
static double a[max_items]; // 多项式系数数组
static double x[max_items-1][max_times]; // 迭代结果数组
enum {no,yes} convergence; // 收敛性
/*
*******************************************************************************
* Function Definition
*******************************************************************************
*/
/*
*******************************************************************************
* Function Name:
* parameter_input
* Description:
* 参数输入
* Input:
*
* Output:
*
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
void parameter_input(file_input,file_output)
FILE *file_input;
FILE *file_output;
{
int i;
/* 由键盘输入参数 */
/* printf("\nPlease Input:\n");
printf("****************************************************************\n");
printf("Rank of Polynomial : ");
scanf("%d",&n);
printf("Factors : ");
for (i=0; i<n+1; i++)
{
scanf("%lf",&a[i]);
}
printf("e : ");
scanf("%lf",&e);
printf("step : ");
scanf("%lf",&step);
printf("Amount of Roots : ");
scanf("%d",&root_amount);
printf("****************************************************************\n\n");
*/
/* 由文件输入参数 */
fscanf(file_input,"%d",&n);
for (i=0; i<n+1; i++)
{
fscanf(file_input,"%lf",&a[i]);
}
fscanf(file_input,"%lf",&e);
fscanf(file_input,"%lf",&step);
fscanf(file_input,"%d",&root_amount);
/* 输出参数至终端 */
printf("\nThe Parameters are:\n");
printf("***********************************************************************\n");
printf("Rank of Polynomial : %d\n",n);
printf("Factors a[0]->a[n] : ");
for (i=0; i<n+1; i++)
{
printf("%f ",a[i]);
}
printf("\n");
printf("e : %f\n",e);
printf("step : %f\n",step);
printf("***********************************************************************\n\n");
/* 输出参数至文件 */
fprintf(file_output,"\nThe Parameters are:\n");
fprintf(file_output,"***********************************************************************\n");
fprintf(file_output,"Rank of Polynomial : %d\n",n);
fprintf(file_output,"Factors a[0]->a[n] : ");
for (i=0; i<n+1; i++)
{
fprintf(file_output,"%f ",a[i]);
}
fprintf(file_output,"\n");
fprintf(file_output,"e : %f\n",e);
fprintf(file_output,"step : %f\n",step);
fprintf(file_output,"***********************************************************************\n\n");
}
/*
*******************************************************************************
* Function Name:
* f
* Description:
* 计算多项式函数 f(x) 的值
* Input:
* xk : 自变量
* Output:
* fx : 函数值
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
double f(xk)
double xk;
{
int i;
double x;
double fx;
double item;
x=1;
fx=0;
for (i=0; i<n+1; i++)
{
item=a[i]*x;
fx=fx+item;
x=x*xk;
}
return(fx);
}
/*
*******************************************************************************
* Function Name:
* df
* Description:
* 计算多项式函数 f(x) 的导函数 f'(x) 的值
* Input:
* xk : 自变量
* Output:
* dfx : 函数值
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
double df(xk)
double xk;
{
int i;
double x;
double dfx;
double item;
x=1;
dfx=0;
for (i=1; i<n+1; i++)
{
item=i*a[i]*x;
dfx=dfx+item;
x=x*xk;
}
return(dfx);
}
/*
*******************************************************************************
* Function Name:
* calculate_one
* Description:
* 使用 Newton 迭代法计算近似根
* Input:
*
* Output:
*
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
void calculate_one(i,file_output)
int i;
FILE *file_output;
{
int j; // 迭代次数
double e_present; // 本次迭代误差
double e_previous; // 前次迭代误差
j=0;
/* Newton 迭代法 */
do
{
x[i][j+1]=x[i][j]-f(x[i][j])/df(x[i][j]);
e_present=fabs(x[i][j+1]-x[i][j]);
if (j!=0)
e_previous=fabs(x[i][j]-x[i][j-1]);
else e_previous=e_present;
if (e_present>e_previous)
convergence=no;
j++;
}
while (e_present>e&&convergence);
/* 输出结果至终端 */
printf("***********************************\n");
printf("Initial Value of x : %f\n",x[i][0]);
printf("Times of Iteration : %d\n",j);
printf("x[%d][%d] : %f\n",i,j,x[i][j]);
printf("x[%d][%d] : %f\n",i,j-1,x[i][j-1]);
printf("Convergence : ");
switch (convergence)
{
case no : printf("No\n"); break;
case yes : printf("Yes\n"); break;
default : break;
}
printf("***********************************\n\n");
/* 输出结果至文件 */
fprintf(file_output,"***********************************\n");
fprintf(file_output,"Initial Value of x : %lf\n",x[i][0]);
fprintf(file_output,"Times of Iteration : %d\n",j);
fprintf(file_output,"x[%d][%d] : %f\n",i,j,x[i][j]);
fprintf(file_output,"x[%d][%d] : %f\n",i,j-1,x[i][j-1]);
fprintf(file_output,"Convergence : ");
switch (convergence)
{
case no : fprintf(file_output,"No\n"); break;
case yes : fprintf(file_output,"Yes\n"); break;
default : break;
}
fprintf(file_output,"***********************************\n\n");
}
/*
*******************************************************************************
* Function Name:
* root_finding
* Description:
* 计算近似根及寻找收敛域
* Input:
*
* Output:
*
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
void root_finding(file_input,file_output)
FILE *file_input;
FILE *file_output;
{
double f();
double df();
int i; // 根数
for (i=0; i<root_amount; i++)
{
/* 由键盘输入初值 */
printf("No.%d Root :\n\n",i+1);
printf("Initial Value of x : ");
scanf("%lf",&x[i][0]);
printf("\n");
/* 由文件输入初值 */
/* fscanf(file_input,"%lf",&x[i][0]);
*/
convergence=yes;
/* 计算近似根 */
/* calculate_one(i,file_output);
*/
/* 计算近似根并寻找收敛域 */
do
{
calculate_one(i,file_output);
if (convergence)
x[i][0]=x[i][0]+step;
}
while (convergence);
}
}
/*
*******************************************************************************
* Main Function Definition
*******************************************************************************
*/
/*
*******************************************************************************
* Function Name:
* main
* Description:
* 利用 Newton 迭代法计算多项式函数近似根
* Input:
*
* Output:
*
* Function Reference:
*
* Author:
* Qiu Jun 2007-05-30 Created
*******************************************************************************
*/
void main(void)
{
void parameter_input();
void root_finding();
FILE *file_input;
FILE *file_output;
file_input=fopen("file_input.txt","r");
file_output=fopen("file_output.txt","w");
parameter_input(file_input,file_output);
root_finding(file_input,file_output);
fclose(file_input);
fclose(file_output);
}
http://hi.baidu.com/roadtowimax/blog/item/0ed406a8645364b0ca130c26.html