Up

簡単な基礎統計量計算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();

                         }


 

Up