#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
tounsigned
, тогда компилятор сможет выполнять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
имеет большое значение в!