Выбор и анализ окна точек в массиве - PullRequest
1 голос
/ 24 августа 2010

Может кто-нибудь, пожалуйста, посоветуйте мне, как решить эту проблему.

У меня есть функция, которая выполняет простой регрессионный анализ наборов точек, содержащихся в массиве. У меня есть один массив (pval), который содержит все данные, на которых я хочу выполнить регрессионный анализ. Вот как я хочу это реализовать.

  1. Я получаю среднее значение для первых 7 элементов массива. Это то, что я называю ref_avg в программе.

  2. Я хочу выполнить регрессионный анализ для каждых пяти элементов массива, взяв первый элемент этого массива в качестве 'ref_avg'. То есть на каждом этапе регрессионного анализа у меня будет 6 точек в массиве.

    например Для 1-го шага ref_avg, рассчитанный ниже, составляет 70,78. Таким образом, первый шаг в простой регрессии будет содержать эти точки

    1-й = {70,78,76,26,69,17,88,68,71,49,73,08},

    Второй шаг будет содержать ref_avg в качестве 1-го элемента и другие элементы, начиная со второго элемента в исходном массиве

    2-й = {70,78,69,17,68,68,71,49,73,08,22,99},

    3-й = {70,78,68,68,71,49,73,08,72,99,70,36},

    4-й = {70.78,71.49,73.08,72.99,70.36,57.82} и так далее до конца.

  3. Функция регрессии также показана ниже.

Я не понимаю, почему первые 3 элемента массива 'calcul' имеют значение 0,00 на первом шаге регрессии, 2 элемента на 2-м шаге, 1 элемент на 3-м. Также последний шаг функции регрессии напечатан 3 раза.

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

   int main()
{

  float pval[]={76.26,69.17,68.68,71.49,73.08,72.99,70.36,57.82,58.98,69.71,70.43,77.53,80.77,70.30,70.5,70.79,75.58,76.88,80.20,77.69,80.80,70.5,85.27,75.25};


   int count,Nhour;
   const int MAX_HOUR = 24;
   float *calcul=NULL;
   float *tab_time =NULL;
   float ref_avg;
   int size_hour=7;
   float sum=0;
   int length = Nhour+1;
   float m;
   float b;
   calcul=(float*)calloc(MAX_HOUR,sizeof(calcul));
     if (calcul==NULL) 
    {
        printf(" error in buffer\n");
        exit(EXIT_FAILURE);
    }

   tab_time= calloc(MAX_HOUR,sizeof(float));

         /* Get the average of the first seven elements */
            int i;
    for (i=0;i<size_hour;i++)
    {
    sum += pval[i];
    }
    ref_avg = sum / size_hour; 

          count=0;
        /* perform the regression analysis on 5 hours increment */

         while(count<=MAX_HOUR)
         {
          ++count;
           Nhour=5;

           int pass = -(Nhour-1);
           int i=0;

           for(i=0;i<Nhour+1;i++)  
             {
             if(count<MAX_HOUR)
               {

              calcul[0]=ref_avg;
              calcul[i] =pval[count+pass];
              pass++;
               }

     printf("calc=%.2f\n",calcul[i]); // For debug only 
     tab_time[i]=i+1; 

               if(i==Nhour)
            {

           linear_regression(tab_time, calcul, length, &m, &b);
           printf("Slope= %.2f\n", m);

            }
           }
     }

    free(calcul);
    calcul=NULL;
    free(tab_time);
    tab_time=NULL;              
    return 0;
  }
  /*  end of the main function */


   /* This function is used to calculate the linear 
    regression as it was called above in the main function. 
    It compiles and runs very well, was just included for the 
    compilation and execution of the main function above where I have a problem. */


    int linear_regression(const float *x,  const float *y, const int n, float *beta1, float *beta0)
    {

          float sumx = 0,
        sumy = 0,
        sumx2 = 0,
        sumxy = 0;

int i;
if (n <= 1) {
    *beta1 = 0;
    *beta0= 0;
    printf("Not enough data for regression \n");
        } 
          else 
            {
    float variance;

    for (i = 0; i < n; i++) 
             {
        sumx += x[i];
        sumy += y[i];

        sumx2 += (x[i] * x[i]);

        sumxy += (x[i] * y[i]);
     }
    variance = (sumx2 - ((sumx * sumx) / n));
    if ( variance != 0) {
        *beta1 = (sumxy - ((sumx * sumy) / n)) /  variance;
        *beta0 = (sumy - ((*beta1) * sumx)) / n;
    } 
           else  
                 {
        *beta1 = 0;
        *beta0 = 0;

         }

        }
          return 0;
      }

