分散分析ライブラリ



[ 簡単な説明 ]

分散分析とは、データのバラツキの原因を解析する手法です。

データのバラツキが正規分布をとるという仮定のもと、バラツキの原因と推定される因子が1つの場合、2つの場合、3つの場合、...でそれぞれ分析法として1元配置、2元配置、3元配置、...という方法を使用します。

本ライブラリでは、1元配置と繰返しのない2元配置(2因子が独立している場合)を準備しています。
(ちなみに繰返しのある2元配置は、2因子相互間の相乗作用あるいは相殺作用がある場合の分析法です。)

1元配置は、バラツキの因子が1種類(例えば、作業者)の場合に適用します。計算法の詳細は省略しますが、計算結果で得た統計量 Fo が危険率に対するF分布のパーセント点 f より大きければ、因子の中に有意差があると判断されます。(例えば、品質が作業者により異なる等)

2元配置も同様に、2種類の因子(例えば、作業者と工作機械)に関して得られた統計量 Fo と危険率に対するF分布のパーセント点 f より、各因子の中に有意差があるかどうかを判定します。

関数名 関数の機能 引数説明 呼び出し例
aov1( ) 1元配置
  • x[ ] : データ
  • m : 因子数
  • l : データ配列第2添字の値
  • n[ ] : 各因子のデータ数
  • al : 危険率
  • sa : 因子の変動
  • se : 誤差変動
  • st : 全変動
  • nua : sa の自由度
  • nue : se の自由度
  • nut : st の自由度
  • va : 因子の不偏分散
  • ve : 誤差の不偏分散
  • f0 : 統計量 Fo (= va/ve)
  • f : 危険率に対する
       F分布のパーセント点
int aov1(x, n, l, m, al,
&sa, &se, &st, &nuamp;a, &nue, &nut,
&va, &ve, &f0, &f);
aov2( ) 2元配置
  • x[ ] : データ
  • m, n : 因子数
  • l : データ配列第2添字の値
  • al : 危険率
  • sa, sb : 因子の変動
  • se : 誤差変動
  • st : 全変動
  • nua, nub : sa の自由度
  • nue : se の自由度
  • nut : st の自由度
  • va, vb : 因子の不偏分散
  • ve : 誤差の不偏分散
  • f0a, f0b : 統計量 Fo (= va/ve, vb/ve)
  • fa, fb : 危険率に対する
         F分布のパーセント点
int aov2(x, l, m, n, al,
&sa, &sb, &se, &st,
&nua, &nub, &nue, &nut,
&va, &vb, &ve,
&f0a, &f0b, &fa, &fb);

   注:データは、m × l のサイズの1次元配列で与えます。

プログラム・ソース("vari.c")           top (トップに戻る)
/*		vari.c				*/
#include <stdio.h>
#include <stdlib.h>
#include "sslib.h"

/* analysis of variance (one-way) */

int aov1(double x[], int n[], int l, int m, double al, double *sa, double *se,
	double *st, int *nua, int *nue, int *nut, double *va, double *ve,
	double *f0, double *f)
{
	int i, j, k, t, it, in;
	double xt, xi, xtb, w;
	double *row;

	if(l < 1 || m < 1 || al <= 0.0 || al >= 1.0)	return 999;
	row = (double *)malloc(m * sizeof(double));
	if(row == NULL)
	{
		fprintf(stderr, "Error : Out of memory in aov1()\n");
		return -1;
	}
	it = 0;
	xt = 0.0;
	for(i = 0; i < m; i++)
	{
		k = i * l;
		xi = 0.0;
		in = n[i];
		if(in < 1 || in > l)	return 999;
		it += in;
		for(j = 0; j < in; j++)	xi += x[k + j];
		row[i] = xi / in;
		xt += row[i];
	}
	xtb = xt / m;
	*se = *st = 0.0;
	for(i = 0; i < m; i++)
	{
		k = i * l;
		in = n[i];
		for(j = 0; j < in; j++)
		{
			t = k + j;
			w = x[t] - row[i];
			*se += (w * w);
			w = x[t] - xtb;
			*st += (w * w);
		}
	}
	*sa = *st - *se;
	*nua = m - 1;
	*nut = it - 1;
	*nue = *nut - *nua;
	*va = *sa / *nua;
	*ve = *se / *nue;
	*f0 = *va / *ve;

	*f = pf(al, *nua, *nue);
	free(row);
	return 0;
}

/* analysis of variance (two-way) */

int aov2(double x[], int l, int m, int n, double al, double *sa, double *sb,
	double *se, double *st, int *nua, int *nub, int *nue, int *nut, double *va,
	double *vb, double *ve, double *f0a, double *f0b, double *fa, double *fb)
{
	int i, j, k;
	double xt, xa, xb, xtb, w;
	double *xat, *xbt, *xab, *xbb;

	if(l < 1 || m < 1 || n < 1 || al <= 0.0 || al >= 1.0)	return 999;
	xat = (double *)malloc(m * sizeof(double));
	if(xat == NULL)
	{
		fprintf(stderr, "Error : Out of memory in aov2()\n");
		return -1;
	}
	xbt = (double *)malloc(n * sizeof(double));
	if(xbt == NULL)
	{
		fprintf(stderr, "Error : Out of memory in aov2()\n");
		free(xat);
		return -1;
	}
	xab = (double *)malloc(m * sizeof(double));
	if(xab == NULL)
	{
		fprintf(stderr, "Error : Out of memory in aov2()\n");
		free(xbt);
		free(xat);
		return -1;
	}
	xbb = (double *)malloc(n * sizeof(double));
	if(xbb == NULL)
	{
		fprintf(stderr, "Error : Out of memory in aov2()\n");
		free(xab);
		free(xbt);
		free(xat);
		return -1;
	}
	xt = 0.0;
	for(i = 0; i < m; i++)
	{
		k = i * l;
		xa = 0.0;
		for(j = 0; j < n; j++)	xa += x[k + j];
		xt += xa;
		xat[i] = xa;
	}
	for(i = 0; i < n; i++)
	{
		xb = 0.0;
		for(j = 0; j < m; j++)	xb += x[i + j * l];
		xbt[i] = xb;
	}
	for(i = 0; i < m; i++)	xab[i] = xat[i] / (double)n;
	for(i = 0; i < n; i++)	xbb[i] = xbt[i] / (double)m;
	xtb = xt / (double)m / (double)n;
	*sa = 0.0;
	for(i = 0; i < m; i++)
	{
		w = xab[i] - xtb;
		*sa += (w * w);
	}
	*sa *= (double)n;
	*sb = 0.0;
	for(i = 0; i < n; i++)
	{
		w = xbb[i] - xtb;
		*sb += (w * w);
	}
	*sb *= (double)m;
	*st = 0.0;
	for(i = 0; i < m; i++)
	{
		k = i * l;
		for(j = 0; j < n; j++)
		{
			w = x[k + j] - xtb;
			*st += (w * w);
		}
	}
	*se = *st - *sa - *sb;
	*nua = m - 1;
	*nub = n - 1;
	*nue = *nua * *nub;
	*nut = *nua + *nub + *nue;
	*va = *sa / *nua;
	*vb = *sb / *nub;
	*ve = *se / *nue;
	*f0a = *va / *ve;
	*f0b = *vb / *ve;

	*fa = pf(al, *nua, *nue);
	*fb = pf(al, *nub, *nue);

	free(xbb);
	free(xab);
	free(xbt);
	free(xat);
	return 0;
}