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

C++ Builder

  1. #include <values.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include "vfunc.h"
  5. matrix valgo::cal(matrix& x) { // 基类的基本算法
  6. matrix xx(x);
  7. if(xshift != 0.0) xx -= xshift;
  8. if(xfactor != 1.0) xx *=xfactor;
  9. calculate(xx);
  10. if(yfactor != 1.0) xx *= yfactor;
  11. if(addconst != 0.0) xx += addconst;
  12. return xx;
  13. }
  14. valgo * valgo::clone() // 克隆自己,必须被继承子类改写
  15. {
  16. return new valgo(*this);
  17. }
  18. valgo * valgo::mul(DOUBLE a) // 乘a
  19. {
  20. valgo * alg;
  21. alg = this;
  22. if(refnum>1) { refnum--;
  23. alg = clone(); // 如引用数大于1,则产生新的对象
  24. }
  25. alg->yfactor *= a;
  26. alg->addconst *= a;
  27. return alg;
  28. }
  29. valgo * valgo::add(DOUBLE a) // 加a
  30. {
  31. valgo * alg;
  32. alg = this;
  33. if(refnum>1) { refnum--;
  34. alg = clone(); // 如引用数大于1,则产生新的对象
  35. }
  36. alg->addconst += a;
  37. return alg;
  38. }
  39. valgo * valgo::neg() // 取负
  40. {
  41. valgo * alg;
  42. alg = this;
  43. if(refnum>1) { refnum--;
  44. alg = clone(); // 如引用数大于1,则产生新的对象
  45. }
  46. alg->addconst = -alg->addconst;
  47. alg->yfactor = -alg->yfactor;
  48. return alg;
  49. }
  50. valgo * valgo::setxfactor(DOUBLE x) // 设置x轴因子
  51. {
  52. valgo * alg;
  53. alg = this;
  54. if(refnum>1) { refnum--;
  55. alg = clone(); // 如引用数大于1,则产生新的对象
  56. }
  57. alg->xfactor = x;
  58. return alg;
  59. }
  60. valgo * valgo::xroom(DOUBLE x) // 将xfactor扩大x倍
  61. {
  62. valgo * alg;
  63. alg = setxfactor(x*xfactor);
  64. if(x!=0.0)
  65. alg->setxshift(alg->xshift/x);
  66. return alg;
  67. }
  68. valgo * valgo::setxshift(DOUBLE x) // 设置xshift的值
  69. {
  70. valgo * alg;
  71. alg = this;
  72. if(refnum>1) { refnum--;
  73. alg = clone(); // 如引用数大于1,则产生新的对象
  74. }
  75. alg->xshift = x;
  76. return alg;
  77. }
  78. valgo * valgo::xshiftas(DOUBLE x) // 从当前开始平移x
  79. {
  80. return setxshift(xshift+x);
  81. }
  82. valgo * valgojoin::clone() // 克隆自己
  83. {
  84. return new valgojoin(*this);
  85. }
  86. matrix& valgojoin::calculate(matrix& x) // 实施结合算法
  87. {
  88. if(leftalgo==0 || rightalgo==0)
  89. throw TMESSAGE("empty valgo pointor!");
  90. if(met == ccom) { // 复合函数
  91. matrix x1;
  92. x1 = rightalgo->cal(x);
  93. x = leftalgo->cal(x1);
  94. return x;
  95. }
  96. matrix xr;
  97. xr = rightalgo->cal(x);
  98. x = leftalgo->cal(x);
  99. if(met == cadd) // 返回各结合运算值
  100. x += xr;
  101. else if(met == csub)
  102. x -= xr;
  103. else if(met == cmul)
  104. x *= xr;
  105. else if(met == cdiv)
  106. x /= xr;
  107. return x;
  108. }
  109. valgo * valgofun::clone() // 克隆自己
  110. {
  111. return new valgofun(*this);
  112. }
  113. matrix& valgofun::calculate(matrix& x) // 实施函数算法
  114. {
  115. if(f)
  116. return x=f(x);
  117. return (x*=0.0);
  118. }
  119. valgo * valgofun1::clone() // 克隆自己
  120. {
  121. return new valgofun1(*this);
  122. }
  123. matrix& valgofun1::calculate(matrix& x) // 实施函数算法
  124. {
  125. DOUBLE xx;
  126. xx = x(0);
  127. if(f)
  128. return (x=f(xx));
  129. return (x*=0.0);
  130. }
  131. matrix& valgodiff::calculate(matrix& x) // 实施函数算法
  132. {
  133. DOUBLE t;
  134. t = x(0);
  135. return calcul(t);
  136. }
  137. valgo * valgodiff::clone() // 克隆自己
  138. {
  139. return new valgodiff(*this);
  140. }
  141. matrix& valgodiff::calcul(DOUBLE t, DOUBLE eps) // 标量算法
  142. {
  143. DOUBLE h,t00;
  144. matrix y00(y0);
  145. t00 = t0;
  146. h = t-t0;
  147. if(t0==t)
  148. return y0;
  149. if(tnow==t)
  150. return ynow;
  151. if(t>tnow) {
  152. t00 = tnow;
  153. h = t - tnow;
  154. y00 = ynow;
  155. }
  156. matrix y(y00);
  157. size_t n = y.rownum;
  158. size_t m,i,j,k;
  159. DOUBLE hh,p,dt,x,tt,q,a[4];
  160. matrix g(n),b(n),c(n),d(n),e(n);
  161. hh=h; m=1; p=1.0+eps; x=t00;
  162. c = y;
  163. while (p>=eps)
  164. { a[0]=hh/2.0; a[1]=a[0]; a[2]=hh; a[3]=hh;
  165.   g = y; y = c;
  166.   dt=h/m; t00=x;
  167.   for (j=0; j<m; j++)
  168.  { d = f(t00,y);  // grkt2f(t,y,n,d);
  169. b = y; e = y;
  170. for (k=0; k<=2; k++)
  171.   {
  172. y = e+(d*a[k]);
  173. b += d*(a[k+1]/3.0);
  174. tt=t00+a[k];
  175. d = f(tt,y);
  176.   }
  177. y = b + d*(hh/6.0);
  178. t00+=dt;
  179.  }
  180.   p=0.0;
  181.   for (i=0; i<n; i++)
  182.  { q=fabs(y(i)-g(i));
  183. if (q>p) p=q;
  184.  }
  185.   hh=hh/2.0; m=m+m;
  186. } // end of while(p>eps)
  187. tnow = t;
  188. ynow = y;
  189. return ynow;
  190. }
  191. vfunc::vfunc()// 缺省构造函数,产生函数f(x)=x;
  192. {
  193. alg = new valgo();
  194. }
  195. vfunc::vfunc(vfunc & fn) // 拷贝构造函数
  196. {
  197. alg = fn.alg;
  198. alg->refnum++;
  199. }
  200. vfunc::vfunc(matrix& (*fun)(matrix&)) // 函数指针的构造函数
  201. {
  202. alg = new valgofun(fun);
  203. }
  204. vfunc::vfunc(matrix (*fun)(DOUBLE)) // 标量到向量的函数指针构造函数
  205. {
  206. alg = new valgofun1(fun);
  207. }
  208. vfunc::vfunc(DOUBLE a) // 常函数构造函数
  209. {
  210. alg = new valgo(a);
  211. }
  212. vfunc& vfunc::operator=(vfunc& fn) // 赋值运算符
  213. {
  214. if(this == &fn) return (*this); // 如果等于自己,干脆啥也别做
  215. if(alg) {
  216. alg->refnum--; // 原算法引用数减1
  217. if(!alg->refnum) // 如结果为0则删除原算法
  218. delete alg;
  219. }
  220. alg = fn.alg; // 将fn的算法移过来
  221. if(alg) alg->refnum++; // 引用数增加
  222. return (*this);
  223. }
  224. vfunc& vfunc::operator=(matrix& (*fn)(matrix&)) // 用函数指针的赋值运算符
  225. {
  226. if(alg) {
  227. alg->refnum--; // 原算法引用数减1
  228. if(!alg->refnum) // 如结果为0则删除原算法
  229. delete alg;
  230. }
  231. alg = new valgofun(fn);
  232. return (*this);
  233. }
  234. vfunc& vfunc::operator=(DOUBLE a) // 常函数的赋值运算符
  235. {
  236. if(alg) {
  237. alg->refnum--; // 原算法引用数减1
  238. if(!alg->refnum) // 如结果为0则删除原算法
  239. delete alg;
  240. }
  241. alg = new valgo(a);
  242. return (*this);
  243. }
  244. vfunc& vfunc::operator+=(vfunc& fn) // 自身加一个函数
  245. {
  246. valgo * a = new valgojoin(alg, fn.alg, cadd);
  247. alg->refnum--; // 因为联合算法对两个算法都加了引用数,因此再减回来
  248. alg = a; // 将新指针赋给alg
  249. return (*this);
  250. }
  251. vfunc& vfunc::operator+=(matrix& (*f)(matrix&)) // 自身加一个函数指针
  252. {
  253. vfunc fn(f); // 将函数指针包装为函数类
  254. operator+=(fn); // 实施加操作
  255. return (*this);
  256. }
  257. vfunc vfunc::operator+(vfunc& fn) // 相加产生新函数
  258. {
  259. valgo * a = new valgojoin(alg, fn.alg, cadd);
  260. vfunc f(a);
  261. return f;
  262. }
  263. vfunc vfunc::operator+(DOUBLE a) // 与常数相加产生新函数
  264. {
  265. vfunc f(*this);
  266. f += a;
  267. return f;
  268. }
  269. vfunc vfunc::operator+(matrix& (*f)(matrix&)) // 加一个函数指针产生新函数
  270. {
  271. vfunc ff(*this);
  272. ff += f;
  273. return ff;
  274. }
  275. vfunc& vfunc::neg() // 自身取负
  276. {
  277. alg=alg->neg();
  278. return (*this);
  279. }
  280. vfunc vfunc::operator-() // 产生负函数
  281. {
  282. vfunc f(*this);
  283. f.neg();
  284. return f;
  285. }
  286. vfunc& vfunc::operator-=(vfunc& fn) // 自身减一个函数
  287. {
  288. valgo * a = new valgojoin(alg, fn.alg, csub);
  289. alg->refnum--; // 因为联合算法对两个算法都加了引用数,因此再减回来
  290. alg = a; // 将新指针赋给alg
  291. return (*this);
  292. }
  293. vfunc& vfunc::operator-=(matrix& (*f)(matrix&)) // 自身减一个函数指针
  294. {
  295. vfunc fn(f); // 将函数指针包装为函数类
  296. operator-=(fn); // 实施减操作
  297. return (*this);
  298. }
  299. vfunc vfunc::operator-(vfunc& fn) // 相减产生新函数
  300. {
  301. valgo * a = new valgojoin(alg, fn.alg, csub);
  302. vfunc f(a);
  303. return f;
  304. }
  305. vfunc vfunc::operator-(DOUBLE a) // 与常数相减产生新函数
  306. {
  307. vfunc f(*this);
  308. f -= a;
  309. return f;
  310. }
  311. vfunc operator-(DOUBLE a, vfunc& f) // 常数减函数
  312. {
  313. return (-f)+a;
  314. }
  315. vfunc vfunc::operator-(matrix& (*f)(matrix&)) // 减一个函数指针产生新函数
  316. {
  317. vfunc ff(*this);
  318. ff -= f;
  319. return ff;
  320. }
  321. vfunc operator-(matrix& (*f)(matrix&),vfunc& fn) // 函数指针减函数
  322. {
  323. vfunc ff(f);
  324. ff -= fn;
  325. return ff;
  326. }
  327. vfunc& vfunc::operator*=(vfunc& fn) // 自身乘一个函数
  328. {
  329. valgo * a = new valgojoin(alg, fn.alg, cmul);
  330. alg->refnum--; // 因为联合算法对两个算法都加了引用数,因此再减回来
  331. alg = a; // 将新指针赋给alg
  332. return (*this);
  333. }
  334. vfunc& vfunc::operator*=(matrix& (*f)(matrix&)) // 自身乘一个函数指针
  335. {
  336. vfunc fn(f); // 将函数指针包装为函数类
  337. operator*=(fn); // 实施乘操作
  338. return (*this);
  339. }
  340. vfunc vfunc::operator*(vfunc& fn) // 相乘产生新函数
  341. {
  342. valgo * a = new valgojoin(alg, fn.alg, cmul);
  343. vfunc f(a);
  344. return f;
  345. }
  346. vfunc vfunc::operator*(DOUBLE a) // 与常数相乘产生新函数
  347. {
  348. vfunc f(*this);
  349. f *= a;
  350. return f;
  351. }
  352. vfunc vfunc::operator*(matrix& (*f)(matrix&)) // 乘一个函数指针产生新函数
  353. {
  354. vfunc ff(*this);
  355. ff *= f;
  356. return ff;
  357. }
  358. vfunc& vfunc::operator/=(vfunc& fn) // 自身除以一个函数
  359. {
  360. valgo * a = new valgojoin(alg, fn.alg, cdiv);
  361. alg->refnum--; // 因为联合算法对两个算法都加了引用数,因此再减回来
  362. alg = a; // 将新指针赋给alg
  363. return (*this);
  364. }
  365. vfunc& vfunc::operator/=(matrix& (*f)(matrix&)) // 自身除以一个函数指针
  366. {
  367. vfunc fn(f); // 将函数指针包装为函数类
  368. operator/=(fn); // 实施除法操作
  369. return (*this);
  370. }
  371. vfunc vfunc::operator/(vfunc& fn) // 相除产生新函数
  372. {
  373. valgo * a = new valgojoin(alg, fn.alg, cdiv);
  374. vfunc f(a);
  375. return f;
  376. }
  377. vfunc vfunc::operator/(DOUBLE a) // 与常数相除产生新函数
  378. {
  379. vfunc f(*this);
  380. f /= a;
  381. return f;
  382. }
  383. vfunc operator/(DOUBLE a, vfunc& f) // 常数除以函数
  384. {
  385. vfunc ff(a);
  386. return ff/f;
  387. }
  388. vfunc vfunc::operator/(matrix& (*f)(matrix&)) // 除以一个函数指针产生新函数
  389. {
  390. vfunc ff(*this);
  391. ff /= f;
  392. return ff;
  393. }
  394. vfunc operator/(matrix& (*f)(matrix&),vfunc& fn) // 函数指针除以函数
  395. {
  396. vfunc ff(f);
  397. ff /= fn;
  398. return ff;
  399. }
  400. void vfunc::setxfactor(DOUBLE a) // 设置x因子为a
  401. {
  402. alg = alg->setxfactor(a);
  403. }
  404. void vfunc::xroom(DOUBLE a)   // x方向扩大a倍
  405. {
  406. alg = alg->xroom(a);
  407. }
  408. vfunc vfunc::operator()(vfunc & fn) // 复合函数,产生新的函数
  409. {
  410. valgo * a = new valgojoin(alg, fn.alg, ccom);
  411. vfunc f(a);
  412. return f;
  413. }
  414. void vfunc::setxshift(DOUBLE a) // 设置函数沿x轴平移a
  415. {
  416. alg = alg->setxshift(a);
  417. }
  418. void vfunc::shiftxas(DOUBLE a) // 函数沿x轴右移a
  419. {
  420. alg = alg->xshiftas(a);
  421. }
  422. linemodel::linemodel(matrix& va, matrix & vh, matrix & q,
  423.  matrix & r, matrix & vx) :a(va),h(vh),w(q),v(r),x(vx),
  424. y(vh.rownum,1)
  425. // 构造函数,va初始状态转移矩阵,vh初始观测矩阵,q当前模型噪声协
  426. // 方差阵,r当前观测噪声协方差阵,vx初始状态变量
  427. {
  428. if(va.rownum != vx.rownum ||
  429. va.rownum != va.colnum ||
  430. vh.colnum != va.rownum ||
  431. q.rownum != va.rownum ||
  432. r.rownum != vh.rownum) throw TMESSAGE("Data not meet need!");
  433. y = h*x+v();
  434. };
  435. void linemodel::setdata(matrix& va, matrix & vh, matrix & q, matrix & r)
  436. {
  437. if(va.rownum != va.colnum ||
  438. va.rownum != x.rownum ||
  439. vh.colnum != va.rownum ||
  440. q.rownum != va.rownum ||
  441. r.rownum != vh.rownum) throw TMESSAGE("Data not meet need!");
  442. a = va;
  443. h = vh;
  444. w.setdata(q);
  445. v.setdata(r);
  446. }
  447. void linemodel::seta(matrix& va)
  448. {
  449. if(va.rownum != va.colnum ||
  450. va.rownum != x.rownum) throw TMESSAGE("a not meet need!");
  451. a = va;
  452. }
  453. void linemodel::seth(matrix& vh)
  454. {
  455. if(vh.rownum != y.rownum ||
  456. vh.colnum != x.rownum ) throw TMESSAGE("h not meet nead!");
  457. h = vh;
  458. }
  459. void linemodel::setq(matrix& q)
  460. {
  461. if(q.rownum != x.rownum ||
  462. !q.issym) throw TMESSAGE("q not meet nead!");
  463. w.setdata(q);
  464. }
  465. void linemodel::setr(matrix& r)
  466. {
  467. if(r.rownum != y.rownum ||
  468. !r.issym) throw TMESSAGE("r not meet nead!");
  469. v.setdata(r);
  470. }
  471. matrix & linemodel::next() // 计算下一级x值并返回新的x对应的y值
  472. {
  473. x = a*x+w(); // 产生新的状态变量值
  474. return (y=h*x+v()); // 产生并返回新的观测值
  475. }
  476. kalman::kalman(matrix &va,matrix& vq,matrix& vr,matrix& vh,matrix& vx,
  477. matrix& vp):
  478. // 构造函数,va为状态转移矩阵,vh观测矩阵,vq模型噪声协方差阵,
  479. // vr当前观测噪声协方差阵,vx初始状态变量估值,vp初始估值协方差阵
  480. a(va),q(vq),r(vr),h(vh),x(vx),p(vp),y(vh.rownum,1)
  481. {
  482. if( va.rownum != va.colnum ||
  483.  !vq.issym || !vr.issym || !vp.issym ||
  484.  vq.rownum != va.rownum || vr.rownum != vh.rownum ||
  485.  vx.rownum != va.rownum || vp.rownum != vx.rownum ||
  486.  vh.colnum != vx.rownum ) throw TMESSAGE("data not meet need!");
  487. if( !vq.ispositive() || !vr.ispositive() )
  488.  throw TMESSAGE("var matrix not positive!");
  489. y = 0.0;
  490. }
  491. void kalman::setdata(matrix &va,matrix& vq,matrix& vr,matrix& vh)
  492. // 为时变系统随时设置系统参数,va为状态转移矩阵,vh观测矩阵,vq模型噪
  493. // 声协方差阵,vr当前观测噪声协方差阵
  494. {
  495. if(va.rownum != va.colnum || va.rownum != x.rownum ||
  496. va.rownum != vq.rownum || !vq.issym ||
  497. vr.rownum != y.rownum || vh.rownum != y.rownum ||
  498. vh.colnum != x.rownum ) throw TMESSAGE("data not meet need!");
  499. if( !vq.ispositive() || !vr.ispositive() )
  500.  throw TMESSAGE("var matrix not positive!");
  501. a = va;
  502. q = vq;
  503. h = vh;
  504. r = vr;
  505. }
  506. void kalman::seta(matrix& va)
  507. {
  508. if(va.rownum != va.colnum || va.rownum != x.rownum)
  509. throw TMESSAGE("data not meet need!");
  510. a = va;
  511. }
  512. void kalman::seth(matrix& vh)
  513. {
  514. if(vh.rownum != y.rownum || vh.colnum != x.rownum)
  515. throw TMESSAGE("data not meet need!");
  516. h = vh;
  517. }
  518. void kalman::setq(matrix& vq)
  519. {
  520. if(vq.rownum != x.rownum || !vq.issym)
  521. throw TMESSAGE("data not meet need!");
  522. if(!vq.ispositive())
  523. throw TMESSAGE("q is not positive!");
  524. q = vq;
  525. }
  526. void kalman::setr(matrix& vr)
  527. {
  528. if(vr.rownum != y.rownum || !vr.issym)
  529. throw TMESSAGE("data not meet need!");
  530. if(!vr.ispositive())
  531. throw TMESSAGE("r is not positive!");
  532. r = vr;
  533. }
  534. matrix& kalman::next(matrix& y) // 根据下一个观测值获得新的状态变量的估值
  535. {
  536. x = a*x; // 预测
  537. p = a*p*a.t()+q; // 预测误差协方差
  538. matrix k=p*h.t()*((h*p*h.t()+r).inv()); // 新息的增益
  539. x += k*(y-h*x); // 由新息校正x得现时估计
  540. p = (unit(p.rownum)-k*h)*p; // 获得最后的误差协方差,注意unit(n)是
  541. // n阶单位矩阵
  542. return x; // 返回x的估计值
  543. }
  544. regress::regress(matrix& x, matrix& y) // x为mXn维矩阵,y为n个观测值
  545. {
  546. if(x.colnum != y.rownum || x.colnum < x.rownum)
  547. throw TMESSAGE("dimension error");
  548. matrix c(x.rownum+1,x.colnum);
  549. size_t i,j;
  550. for(i=0; i<x.rownum; i++)
  551. for(j=0; j<x.colnum; j++)
  552. c.set(i,j,x(i,j));
  553. for(j=0; j<c.colnum; j++)
  554. c.set(x.rownum,j,1.0);
  555. matrix y1(c*y);
  556. c *= c.t();
  557. a = c.cholesky(y1);
  558. v = matrix(x.rownum);
  559. // 计算偏差平方和
  560. q = 0;
  561. DOUBLE yy;
  562. matrix dd(y.rownum);
  563. for(i=0; i<y.rownum; i++) {
  564. yy = y(i);
  565. for(j=0; j<x.rownum; j++)
  566. yy -= a(j)*x(j,i);
  567. yy -= a(a.rownum-1);
  568. dd.set(i,yy);
  569. q += yy*yy;
  570. }
  571. s = sqrt(q/(y.rownum));
  572. yy = 0.0;
  573. for(i=0; i<y.rownum; i++)
  574. yy += y(i);
  575. DOUBLE ye;
  576. ye = yy/(y.rownum);
  577. r = 0.0;
  578. for(i=0; i<y.rownum; i++)
  579. r += (y(i)-ye)*(y(i)-ye);
  580. r = sqrt(1.0-q/r);
  581. for(j=0;j<v.rownum;j++) {
  582. yy = 0;
  583. for(i=0;i<y.rownum;i++)
  584. yy += (dd(i)+a(j)*x(j,i))*(dd(i)+a(j)*x(j,i));
  585. v.set(j,sqrt(1.0-q/yy));
  586. }
  587. u = 0.0;
  588. for(i=0; i<y.rownum; i++) {
  589. yy = ye;
  590. for(j=0; j<x.rownum; j++)
  591. yy -= a(j)*x(j,i);
  592. yy -= a(x.rownum);
  593. u += yy*yy;
  594. }
  595. }
  596. DOUBLE regress::operator()(matrix& x) // 回归后的线性函数,x是自变量
  597. {
  598. if(x.rownum != a.rownum-1) throw TMESSAGE("wrong dimension!");
  599. DOUBLE y = a(a.rownum-1);
  600. for(size_t i=0; i<x.rownum; i++)
  601. y += x(i)*a(i);
  602. return y;
  603. }