C文件输入/梯形规则程序

时间:2010-11-29 19:45:45

标签: c file input openmp

2分的一点点。首先,我试图在所有c中做到这一点。首先,我会继续发布我的程序

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#include <string.h>

double f(double x);    
void Trap(double a, double b, int n, double* integral_p);

int main(int argc, char* argv[]) {

   double  integral=0.0;  //Integral Result
   double  a=6, b=10;   //Left and Right Points
   int    n;     //Number of Trapezoids (Higher=more accurate) 
   int degree;

  if (argc != 3) {
      printf("Error: Invalid Command Line arguements, format:./trapezoid N filename");
      exit(0);
   }
   n = atoi(argv[2]);

   FILE *fp = fopen( argv[1], "r" );

#  pragma omp parallel 
   Trap(a, b, n, &integral);
   printf("With n = %d trapezoids....\n", n);
   printf("of the integral from %f to %f = %.15e\n",a, b, integral);
   return 0;
}  

double f(double x) {
   double return_val;
   return_val = pow(3.0*x,5)+pow(2.5*x,4)+pow(-1.5*x,3)+pow(0*x,2)+pow(1.7*x,1)+4;
   return return_val;
}  
void Trap(double a, double b, int n, double* integral_p) {
   double  h, x, my_integral;
   double  local_a, local_b;
   int  i, local_n;
   int my_rank = omp_get_thread_num();
   int thread_count = omp_get_num_threads();

   h = (b-a)/n;
   local_n = n/thread_count;
   local_a = a + my_rank*local_n*h;
   local_b = local_a + local_n*h;
   my_integral = (f(local_a) + f(local_b))/2.0;
   for (i = 1; i <= local_n-1; i++) {
     x = local_a + i*h;
     my_integral += f(x);
   }
   my_integral = my_integral*h;

#  pragma omp critical
   *integral_p += my_integral;
}  

如您所见,它在给定间隔的情况下计算梯形规则。 首先,如果您对值和功能进行硬编码,它会起作用。但我需要以

的格式从文件中读取
5
3.0 2.5 -1.5 0.0 1.7 4.0
6 10

这意味着: 它是5级(不超过50) 3.0x ^ 5 + 2.5x ^ 4 -1.5x ^ 3 + 1.7x + 4是多项式(我们跳过^ 2,因为它是0) 间隔时间为6到10

我主要担心的是我硬编码的f(x)函数。我没有IDEA如何让它最多需要50个,除了字面输入50 POWS并阅读价值观以查看它们可能是什么.......其他人有任何想法可能吗?

另外,阅读文件的最佳方式是什么?龟etc?我不确定什么时候阅读C输入(特别是因为我读到的所有东西都是INT,有没有办法转换它们?)

2 个答案:

答案 0 :(得分:3)

对于很大程度的多项式,这样的工作会起作用吗?

double f(double x, double coeff[], int nCoeff)
{
    double return_val = 0.0;
    int exponent = nCoeff-1;

    int i;
    for(i=0; i<nCoeff-1; ++i, --exponent)
    {
        return_val = pow(coeff[i]*x, exponent) + return_val;
    }
    /* add on the final constant, 4, in our example */
    return return_val + coeff[nCoeff-1];  
}

在您的示例中,您可以将其命名为:

sampleCall()
{
    double coefficients[] = {3.0, 2.5, -1.5, 0, 1.7, 4};
    /* This expresses 3x^5 + 2.5x^4 + (-1.5x)^3 + 0x^2 + 1.7x + 4 */
    my_integral = f(x, coefficients, 6);
}

通过传递一系列系数(假定指数),您不必处理可变参数。最难的部分是构建数组,这非常简单。


不言而喻,如果你将系数数组和系数数放入全局变量,那么f(x)的签名就不需要改变了:

double f(double x)
{
   // access glbl_coeff and glbl_NumOfCoeffs, instead of parameters
}

答案 1 :(得分:0)

对于你f()函数,考虑将其变为variadic(varargs是另一个名称)

http://www.gnu.org/s/libc/manual/html_node/Variadic-Functions.html

这样你可以传递函数1 arg告诉它你想要多少“pows”,每个后续参数都是double值。这是你问题的f()函数部分要求的吗?