簡単な基礎統計量計算Visual C++プログラム例
平均値や分散などの1変量記述統計量および相関係数などの2変量記述統計量の計算を行う簡単なVisual C++2008プログラム例を用意した。それぞれ圧縮ファイルStatOneVar.ZIPおよびStatTwoVars.ZIPとしてアップロードしたので、ファイル名をクリックしてダウンロードすることができる。ダウンロードしたファイルは、ファイル名をマウスの右ボタンクリックで表示されるメニュから適当な項目(「解凍」とか「展開」)を選ぶと解凍される。解凍して作成されたフォルダのソリューションファイル(*.sln)をVisual StudioあるいはVisual C++から開くとプログラムをビルド・実行することができる。それぞれのプログラムの実行における使用法はここをクリックして表示されるpdfファイルreadme.pdfを参照のこと。
Visual C++の無料版はマイクロソフト社のホームページ
http://www.microsoft.com/japan/msdn/vstudio/express/
からダウンロードできる。使用法については
http://mcn-www.jwu.ac.jp/~yokamoto/openwww/cpp/introvcppg/
を参照のこと。
プログラムは、実行形式(.NET対応)のものStatOneVar.exeおよびStatTwoVars.exeもアップロードした。これらのファイルは、ファイル名をクリックしてダウンロードしたもののダブルクリックなどによって直接実行することができる。
なお、以下にStatOneVarおよびStatTwoVarsにおいて統計量計算を行っている関数のリストを上げておく。これらの関数は「GO」ボタンのクリックで実行されるイベントハンドラである。また、ファイル名の設定に用いているコントロールのプログラミング時におけるコピー・貼り付け方法については、OpenFileDialogコントロールの場合は次のページ
http://mcn-www.jwu.ac.jp/~yokamoto/openwww/cpp/txtfin/
SaveFileDialogコントロールの場合は次のページ
http://mcn-www.jwu.ac.jp/~yokamoto/openwww/cpp/txtfout/
を参照されたい。
StatOneVarにおける統計量計算プログラムコード
private: System::Void
buttonGO_Click(System::Object^
sender, System::EventArgs^
e) {
//
// 入出力ファイルの名の設定
//
openFileDialog1->Title = "入力データファイル名";
if
(openFileDialog1->ShowDialog() ==
System::Windows::Forms::DialogResult::Cancel) return;
saveFileDialog1->Title = "出力ファイル名";
if
(saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::Cancel)
return;
using namespace System::IO;
//
// 入力ストリームと出力ストリームの設定
//
StreamReader ^ fin = gcnew StreamReader( openFileDialog1->FileName,
System::Text::Encoding::GetEncoding("shift-jis")
);
StreamWriter ^ fout = gcnew StreamWriter( saveFileDialog1->FileName, false, System::Text::Encoding::GetEncoding("shift-jis") );
//
// データの先頭行まで読み捨てる
//
while(true){
String ^ s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
//
// データの読み込みと書き出し
//
int n =
0;
double
x[100];
while (true) {
String ^ s = fin->ReadLine();
if (s[0]
== '/') break;
x[n++] = double::Parse(s);
}
fin->Close();
fout->WriteLine("入力データファイル..." +
openFileDialog1->FileName);
for (int i = 0; i < n; i++)
fout->WriteLine("x[" + i.ToString() + "] = " + x[i].ToString());
//
// 統計量の計算
//
double
sum = 0.0, ssum = 0.0;
for (int i = 0; i < n; i++){
sum
+= x[i];
ssum
+= x[i] * x[i];
}
double
mean = sum / n;
double
variance = (ssum - (sum * sum)/n) / n;
double sd
= Math::Sqrt(variance);
double
uvar = variance * n / (n - 1.0);
double
usd = Math::Sqrt(uvar);
fout->WriteLine();
fout->WriteLine("平均値= " + mean.ToString("F3"));
fout->WriteLine("分散 = " + variance.ToString("F3"));
fout->WriteLine("SD = " +
sd.ToString("F3"));
fout->WriteLine("不偏分散= " + uvar.ToString("F3"));
fout->WriteLine("SD(不偏分散) = " + usd.ToString("F3"));
fout->Close();
MessageBox::Show(saveFileDialog1->FileName
+ " を保存しました。");
Close();
}
StatTwoVarsにおける統計量計算プログラムコード
bool checkNum( char c
){
bool ck = false;
if ((c >= '0')
&& (c <= '9')) ck = true;
return ck;
}
//
// pos
番目の文字列の取り出し
//
String
^ SeekStr( String ^ str, int pos ){
String
^ vstr = "";
int i = 0;
while (!checkNum(char(str[i])))
{ i++; };
do {
vstr
+= str[i];
if (!checkNum(char(str[++i])))
break;
}
while (true);
if (pos > 0){
vstr
= "";
while (!checkNum(char(str[i])))
{ i++; };
do {
vstr
+= str[i];
if (i >= str->Length - 1) break;
if (!checkNum(char(str[++i])))
break;
}
while (true);
}
return vstr;
}
private: System::Void
buttonExit_Click(System::Object^
sender, System::EventArgs^
e) {
Close();
}
private: System::Void
buttonGO_Click(System::Object^
sender, System::EventArgs^
e) {
//
// 入出力ファイルの名の設定
//
#define
MyDialgRslt System::Windows::Forms::DialogResult
openFileDialog1->Title = "入力データファイル名";
if
(openFileDialog1->ShowDialog() == MyDialgRslt::Cancel) return;
saveFileDialog1->Title = "出力ファイル名";
if
(saveFileDialog1->ShowDialog() == MyDialgRslt::Cancel) return;
using namespace System::IO;
//
// 入力ストリームと出力ストリームの設定
//
#define
MyEncd System::Text::Encoding
StreamReader ^ fin = gcnew StreamReader( openFileDialog1->FileName,
MyEncd::GetEncoding("shift-jis")
);
StreamWriter ^ fout = gcnew StreamWriter( saveFileDialog1->FileName, false, MyEncd::GetEncoding("shift-jis")
);
//
// データの先頭行まで読み捨てる
//
while(true){
String ^ s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
//
// データの読み込みと書き出し
//
int n =
0;
double
x[100], y[100];
while (true) {
String ^ s = fin->ReadLine();
if (s[0]
== '/') break;
x[n] = double::Parse(SeekStr(s,
0));
y[n++] = double::Parse(SeekStr(s,
1));
}
fin->Close();
fout->WriteLine("入力データファイル..." +
openFileDialog1->FileName);
for (int i = 0; i < n; i++)
fout->WriteLine("x[" + i.ToString() + "] = " + x[i].ToString() +
" y[" + i.ToString() + "] = " + y[i].ToString() );
//
// 統計量の計算
//
double
sumx = 0.0, sumxx = 0.0, sumy = 0.0, sumyy = 0.0, sumxy = 0.0;
for (int i = 0; i < n; i++){
sumx
+= x[i];
sumxx
+= x[i] * x[i];
sumy
+= y[i];
sumyy
+= y[i] * y[i];
sumxy
+= x[i] * y[i];
}
double
meanx = sumx / n;
double
meany = sumy / n;
double
variancex = (sumxx - (sumx * sumx)/n) / n;
double
variancey = (sumyy - (sumy * sumy)/n) / n;
double
sdx = Math::Sqrt(variancex);
double
sdy = Math::Sqrt(variancey);
double
uvarx = variancex * n / (n - 1.0);
double
uvary = variancey * n / (n - 1.0);
double
usdx = Math::Sqrt(uvarx);
double
usdy = Math::Sqrt(uvary);
double
cov = (sumxy - (sumx * sumy)/n) / n;
double r
= cov / (sdx * sdy);
fout->WriteLine();
fout->WriteLine("平均値:X = " + meanx.ToString("F3"));
fout->WriteLine("平均値:Y = " + meany.ToString("F3"));
fout->WriteLine("分散:X = " + variancex.ToString("F3"));
fout->WriteLine("分散:Y = " + variancey.ToString("F3"));
fout->WriteLine("SD:X = " +
sdx.ToString("F3"));
fout->WriteLine("SD;Y = " +
sdy.ToString("F3"));
fout->WriteLine("不偏分散:X = " + uvarx.ToString("F3"));
fout->WriteLine("不偏分散:Y = " + uvary.ToString("F3"));
fout->WriteLine("SD(不偏分散):X = " + usdx.ToString("F3"));
fout->WriteLine("SD(不偏分散)*Y = " + usdy.ToString("F3"));
fout->WriteLine("共分散= " + cov.ToString("F3"));
fout->WriteLine("相関係数= " + r.ToString("F5"));
fout->Close();
MessageBox::Show(saveFileDialog1->FileName
+ " を保存しました。");
Close();
}