CertainTrustSimple.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /**
  2. * CertainTrust SDK
  3. *
  4. * Implements the computational trust model "CertainTrust"
  5. * in Java.
  6. * See <http://www.tk.informatik.tu-darmstadt.de/de/research/smart-security-and-trust/> for further details.
  7. *
  8. *
  9. * Telecooperation Department, Technische Universit�t Darmstadt
  10. * <http://www.tk.informatik.tu-darmstadt.de/>
  11. *
  12. * Prof. Dr. Max Mühlhäuser <max@informatik.tu-darmstadt.de>
  13. * Florian Volk <florian.volk@cased.de>
  14. *
  15. *
  16. * @author Maria Pelevina
  17. * @author David Kalnischkies
  18. * @version 1.1
  19. */
  20. /* This Source Code Form is subject to the terms of the Mozilla Public
  21. * License, v. 2.0. If a copy of the MPL was not distributed with this
  22. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  23. package CertainTrust;
  24. import java.util.Observable;
  25. /**
  26. *
  27. * t - average rating value, [0; 1], from very negative to very positive
  28. * c - certainty value, [0; 1] from low certainty (no evidence) to the maximal maximal certainty.
  29. * f - initial trust value
  30. * w - weight
  31. * r - number of positive evidence
  32. * s - number of negative evidence
  33. * n - maximal number of expected evidence
  34. * doc - degree of conflict
  35. *
  36. */
  37. public class CertainTrustSimple extends Observable {
  38. private double c, t, f, r, s, doc;
  39. private int n = 1, weight = 2;
  40. //=========== Constructors =================
  41. /**
  42. * Constructs a CertainTrustSimple object with predefined n value.
  43. * @param n - maximal number of expected evidence
  44. */
  45. public CertainTrustSimple(int n) {
  46. if (n > 0) {
  47. this.n = n;
  48. c = 0;
  49. t = 0.5;
  50. f = 0.5;
  51. r = 0;
  52. s = 0;
  53. }
  54. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  55. }
  56. /**
  57. * Constructs a CertainTrustSimple object with predefined c, t, f, n values.
  58. * @param c - certainty
  59. * @param t - average rating
  60. * @param f - initial trust value
  61. */
  62. public CertainTrustSimple(double t, double c, double f) {
  63. this.f = f;
  64. setTC(t, c);
  65. }
  66. /**
  67. * Constructs a CertainTrustSimple object with predefined c, t, f, n values.
  68. * @param c - certainty
  69. * @param t - average rating
  70. * @param f - initial trust value
  71. * @param n - maximal number of expected evidence
  72. * @param doc - initial degree of conflict
  73. */
  74. private CertainTrustSimple(double t, double c, double f, double doc) {
  75. if (n > 0) {
  76. if (f <= 1 && f >= 0) {
  77. this.f = f;
  78. this.doc = doc;
  79. setTC(t, c);
  80. }
  81. else throw new IllegalArgumentException("f should lie within [0;1]. Entered f = " + f + "\n");
  82. }
  83. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  84. }
  85. //=========== Setters =================
  86. /**
  87. * Sets f value.
  88. * @param f - initial trust value.
  89. */
  90. public void setF(double f) {
  91. if (f >= 0 && f <= 1) {
  92. this.f = f;
  93. setChanged();
  94. notifyObservers();
  95. }
  96. else throw new IllegalArgumentException("f should lie within [0;1]. Entered f = " + f + "\n");
  97. }
  98. /**
  99. * Sets Distance of Conflict value.
  100. * @param doc is the new value for DoC
  101. */
  102. public void setDoC(double doc) {
  103. if (doc > 0) {
  104. this.doc = doc;
  105. }
  106. else throw new IllegalArgumentException("DoC should be greater than 0. Entered DoC = " + doc + "\n");
  107. }
  108. /**
  109. * Sets c and t values. Recalculates r and s values accordingly.
  110. * @param t - new average trust value
  111. * @param c - new certainty value
  112. */
  113. public void setTC(double t, double c) {
  114. if (c >= 0 && c <= 1) {
  115. if (t >= 0 && t <= 1) {
  116. this.c = c;
  117. this.t = t;
  118. setChanged();
  119. notifyObservers();
  120. }
  121. else throw new IllegalArgumentException("t should be greater than 0. Entered t = " + t + "\n");
  122. }
  123. else throw new IllegalArgumentException("c should lie within [0;1]. Entered c = " + c + "\n");
  124. }
  125. //=========== Internal Calculations ==========
  126. //=========== Getters =================
  127. public double getC() {
  128. return c;
  129. }
  130. public double getT() {
  131. return t;
  132. }
  133. public double getF() {
  134. return f;
  135. }
  136. public double getDoC() {
  137. return doc;
  138. }
  139. public double getExpectation() {
  140. return t*c + (1-c)*f;
  141. }
  142. //=========== Logic =================
  143. /**
  144. * Computes OR function for this CertainTrustSimple object and the specified argument. Result is returned as a new object,
  145. * argument and this CertainTrust object remain unchanged.
  146. * N values of both objects should be equal.
  147. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  148. * @param arg - CertainTrust object
  149. * @return - result of OR computation for this object and an argument.
  150. */
  151. private CertainTrustSimple OR(CertainTrustSimple arg){
  152. double c1 = getC();
  153. double t1 = getT();
  154. double f1 = getF();
  155. double c2 = arg.getC();
  156. double t2 = arg.getT();
  157. double f2 = arg.getF();
  158. double resT = 0.5, resF = 0.5, resC = 0;
  159. // if (this.getN() != arg.getN())
  160. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  161. resF = f1 + f2 - f1*f2;
  162. if (almostEqual(resF, 0))
  163. resC = c1 + c2 - c1*c2;
  164. else
  165. resC = c1 + c2 - c1*c2 - (c1*f2*(1-c2)*(1-t1)+c2*f1*(1-c1)*(1-t2)) / resF;
  166. if (almostEqual(resC, 0))
  167. resT = 0.5;
  168. else resT = (1/resC) * (c1*t1 + c2*t2 - c1*c2*t1*t2);
  169. resT = adjustValue(resT);
  170. resC = adjustValue(resC);
  171. resF = adjustValue(resF);
  172. CertainTrustSimple result = new CertainTrustSimple(resT, resC, resF,0);
  173. return result;
  174. }
  175. /**
  176. * Computes OR function for this CertainTrustSimple object and the specified arguments.
  177. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  178. * Example: a.OR(b, c, d) returns new CertainTrust object that equals a OR b OR c OR d.
  179. * Multiple arguments allowed, but not less than one.
  180. * N values of all objects should be equal.
  181. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  182. * @param args - arguments
  183. * @return - result of OR computation for this object and all arguments.
  184. */
  185. public CertainTrustSimple OR(CertainTrustSimple ...args) {
  186. CertainTrustSimple result = clone();
  187. for (CertainTrustSimple m: args) {
  188. // if (n != m.getN())
  189. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  190. result = result.OR(m);
  191. }
  192. return result;
  193. }
  194. /**
  195. * Computes AND function for this CertainTrustSimple object and the specified argument. Result is returned as a new object,
  196. * argument and this CertainTrust object remain unchanged.
  197. * N values of both objects should be equal.
  198. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  199. * @param arg - CertainTrust object
  200. * @return - result of AND computation for this object and an argument.
  201. */
  202. private CertainTrustSimple AND(CertainTrustSimple arg){
  203. double c1 = getC();
  204. double f1 = getF();
  205. double t1 = getT();
  206. double c2 = arg.getC();
  207. double f2 = arg.getF();
  208. double t2 = arg.getT();
  209. double resC = 0, resT = 0.5, resF = 0.5;
  210. // if (n != arg.getN())
  211. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  212. resF = f1*f2;
  213. if (almostEqual(resF, 1)) //avoid division by 0
  214. resC = c1 + c2 - c1*c2;
  215. else
  216. resC = c1 + c2 - c1*c2 - (c2*t2*(1-c1)*(1-f1)+c1*t1*(1-c2)*(1-f2)) / (1 - resF);
  217. if (almostEqual(resC, 0))
  218. resT = 0.5;
  219. else if (almostEqual(resF, 1)) //avoid division by 0
  220. resT = (1/resC) * (c1*t1*c2*t2);
  221. else resT = (1/resC) * ((c1*t1*c2*t2) + (c1*f2*t1*(1-c2)*(1-f1)+c2*f1*t2*(1-c1)*(1-f2)) / (1 - resF));
  222. resT = adjustValue(resT);
  223. resC = adjustValue(resC);
  224. resF = adjustValue(resF);
  225. CertainTrustSimple result = new CertainTrustSimple(resT, resC, resF,0);
  226. return result;
  227. }
  228. /**
  229. * Computes AND function for this CertainTrustSimple object and the specified arguments.
  230. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  231. * Example: a.AND(b, c, d) returns new CertainTrust object that equals a AND b AND c AND d.
  232. * Multiple arguments allowed, but not less than one.
  233. * N values of all objects should be equal.
  234. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  235. * @param args - arguments
  236. * @return - result of AND computation for this object and all arguments.
  237. */
  238. public CertainTrustSimple AND(CertainTrustSimple ...args) {
  239. CertainTrustSimple result = clone();
  240. for (CertainTrustSimple m: args) {
  241. // if (n != m.getN())
  242. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  243. result = result.AND(m);
  244. }
  245. return result;
  246. }
  247. /**
  248. * Returns NOT of this CertainTrustSimple object.
  249. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  250. * @return - NOT of this CertainTrustSimple object.
  251. */
  252. public CertainTrustSimple NOT(){
  253. return new CertainTrustSimple(getC(), adjustValue(1 - getT()), adjustValue(1 - getF()));
  254. }
  255. /**
  256. * an internal implementation of fusion function.
  257. * Is called by wFusion and cFusion
  258. * @param args - an array of CertainTrustSimple objects
  259. * @param weights - an integer array of corresponding weights
  260. * @param doc - a degree of conflict (always 0 for wFusion)
  261. * @return - new CertainTrustSimple object
  262. */
  263. private static CertainTrustSimple internalFusion(CertainTrustSimple[] args, int[] weights, double doc) {
  264. double resC, resT, resF;
  265. boolean allOne = true;
  266. boolean allZero = true;
  267. boolean allWeightsZero = true;
  268. boolean atLeastOne1 = false;
  269. int arrLength = args.length;
  270. // set the flags about C and Weight values
  271. for (int i = 0; i < arrLength; i++)
  272. if (args[i].getC() != 1) {
  273. allOne = false;
  274. i = arrLength;
  275. }
  276. for (int i = 0; i < arrLength; i++)
  277. if (args[i].getC() != 0) {
  278. allZero = false;
  279. i = arrLength;
  280. }
  281. for (int i = 0; i < arrLength; i++)
  282. if (weights[i] != 0) {
  283. allWeightsZero = false;
  284. i = arrLength;
  285. }
  286. for (int i = 0; i < arrLength; i++)
  287. if (args[i].getC() == 1) {
  288. atLeastOne1 = true;
  289. i = arrLength;
  290. }
  291. //Calculate T and C
  292. // 1. all C's = 1
  293. if (allOne) {
  294. // set C
  295. resC = 1 * (1 - doc);
  296. // set T
  297. if (allWeightsZero) {// save some calculation time
  298. resT = 0;
  299. }
  300. else { // or use the function
  301. double numeratorT = 0, denominatorT = 0;
  302. for (int i = 0; i < arrLength; i++) {
  303. numeratorT += weights[i] * args[i].getT();
  304. denominatorT += weights[i];
  305. }
  306. resT = numeratorT/denominatorT;
  307. }
  308. }
  309. else {
  310. if (atLeastOne1)
  311. throw new IllegalStateException("Illeagal arguments. Either all C values must equal 1 or none of them. Operation not allowed \n");
  312. // 2. Any other combination
  313. if (allWeightsZero) { // save some calculation time
  314. resT = 0;
  315. resC = 0;
  316. }
  317. else { // or use the function
  318. double numeratorT = 0, denominatorT = 0, numeratorC = 0, denominatorC = 0, mult;
  319. for (int i = 0; i < arrLength; i++) {
  320. mult = 1;
  321. for (int j = 0; j < arrLength; j++) // Count the product for each sum element
  322. if (j != i)
  323. mult *= 1 - args[j].getC();
  324. numeratorT += weights[i] * args[i].getT() * args[i].getC() * mult;
  325. denominatorT += weights[i] * args[i].getC() * mult;
  326. denominatorC += weights[i] * mult;
  327. }
  328. numeratorC = denominatorT;
  329. resC = (numeratorC/denominatorC) * (1 - doc);
  330. if (allZero)
  331. resT = 0.5;
  332. else
  333. resT = numeratorT/denominatorT;
  334. }
  335. // Special case for T
  336. if (allZero)
  337. resT = 0.5;
  338. }
  339. // Calculate F
  340. if (allWeightsZero)
  341. resF = 0;
  342. else {
  343. double numerator = 0, denominator = 0;
  344. for (int i = 0; i < arrLength; i ++) {
  345. numerator += weights[i] * args[i].getF();
  346. denominator += weights[i];
  347. }
  348. resF = numerator/denominator;
  349. }
  350. return new CertainTrustSimple(resT, resC, resF, doc);
  351. }
  352. /**
  353. * Performs weighted fusion for an array of CertainTrustSimple objects in correspondence with
  354. * an array of weights. Returns new CertainTrust object.
  355. * Requirements: N values of CertainTrust objects must be equal.
  356. * Number of weights should equal the number of CertainTrustSimple objects.
  357. * Arrays must be non-empty
  358. * Either all of CertainTrustSimple must be of certainty 1 or none of them.
  359. * @param args - an array of CertainTrustSimple objects
  360. * @param weights - an integer array of corresponding weights
  361. * @return - new CertainTrustSimple object
  362. */
  363. public static CertainTrustSimple wFusion(CertainTrustSimple[] args, int[] weights) {
  364. //arrays should be equal
  365. if (args.length == weights.length) {
  366. //and not empty
  367. if (args.length != 0) {
  368. boolean equalNs = true;
  369. // int N = args[0].getN();
  370. for (int i = 1; i < args.length; i++)
  371. // if (N != args[i].getN()) {
  372. equalNs = false;
  373. // i = args.length;
  374. // }
  375. //and all N's of TC's must be equal
  376. if (equalNs) {
  377. return internalFusion(args, weights, 0);
  378. }
  379. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  380. }
  381. throw new IllegalStateException("Arrays are empty. Operation not allowed. \n");
  382. }
  383. throw new IllegalStateException("Different lengths of arrays. Operation not allowed. \n");
  384. }
  385. /**
  386. * Conflicted Fusion is a variation of weighted fusion, which additionally computes the degree of conflict
  387. * between given opinions (CertainTrustSimple objects) and takes it into consideration while performing fusion.
  388. * The degree of conflict is then saved in the resulting CertainTrustSimple object and may be checked with getDoC() function.
  389. * @param args - an array of CertainTrustSimple objects
  390. * @param weights - an integer array of corresponding weights
  391. * @return - new CertainTrustSimple object
  392. */
  393. public static CertainTrustSimple cFusion(CertainTrustSimple[] args, int[] weights) {
  394. //arrays should be equal
  395. if (args.length == weights.length) {
  396. //and not empty
  397. if (args.length != 0) {
  398. boolean equalNs = true;
  399. // int N = args[0].getN();
  400. // for (int i = 1; i < args.length; i++)
  401. // if (N != args[i].getN()) {
  402. equalNs = false;
  403. // i = args.length;
  404. // }
  405. //and all N's of TC's must be equal
  406. if (equalNs) {
  407. double denominator = args.length*(args.length - 1) / 2;
  408. double numerator = 0;
  409. for (int i = 0; i < args.length; i++)
  410. for (int j = i; j < args.length; j++)
  411. numerator += Math.abs(args[i].getT() - args[j].getT()) * args[i].getC() * args[j].getC()*(1 - Math.abs((double)(weights[i] - weights[j])/(weights[i] + weights[j])));
  412. double doc = numerator/denominator;
  413. return internalFusion(args, weights, doc);
  414. }
  415. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  416. }
  417. throw new IllegalStateException("Arrays are empty. Operation not allowed. \n");
  418. }
  419. throw new IllegalStateException("Different lengths of arrays. Operation not allowed. \n");
  420. }
  421. /**
  422. * Computes CONSENSUS function for this CertainTrustSimple object and the specified argument. Result is returned as a new object,
  423. * argument and this CertainTrustSimple object remain unchanged.
  424. * N values of both objects should be equal.
  425. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  426. * @param arg - CertainTrustSimple object
  427. * @return - result of CONSENSUS computation for this object and an argument.
  428. */
  429. private CertainTrustSimple CONSENSUS(CertainTrustSimple arg){
  430. double c1 = getC();
  431. double f1 = getF();
  432. double t1 = getT();
  433. double c2 = arg.getC();
  434. double f2 = arg.getF();
  435. double t2 = arg.getT();
  436. double resC = 0, resT = 0.5, resF = 0.5;
  437. // if (n != arg.getN())
  438. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  439. //resF = f1*f2;
  440. if (almostEqual(resF, 1)) //avoid division by 0
  441. resC = (c1+c2-2*c1*c2)/(1-c1*c2);
  442. else
  443. resC = (c1+c2-2*c1*c2)/(1-c1*c2);
  444. if (almostEqual(resC, 0))
  445. resT = 0.5;
  446. else if (almostEqual(resF, 1)) //avoid division by 0
  447. resT = (c1*t1*(1-c2)+c2*t2*(1-c1))/(c1*(1-c2)+c2*(1-c1));
  448. else resT = (c1*t1*(1-c2)+c2*t2*(1-c1))/(c1*(1-c2)+c2*(1-c1));
  449. resT = adjustValue(resT);
  450. resC = adjustValue(resC);
  451. resF = adjustValue(resF);
  452. CertainTrustSimple result = new CertainTrustSimple(resT, resC, resF, 0);
  453. return result;
  454. }
  455. /**
  456. * Computes CONSENSUS function for this CertainTrustSimple object and the specified arguments.
  457. * Result is returned as a new object, arguments and this CertainTrustSimple object remain unchanged.
  458. * Example: a.CONSENSUS(b, c, d) returns new CertainTrustSimple object that equals a CONSENSUS b CONSENSUS c CONSENSUS d.
  459. * Multiple arguments allowed, but not less than one.
  460. * N values of all objects should be equal.
  461. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  462. * @param args - arguments
  463. * @return - result of CONSENSUS computation for this object and all arguments.
  464. */
  465. public CertainTrustSimple CONSENSUS(CertainTrustSimple ...args) {
  466. CertainTrustSimple result = clone();
  467. for (CertainTrustSimple m: args) {
  468. // if (n != m.getN())
  469. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  470. result = result.CONSENSUS(m);
  471. }
  472. return result;
  473. }
  474. /**
  475. * Computes DISCOUNTING function for this CertainTrustSimple object and the specified argument. Result is returned as a new object,
  476. * argument and this CertainTrustSimple object remain unchanged.
  477. * N values of both objects should be equal.
  478. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  479. * @param arg - CertainTrust object
  480. * @return - result of DISCOUNTING computation for this object and an argument.
  481. */
  482. private CertainTrustSimple DISCOUNTING(CertainTrustSimple arg){
  483. double c1 = getC();
  484. double f1 = getF();
  485. double t1 = getT();
  486. double c2 = arg.getC();
  487. double f2 = arg.getF();
  488. double t2 = arg.getT();
  489. double resC = 0, resT = 0.5, resF = 0.5;
  490. // if (n != arg.getN())
  491. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  492. //resF = f1*f2;
  493. if (almostEqual(resF, 1))
  494. resC = t1*c1*c2;
  495. else
  496. resC = t1*c1*c2;
  497. if (almostEqual(resC, 0))
  498. resT = 0.5;
  499. else if (almostEqual(resF, 1))
  500. resT = t2;
  501. else resT = t2;
  502. resT = adjustValue(resT);
  503. resC = adjustValue(resC);
  504. resF = adjustValue(resF);
  505. CertainTrustSimple result = new CertainTrustSimple(resT, resC, resF, 0);
  506. return result;
  507. }
  508. /**
  509. * Computes DISCOUNTING function for this CertainTrust object and the specified arguments.
  510. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  511. * Example: a.DISCOUNTING(b, c, d) returns new CertainTrust object that equals a DISCOUNTING b DISCOUNTING c DISCOUNTING d.
  512. * Multiple arguments allowed, but not less than one.
  513. * N values of all objects should be equal.
  514. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  515. * @param args - arguments
  516. * @return - result of DISCOUNTING computation for this object and all arguments.
  517. */
  518. public CertainTrustSimple DISCOUNTING(CertainTrustSimple ...args) {
  519. CertainTrustSimple result = clone();
  520. for (CertainTrustSimple m: args) {
  521. // if (n != m.getN())
  522. // throw new IllegalStateException("Different N values. Operation not allowed. \n");
  523. result = result.DISCOUNTING(m);
  524. }
  525. return result;
  526. }
  527. //=========== Additional Functions =================
  528. @Override
  529. public CertainTrustSimple clone() {
  530. CertainTrustSimple copy = new CertainTrustSimple(n);
  531. copy.c = this.c;
  532. copy.t = this.t;
  533. copy.f = this.f;
  534. copy.r = this.r;
  535. copy.s = this.s;
  536. copy.doc = this.doc;
  537. return copy;
  538. }
  539. /**
  540. * Adjusts the value of a into the allowed range [0,1].
  541. * @param a - value to be adjusted
  542. */
  543. private double adjustValue(double a) {
  544. return Math.max(Math.min(a, 1), 0);
  545. }
  546. /**
  547. * compares two double values using an epsilon
  548. * @param value - given value
  549. * @param target - expected value
  550. * @return
  551. */
  552. private boolean almostEqual(double value, double target) {
  553. return Math.abs(value - target) < 1E-10;
  554. }
  555. }