2010-11-29 4 views
0

Petit peu d'un 2 parter. Tout d'abord im essayant de faire cela dans tous les c. Tout d'abord, je vais aller de l'avant et après mon programmeProgramme d'entrée de fichier/règle de trapèze

#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; 
} 

Comme vous pouvez le voir, il calcule la règle trapézoïdale étant donné un intervalle. Tout d'abord cela fonctionne, si vous codez les valeurs et la fonction. Mais je dois lire un fichier dans le format de

5 
3.0 2.5 -1.5 0.0 1.7 4.0 
6 10 

Ce qui signifie: Il est de degré 5 (pas plus de 50 jamais) 3,0x^5 + 2,5x^4 -1.5x^3 + 1.7x + 4 est le polynôme (nous sautons^2 puisqu'il est 0) et l'intervalle est de 6 à 10

Ma principale préoccupation est la fonction f (x) que j'ai codée en dur. Je n'ai aucune idée comment le faire prendre jusqu'à 50 en plus de taper 50 POWS littéralement et en lisant dans les valeurs pour voir ce qu'ils pourraient être ....... Quelqu'un d'autre a peut-être des idées?

Aussi quelle serait la meilleure façon de lire dans le fichier? fgetc? Je ne suis pas vraiment sûr quand il s'agit de lire en entrée C (d'autant plus que tout ce que je lis est un INT, y a-t-il un moyen de les convertir?)

Répondre

3

Pour un polynôme de grand degré, est-ce que quelque chose comme ça fonctionnerait?

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]; 
} 

Dans votre exemple, vous l'appelez comme:

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); 
} 

En passant un tableau de coefficients (les exposants sont pris en charge), vous ne devez pas traiter avec des arguments variadique. La partie la plus difficile est la construction du tableau, et c'est assez simple.


Il va sans dire, si vous mettez le tableau des coefficients et de nombre de coefficients dans les variables globales, puis la signature de f (x) n'a pas besoin de changer:

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

+1 Battez-moi. – chrisaycock

+0

Hmmm ce prolly semble être le meilleur moyen, je ré-appelle f (x) dans la fonction trapèze mais serait-ce un problème? Je voudrais juste réajuster le f (x) dans cette fonction aussi bien je suppose que –

+0

Vraiment une bonne réponse mais pour les devoirs sommes-nous censés fournir un code complet comme vous l'avez fait? Ma prise est peut-être pas. Je ne sais pas. –

0

Pour vous f() fonction envisager de le rendre variadique (varargs est un autre nom)

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

de cette façon, vous pouvez passer la fonction 1 arg indique combien de « prisonniers de guerre » que vous voulez, avec chaque argument susequent étant une valeur double. Est-ce ce que vous demandez avec la partie f() de votre question?

+2

Cela ne résout pas son problème de lecture du fichier de configuration. – chrisaycock

+0

Vous avez raison - j'ai répondu à 1 question 2. C'est devoirs, je ne peux pas juste poster du code. –

+0

Non, je veux dire, cela ne résout même pas son problème avec 'f()' car les arguments de la fonction variadique doivent être connus au moment de la compilation, comme 'f (3, a, b, c)'. Comme il lit à partir d'un fichier de configuration, la liste des arguments ne peut pas être fournie au moment de la compilation. – chrisaycock