我尝试使用此公式使用梯形近似来实现数值积分:
我的问题是我不知道如何正确实现这一点。为了测试,我编写了一个文件,22050
双值都等于2,如:
....................
value =2.0;
for ( index = 0 ; index < 22050;index++){
fwrite(&value,sizeof(double),1,inp2);
}
保持问题简单,说我想要每100个样本的积分值:
X Area integral value
0-100 should be 200
100-200 should be 200
..... ...........
22000-22050 should be 100
要做到这一点,我已经编写了一个应该这样做的程序,但4387950
100 samples
得到的结果是我的代码:
..............................
// opening the files
double* inputData= NULL;
unsigned int N = 100;
double h= 0.0;
unsigned int index= 0;
FILE* inputFile=NULL;
double value =0.0;
int i =0,j=0;
inputFile = fopen("sinusD","rb");
outputFile=fopen("Trapez","wb+");
if( inputFile==NULL || outputFile==NULL){
printf("Couldn't open the files \n");
return -1;
}
inputData = (double*) malloc(sizeof(double)*N);
h=22050/2;
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value += inputData[0] +inputData[N];
for(index=1;index<N;index++){
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
if(i!=0){
value = 0;
i=-i;
printf("i value %i\n", i);
fseek(inputFile,i*sizeof(double),SEEK_END);
fread(inputData,sizeof(double),i,inputFile);
for(index=0;index<-i;index++){
printf("index %d\n",index);
value += inputData[0] +inputData[i];
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
fclose(inputFile);
fclose(outputFile);
free(inputData);
return 0;}
任何想法怎么做?
更新
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value = (inputData[0] + inputData[N])/2.0;
for(index=1;index<N;index++){
value+=inputData[index];
}
value *=h;
fprintf(outputFile,"%lf ",value);
printf(" value %lf\n",value);
value =0;
}
我得到199.000
作为每个细分的结果。
答案 0 :(得分:2)
为什么你没有从简单的事情开始。假设您有以下数据{1,2,3,4,5,6,7,8,9,10}
并假设h = 1
。这很简单,
#include <stdio.h>
#define SIZE 10
int main()
{
double a[SIZE] = {1,2,3,4,5,6,7,8,9,10}, sum = 0.0, trapz;
int h = 1;
int i = 0;
for ( i; i < SIZE; ++i){
if ( i == 0 || i == SIZE-1 ) // for the first and last elements
sum += a[i]/2;
else
sum += a[i]; // the rest of data
}
trapz = sum*h; // the result
printf("Result: %f \n", trapz);
return 0;
}
这是结果
Result: 49.500000
使用Matlab仔细检查您的工作:
Y = [1 2 3 4 5 6 7 8 9 10];
Q = trapz(Y)
Q =
49.5000
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$
编辑:对于评论中的问题: 这是matlab代码:
X = 0:pi/100:pi; % --> h = pi/100
Y = sin(X); % get values as many as the size of X
Q = trapz(X,Y);
Q =
1.9998
现在要在C中实现相同的方案,请执行以下操作
#include <stdio.h>
#include <math.h>
#define SIZE 101
#define PI 3.14159265358
int main()
{
double X[SIZE], Y[SIZE], incr = 0.0, h = PI/100.0, sum = 0.0, trapz;
int i = 0, k = 0, j = 0;
// Generate samples
for ( i; i < SIZE; ++i)
{
X[i] = incr;
incr += h;
}
// Generate the function Y = sin(X)
for ( k; k < SIZE; ++k)
{
Y[k] = sin(X[k]);
}
// Compute the integral of sin(X) using Trapezoidal numerical integration method
for ( j; j < SIZE; ++j){
if ( j == 0 || j == SIZE-1 ) // for the first and last elements
sum += Y[j]/2;
else
sum += Y[j]; // the rest of data
}
trapz = sum * h; // compute the integral
printf("Result: %f \n", trapz);
return 0;
}
结果是
Result: 1.999836
答案 1 :(得分:1)
首先,你的等式是正确的,所以这是一个良好的开端。但是,您的问题中有许多变量声明没有提供,因此我们不得不猜测。
首先,让我们从数学开始。对于从0到100等于200的积分,每个值等于2.0意味着h = 1
,但您的代码似乎使用22050/2
的值,这可能不是您想要的。
循环中的代码应如下所示:
double value = (inputData[0] + inputData[N])/2.0;
for(index = 1; index < N; ++index){
value += inputData[index];
}
value *= h;
这将提供从0
到N
的积分。如果您希望在两个任意值之间进行计算,则必须适当地修改代码:
int a = 100; // lower limit
int b = 200; // upper limit
double value = (inputData[a] + inputData[b])/2.0;
for(index = a+1; index < b; ++index){
value += inputData[index];
}
value *= h;
作为一个完整的使用示例,这是一个计算sin(x)
从x=pi/4
到x=pi/2
的积分的程序:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M_PI 3.14159265358979323846
int main()
{
int a = 45; // 45 degrees = pi/4 radians
int b = 90; // 90 degrees = pi/2 radians
double h = M_PI/180; // how far apart are samples?
double *inputData = malloc(360*sizeof(double));
if (inputData == NULL) {
printf("Error: ran out of memory!\n");
exit(1);
}
for (int i=0; i<360; ++i)
inputData[i] = sin(i*h);
double value = (inputData[a] + inputData[b])/2.0;
for (int index = a+1; index < b; ++index)
value += inputData[index];
value *= h;
printf("integral from %d to %d = %f\n", a, b, value);
double expected = 1.0/sqrt(2);
printf("(expected value = %f, error = %f)\n", expected, expected-value);
free(inputData);
}
我的机器上此程序的输出:
integral from 45 to 90 = 0.707089
(expected value = 0.707107, error = 0.000018)