как численно интегрировать переменную, которая вычисляется в программе, как указатель (используя, например, правило трапеции) на языке c - PullRequest
1 голос
/ 26 июня 2011

У меня есть код, который я не сделал. В этом сложном коде применяется много правил для вычисления величины d (x). в коде используется указатель для его вычисления.

Я хочу вычислить интеграл по этому, например: W = Int_0 ^ L d (x) dx?

Я делаю это:

#define DX 0.003
void WORK(double *d, double *W)
{
    double INTE5=0.0;
    int N_X_POINTS=333;
    double h=((d[N_X_POINTS]-d[0])/N_X_POINTS); 
    W[0]=W[0]+((h/2)*(d[1]+2.0*d[0]+d[N_X_POINTS-1])); /*BC*/
    for (i=1;i<N_X_POINTS-1;i++) 
    {
        W[i]=W[i]+((h/2)*(d[0]+2*d[i]+d[N_X_POINTS]))*DX;
        INTE5+=W[i];
    }
    W[N_X_POINTS-1]=W[N_X_POINTS-1]+((h/2)*(d[0]+2.0*d[N_X_POINTS-1]+d[N_X_POINTS-2])); /*BC*/
}

И я получаю "Ошибка сегментации". Мне было интересно узнать, правильно ли я делаю вычисление W как указатель, или я должен объявить его как простой дубль? Я предполагаю, что ошибка Сегментации прибывает для этого.

Другой вопрос, правильно ли я использую правило трапеции?

Любая помощь / совет, буду очень признателен.

Луиз

Ответы [ 3 ]

1 голос
/ 26 июня 2011

Я не знаю, откуда взялся этот код, но он очень уродливый и имеет некоторые ограничения, жестко закодированные (333 пункта и приращение на 0,003). Чтобы использовать его, вам нужно правильно «сэмплировать» свою функцию и сгенерировать пары (x, f (x)) ...

Возможное более ясное решение вашей проблемы: здесь .

Давайте рассмотрим вашу функцию и предположим, что она работает (я полагаю, что это не так, это действительно неясный код ...; например, когда вы интегрируете функцию, вы ожидаете число как результат; где это число? Может быть, INTE5? Он не возвращается ... и если это так, то почему окончательное обновление массива W? Это бесполезно, или, может быть, у нас есть что-то значимое в W?). Как бы вы его использовали?

Прототип

  void WORK(double *d, double *W);

означает, что РАБОТА требует двух указателей. Что эти указатели должны быть, зависит от кода; если взглянуть на это, можно предположить, что вам действительно нужны два массива, каждый из которых содержит элементы N_X_POINTS. Код читает из массива W и записывает его, а читает только из d. Значение N_X_POINTS int равно 333, поэтому вам необходимо передать в функциональные массивы не менее 333 значений типа double:

   double d[333];
   double W[333];

Тогда вы должны заполнить их правильно. Я подумал, что вам нужно заполнить их (x, f (x)), выбрав функцию с правильным шагом. Но, конечно, это не имеет особого смысла. Уже сказано, что код неясен (теперь я не хочу пытаться изменить инженерию намерений кодера ...).

В любом случае, если вы позвоните с помощью WORK(d, W), вы не получите ошибку сегмента, так как массивы достаточно велики. Результат будет неправильным, но его сложнее отследить (опять же, извините, для этого нет «реверс-инжиниринга»).

Последнее замечание (из комментариев тоже): если у вас double a[N], то a имеет тип double *.

0 голосов
/ 26 июня 2011

Вот простая программа, которая интегрирует $ f (x) = x ^ 2 $ в диапазоне [0..10]. Он должен отправить вас в правильном направлении.

#include <stdio.h>
#include <stdlib.h>

double int_trapezium(double f[], double dX, int n)
{
   int i;
   double sum;

   sum = (f[0] + f[n-1])/2.0;
   for (i = 1; i < n-1; i++)
       sum += f[i];
   return dX*sum;
}

#define N 1000
int main()
{
    int i;
    double x;
    double from = 0.0;
    double to = 10.0;
    double dX = (to-from)/(N-1);
    double *f = malloc(N*sizeof(*f));

    for (i=0; i<N; i++)
    {
        x = from + i*dX*(to-from);
        f[i] = x*x;
    }
    printf("%f\n", int_trapezium(f, dX, N));
    free(f);
    return 0;
}
0 голосов
/ 26 июня 2011

Ошибка ошибки сегментации часто возникает в C, когда вы пытаетесь получить доступ к некоторой части памяти, к которой вы не должны обращаться. Я подозреваю, что выражение d[N_X_POINTS] является виновником (потому что массивы в C индексируются нулем), но не видя определения d, я не могу быть уверен.

Попробуйте поместить информативные printf операторы отладки до / после каждой строки кода в вашей функции, чтобы вы могли сузить возможные источники проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...