9回目 課題 解説


#include <stdio.h>

double sum(double ar[], const int n){ //n個の配列の和を計算して返す関数
 double s = 0;
 for(int i = 0; i < n; i++){
  s += ar[i];
 }
 return s;
}

double square_sum(double ar[], const int n){ //n個の配列の二乗の和を計算して返す関数
 double s = 0;
 for(int i = 0; i < n; i++){
  s += ar[i]*ar[i];
 }
 return s;
}

double ip_sum(double ar1[], double ar2[], const int n){ //xとyの積の和(内積)を計算して返す関数
 double s = 0;
 for(int i = 0; i < n; i++){
  s += ar1[i] * ar2[i];
 }
 return s;
}

int main(){
//変数の宣言と初期化
 const int N = 10;
 /* あるばねにおける荷重 x[kg] に対する 変位 y[m] */
 double x[N]={1.1, 2.05, 3.0, 4.1, 5.0, 5.9, 7.1, 7.8, 8.9, 10.0};
 double y[N]={1.0, 2.1 , 2.9, 4.05, 5.01, 5.99, 7.0, 8.1, 8.7, 9.5 };
 double a = 0, b = 0; /* 一次関数の係数 */
 double Sigmax = 0, Sigmay = 0; //x,yの和
 double Ssquarex = 0; //xの二乗の和
 double Inpro = 0; //内積
 double Denom = 0; //分母

 //式(4)に出現する各値の計算
 Sigmax = sum(x, N);
 Sigmay = sum(y, N);
 Ssquarex = square_sum(x, N);
 Inpro = ip_sum(x, y, N);

 Denom = Sigmax*Sigmax - N*Ssquarex; //式(4)でaとbの分母が共通なので先に計算しておく

 //最小二乗法による一次関数の各係数の導出
 a = (Sigmax*Sigmay - N*Inpro)/Denom;
 b = (Inpro*Sigmax - Ssquarex*Sigmay)/Denom;

 //計算結果を画面に表示
 printf("最小二乗法による係数 a, b \n");
 printf("a = %lf, b = %lf \n", a, b);
 return 0;
}