
1.目的
目次
2.単純移動平均とは
2.加算平均とは
・複数の数値を足してその個数で割る平均値のことを指す。
3.プログラムの作成(移動平均)
#include <stdio.h> /* ******************** * 移動平均計算 * @param arr : データ * @param n : データ数 * @param period : 計算する期間 * @return void : None ********************** */ void calculate_sma(int arr[], int n, int period) { double sum; double average; if (n < period) { ///<データ数確認 printf("データ数が移動平均の期間より少ないです。\n"); return; } ///データ数有り printf("データ数:%d,期間:%d\n",n,period); ///データ数 - 期間 + 1 分ループ for (int i = 0; i <= n - period; i++) { sum = 0; //期間分ループ (対象期間の合計値算出) for (int j = i; j < i + period; j++) { sum += arr[j]; ///<合計値算出 } if(period != 0){ ///<0除算防止 average = sum / period; ///<期間の平均値算出 } printf("期間 [%d - %d] の単純移動平均: %.2f\n", i + 1, i + period, average); } } int main() { int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 15,20}; int size = sizeof(data) / sizeof(data[0]); int period = 3; ///< 移動平均の期間 calculate_sma(data, size, period); return 0; }

3.プログラム作成(加算平均)
#include <stdio.h> //加算平均算出関数 double calculate_sum_average(int arr[], int n) { double ave = 0.0; ///<平均値 int sum = 0;///<合計値 for (int i = 0; i < n; i++) { sum += arr[i]; } if(n != 0){ ave = sum / n; } return ave; } int main() { int data[] = {1, 2, 3, 4, 5}; int size = sizeof(data) / sizeof(data[0]); ///データ数の算出 ///平均値の算出 double average = calculate_sum_average(data, size); printf("加算平均: %.2f\n", average); return 0; }

5.プログラムの作成(移動平均2)
3.移動平均のプログラムでは、全てのデータが事前に分かっていて、データ数が分かっている場合しか計算出来ない。
組み込みの場合、AD変換などを割り込みで、発生させ、定期的に移動平均を算出したい場合がある。
その場合の移動平均処理を記載する。
#include <stdio.h> #define BUF_SIZE 3 ///移動平均用構造体 typedef struct{ int bufnum; int buf[BUF_SIZE]; }Add_Ave; /* ******************** * バッファシフト用関数 * @param data:バッファに格納するデータ * @param pAdd_Ave:移動平均用構造体 * @return void : None ********************** */ void ShiftBuf(int data,Add_Ave *pAdd_Ave) { if(pAdd_Ave == NULL){ return; } pAdd_Ave->bufnum++;///データ数更新 ///バッファ最大値確認 pAdd_Ave->bufnum = (pAdd_Ave->bufnum>BUF_SIZE)?BUF_SIZE:pAdd_Ave->bufnum; // バッファをシフトして最新のデータを挿入 for (int i = 0; i < BUF_SIZE - 1; i++) { // printf("i:%d,%d\n",i,pAdd_Ave->buf[i + 1]); pAdd_Ave->buf[i] = pAdd_Ave->buf[i + 1]; } pAdd_Ave->buf[BUF_SIZE - 1] = data; //一番最後にデータを入れる。 } //加算平均算出関数 double Calc_AddAve(Add_Ave *pAdd_Ave) { double ave = 0.0; ///<平均値 int sum = 0;///<合計値 if(pAdd_Ave->bufnum <BUF_SIZE){///計算に必要なデータ数確認より小さい時 return (double)pAdd_Ave->buf[pAdd_Ave->bufnum];///新しいデータをそのまま返す。 } ///合計値算出 for (int i = 0; i < pAdd_Ave->bufnum; i++) { sum += pAdd_Ave->buf[i]; } ave = (double)sum / pAdd_Ave->bufnum; return ave; } int main() { //計算用構造体の初期化 Add_Ave g_Add_Ave = { 0, {0} }; ///用意したデータ int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 15,20}; int size = sizeof(data) / sizeof(data[0]); ///データ数の算出 ///平均値の算出 for(int i=0;i<size;i++){ printf("--入力値:%d--\n",data[i]); //計算バッファへの格納 ShiftBuf(data[i],&g_Add_Ave);///<計算バッファ更新 for (int i = 0; i < BUF_SIZE; i++) {///バッファに格納されている数値確認 printf("buf:%d\n",g_Add_Ave.buf[i]); } double average = Calc_AddAve(&g_Add_Ave);///平均値の計算 printf("加算平均: %.2f\n", average); } return 0; }



関連記事
過去の記事:
C言語:
・組み込みの為のC言語基礎知識1(printf) - Project_OKI’s diary
・C言語基礎知識2(for分で処理を繰り返す) - Project_OKI’s diary
・C言語基礎知識3(配列) - Project_OKI’s diary
・知らないと損するお金の話(ふるさと納税、確定申告とワンストップ納税どっちが得?) - Project_OKI’s diary
組み込みC言語:
・STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・STM32マイコン_3(UART通信:複数文字送信) - Project_OKI’s diary
・STM32マイコン_4(NVICの設定内容) - Project_OKI’s diary
・STM32マイコン_5(スイッチ入力とLED点灯、消灯) - Project_OKI’s diary