赞
踩
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <cmath>
-
- class LinearRegression
- {
- private:
- int k;
- double* data_a;
- double* data_b;
-
- double x_average;
- bool x_average_mark;
- double y_average;
- bool y_average_mark;
- double xy_average;
- bool xy_average_mark;
- double xx_average;
- bool xx_average_mark;
- double yy_average;
- bool yy_average_mark;
-
- double a;
- bool a_mark;
-
- double b;
- bool b_mark;
-
- double r;
- bool r_mark;
-
- double u_a;
- bool u_a_mark;
- double u_b;
- bool u_b_mark;
- double u_c;
- bool u_c_mark;
- double u_d;
- bool u_d_mark;
-
- void cal_x_average();
- void cal_y_average();
- void cal_xy_average();
- void cal_xx_average();
- void cal_yy_average();
- void pri_cal_u_a();
- void pri_cal_u_b();
- void pri_cal_u_c();
- void pri_cal_u_d();
-
- public:
- LinearRegression(int p_k);
- ~LinearRegression();
- bool accuire_data(std::string& file_name);
- void reverse_data(std::string choice="a");
- double cal_a();
- double cal_b();
- double cal_r();
- double cal_u_a();
- double cal_u_b();
- double cal_u_c();
- double cal_u_d();
- };
-
- int main(int argc,char** argv)
- {
- //本程序有两个参数,第一个参数为k,第二个参数为数据文件(txt格式)
- if (argc!=3)
- return 1;
- std::string length_string=(std::string)argv[1];
- std::string name_string=(std::string)argv[2];
-
- //创建一个自定义的LinearRegression类的对象实例example
- LinearRegression example(std::stoi(length_string));
-
- //获取数据,调用accuire_data方法
- example.accuire_data(name_string);
-
- //将因变量组的所有元素取倒数
- //这个函数用于自变量或因变量组的所有元素取倒数
- //参数为"a",则对自变量组取倒数;参数为"b",则对因变量组取倒数。
- //如果不需要取倒数,直接注释这一行即可。
- //example.reverse_data("b");
-
- //调用cal_a方法计算a
- std::cout<<"a:"<<example.cal_a()<<std::endl;
- //调用cal_b方法计算b
- std::cout<<"b:"<<example.cal_b()<<std::endl;
- //调用cal_r方法计算r
- std::cout<<"r:"<<example.cal_r()<<std::endl;
- //调用cal_u_a方法计算a的A类不确定度
- std::cout<<"u_a(a):"<<example.cal_u_a()<<std::endl;
- //调用cal_u_b方法计算b的A类不确定度
- std::cout<<"u_a(b):"<<example.cal_u_b()<<std::endl;
- //调用cal_u_c方法计算a的B类不确定度
- std::cout<<"u_b(a):"<<example.cal_u_c()<<std::endl;
- //调用cal_u_d方法计算b的B类不确定度
- std::cout<<"u_b(b):"<<example.cal_u_d()<<std::endl;
-
- //以上7个方法均可以单独使用。
- //我已经把可能存在的问题解决了!
- }
-
- LinearRegression::LinearRegression(int p_k)
- {
- k=p_k;
- data_a=new double [k];
- data_b=new double [k];
- x_average_mark=false;
- y_average_mark=false;
- xy_average_mark=false;
- xx_average_mark=false;
- yy_average_mark=false;
- a_mark=false;
- b_mark=false;
- r_mark=false;
- u_a_mark=false;
- u_b_mark=false;
- u_c_mark=false;
- u_d_mark=false;
- }
-
- LinearRegression::~LinearRegression()
- {
- delete [] data_a;
- delete [] data_b;
- }
-
- bool LinearRegression::accuire_data(std::string& file_name)
- {
- using namespace std;
- ifstream file(file_name);
- string double_string;
- char ch;
- int j;
-
- if (file.is_open())
- {
- for (int i=0;i<k;i++)
- {
- j=0;
- double_string="";
- while(1)
- {
- ch=file.get();
- if (ch>='0'&&ch<='9'||ch=='.')
- double_string[j++]=ch;
- else
- break;
- }
- data_a[i]=std::stod(double_string);
- }
-
- for (int i=0;i<k;i++)
- {
- j=0;
- double_string="";
- while(1)
- {
- ch=file.get();
- if (ch>='0'&&ch<='9'||ch=='.')
- double_string[j++]=ch;
- else
- break;
- }
- data_b[i]=std::stod(double_string);
- }
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
- void LinearRegression::reverse_data(std::string choice)
- {
- if (choice=="a")
- for (int i=0;i<k;i++)
- data_a[i]=1/data_a[i];
- else if (choice=="b")
- for (int i=0;i<k;i++)
- data_b[i]=1/data_b[i];
- }
-
- void LinearRegression::cal_x_average()
- {
- if (x_average_mark==false)
- {
- double sum=0;
- for (int i=0;i<k;i++)
- sum+=data_a[i];
- x_average=sum/k;
- x_average_mark=true;
- }
- }
-
- void LinearRegression::cal_y_average()
- {
- if (y_average_mark==false)
- {
- double sum=0;
- for (int i=0;i<k;i++)
- sum+=data_b[i];
- y_average=sum/k;
- y_average_mark=true;
- }
- }
-
- void LinearRegression::cal_xy_average()
- {
- if (xy_average_mark==false)
- {
- double sum=0;
- for (int i=0;i<k;i++)
- sum+=data_a[i]*data_b[i];
- xy_average=sum/k;
- xy_average_mark=true;
- }
- }
-
- void LinearRegression::cal_xx_average()
- {
- if (xx_average_mark==false)
- {
- double sum=0;
- for (int i=0;i<k;i++)
- sum+=data_a[i]*data_a[i];
- xx_average=sum/k;
- xx_average_mark=true;
- }
- }
-
- void LinearRegression::cal_yy_average()
- {
- if (yy_average_mark==false)
- {
- double sum=0;
- for (int i=0;i<k;i++)
- sum+=data_b[i]*data_b[i];
- yy_average=sum/k;
- yy_average_mark=true;
- }
- }
-
- double LinearRegression::cal_a()
- {
-
- if (a_mark==false)
- {
- this->cal_y_average();
- this->cal_x_average();
- this->cal_b();
-
- a=y_average-b*x_average;
- a_mark=true;
- }
-
- return a;
- }
-
- double LinearRegression::cal_b()
- {
-
- if (b_mark==false)
- {
- this->cal_x_average();
- this->cal_y_average();
- this->cal_xy_average();
- this->cal_xx_average();
-
- b=(x_average*y_average-xy_average)/(x_average*x_average-xx_average);
- b_mark=true;
- }
-
- return b;
- }
-
- double LinearRegression::cal_r()
- {
- if (r_mark==false)
- {
- this->cal_x_average();
- this->cal_y_average();
- this->cal_xy_average();
- this->cal_xx_average();
- this->cal_yy_average();
-
- r=(xy_average-x_average*y_average)/sqrt((xx_average-x_average*x_average)*(yy_average-y_average*y_average));
- r_mark=true;
- }
-
- return r;
- }
-
-
- void LinearRegression::pri_cal_u_b()
- {
- if (u_b_mark==false)
- {
- u_b=b*sqrt((1/(r*r)-1)/(k-2));
- u_b_mark=true;
- }
- }
-
- void LinearRegression::pri_cal_u_a()
- {
- this->pri_cal_u_b();
-
- if (u_a_mark==false)
- {
- u_a=sqrt(xx_average)*u_b;
- u_a_mark=true;
- }
- }
-
- void LinearRegression::pri_cal_u_c()
- {
- this->pri_cal_u_d();
-
- if (u_c_mark==false)
- {
- u_c=sqrt(xx_average)*u_d;
- u_c_mark=true;
- }
- }
-
- void LinearRegression::pri_cal_u_d()
- {
- if (u_d_mark==false)
- {
- double u_b_y;
- std::cout<<"Please input the type B evaluation of uncertainty of dependent variable --- y:"<<std::endl;
- std::cout<<"(Attention! Do not forget the confidence coefficient)"<<std::endl;
- std::cin>>u_b_y;
- u_d=u_b_y*sqrt(1/(k*(xx_average-x_average*x_average)));
- u_d_mark=true;
- }
- }
-
- double LinearRegression::cal_u_a()
- {
- this->pri_cal_u_a();
- return u_a;
- }
-
- double LinearRegression::cal_u_b()
- {
- this->pri_cal_u_b();
- return u_b;
- }
-
- double LinearRegression::cal_u_c()
- {
- this->pri_cal_u_c();
- return u_c;
- }
-
- double LinearRegression::cal_u_d()
- {
- this->pri_cal_u_d();
- return u_d;
- }
复制上面这个代码段到新的cpp文件后编译。
由于调用了string库中的std::stod()函数,所以需要以C++11标准对此cpp文件进行编译。
具体方法可以参考:
DEV c++中添加c++11编译环境_devcpp支持c11_中国“名猿”的博客-CSDN博客
该程序运行依赖数据文件(txt格式), 把数据文件和cpp原文件放在一个文件夹里!
并且,数据文件需要按如下方式处理:
假设数据量为k,则需要输入2k组double型数据。数据与数据之间用任意单个空格符/换行符分割!
本程序有两个参数,第一个参数为k,第二个参数为数据文件(txt格式)。运行参数可以如下输入:
5 test.txt
其中前者为数据量,后者为数据文件名称。
具体如何添加运行参数,可以参考下面这一篇文章:
关于devc++中程序运行参数的输入问题_如何用dev运行命令行参数_yupl的博客-CSDN博客
又或者,你可以直接用控制台!
一共包含了9个公有类方法。其中第一个方法必须是accuire_data,用于获取数据;第二个方法可以选择按照自身需求对数据取倒数(也可以不执行!看你的需要!)
其他7个方法可以按照任意顺序调用。
所有的函数和变量都被封装在了LinearRegression类中。欢迎各位大神继承这个类编写更多功能,也欢迎直接大刀阔斧地改写这个类!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。