PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/@QMITL_Formula/private/src/robusthom/robustness.cpp

https://bitbucket.org/donze/breach
C++ | 797 lines | 586 code | 140 blank | 71 comment | 145 complexity | beebe878d863a4436b239163904a61fe MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #include "robustness.h"
  2. #include <list>
  3. using namespace std;
  4. /*---------------------------------------------------------------------------*
  5. * MAIN FUNCTIONS *
  6. *---------------------------------------------------------------------------*/
  7. Signal * computeNot(Signal * y) {
  8. Signal * z = new Signal();
  9. Signal::iterator i;
  10. z->beginTime=y->beginTime;
  11. z->endTime=y->endTime;
  12. for(i = y->begin(); i != y->end(); i++) {
  13. z->push_back(Sample(i->time, -(i->value), -(i->derivative)));
  14. }
  15. return z;
  16. }
  17. Signal * computeAnd(Signal * x, Signal * y) {
  18. Signal::reverse_iterator i=x->rbegin();
  19. Signal::reverse_iterator j=y->rbegin();
  20. Signal * z=new Signal();
  21. z->beginTime=fmax(x->beginTime, y->beginTime);
  22. z->endTime=fmin(x->endTime, y->endTime);
  23. while(i->time >= z->endTime) i++;
  24. while(j->time >= z->endTime) j++;
  25. computePartialAnd(z, i, j, z->beginTime, z->endTime);
  26. z->simplify();
  27. return z;
  28. }
  29. Signal * computeOr(Signal * x, Signal * y) {
  30. Signal::reverse_iterator i=x->rbegin();
  31. Signal::reverse_iterator j=y->rbegin();
  32. Signal * z=new Signal();
  33. z->beginTime=fmax(x->beginTime, y->beginTime);
  34. z->endTime=fmin(x->endTime, y->endTime);
  35. while(i->time >= z->endTime) i++;
  36. while(j->time >= z->endTime) j++;
  37. computePartialOr(z, i, j, z->beginTime, z->endTime);
  38. z->simplify();
  39. return z;
  40. }
  41. Signal * computeEventually(Signal * x) {
  42. #ifdef DEBUG__
  43. cout << "Entering computeEventually" << endl;
  44. #endif
  45. Signal * z=new Signal();
  46. z->beginTime=x->beginTime;
  47. z->endTime=x->endTime;
  48. Signal::reverse_iterator i=x->rbegin();
  49. computePartialEventually(z,i,z->beginTime, z->endTime);
  50. return z;
  51. }
  52. Signal * computeUntil(Signal * x, Signal * y) {
  53. #ifdef DEBUG__
  54. cout << "Entering computeUntil" << endl;
  55. #endif
  56. double s, t;
  57. double z_max=BOTTOM;
  58. Signal * z=new Signal();
  59. Signal::reverse_iterator i=x->rbegin();
  60. Signal::reverse_iterator j=y->rbegin();
  61. z->beginTime=fmax(x->beginTime, y->beginTime);
  62. z->endTime=fmin(x->endTime, y->endTime);
  63. while(i->time >= z->endTime) i++;
  64. while(j->time >= z->endTime) j++;
  65. s=z->beginTime;
  66. t=z->endTime;
  67. while(i->time > s) {
  68. computeSegmentUntil(z, *i, t, j, z_max);
  69. z_max=z->front().value;
  70. if(j->time == i->time) j++;
  71. t=i->time;
  72. i++;
  73. }
  74. if(i->time == s) computeSegmentUntil(z, *i, t, j, z_max);
  75. else computeSegmentUntil(z, Sample(s, i->valueAt(s), i->derivative), t, j, z_max);
  76. z->simplify();
  77. return z;
  78. }
  79. Signal * computeBoundedEventually(Signal * x, double a) {
  80. #ifdef DEBUG__
  81. cout << "Entering computeBoundedEventually" << endl;
  82. #endif
  83. Signal *z, *z1, *z2, *z3;
  84. z1=plateauMax(x, a);
  85. z2=new Signal(*x);
  86. z2->resize(x->beginTime + a, x->endTime + a, BOTTOM);
  87. z2->shift(-a);
  88. z3=computeOr(z2, z1);
  89. delete z1;
  90. delete z2;
  91. z=new Signal();
  92. z=computeOr(x, z3);
  93. delete z3;
  94. z->simplify();
  95. return z;
  96. }
  97. Signal * computeBoundedGlobally(Signal * x, double a) {
  98. Signal *z, *z1, *z2, *z3;
  99. z1=plateauMin(x, a);
  100. z2=new Signal(*x);
  101. z2->resize(x->beginTime + a, x->endTime + a, TOP);
  102. z2->shift(-a);
  103. z3=computeAnd(z2, z1);
  104. delete z1;
  105. delete z2;
  106. z=new Signal();
  107. z=computeAnd(x, z3);
  108. delete z3;
  109. z->simplify();
  110. return z;
  111. }
  112. Signal * computeTimedUntil(Signal * x, Signal * y, double a, double b) {
  113. Signal *z, *z1, *z2, *z3, *z4;
  114. z=new Signal();
  115. if (a>0)
  116. z1=computeBoundedGlobally(x,a);
  117. z2=computeBoundedEventually(y,b-a);
  118. z3=computeUntil(x,y);
  119. z4=computeAnd(z2,z3);
  120. if (a>0) {
  121. z4->shift(-a);
  122. z=computeAnd(z1,z4);
  123. }
  124. else
  125. z=computeAnd(x,z4);
  126. return z;
  127. }
  128. /*---------------------------------------------------------------------------*
  129. * CONJUNCTION SUBROUTINES *
  130. *---------------------------------------------------------------------------*/
  131. //PRECONDITIONS: j->time < t, i.time < t.
  132. //POSTCONDITIONS: j->time <= i.time.
  133. void computeSegmentAnd(Signal * z, const Sample & i, double t, Signal::reverse_iterator & j) {
  134. bool continued=false;
  135. double s=j->time;
  136. // for every sample *j in (i.time, t)
  137. while(s > i.time) {
  138. if(i.valueAt(t) < j->valueAt(t)) {
  139. if (i.valueAt(s) > j->value) {
  140. t=i.timeIntersect(*j);
  141. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  142. z->push_front(Sample(s,j->value,j->derivative));
  143. continued=false;
  144. }
  145. else continued=true;
  146. }
  147. else if (i.valueAt(t) == j->valueAt(t)) {
  148. if (i.valueAt(s) > j->value) {
  149. if(continued) {
  150. z->push_front(Sample(t,i.valueAt(t), i.derivative));
  151. continued=false;
  152. }
  153. z->push_front(Sample(s,j->value,j->derivative));
  154. }
  155. else continued=true;
  156. }
  157. else {
  158. if (i.valueAt(s) < j->value) {
  159. if(continued) {
  160. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  161. }
  162. t=i.timeIntersect(*j);
  163. z->push_front(Sample(t,j->valueAt(t),j->derivative));
  164. continued=true;
  165. }
  166. else {
  167. if(continued) {
  168. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  169. continued=false;
  170. }
  171. z->push_front(Sample(s,j->value,j->derivative));
  172. }
  173. }
  174. //increment reverse iterator j
  175. t = s;
  176. j++;
  177. s = j->time;
  178. }
  179. //here we may have j->time < i.time
  180. // "i" values of z are no longer "continued"
  181. s=i.time;
  182. if(i.valueAt(t) < j->valueAt(t)) {
  183. if (i.value > j->valueAt(s)) {
  184. t=i.timeIntersect(*j);
  185. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  186. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  187. }
  188. else {
  189. z->push_front(i);
  190. }
  191. }
  192. else if (i.valueAt(t) == j->valueAt(t)) {
  193. if (i.value > j->valueAt(s)) {
  194. if(continued) {
  195. z->push_front(Sample(t,i.valueAt(t), i.derivative));
  196. }
  197. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  198. }
  199. else {
  200. z->push_front(i);
  201. }
  202. }
  203. else {
  204. if (i.value < j->valueAt(s)) {
  205. if(continued) {
  206. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  207. }
  208. t=i.timeIntersect(*j);
  209. z->push_front(Sample(t,j->valueAt(t),j->derivative));
  210. z->push_front(i);
  211. }
  212. else {
  213. if(continued) {
  214. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  215. }
  216. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  217. }
  218. }
  219. }
  220. //void computeConstantSegmentAnd(Signal *, double, Signal::reverse_iterator &, double, double) { }
  221. void computePartialAnd(Signal * z, Signal::reverse_iterator & i, Signal::reverse_iterator & j, double s, double t) {
  222. while(i->time > s) {
  223. computeSegmentAnd(z,*i,t,j);
  224. if (j->time == i->time) j++;
  225. t=i->time;
  226. i++;
  227. }
  228. if(i->time == s) computeSegmentAnd(z, *i, t, j);
  229. else computeSegmentAnd(z, Sample(s,i->valueAt(s),i->derivative), t, j);
  230. }
  231. /*---------------------------------------------------------------------------*
  232. * DISJUNCTION SUBROUTINES *
  233. *---------------------------------------------------------------------------*/
  234. // copy of computeSegmentAnd, operator "<" switched with operator ">"
  235. void computeSegmentOr(Signal * z, const Sample & i, double t, Signal::reverse_iterator & j) {
  236. bool continued=false;
  237. double s=j->time;
  238. // for every sample *j in (i.time, t)
  239. while(s > i.time) {
  240. if(i.valueAt(t) > j->valueAt(t)) {
  241. if (i.valueAt(s) < j->value) {
  242. t=i.timeIntersect(*j);
  243. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  244. z->push_front(Sample(s,j->value,j->derivative));
  245. continued=false;
  246. }
  247. else continued=true;
  248. }
  249. else if (i.valueAt(t) == j->valueAt(t)) {
  250. if (i.valueAt(s) < j->value) {
  251. if(continued) {
  252. z->push_front(Sample(t,i.valueAt(t), i.derivative));
  253. continued=false;
  254. }
  255. z->push_front(Sample(s,j->value,j->derivative));
  256. }
  257. else continued=true;
  258. }
  259. else {
  260. if (i.valueAt(s) > j->value) {
  261. if(continued) {
  262. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  263. }
  264. t=i.timeIntersect(*j);
  265. z->push_front(Sample(t,j->valueAt(t),j->derivative));
  266. continued=true;
  267. }
  268. else {
  269. if(continued) {
  270. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  271. continued=false;
  272. }
  273. z->push_front(Sample(s,j->value,j->derivative));
  274. }
  275. }
  276. //increment reverse iterator j
  277. t = s;
  278. j++;
  279. s = j->time;
  280. }
  281. //here we may have j->time < i.time
  282. // "i" values of z are no longer "continued"
  283. s=i.time;
  284. if(i.valueAt(t) > j->valueAt(t)) {
  285. if (i.value < j->valueAt(s)) {
  286. t=i.timeIntersect(*j);
  287. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  288. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  289. }
  290. else {
  291. z->push_front(i);
  292. }
  293. }
  294. else if (i.valueAt(t) == j->valueAt(t)) {
  295. if (i.value < j->valueAt(s)) {
  296. if(continued) {
  297. z->push_front(Sample(t,i.valueAt(t), i.derivative));
  298. }
  299. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  300. }
  301. else {
  302. z->push_front(i);
  303. }
  304. }
  305. else {
  306. if (i.value > j->valueAt(s)) {
  307. if(continued) {
  308. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  309. }
  310. t=i.timeIntersect(*j);
  311. z->push_front(Sample(t,j->valueAt(t),j->derivative));
  312. z->push_front(i);
  313. }
  314. else {
  315. if(continued) {
  316. z->push_front(Sample(t,i.valueAt(t),i.derivative));
  317. }
  318. z->push_front(Sample(s,j->valueAt(s),j->derivative));
  319. }
  320. }
  321. }
  322. void computePartialOr(Signal * z, Signal::reverse_iterator & i, Signal::reverse_iterator & j, double s, double t) {
  323. while(i->time > s) {
  324. computeSegmentOr(z,*i,t,j);
  325. if (j->time == i->time) j++;
  326. t=i->time;
  327. i++;
  328. }
  329. if(i->time == s) computeSegmentOr(z, *i, t, j);
  330. else computeSegmentOr(z, Sample(s,i->valueAt(s),i->derivative), t, j);
  331. }
  332. /*---------------------------------------------------------------------------*
  333. * UNTIL SUBROUTINES *
  334. *---------------------------------------------------------------------------*/
  335. void computePartialEventually(Signal* z, Signal::reverse_iterator & i, double s, double t) {
  336. bool continued=false;
  337. double z_max=BOTTOM;
  338. while(i->time > s) {
  339. if(i->derivative >= 0) {
  340. if(z_max < i->valueAt(t)) {
  341. if(continued) {
  342. z->push_front(Sample(t,z_max,0));
  343. }
  344. z_max=i->valueAt(t);
  345. }
  346. continued=true;
  347. //z->push_front(Sample(i->time, z_max, 0));
  348. }
  349. else if(i->valueAt(t) >= z_max) {
  350. if(continued) {
  351. z->push_front(Sample(t,z_max,0));
  352. continued=false;
  353. }
  354. z_max=i->value;
  355. z->push_front(*i);
  356. }
  357. else if(z_max >= i->value) {
  358. continued=true;
  359. //z->push_front(Sample(i->time, z_max, 0));
  360. }
  361. else {
  362. z->push_front(Sample(i->time + (z_max-i->value)/i->derivative, z_max, 0)); //time at which y reaches value next_z
  363. z->push_front(*i);
  364. z_max=i->value;
  365. continued=false;
  366. }
  367. t=i->time;
  368. i++;
  369. }
  370. //leftmost sample *i may not be on s
  371. //"z_max" values of z are not longer "continued".
  372. if(i->derivative >= 0) {
  373. if(z_max < i->valueAt(t)) {
  374. if(continued) {
  375. z->push_front(Sample(t,z_max,0));
  376. }
  377. z_max=i->valueAt(t);
  378. }
  379. z->push_front(Sample(s, z_max, 0));
  380. }
  381. else if(i->valueAt(t) >= z_max) {
  382. if(continued) {
  383. z->push_front(Sample(t,z_max,0));
  384. }
  385. z->push_front(Sample(s, i->valueAt(s), i->derivative));
  386. }
  387. else if(z_max >= i->valueAt(s)) {
  388. z->push_front(Sample(s, z_max, 0));
  389. }
  390. else {
  391. z->push_front(Sample(s + (z_max-i->value)/i->derivative, z_max, 0)); //time at which y reaches value next_z
  392. z->push_front(Sample(s, i->valueAt(s), i->derivative));
  393. }
  394. }
  395. void computeSegmentUntil(Signal * z, const Sample & i, double t, Signal::reverse_iterator & j, double z_max) {
  396. Signal *z1, *z2, *z3;
  397. Signal::reverse_iterator k, l;
  398. double s=i.time;
  399. if(i.derivative <= 0) {
  400. z1=new Signal();
  401. computeSegmentAnd(z1, i, t, j);
  402. z2=new Signal();
  403. k=z1->rbegin();
  404. computePartialEventually(z2, k, s, t);
  405. delete z1;
  406. l=z2->rbegin();
  407. computeSegmentOr(z, Sample(s, fmin(z_max, i.valueAt(t)), 0), t, l);
  408. delete z2;
  409. }
  410. else {
  411. z1=new Signal();
  412. computePartialEventually(z1, j, s, t);
  413. z2=new Signal();
  414. k=z1->rbegin();
  415. computeSegmentAnd(z2, i, t, k);
  416. delete z1;
  417. z1=new Signal();
  418. z3=new Signal();
  419. z3->push_front(Sample(s, z_max, 0));
  420. k=z3->rbegin();
  421. computeSegmentAnd(z1, i, t, k);
  422. delete z3;
  423. k=z1->rbegin();
  424. l=z2->rbegin();
  425. computePartialOr(z, k, l, s, t);
  426. delete z1;
  427. delete z2;
  428. }
  429. }
  430. /*---------------------------------------------------------------------------*
  431. * TIMED UNTIL SUBROUTINES *
  432. *---------------------------------------------------------------------------*/
  433. //computation of the max induced by discontinuity points of x in t+(0,a]
  434. //a is assumed to be smaller than length of x.
  435. //based on Lemire algorithm for "streaming min-max filter"
  436. Signal * plateauMax(Signal * x, double a) {
  437. #ifdef DEBUG__
  438. cout << "Entering plateauMax" << endl;
  439. #endif
  440. bool new_candidate, end_candidate;
  441. double t, v;
  442. Signal::reverse_iterator j;
  443. Sequence M; //sorted in ascending times from front to back
  444. Sequence y; //maximum of x(t) and x(t-) at discontinuity points of x
  445. Sequence::iterator i;
  446. Signal * z=new Signal();
  447. z->beginTime=x->beginTime;
  448. z->endTime=x->endTime;
  449. //PRECOMPUTATION: list the local maximums of x
  450. t=x->endTime;
  451. v=BOTTOM;
  452. for(j=x->rbegin(); j!= x->rend(); j++) {
  453. y.push_front(Point(t, fmax(v,j->valueAt(t))));
  454. // cout << "y.time:" << y.front().time << " y->value:" << y.front().value << endl;
  455. t=j->time;
  456. v=j->value;
  457. }
  458. y.push_front(Point(x->front().time, x->front().value));
  459. //INIT: read values in [0, a)
  460. i=y.begin();
  461. while(i->time < x->beginTime + a) {
  462. while(!M.empty() && i->value >= M.back().value) {
  463. M.pop_back();
  464. }
  465. // cout << "i->time:" << i->time << " i->value:" << i->value << endl;
  466. M.push_back(*i);
  467. i++;
  468. }
  469. if(i->time == x->beginTime + a) new_candidate=true;
  470. else new_candidate=false;
  471. end_candidate=false;
  472. t=x->beginTime;
  473. // cout << "M.front " << M.front().value << endl;;
  474. //STEP
  475. bool cont=true;
  476. while(cont) {
  477. //UPDATE OF CANDIDATE LIST
  478. //candidate crosses t: remove it from list
  479. if(end_candidate) {
  480. // cout << "end_candidate: M.pop front" << endl;
  481. M.pop_front();
  482. }
  483. //sample crosses t+a: add it to candidate list
  484. if(new_candidate) {
  485. //cout << "new_candidate: doing stuff" << endl;
  486. while(!M.empty() && i->value >= M.back().value) {
  487. M.pop_back();
  488. }
  489. //detect if new maximum is found
  490. if(!M.empty()) {
  491. //if M non empty then t + a does not generate new maximum
  492. new_candidate=false;
  493. }
  494. //add candidate
  495. M.push_back(*i);
  496. //increment iterator
  497. i++;
  498. }
  499. //OUTPUT OF NEW MAXIMUM
  500. // cout << "Output new maximum" << endl;
  501. //no candidate
  502. if(M.empty()) {
  503. //cout << "No candidate" << endl;
  504. z->push_back(Sample(t, BOTTOM, 0));
  505. }
  506. //next best candidate
  507. else {
  508. z->push_back(Sample(t, M.front().value, 0));
  509. // cout << "Pushed " << M.front().value << endl;
  510. }
  511. //NEXT EVENT DETECTION
  512. if(! M.empty()) {
  513. if(i != y.end()) {
  514. if(i->time - a == M.front().time) {
  515. t=M.front().time;
  516. new_candidate=true;
  517. end_candidate=true;
  518. }
  519. else if(i->time - a < M.front().time) {
  520. t=i->time - a;
  521. new_candidate=true;
  522. end_candidate=false;
  523. }
  524. else { //M.back().time < i->time - a
  525. t=M.front().time;
  526. new_candidate=false;
  527. end_candidate=true;
  528. }
  529. }
  530. else {
  531. t=M.front().time;
  532. new_candidate=false;
  533. end_candidate=true;
  534. }
  535. }
  536. else {
  537. if(i != y.end()) {
  538. t=i->time - a;
  539. new_candidate=true;
  540. end_candidate=false;
  541. }
  542. else {
  543. new_candidate=false;
  544. end_candidate=false;
  545. }
  546. }
  547. cont = (new_candidate||end_candidate);
  548. }
  549. if(z->back().time==z->endTime) z->pop_back();
  550. return z;
  551. }
  552. //copy of plateauMax, operator < switched with operator >, TOP replaces BOTTOM
  553. Signal * plateauMin(Signal * x, double a) {
  554. bool new_candidate, end_candidate;
  555. double t, v;
  556. Signal::reverse_iterator j;
  557. Sequence M; //sorted in ascending times from front to back
  558. Sequence y; //minimum of x(t) and x(t-) at discontinuity points of x
  559. Sequence::iterator i;
  560. Signal * z=new Signal();
  561. z->beginTime=x->beginTime;
  562. z->endTime=x->endTime;
  563. //PRECOMPUTATION: list the local minimums of x
  564. t=x->endTime;
  565. v=TOP;
  566. for(j=x->rbegin(); j!= x->rend(); j++) {
  567. y.push_front(Point(t, fmin(v,j->valueAt(t))));
  568. t=j->time;
  569. v=j->value;
  570. }
  571. y.push_front(Point(x->front().time, x->front().value));
  572. //INIT: read values in [0, a)
  573. i=y.begin();
  574. while(i->time < x->beginTime + a) {
  575. while(!M.empty() && i->value <= M.back().value) {
  576. M.pop_back();
  577. }
  578. M.push_back(*i);
  579. i++;
  580. }
  581. if(i->time == x->beginTime + a) new_candidate=true;
  582. else new_candidate = false;
  583. end_candidate=false;
  584. t=x->beginTime;
  585. //STEP
  586. bool cont=true;
  587. while(cont) {
  588. //UPDATE OF CANDIDATE LIST
  589. //candidate crosses t: remove it from list
  590. if(end_candidate) {
  591. M.pop_front();
  592. }
  593. //sample crosses t+a: add it to candidate list
  594. if(new_candidate) {
  595. while(!M.empty() && i->value <= M.back().value) {
  596. M.pop_back();
  597. }
  598. //detect if new minimum is found
  599. if(!M.empty()) {
  600. //if M non empty then t + a does not generate new minimum
  601. new_candidate=false;
  602. }
  603. //add candidate
  604. M.push_back(*i);
  605. //increment iterator
  606. i++;
  607. }
  608. //OUTPUT OF NEW MINIMUM
  609. //no candidate
  610. if(M.empty()) {
  611. z->push_back(Sample(t, TOP, 0));
  612. }
  613. //next best candidate
  614. else {
  615. z->push_back(Sample(t, M.front().value, 0));
  616. }
  617. //NEXT EVENT DETECTION
  618. if(! M.empty()) {
  619. if(i != y.end()) {
  620. if(i->time - a == M.front().time) {
  621. t=M.front().time;
  622. new_candidate=true;
  623. end_candidate=true;
  624. }
  625. else if(i->time - a < M.front().time) {
  626. t=i->time - a;
  627. new_candidate=true;
  628. end_candidate=false;
  629. }
  630. else { //M.back().time < i->time - a
  631. t=M.front().time;
  632. new_candidate=false;
  633. end_candidate=true;
  634. }
  635. }
  636. else {
  637. t=M.front().time;
  638. new_candidate=false;
  639. end_candidate=true;
  640. }
  641. }
  642. else {
  643. if(i != y.end()) {
  644. t=i->time - a;
  645. new_candidate=true;
  646. end_candidate=false;
  647. }
  648. else {
  649. new_candidate=false;
  650. end_candidate=false;
  651. }
  652. }
  653. cont = (new_candidate||end_candidate);
  654. }
  655. if(z->back().time==z->endTime) z->pop_back();
  656. return z;
  657. }