Как я могу усреднить подмножество массива и сохранить результат в другом массиве?

#c #arrays #math #arduino #average

#c #массивы #математика #arduino #среднее

Вопрос:

У меня есть массив C fftArray[64] , который содержит значения, которые я хочу усреднить и поместить в другой массив frequencyBar[8] . Получить среднее значение для всего массива было бы достаточно просто с помощью оператора for .

 int average, sum = 0;
for (i = 0; i < 64; i  )
{
     sum  = fftArray[i];
}
average = sum/64;
  

Но я просто не могу понять, как получить среднее значение от fftArray[0] конца fftArray[8] и сохранить это в frequencyBar[0] , среднее значение от fftArray[9] конца fftArray[16] и сохранить это в frequencyBar[1] и т.д. Кто-нибудь может мне помочь с этим? Спасибо

Ответ №1:

Это похоже на домашнее задание, поэтому, вместо того, чтобы давать вам прямой ответ, я бы предпочел просто указать вам правильное направление…

используйте вложенный цикл (один внутри другого). Один цикл повторяет 0-7, другой 0-63. Используйте меньшее значение для заполнения ваших нарезанных средних значений.

или, еще лучше, используйте оператор%, чтобы увидеть, когда вы прошли через 8 элементов, и вычислите среднее значение вашего общего количества, а затем сбросьте общее количество для следующего набора. Тогда вы тоже научитесь использовать оператор%! 🙂

[РЕДАКТИРОВАТЬ] хорошо, если не домашнее задание, тогда что-то вроде этого… Я не писал C 5 лет, поэтому рассматривайте это как псевдокод:

 //assuming you have a fftArray[64] with data, as per your question
int i,sum,avCounter,total;
int averages[8]; 
for(i=0 , avCounter=0, total=0 ; i<64; ){
    total  = fftArray[i];
    if(  i % 8 == 0){   //%gives you the remainder which will be 0 every 8th cycle
      averages[avCounter  ] = total / 8
      total = 0;  //reset for next cycle
    }
}
  

Я думаю, что это будет работать лучше, чем вложенный цикл… но я не уверен, поскольку% — это деление, которое требует больше ресурсов процессора, чем сложение… однако… Я сомневаюсь, что кто-нибудь заметит 🙂

Комментарии:

1. Я использую это с моим Arduino и библиотекой FFT для извлечения значений частоты из аудиосигнала для создания музыкального визуализатора Arduino. Спасибо за предложение, хотя

2. Спасибо Dr. Dredel. Я попробую это и вложенный оператор и посмотрю, что быстрее. Умное использование%!

3. Если вы измените тип i to unsigned , тогда компилятор сможет выполнять i % 8 логическое И, а не деление.

Ответ №2:

 int i, j;
for (i = 0; i < 8; i  ) {
    int sum = 0;
    for (j = 0; j < 8; j  ) {
        sum  = fftArray[ 8*i   j ];
    }
    frequencyBar[i] = sum / 8;
}
  

Бонусное упражнение: оптимизируйте этот код для повышения скорости на выбранной вами платформе.

Комментарии:

1. Спасибо, похоже на то, что мне нужно. И я постараюсь выжать из этого каждую унцию производительности, поскольку алгоритм FFT отнимает много сил у моего маленького Arduino!

Ответ №3:

TF,

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: этот код просто не укладывается у меня в голове … он даже не был скомпилирован, не говоря уже о тестировании.

 // returns the average of array[first..last] inclusive.
int average(int[] array, int first, int last) {
    int sum = 0; 
    for (i = first; i <= last; i  )
        sum  = array[i];
    return sum / (last - first   1); // not sure about the  1
}
  

Затем, что вы должны сделать, это перебрать индексы вашего frequencyBar массива [0..7], установив frequencyBar[i] = average(array, first, last); … сложность заключается в вычислении индексов first and last … попробуйте i*8 и (i 1)*8 соответственно… это может быть не совсем правильно, но это будет близко 😉

Приветствия. Кит.


РЕДАКТИРОВАТЬ: скучно … жду возвращения результатов моего теста. Отсутствие новостей — хорошая новость, верно? 😉

Оказывается, передача length немного проще, чем передача last индекса.

 #include <stdio.h>

int sum(int array[], int first, int length) {
    int sum = 0;
    for (int i = first; i < first length; i  )
        sum  = array[i];
    return sum;
} 

double average(int array[], int first, int length) {
    double total = sum(array, first, length);
#ifdef DEBUG
    printf("DEBUG: [-..-] %d", first, first length-1, array[first]);
    for (int i = first 1; i < first length; i  )
        printf("   %d", array[i]);
    printf(" = %d / %d = %fn", (int)total, length, total/length);
#endif
    return total / length;
} 

int main(int argc, char* argv[]) {
    int array[] = {             // average
        1, 2, 3, 4, 5, 1, 2, 3, // 2.625 
        4, 5, 1, 2, 3, 4, 5, 1, // 3.125 
        2, 3, 4, 5, 1, 2, 3, 4, // 3
        5, 1, 2, 3, 4, 5, 1, 2, // 2.875
        3, 4, 5, 1, 2, 3, 4, 5, // 3.375
        1, 2, 3, 4, 5, 1, 2, 3, // 2.625
        4, 5, 1, 2, 3, 4, 5, 1, // 3.125
        2, 3, 4, 5, 1, 2, 3, 4  // 3
    };
    double frequency[8];
    for (int i = 0; i < 8; i  )
        frequency[i] = average(array, i*8, 8);

    for (int i = 0; i < 8; i  )
        printf("%f ", frequency[i]);
    printf("n");
}
  

Ответ №4:

Следите за тем, чтобы ваш sum не обтекался, если fftArray имеет большое значение в!