Instantly share code, notes, and snippets.

# komasaru/calc.cpp

Last active July 31, 2020 01:30
Show Gist options
• Save komasaru/03a557aa5ef672a876abe3f496269896 to your computer and use it in GitHub Desktop.
C++ source code to compute multiple regression equations.(3 explanatory variables)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 #include "calc.hpp" #include #include #include #include /** * @brief 重回帰式（説明変数3個）の計算 * * @param[ref] a (double) * @param[ref] b (double) * @param[ref] c (double) * @param[ref] d (double) * @return 真偽(bool) * @retval true 成功 * @retval false 失敗 */ bool Calc::reg_multi_3e(double& a, double& b, double& c, double& d) { unsigned int i; // loop インデックス double s_x1 = 0.0; // sum(x1) double s_x2 = 0.0; // sum(x2) double s_x3 = 0.0; // sum(x3) double s_y = 0.0; // sum(y) double s_x1x1 = 0.0; // sum(x1 * x1) double s_x1x2 = 0.0; // sum(x1 * x2) double s_x1x3 = 0.0; // sum(x1 * x3) double s_x1y = 0.0; // sum(x1 * y) double s_x2x1 = 0.0; // sum(x2 * x1) double s_x2x2 = 0.0; // sum(x2 * x2) double s_x2x3 = 0.0; // sum(x2 * x3) double s_x2y = 0.0; // sum(x2 * y) double s_x3x1 = 0.0; // sum(x3 * x1) double s_x3x2 = 0.0; // sum(x3 * x2) double s_x3x3 = 0.0; // sum(x3 * x3) double s_x3y = 0.0; // sum(x3 * y) double x1 = 0.0; // x1 計算用 double x2 = 0.0; // x2 計算用 double x3 = 0.0; // x3 計算用 double y = 0.0; // y 計算用 try { // データ数 cnt = data.size(); // sum(x1), sum(x2), sum(x3), sum(y), ... for (i = 0; i < cnt; i++) { x1 = data[i][0]; x2 = data[i][1]; x3 = data[i][2]; y = data[i][3]; s_x1 += x1; s_x2 += x2; s_x3 += x3; s_y += y; s_x1x1 += x1 * x1; s_x1x2 += x1 * x2; s_x1x3 += x1 * x3; s_x1y += x1 * y; s_x2x1 += x2 * x1; s_x2x2 += x2 * x2; s_x2x3 += x2 * x3; s_x2y += x2 * y; s_x3x1 += x3 * x1; s_x3x2 += x3 * x2; s_x3x3 += x3 * x3; s_x3y += x3 * y; } // 行列1行目 mtx.push_back({(double)cnt, s_x1, s_x2, s_x3, s_y}); // 行列2行目 mtx.push_back({s_x1, s_x1x1, s_x1x2, s_x1x3, s_x1y}); // 行列3行目 mtx.push_back({s_x2, s_x2x1, s_x2x2, s_x2x3, s_x2y}); // 行列4行目 mtx.push_back({s_x3, s_x3x1, s_x3x2, s_x3x3, s_x3y}); // 計算（ガウスの消去法） if (!solve_ge(mtx)) { std::cout << "[ERROR] Failed to solve by the Gauss-Ellimination method!" << std::endl; return false; } // a, b, c, d a = mtx[0][4]; b = mtx[1][4]; c = mtx[2][4]; d = mtx[3][4]; } catch (...) { return false; // 計算失敗 } return true; // 計算成功 } /** * @brief ガウスの消去法 * * @param[ref] 行列（配列） mtx (double) * @return 真偽(bool) * @retval true 成功 * @retval false 失敗 */ bool Calc::solve_ge(std::vector>& mtx) { int i; // loop インデックス int j; // loop インデックス int k; // loop インデックス int n; // 元（行）の数 double d; // 計算用 try { n = (int)mtx.size(); // 前進消去 for (k = 0; k < n - 1; k++) { for (i = k + 1; i < n; i++) { d = mtx[i][k] / mtx[k][k]; for (j = k + 1; j <= n; j++) mtx[i][j] -= mtx[k][j] * d; } } // 後退代入 for (i = n - 1; i >= 0; i--) { d = mtx[i][n]; for (j = i + 1; j < n; j++) d -= mtx[i][j] * mtx[j][n]; mtx[i][n] = d / mtx[i][i]; } } catch (...) { return false; // 計算失敗 } return true; // 計算成功 }
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 #ifndef REGRESSION_MULTI_3E_CALC_HPP_ #define REGRESSION_MULTI_3E_CALC_HPP_ #include class Calc { std::vector> data; // 元データ std::vector> mtx; // 計算用行列 bool solve_ge(std::vector>&); // ガウスの消去法 public: Calc(std::vector>& data) : data(data) {} unsigned int cnt; // データ件数 bool reg_multi_3e(double&, double&, double&, double&); // 重回帰式（説明変数3個）の計算 }; #endif
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 #include "file.hpp" #include #include #include #include bool File::get_text(std::vector>& data) { try { // ファイル OPEN std::ifstream ifs(f_data); if (!ifs.is_open()) return false; // 読み込み失敗 // ファイル READ std::string buf; // 1行分バッファ while (getline(ifs, buf)) { std::vector rec; // 1行分ベクタ std::istringstream iss(buf); // 文字列ストリーム std::string field; // 1列分文字列 // 1行分文字列を1行分ベクタに追加 double x1, x2, x3, y; while (iss >> x1 >> x2 >> x3 >> y) { rec.push_back(x1); rec.push_back(x2); rec.push_back(x3); rec.push_back(y); } // １行分ベクタを data ベクタに追加 if (rec.size() != 0) data.push_back(rec); } } catch (...) { std::cerr << "EXCEPTION!" << std::endl; return false; } return true; // 読み込み成功 }
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 #ifndef REGRESSION_MULTI_3E_FILE_HPP_ #define REGRESSION_MULTI_3E_FILE_HPP_ #include #include #include class File { std::string f_data; public: File(std::string f_data) : f_data(f_data) {} bool get_text(std::vector>&); }; #endif
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 /*********************************************************** 重回帰式計算（説明（独立）変数3個限定） DATE AUTHOR VERSION 2020.07.10 mk-mode.com 1.00 新規作成 Copyright(C) 2020 mk-mode.com All Rights Reserved. ***********************************************************/ #include "calc.hpp" #include "file.hpp" #include // for EXIT_XXXX #include // for setprecision #include #include #include int main(int argc, char* argv[]) { std::string f_data; // データファイル名 std::vector> data; // データ配列 std::size_t i; // loop インデックス double a; // 定数 a double b; // 係数 b double c; // 係数 c double d; // 係数 d try { // コマンドライン引数のチェック if (argc != 2) { std::cerr << "[ERROR] Number of arguments is wrong!\n" << "[USAGE] ./regression_multi_3e " << std::endl; return EXIT_FAILURE; } // ファイル名取得 f_data = argv[1]; // データ取得 File file(f_data); if (!file.get_text(data)) { std::cout << "[ERROR] Failed to read the file!" << std::endl; return EXIT_FAILURE; } // データ一覧出力 std::cout << std::fixed << std::setprecision(4); std::cout << "説明変数 X1 説明変数 X2 説明変数 X3 目的変数 Y" << std::endl; for (i = 0; i < data.size(); i++) std::cout << std::setw(11) << std::right << data[i][0] << " " << std::setw(11) << std::right << data[i][1] << " " << std::setw(11) << std::right << data[i][2] << " " << std::setw(10) << std::right << data[i][3] << std::endl; // 計算 Calc calc(data); if (!calc.reg_multi_3e(a, b, c, d)) { std::cout << "[ERROR] Failed to calculate!" << std::endl; return EXIT_FAILURE; } // 結果出力 std::cout << std::fixed << std::setprecision(8); std::cout << "---\n" << "a = " << std::setw(16) << std::right << a << "\n" << "b = " << std::setw(16) << std::right << b << "\n" << "c = " << std::setw(16) << std::right << c << "\n" << "d = " << std::setw(16) << std::right << d << std::endl; } catch (...) { std::cerr << "EXCEPTION!" << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }