M5NanoC6、最小二乗法で遊ぶ(論理編)(アナログジョイスティックの予測地点を求める?)



参考

最小ニ乗法とは　簡単説明


![o_coq807.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cf0da833-37c0-74c7-7bf7-bbaf404798af.jpeg)


https://qiqumo.jp/contents/dictionary/3718/


線形単回帰

![o_coq808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8332f1fd-8a60-fb8c-3c5e-5bc3ad05ab51.jpeg)



https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%9B%9E%E5%B8%B0


x M5NanoC6での予定は、未定
x 原理モデルだから最適化は、していない。(ネットに落ちているのは、最適化されている(難読でわからない))(計算が省略されている(計算ずみ))
x 思い出しつつやつた
x 平均を出す為にnで割ってあるが、双方を割るのでnは、外せる(なんのこと)

目的
アナログジョイスティックの場合、サンプリング数と送信数の
差が生まれるので統計上の予測地点を軽く求める。異議、申立は、認める。
最大約80khzでサンプリングして約0.3秒毎に送る。
アナログジョイスティックの予想値を求める。
一般的には、予測地点とか予想値とか言う?
アニメとかで予測地点は、どこだーとか大佐が言っている。
経済学では、予想値と言っている？
(考えすぎで平均でもいいのかも、ただし、移動がある場合は、値が半分になる)

図

![o_coq806.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7fcde0b1-557d-6d4e-3b09-1a24d750651b.jpeg)



プログラム
----

オンラインコンパイラ paiza


```c++

#include <stdio.h>
int main(void){
    // Your code here!

    //xの個数
    #define x_num 6
    //yの個数
    #define y_num 6

    
    float x_ave; //xの平均
    float x_sum; //xの合計
    float y_ave; //yの平均
    float y_sum; //yの合計
    float x_de2; //x分散
    float xydev; //x,yの共分散


    //                 0   1   2   3   4   5
    float x_item[6]={ 10, 20, 30, 40, 50, 60}; //xの配列
    float y_item[6]={ 40, 60, 60,100,130,120}; //yの配列

    float x_dev_item[6]; //x偏差の配列
    float y_dev_item[6]; //y偏差の配列

    float x_de2_item[6]; //x偏差のべき乗の配列

    float xydev_item[6]; //x偏差×y偏差の配列

    //xの平均を求める
    x_sum = 0.0f;
    for(int i = 0;i < x_num;i++){
        x_sum = x_sum + x_item[i];
    }
    x_ave = x_sum / (float)x_num;
    
    printf("x_ave = %.2f\n",x_ave);

    //yの平均を求める
    y_sum = 0.0f;
    for(int i = 0;i < y_num;i++){
        y_sum = y_sum + y_item[i];
    }
    y_ave = y_sum / (float)y_num;

    printf("y_ave = %.2f\n",y_ave);
    printf("\n");

    //x偏差を求める
    for(int i = 0;i < x_num;i++){
        x_dev_item[i] =  x_item[i] - x_ave;
        printf("x_dev_item[ = %.2f\n",x_dev_item[i]);
    }
    printf("\n");
    
    //y偏差を求める
    for(int i = 0;i < x_num;i++){
        y_dev_item[i] =  y_item[i] - y_ave;
        printf("y_dev_item[ = %.2f\n",y_dev_item[i]);
    }
    printf("\n");

    //x偏差の二乗を求める
    for(int i = 0;i < x_num;i++){
        x_de2_item[i] =  x_dev_item[i] * x_dev_item[i];
        printf("x_de2_item[ = %.2f\n",x_de2_item[i]);
    }
    printf("\n");

    //x分散を求める
    x_de2 = 0.0f;
    for(int i = 0;i < y_num;i++){
        x_de2 = x_de2 + x_de2_item[i];
    }
    x_de2 = x_de2 / (float)y_num;
    printf("x_de2 = %.2f\n",x_de2);
    printf("\n");
    
    //x偏差×y偏差を求める
    for(int i = 0;i < x_num;i++){
        xydev_item[i] =  x_dev_item[i] * y_dev_item[i];
        printf("xydev_item[ = %.2f\n",xydev_item[i]);
    }
    printf("\n");
    
    //x,yの共分散を求める
    xydev = 0.0f;
    for(int i = 0;i < y_num;i++){
        xydev = xydev + xydev_item[i];
    }
    xydev = xydev / (float)y_num;
    printf("xydev = %.2f\n",xydev);
    printf("\n");

    printf("a = %.3f\n",xydev / x_de2);
    printf("b = %.3f\n",y_ave  - (xydev / x_de2) * x_ave);
    
}


```


```

x_ave = 35.00
y_ave = 85.00

x_dev_item[ = -25.00
x_dev_item[ = -15.00
x_dev_item[ = -5.00
x_dev_item[ = 5.00
x_dev_item[ = 15.00
x_dev_item[ = 25.00

y_dev_item[ = -45.00
y_dev_item[ = -25.00
y_dev_item[ = -25.00
y_dev_item[ = 15.00
y_dev_item[ = 45.00
y_dev_item[ = 35.00

x_de2_item[ = 625.00
x_de2_item[ = 225.00
x_de2_item[ = 25.00
x_de2_item[ = 25.00
x_de2_item[ = 225.00
x_de2_item[ = 625.00

x_de2 = 291.67

xydev_item[ = 1125.00
xydev_item[ = 375.00
xydev_item[ = 125.00
xydev_item[ = 75.00
xydev_item[ = 675.00
xydev_item[ = 875.00

xydev = 541.67

a = 1.857
b = 20.000

```