FUNC.H
上传用户:zengbais
上传日期:2022-08-08
资源大小:49k
文件大小:12k
开发平台:

C++ Builder

  1. #ifndef FUNC_H
  2. #define FUNC_H
  3. #include <math.h>
  4. #include "matrix.h"
  5. #ifndef DOUBLE
  6. #define DOUBLE double
  7. #endif
  8. class cmatrix;
  9. DOUBLE gamma(DOUBLE x); // 计算伽马函数
  10. DOUBLE gamma2(DOUBLE a, DOUBLE x); // 计算不完全伽马函数
  11. DOUBLE erf(DOUBLE x); // 计算误差函数
  12. DOUBLE beta(DOUBLE a,DOUBLE b,DOUBLE x); // 计算不完全贝塔函数
  13. DOUBLE gass(DOUBLE a,DOUBLE d,DOUBLE x); // 给定均值a,标准差d的正态分布函数
  14. DOUBLE student(DOUBLE t, size_t n); // t-分布函数
  15. DOUBLE chii(DOUBLE x,size_t n); // X-方分布函数
  16. DOUBLE fdisp(DOUBLE f,size_t n1,size_t n2); // F-分布函数
  17. DOUBLE integral(DOUBLE (*f)(DOUBLE),DOUBLE a, DOUBLE b, DOUBLE eps=defaulterr);
  18.  // 函数f,在(a,b)区间积分,采用勒让德高斯求积法
  19. DOUBLE sinn(DOUBLE x); // 正弦积分函数
  20. DOUBLE coss(DOUBLE x); // 余弦积分函数
  21. DOUBLE expp(DOUBLE x); // 指数积分函数
  22. DOUBLE getroot(DOUBLE (*f)(DOUBLE), DOUBLE x0=0.9, DOUBLE eps=defaulterr);
  23.  // 求函数f(x)=0在x0附近的根,返回此根,如找不到根,则丢出例外
  24. class algo;
  25. DOUBLE getroot(algo & alg, DOUBLE x0=0.9, DOUBLE eps=defaulterr);
  26.  // 同上,但函数为algo类变量
  27. class algo // 算法类
  28. {
  29.  public:
  30. DOUBLE yfactor; // 乘因子,初始化为1
  31. DOUBLE xfactor; // x轴放大因子,初始化为1
  32. DOUBLE addconst; // 加和,初始化为0
  33. DOUBLE xshift; // x平移量,初始化为0
  34. unsigned refnum; // 引用数,初始化为1
  35. algo():refnum(1),yfactor(1.0),xfactor(1.0),addconst(0.0),xshift(0.0){};
  36.  // 构造函数,产生y=x线性函数
  37. algo(DOUBLE xs, DOUBLE xf,DOUBLE adc=0, DOUBLE yf=1):refnum(1),yfactor(yf),
  38. addconst(adc),xshift(xs),xfactor(xf){};
  39. algo(DOUBLE a):refnum(1),yfactor(0.0),xfactor(1.0),addconst(a),xshift(0.0){};
  40.  // 常函数的构造
  41. algo(algo & alg):yfactor(alg.yfactor),xfactor(alg.xfactor),
  42. addconst(alg.addconst),xshift(alg.xshift),refnum(1){}; // 拷贝构造函数
  43. virtual ~algo(){}; // 虚析构函数
  44. DOUBLE cal(DOUBLE x); // 计算算法值
  45. virtual DOUBLE calculate(DOUBLE x)
  46. {return x;}; // 本身算法,将被继承子类改写
  47. virtual algo * clone(); // 克隆自己,必须被继承子类改写
  48. algo * mul(DOUBLE a); // 乘a
  49. algo * add(DOUBLE a); // 加a
  50. algo * neg(); // 取负
  51. algo * setxfactor(DOUBLE x); // 设置x轴因子
  52. algo * xroom(DOUBLE x); // 将xfactor扩大x倍
  53. algo * setxshift(DOUBLE x); // 设置xshift的值
  54. algo * xshiftas(DOUBLE x); // 从当前开始平移x
  55. DOUBLE integ(DOUBLE a, DOUBLE b, DOUBLE eps = defaulterr); // 在(a,b)区间积分
  56. // 采用勒让德高斯求积法
  57. };
  58. enum method {cadd,csub,cmul,cdiv,cpow,ccom}; // 枚举加减乘除乘方复合这四种运算
  59. class algojoin : public algo // 结合算法
  60. {
  61.  public:
  62. algo * leftalgo; // 左算法,初始化为0
  63. algo * rightalgo; // 右算法,初始化为0
  64. method met; // 指明算法
  65. algojoin(algo * l, algo * r, method m):leftalgo(l),
  66. rightalgo(r), met(m)
  67. { if(leftalgo)
  68. leftalgo->refnum++;
  69.   if(rightalgo)
  70. rightalgo->refnum++;
  71. };
  72. algojoin(algojoin& alg):algo(alg),
  73. leftalgo(alg.leftalgo),rightalgo(alg.rightalgo),met(alg.met){
  74. if(leftalgo)
  75. leftalgo->refnum++;
  76. if(rightalgo)
  77. rightalgo->refnum++;};
  78. // 拷贝构造函数
  79. virtual ~algojoin() {
  80. if(leftalgo) { // 如左或者右算法已经没有被引用,则删除
  81. leftalgo->refnum--;
  82. if(!leftalgo->refnum) delete leftalgo;
  83. }
  84. if(rightalgo) {
  85. rightalgo->refnum--;
  86. if(!rightalgo->refnum) delete rightalgo;
  87. }
  88. };
  89. virtual algo * clone(); // 克隆自己
  90. virtual DOUBLE calculate(DOUBLE x); // 实施结合算法
  91. };
  92. class algofun : public algo // 函数算法
  93. {
  94.  public:
  95. DOUBLE (*f)(DOUBLE); // 函数指针
  96. algofun(DOUBLE (*fun)(DOUBLE)):f(fun){}; // 用函数指针进行初始化
  97. algofun(algofun& alg):algo(alg),f(alg.f){}; // 拷贝构造函数
  98. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  99. virtual algo * clone(); // 克隆自己
  100. };
  101. class algogass : public algo // 正态分布函数
  102. {
  103.  public:
  104. algogass(DOUBLE a, DOUBLE d):algo(a,1.0/d){}; // 用均值a和标准差d进行初始化
  105. algogass(algogass& alg):algo(alg){}; // 拷贝构造函数
  106. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  107. virtual algo * clone(); // 克隆自己
  108. };
  109. class algoinverse : public algo // 根据一个算法求反函数的算法
  110. // 通过不断求f(x)-y=0在给定的各个y值下的根来进行
  111. {
  112.  public:
  113. algo * al;
  114. algoinverse(algo * a):al(a){if(al) al->refnum++;}; // a 是要求反函数的算法
  115. algoinverse(algoinverse& alg):algo(alg),al(alg.al){
  116.     al->refnum++; }; // 拷贝构造函数
  117. ~algoinverse() {
  118. if(al) {
  119. al->refnum--;
  120. if(!al->refnum)
  121. delete al;
  122. }
  123. }; // 析构函数
  124. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  125. virtual algo * clone(); // 克隆自己
  126. };
  127. class algoregress : public algo // 线性回归算法产生线性函数
  128. {
  129.  public:
  130. algoregress(matrix & xy, matrix* dt=0); // xy为n行2列的矩阵为n个样本点
  131. // dt必须指向一个6列一行的矩阵向量,六个数依次为偏差平方和,平均标准
  132. // 偏差,回归平方和,最大偏差,最小偏差,偏差平均值
  133. };
  134. class algopoly : public algo // 多项式
  135. {
  136.  public:
  137. matrix data; // n乘1矩阵,存放n-1次多项式的系数a(0)到a(n-1)
  138. algopoly(){}; // 缺省构造函数,给子类作调用
  139. algopoly(matrix& d):data(d){}; // 用矩阵构造多项式
  140. algopoly(algopoly& alg):algo(alg),data(alg.data){}; // 拷贝构造函数
  141. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  142. virtual algo * clone(); // 克隆自己
  143. cmatrix getroots(); // 求出此多项式的所有根
  144. };
  145. class algopair : public algopoly // 最小二乘拟合类
  146. {
  147.  public:
  148. algopair(matrix& xy, size_t m, DOUBLE & t0,DOUBLE &t1,DOUBLE &t2);
  149. // m为拟合多项式的项数,dt0为误差平方和,dt1为误差绝对值和,
  150. // dt2为最大误差绝对值
  151. algopair(algopair& alg):algopoly(alg){}; // 拷贝构造函数
  152. };
  153. class algoenter2 : public algo // 一元全区间不等距插值
  154. {
  155.  public:
  156. matrix data; // n乘2矩阵,n个坐标,先x后y,x必须从小到大
  157. algoenter2(matrix& d):data(d){}; // 用矩阵构造多项式
  158. algoenter2(algoenter2& alg):algo(alg),data(alg.data){}; // 拷贝构造函数
  159. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  160. virtual algo * clone(); // 克隆自己
  161. };
  162. class algoenter : public algo // 一元全区间等距插值
  163. {
  164.  public:
  165. DOUBLE x0; // 起始点
  166. DOUBLE h; // 步长
  167. matrix data; // n乘1矩阵,n个函数值
  168. algoenter(matrix& d,DOUBLE xx0, DOUBLE hh):
  169. data(d),x0(xx0),h(hh){};
  170. algoenter(algoenter& alg):algo(alg),data(alg.data),
  171. x0(alg.x0),h(alg.h){}; // 拷贝构造函数
  172. virtual DOUBLE calculate(DOUBLE x); // 实施函数算法
  173. virtual algo * clone(); // 克隆自己
  174. };
  175. enum funckind {polyfunc, enter2func, gammafunc}; // 函数种类
  176. class func { // 函数类
  177.  public:
  178. algo * alg; // 决定函数的算法
  179. func(); // 缺省构造函数
  180. func(DOUBLE a); // 常函数的构造函数
  181. func(DOUBLE (*fun)(DOUBLE)); // 函数指针的构造函数
  182. func(func & fn); // 拷贝构造函数
  183. func(algo * a); // 算法构造函数
  184.    func(algo& a); // 算法构造函数
  185. func(DOUBLE a, DOUBLE d); // 产生正态分布函数a为均值,d为标准差
  186. func(matrix& m, funckind kind=polyfunc); // 构造数值相关函数,
  187. // 如kind = polyfunc, 则m为nX1矩阵,是n-1阶多项式系数,
  188. // 其中m(0,0)为常数项,m(n-1,0)为n-1次项。
  189. // 如kind = enter2func, 则m为nX2矩阵,代表n个坐标点
  190. // 其中第1列是由小到大排过序的各点的x坐标
  191. func(matrix& m, DOUBLE x0, DOUBLE h); // 构造等距插值函数
  192. // 其中m是nX1阶矩阵,代表n个y值,x0是起始点,h是步长(采样间隔)
  193. virtual ~func() { // 析构函数
  194. if(alg) {
  195. alg->refnum--; // 引用数减一,如再无其它引用,则删除算法
  196. if(!alg->refnum)
  197. delete alg;
  198. }
  199. };
  200. DOUBLE operator()(DOUBLE x){return alg->cal(x);}; // 计算x的函数值
  201. func& operator=(func& fn); // 赋值运算符
  202. func& operator=(DOUBLE (*fn)(DOUBLE)); // 用函数指针的赋值运算符
  203. func& operator=(DOUBLE a); // 常函数的赋值运算符
  204. func& operator+=(func& fn); // 自身加一个函数
  205. func& operator+=(DOUBLE a){alg=alg->add(a);return (*this);};//自身加一个常数
  206. func& operator+=(DOUBLE (*f)(DOUBLE)); // 自身加一个函数指针
  207. func operator+(func& fn); // 相加产生新函数
  208. func operator+(DOUBLE a); // 与常数相加产生新函数
  209. friend func operator+(DOUBLE a, func& f); // 同上但常数在前
  210. func operator+(DOUBLE (*f)(DOUBLE)); // 加一个函数指针产生新函数
  211. friend func operator+(DOUBLE (*f)(DOUBLE),func& fn); // 同上但函数指针在前
  212. func& neg(); // 自身取负
  213. func operator-(); // 产生负函数
  214. func& operator-=(func& fn); // 自身减一个函数
  215. func& operator-=(DOUBLE a){alg=alg->add(-a);return (*this);};//自身减一个常数
  216. func& operator-=(DOUBLE (*f)(DOUBLE)); // 自身减一个函数指针
  217. func operator-(func& fn); // 相减产生新函数
  218. func operator-(DOUBLE a); // 与常数相减产生新函数
  219. friend func operator-(DOUBLE a, func& f); // 同上但常数在前
  220. func operator-(DOUBLE (*f)(DOUBLE)); // 减一个函数指针产生新函数
  221. friend func operator-(DOUBLE (*f)(DOUBLE),func& fn); // 函数指针减函数
  222. func& operator*=(func& fn); // 自身乘一个函数
  223. func& operator*=(DOUBLE a){alg=alg->mul(a);return (*this);};//自身乘一个常数
  224. func& operator*=(DOUBLE (*f)(DOUBLE)); // 自身乘一个函数指针
  225. func operator*(func& fn); // 相乘产生新函数
  226. func operator*(DOUBLE a); // 与常数相乘产生新函数
  227. friend func operator*(DOUBLE a, func& f); // 同上但常数在前
  228. func operator*(DOUBLE (*f)(DOUBLE)); // 乘一个函数指针产生新函数
  229. friend func operator*(DOUBLE (*f)(DOUBLE),func& fn); // 函数指针乘函数
  230. func& operator/=(func& fn); // 自身除以一个函数
  231. func& operator/=(DOUBLE a){alg=alg->mul(1.0/a);return (*this);
  232. };//自身除以常数
  233. func& operator/=(DOUBLE (*f)(DOUBLE)); // 自身除以一个函数指针
  234. func operator/(func& fn); // 相除产生新函数
  235. func operator/(DOUBLE a); // 与常数相除产生新函数
  236. friend func operator/(DOUBLE a, func& f); // 常数除以函数
  237. func operator/(DOUBLE (*f)(DOUBLE)); // 除以一个函数指针产生新函数
  238. friend func operator/(DOUBLE (*f)(DOUBLE),func& fn); // 函数指针除以函数
  239. void setxfactor(DOUBLE a); // 设置x因子为a
  240. void xroom(DOUBLE a);   // x方向扩大a倍
  241. void setxshift(DOUBLE a); // 设置函数沿x轴平移a
  242. void shiftxas(DOUBLE a); // 函数沿x轴右移a
  243. func& power(func& f); // 函数的f次乘幂,函数自身改变
  244. func& power(DOUBLE a); // 函数的a次幂,函数自身改变
  245. func operator^(func & fn); // 函数的fn次乘幂,产生新函数,原函数不变
  246. func operator^(DOUBLE a);  // 函数的a次幂,产生新函数,原函数不变
  247. func operator()(func & fn); // 复合函数,产生新的函数
  248. DOUBLE integ(DOUBLE a, DOUBLE b, DOUBLE eps=defaulterr);
  249. // 从a到b计算函数的定积分
  250. DOUBLE singleroot(DOUBLE x=0.9, DOUBLE eps = defaulterr);
  251. // 计算函数f(x)=0的一个单根
  252. func inverse(); // 产生反函数
  253. void getab(DOUBLE& a,DOUBLE& b) { // 主要被线性回归子类用,返回线性因子
  254.     // 和加常数
  255. a = alg->yfactor;
  256. b = alg->addconst;
  257. };
  258. };
  259. inline func operator+(DOUBLE a, func& f) // 常数加函数
  260. { return f+a; }
  261. inline func operator+(DOUBLE (*f)(DOUBLE),func& fn) // 函数指针加函数
  262. { return fn+f;}
  263. func operator-(DOUBLE a, func& f); // 常数减函数
  264. func operator-(DOUBLE (*f)(DOUBLE),func& fn); // 函数指针减函数
  265. inline func operator*(DOUBLE a, func& f) // 常数乘函数
  266. { return f*a; }
  267. inline func operator*(DOUBLE (*f)(DOUBLE),func& fn) // 函数指针乘函数
  268. { return fn*f;}
  269. func operator/(DOUBLE a, func& f); // 常数除以函数
  270. func operator/(DOUBLE (*f)(DOUBLE),func& fn); // 函数指针除以函数
  271. class funcgass : public func // 正态分布函数
  272. {
  273.  public:
  274. funcgass(DOUBLE a=0.0, DOUBLE d=1.0):func(new algogass(a,d)){};
  275. void setmandd(DOUBLE a, DOUBLE d){
  276. alg->xshift = a;
  277. alg->xfactor = 1.0/d; }; // 设置均值和标准差
  278. void getmandd(DOUBLE &a, DOUBLE &d) {
  279. a = alg->xshift; d=1.0/alg->xfactor;}; // 获得均值和标准差
  280. };
  281. class funcpoly : public func // 多项式函数
  282. {
  283.  public:
  284. funcpoly(matrix& d):func(new algopoly(d)){};
  285. matrix& getdata(){return ((algopoly*)alg)->data;};
  286. cmatrix getroots(){return ((algopoly*)alg)->getroots();};
  287. };
  288. class funcenter2 : public func // 一元全区间不等距插值
  289. {
  290.  public:
  291. funcenter2(matrix& d):func(new algoenter2(d)){};
  292. matrix& getdata(){return ((algoenter2*)alg)->data;};
  293. };
  294. class funcenter : public func // 一元全区间等距插值
  295. {
  296.  public:
  297. funcenter(matrix& d, DOUBLE x0, DOUBLE h):
  298. func(new algoenter(d,x0,h)){};
  299. matrix& getdata(DOUBLE &xx0, DOUBLE &hh){
  300. xx0 = ((algoenter*)alg)->x0; hh = ((algoenter*)alg)->h;
  301. return ((algoenter*)alg)->data; };
  302. };
  303. class funcpair : public func // 最小二乘拟合函数
  304. {
  305.  public:
  306. funcpair(matrix& xy, size_t m, DOUBLE & t0,DOUBLE &t1,DOUBLE &t2);
  307. // xy为n行2列数组,存放n个样本点
  308. // m为拟合多项式的项数,dt0为误差平方和,dt1为误差绝对值和,
  309. // dt2为最大误差绝对值
  310. matrix & getdata(){return ((algopair*)alg)->data;};
  311.  // 返回结果拟合系数一维矩阵
  312. cmatrix getroots(){return ((algopoly*)alg)->getroots();};
  313. // 求出所有根
  314. };
  315. class funcregress : public func // 线性回归函数,其实就是线性函数ax+b
  316. // 但由数据样本点构成a与b
  317. {
  318.  public:
  319. funcregress(matrix & xy, matrix* dt=0);  // xy为n行2列的矩阵为n个样本点
  320. // dt必须指向一个6列一行的矩阵向量,六个数依次为偏差平方和,平均标准
  321. // 偏差,回归平方和,最大偏差,最小偏差,偏差平均值
  322. };
  323. #endif // FUNC_H