1 Ответ

0 голосов
/ 25 сентября 2010

Я думаю, что этот код дает вменяемые ответы. Ссылочная средняя, ​​приведенная в вопросе, кажется неверной. Выделение памяти не требуется. Значение MAX_HOUR было 24, но в массиве было только 23 значения данных. Индексирование при построении массива для регрессии было поддельным, ссылаясь на отрицательные индексы в массиве pval (и, следовательно, приводило к ошибочным результатам). На переменную Nhour ссылались до ее инициализации; переменная длина была установлена ​​неправильно. Не было хорошей диагностической печати. ​​

Тело main() здесь существенно переписано; редактирование на linear_regression() намного более минимально. Код выстроен более последовательно, и для облегчения чтения используется пробел. Эта версия завершает регрессию, когда больше не хватает данных для заполнения массива 5 значениями - неясно, каким было предполагаемое условие завершения.

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

void linear_regression(const float *x, const float *y, const int n,
                       float *beta1, float *beta0);

int main(void)
{
    float pval[]={
        76.26, 68.68, 71.49, 73.08, 72.99, 70.36, 57.82, 58.98,
        69.71, 70.43, 77.53, 80.77, 70.30, 70.50, 70.79, 75.58,
        76.88, 80.20, 77.69, 80.80, 70.50, 85.27, 75.25,
        };
    const int Nhour = 5;
    const int MAX_HOUR = sizeof(pval)/sizeof(pval[0]);
    const int size_hour = 7;
    float ref_avg;
    float sum = 0.0;
    float m;
    float b;
    float calc_y[6];
    float calc_x[6];

    /* Get the average of the first seven elements */
    for (int i = 0; i < size_hour; i++)
        sum += pval[i];
    ref_avg = sum / size_hour; 
    printf("ref avg = %5.2f\n", ref_avg); // JL

    /* perform the regression analysis on 5 hours increment */
    for (int pass = 0; pass <= MAX_HOUR - Nhour; pass++) // JL
    {
        calc_y[0] = ref_avg;
        calc_x[0] = pass + 1;
        printf("pass %d\ncalc_y[0] = %5.2f, calc_x[0] = %5.2f\n",
               pass, calc_y[0], calc_x[0]);
        for (int i = 1; i <= Nhour; i++)  
        {
            int n = pass + i - 1;
            calc_y[i] = pval[n];
            calc_x[i] = pass + i + 1; 
            printf("calc_y[%d] = %5.2f, calc_x[%d] = %5.2f, n = %2d\n",
                   i, calc_y[i], i, calc_x[i], n);
        }

        linear_regression(calc_x, calc_y, Nhour+1, &m, &b);
        printf("Slope= %5.2f, intercept = %5.2f\n", m, b);
    }

    return 0;
}

void linear_regression(const float *x, const float *y, const int n, float *beta1, float *beta0)
{
    float sumx1 = 0.0;
    float sumy1 = 0.0;
    float sumx2 = 0.0;
    float sumxy = 0.0;

    assert(n > 1);

    for (int i = 0; i < n; i++) 
    {
        sumx1 += x[i];
        sumy1 += y[i];
        sumx2 += (x[i] * x[i]);
        sumxy += (x[i] * y[i]);
    }
    float variance = (sumx2 - ((sumx1 * sumx1) / n));
    if (variance != 0.0)
    {
        *beta1 = (sumxy - ((sumx1 * sumy1) / n)) /  variance;
        *beta0 = (sumy1 - ((*beta1) * sumx1)) / n;
    } 
    else  
    {
        *beta1 = 0.0;
        *beta0 = 0.0;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...