動作環境
stdint.hが使えない組込みC
http://qiita.com/7of9/items/c1e67a19efcfa7eed500
でC#実装したExcelのTrend()関数をCで実装した。
# include <stdio.h>
# include <stdbool.h>
# include <math.h>
typedef struct point {
float x, y;
} point_t;
float calcAverageValues(point_t *points, int size, bool isX)
{
double sum = 0.0;
for(int idx=0; idx<size; idx++) {
if (isX) {
sum += points[idx].x;
} else {
sum += points[idx].y;
}
}
return sum / (float)size;
}
float calcSumDiffXDiffY(point_t *points, int size, float xBar, float yBar)
{
double sum = 0.0;
for(int idx=0; idx<size; idx++) {
sum += (points[idx].x - xBar) * (points[idx].y - yBar);
}
return sum;
}
float calcSumDiffXSquared(point_t *points, int size, float xBar)
{
double sum = 0.0;
double xdiff;
for(int idx=0; idx<size; idx++) {
xdiff = (points[idx].x - xBar);
sum += xdiff * xdiff;
}
return sum;
}
float SlopeOfPoints(point_t *points, int size)
{
float xBar = calcAverageValues(points, size, /*isX=*/true);
float yBar = calcAverageValues(points, size, /*isX=*/false);
float dividend = calcSumDiffXDiffY(points, size, xBar, yBar);
float divisor = calcSumDiffXSquared(points, size, xBar);
return dividend / divisor;
}
float YInterceptOfPoints(point_t *points, int size, float slope)
{
float xBar = calcAverageValues(points, size, /*isX=*/true);
float yBar = calcAverageValues(points, size, /*isX=*/false);
return yBar - (slope * xBar);
}
float LeastSquaresValueAtX(point_t *points, int size, float x) {
float slope = SlopeOfPoints(points, size);
float yIntercept = YInterceptOfPoints(points, size, slope);
return (slope * x) + yIntercept;
}
int main(void) {
point_t P[] = {
{ 600, 6 }, // X,Y
{ 800, 7 },
{ 1000, 10 },
{ 1200, 12 },
{ 1400, 14 },
};
int size = sizeof(P) / sizeof(P[0]);
float res = LeastSquaresValueAtX(P, size, 650.0);
printf("%.3f\n", res);
return 0;
}
結果
Success time: 0 memory: 2168 signal:0
6.125
同じ結果が出た。
各所のnamingが良くないが、とりあえずこれで。
エラー処理も入れた方がいいが、とりあえず。
ExcelのTrend()の引数の順番に注意
(追記 2016/09/06)
Excelの結果とC実装を比べていて、引数の順番に関してはまった。
Officeのサイトにおいて
書式
TREND(既知の y, [既知の x], [新しい x], [定数])
とある。
1つ目の引数(既知のy)と2つ目の引数(既知のx)を勘違いして反対に指定して、実際のデータを用いてEXCEL結果とC実装結果を比較する時にはまった。