Nano Hash - криптовалюты, майнинг, программирование

как численно интегрировать переменную, которая вычисляется в программе в качестве указателя (например, с использованием трапециевидного правила) на языке c

У меня есть код, который был сделан не мной. В этом сложном коде применяется множество правил для вычисления величины 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 как указателя или должен объявить его как простой двойной? Я предполагаю, что ошибка сегментации подходит для этого.

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

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

Луис


  • это не ФОРТРАН, вам не обязательно использовать все заглавные буквы 26.06.2011
  • Чтобы ответить на этот вопрос, нам нужно увидеть определения и распределения d, W и Z. 26.06.2011
  • даже в современном фортране вам не нужны все заглавные буквы 26.06.2011
  • @David Grayson И немного ioccc.org 26.06.2011
  • @Shin Я знаю это, но взгляните на netlib, и вы увидите, откуда я. 26.06.2011
  • @ Дэвид Хеффернан, спасибо, чувак, $ d $ - это плотность людей, я беру это из конкретной проблемы динамики населения. $W$ является (должно быть) интегралом по этой плотности, т. е. полным ее числом. $Z$ была ошибкой, я исправляю. 26.06.2011
  • int INTE5=0.0'? Зачем назначать float для int? 26.06.2011
  • @ziulfer Нет. Покажите нам, как эти 3 переменные объявляются и распределяются. Пожалуйста, не ожидайте, что мы решим проблему, не видя кода. Мы не можем видеть ваш экран. Проблема наверняка в том, что массив выходит за пределы ошибки. Отсюда необходимость посмотреть, как распределяются массивы. 26.06.2011
  • @все, простите, ребята. Я знаю, что все это полный бардак. Все эти штучки для меня как-то новы. Итак, буквы «Z» нет, я ее просто удалил. Это должно было быть «W» с самого начала. 26.06.2011

Ответы:


1

Я не знаю, откуда взялся этот код, но он очень уродлив и имеет жестко закодированные ограничения (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 d[333];
   double W[333];

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

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

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

26.06.2011
  • Как это объясняет ошибку seg? 26.06.2011
  • это не так. Я полагал, вам нужен работающий код для алгоритма, а не только этот работающий. Скорее всего, вы не передали нужное количество данных/комнаты для d и W; у вас должны быть W и d как массивы не менее N_X_POINTS элементов 26.06.2011
  • то есть double d[N_X_POINTS], W[N_X_POINTS]; /* ... */ WORK(d, W); /* ... */ или что-то в этом роде 26.06.2011
  • +1 @ziulfer перейдите по ссылке, которую дает вам Шин. Это ссылки на код, который ясен и понятен. Ваш код, даже если вы исправите ошибку seg, безусловно, неверен. 26.06.2011
  • В общем случае ответ будет таков: чтобы использовать его, вам нужно правильно «сэмплировать» вашу функцию и генерировать пары (x, f (x)) означает, что пользователь не правильно сэмплировал функцию, поэтому он / она получает ошибку seg. Надеюсь, комментарии, которые отвечают на вопрос Хеффрнана, должны прояснить это для пользователя. 26.06.2011
  • хорошо, ребята, спасибо вам большое. Я вижу, что проблема должна быть в чем-то другом. Это некрасиво и непонятно, и.... Но чтобы интегрировать по указателю, должен ли я использовать другой указатель? Можете ли вы помочь мне с этим? 26.06.2011
  • указатель просто указывает на последовательность двойных чисел (т. е. массив): с double d[1000];, если вы переходите к функции просто d, как в WORK(d, W), d является не чем иным, как указателем на двойные числа. *(d+1) это d[1] и так далее. На самом деле в вашем РАБОЧЕМ коде, даже если у вас есть указатель, переданный как arg, он индексирует его как массив; это потому, что A[B] есть не что иное, как *(A+B). Может быть, это было ваше непонимание о func? 26.06.2011
  • @ShinTakezou Да, я лучше прочитал ссылку, которую ты мне прислал. Итак, еще одна вещь, наконец, я должен объявить в WORK(*(d)(),w). И сделать то же самое для d во всех других частях кода, где вычисляется d? Возврат в конце каждого? P.S.: Прошу прощения за все эти глупые вопросы.... 27.06.2011
  • спасибо, обязательно мне очень поможет!!! Я попробую, и как можно скорее вернусь к вам, ребята !!! этот stackoverflow действительно потрясающий веб-сайт 27.06.2011
  • код в ссылке использует другой подход: вы передаете функцию, которую хотите интегрировать, и диапазон интервалов (в основном). Функция WORK требует два массива (поэтому я предположил, что вам нужно попробовать функцию самостоятельно, но прочитайте отредактированный ответ, где я сомневаюсь, что это имеет смысл, для этого потребуется только один массив, а не два) 27.06.2011

  • 2

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

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

    26.06.2011

    3

    Вот простая программа, которая интегрирует $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;
    }
    
    26.06.2011
  • спасибо, обязательно мне очень поможет!!! Я попробую, и как можно скорее вернусь к вам, ребята!!! этот stackoverflow действительно потрясающий сайт 27.06.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..