2010-11-29 16 views
0

2パターのビット。まず第一に、私はこれをすべてCでしようとしています。まず最初に私のプログラムを投稿してください。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; 
} 

ご覧のとおり、一定の間隔で台形則が計算されます。 まず、値と関数をハードコードすれば、それは動作します。^3 -1.5x それは度5(これまでより多くない50)である 3.0xの^ 5 + 2.5倍^ 4:しかし、私は意味

5 
3.0 2.5 -1.5 0.0 1.7 4.0 
6 10 

の形式のファイルから読み込む必要があります+ 1.7x + 4は多項式です(0なので^ 2をスキップします) 、間隔は6~10です。

私の主な関心事は、ハードコードされたf(x)関数です。私は、50人の囚人を文字通り入力して、値段で読むことができるのを除いて、50になるようにする方法はありません。誰でも他のアイデアはおそらくありますか?

また、ファイルを読むにはどうすればよいでしょうか? fgetc?私が読み込んだものはすべてINTなので、特にそれらを変換する方法はありますか?

答えて

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 
} 
+0

+1私にそれを打つ。 – chrisaycock

+0

Hmmmこれは最善の方法のように思えますが、私は台形関数でf(x)を再呼び出ししますが、これは問題になりますか?私はちょうどその関数のf(x)を再調整する必要があるだろうと思う。 –

+0

本当に良い答えだが、宿題のためにあなたが実際に完全なコードを提供するはずですか?私のテイクは多分そうではありません。私は知らないよ。 –

0

あなたはf()関数をvaradicとすることを検討してください(varargsは別です名)

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

あなたは、各susequent引数はdouble値であることと、あなたが望むどのように多くの「捕虜」それを伝えるARG機能1を渡すことができますこの方法です。これはあなたの質問のf()関数の部分で求めているものですか?

+2

これは設定ファイルからの読書の問題を扱っていません。 – chrisaycock

+0

あなたは正しいです - 私は2つの質問に答えました。これは宿題です、私はちょうどコードを投稿することはできません。 –

+0

いいえ、私はf()で問題を解決することさえできません。なぜなら、変数の関数の引数は 'f(3、a、b、c)'のようにコンパイル時に知っていなければならないからです。彼は設定ファイルから読み込んでいるので、コンパイル時に引数のリストを提供することはできません。 – chrisaycock