2
0

TestMathLong.Mos 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. MODULE TestMathLong;
  2. IMPORT
  3. SYSTEM, OFS, Tools, Log, Minos, Kernel, Math, FPE64, Platform;
  4. CONST
  5. eps = 1.1920929E-7;
  6. eps3 = 3.5762787E-7;
  7. eps4 = 4.7683716E-7;
  8. eps9 = 10.728836E-7;
  9. eps31 = 3.6954880E-6;
  10. epsD = 1.1920929D-7;
  11. TYPE
  12. Command = POINTER TO CommandDesc;
  13. CompareHandler = PROCEDURE(): BOOLEAN;
  14. CalcHandler = PROCEDURE();
  15. ShowHandler = PROCEDURE(cmd: Command);
  16. CommandDesc = RECORD
  17. name: ARRAY 12 OF CHAR;
  18. partypes: ARRAY 12 OF CHAR;
  19. restype: ARRAY 4 OF CHAR;
  20. calc: CalcHandler;
  21. compare: CompareHandler;
  22. show: ShowHandler;
  23. n, ok: LONGINT;
  24. next: Command;
  25. END;
  26. ResultDesc = RECORD
  27. single: REAL;
  28. boolean: BOOLEAN;
  29. int: LONGINT;
  30. double: LONGREAL;
  31. END;
  32. VAR
  33. filenames: ARRAY 2, 20 OF CHAR;
  34. rd: OFS.Rider;
  35. cmds: Command;
  36. singlepar: ARRAY 2 OF REAL;
  37. intpar: LONGINT;
  38. doublepar: ARRAY 2 OF LONGREAL;
  39. trueres: ResultDesc;
  40. calcres: ResultDesc;
  41. (* single precision operations *)
  42. PROCEDURE CalcABS(); BEGIN calcres.single := ABS(singlepar[0]) END CalcABS;
  43. PROCEDURE CalcNEG(); BEGIN calcres.single := -singlepar[0] END CalcNEG;
  44. PROCEDURE CalcADD(); BEGIN calcres.single := singlepar[0]+singlepar[1] END CalcADD;
  45. PROCEDURE CalcSUB(); BEGIN calcres.single := singlepar[0]-singlepar[1] END CalcSUB;
  46. PROCEDURE CalcMUL(); BEGIN calcres.single := singlepar[0]*singlepar[1] END CalcMUL;
  47. PROCEDURE CalcDIV(); BEGIN calcres.single := singlepar[0]/singlepar[1] END CalcDIV;
  48. PROCEDURE CalcENTIER(); BEGIN calcres.int := ENTIER(singlepar[0]) END CalcENTIER;
  49. PROCEDURE CalcREAL(); BEGIN calcres.single := REAL(intpar) END CalcREAL;
  50. PROCEDURE CalcGREATER(); BEGIN calcres.boolean := (singlepar[0]>singlepar[1]) END CalcGREATER;
  51. PROCEDURE CalcLOWER(); BEGIN calcres.boolean := (singlepar[0]<singlepar[1]) END CalcLOWER;
  52. PROCEDURE CalcSIN(); BEGIN calcres.single := Math.Sin(singlepar[0]) END CalcSIN;
  53. PROCEDURE CalcCOS(); BEGIN calcres.single := Math.Cos(singlepar[0]) END CalcCOS;
  54. PROCEDURE CalcSQRT(); BEGIN calcres.single := Math.Sqrt(singlepar[0]) END CalcSQRT;
  55. PROCEDURE CalcEXP(); BEGIN calcres.single := Math.Exp(singlepar[0]) END CalcEXP;
  56. PROCEDURE CalcLN(); BEGIN calcres.single := Math.Ln(singlepar[0]) END CalcLN;
  57. PROCEDURE CalcARCTAN(); BEGIN calcres.single := Math.Arctan(singlepar[0]) END CalcARCTAN;
  58. PROCEDURE CalcARCTAN2(); BEGIN calcres.single := Math.Arctan2(singlepar[0], singlepar[1]) END CalcARCTAN2;
  59. (* double precision operations *)
  60. PROCEDURE CalcABSD(); BEGIN calcres.double := ABS(doublepar[0]) END CalcABSD;
  61. PROCEDURE CalcNEGD(); BEGIN calcres.double := -doublepar[0] END CalcNEGD;
  62. PROCEDURE CalcADDD(); BEGIN calcres.double := doublepar[0] + doublepar[1] END CalcADDD;
  63. PROCEDURE CalcSUBD(); BEGIN calcres.double := doublepar[0] - doublepar[1] END CalcSUBD;
  64. PROCEDURE CalcMULD(); BEGIN calcres.double := doublepar[0]*doublepar[1] END CalcMULD;
  65. PROCEDURE CalcDIVD(); BEGIN calcres.double := doublepar[0]/doublepar[1] END CalcDIVD;
  66. PROCEDURE CalcLOWERD(); BEGIN calcres.boolean := doublepar[0] < doublepar[1] END CalcLOWERD;
  67. PROCEDURE CalcFLOATD(); BEGIN calcres.double := intpar END CalcFLOATD;
  68. PROCEDURE CalcFIXD(); BEGIN calcres.int := ENTIER(doublepar[0]) END CalcFIXD;
  69. PROCEDURE CalcSINGLED(); BEGIN calcres.single := REAL(doublepar[0]) END CalcSINGLED;
  70. PROCEDURE CalcDOUBLED(); BEGIN calcres.double := singlepar[0] END CalcDOUBLED;
  71. PROCEDURE GetRelativeError(a, b: REAL): REAL;
  72. BEGIN
  73. IF b # 0.0 THEN
  74. a := ABS(a/b) - 1.0;
  75. END;
  76. RETURN ABS(a);
  77. END GetRelativeError;
  78. PROCEDURE CompareR(): BOOLEAN; BEGIN RETURN calcres.single = trueres.single END CompareR;
  79. PROCEDURE CompareB(): BOOLEAN; BEGIN RETURN calcres.boolean = trueres.boolean END CompareB;
  80. PROCEDURE CompareI(): BOOLEAN; BEGIN RETURN calcres.int = trueres.int END CompareI;
  81. PROCEDURE CompareLR(): BOOLEAN; BEGIN RETURN calcres.double = trueres.double END CompareLR;
  82. PROCEDURE CompareAbsolute4eps(): BOOLEAN;
  83. BEGIN
  84. RETURN ABS(calcres.single - trueres.single) <= eps4;
  85. END CompareAbsolute4eps;
  86. PROCEDURE CompareRelative1eps(): BOOLEAN;
  87. BEGIN
  88. RETURN GetRelativeError(calcres.single, trueres.single) <= eps;
  89. END CompareRelative1eps;
  90. PROCEDURE CompareRelative3eps(): BOOLEAN;
  91. BEGIN
  92. RETURN GetRelativeError(calcres.single, trueres.single) <= eps3;
  93. END CompareRelative3eps;
  94. PROCEDURE CompareRelative9eps(): BOOLEAN;
  95. BEGIN
  96. RETURN GetRelativeError(calcres.single, trueres.single) <= eps9;
  97. END CompareRelative9eps;
  98. PROCEDURE CompareRelative31eps(): BOOLEAN;
  99. BEGIN
  100. RETURN GetRelativeError(calcres.single, trueres.single) <= eps31;
  101. END CompareRelative31eps;
  102. PROCEDURE CompareRelative1epsLR(): BOOLEAN;
  103. VAR x0, y0: LONGREAL;
  104. BEGIN
  105. x0 := calcres.double;
  106. y0 := trueres.double;
  107. IF ABS(x0-y0) <= epsD THEN RETURN TRUE;
  108. ELSE RETURN FALSE;
  109. END;
  110. END CompareRelative1epsLR;
  111. PROCEDURE ShowRR(cmd: Command);
  112. BEGIN
  113. Log.S(cmd.name); Log.S("("); Log.R(singlepar[0]); Log.S(") ="); Log.RL(calcres.single);
  114. Log.S(" TRUE RESULT: "); Log.R(trueres.single);
  115. Log.S(" ERR: abs:"); Log.R(ABS(calcres.single-trueres.single));
  116. Log.S(" rel:"); Log.RL(GetRelativeError(calcres.single, trueres.single));
  117. END ShowRR;
  118. PROCEDURE ShowRRR(cmd: Command);
  119. BEGIN
  120. Log.S(cmd.name); Log.S(" "); Log.R(singlepar[0]); Log.S(" "); Log.R(singlepar[1]);
  121. Log.S(" "); Log.R(calcres.single);
  122. Log.S(" ("); Log.R(trueres.single); Log.SL(")");
  123. END ShowRRR;
  124. PROCEDURE ShowIR(cmd: Command);
  125. BEGIN
  126. Log.S(cmd.name); Log.S(" "); Log.I(intpar); Log.S(" ");
  127. Log.S(" "); Log.R(calcres.single);
  128. Log.S(" ("); Log.R(trueres.single); Log.SL(")");
  129. END ShowIR;
  130. PROCEDURE ShowLR(a: LONGREAL);
  131. VAR x: FPE64.Float64;
  132. BEGIN
  133. x := SYSTEM.VAL(FPE64.Float64, a);
  134. Log.H(x.high); Log.H(x.low);
  135. END ShowLR;
  136. PROCEDURE ShowLRLRLR(cmd: Command);
  137. BEGIN
  138. Log.S(cmd.name); Log.S(" ");
  139. ShowLR(doublepar[0]); Log.S(" ");
  140. ShowLR(doublepar[1]); Log.S(" ");
  141. ShowLR(calcres.double); Log.S(" ");
  142. Log.S(" (");
  143. ShowLR(trueres.double);
  144. Log.SL(")")
  145. END ShowLRLRLR;
  146. PROCEDURE ShowLRR(cmd: Command);
  147. BEGIN
  148. Log.S(cmd.name); Log.S(" ");
  149. ShowLR(doublepar[0]); Log.S(" ");
  150. Log.R(calcres.single); Log.S(" ");
  151. Log.S(" (");
  152. Log.R(trueres.single);
  153. Log.SL(")")
  154. END ShowLRR;
  155. PROCEDURE ShowRLR(cmd: Command);
  156. BEGIN
  157. Log.S(cmd.name); Log.S(" ");
  158. Log.R(singlepar[0]); Log.S(" ");
  159. ShowLR(calcres.double); Log.S(" ");
  160. Log.S(" (");
  161. ShowLR(trueres.double);
  162. Log.SL(")")
  163. END ShowRLR;
  164. PROCEDURE ShowLogDate();
  165. VAR ch: CHAR;
  166. BEGIN
  167. OFS.Read(rd, ch);
  168. WHILE ch # 0X DO
  169. Log.C(ch);
  170. OFS.Read(rd, ch);
  171. END;
  172. Log.L;
  173. Log.L;
  174. END ShowLogDate;
  175. PROCEDURE GetCommandName(VAR s: ARRAY OF CHAR);
  176. VAR ch: CHAR; i: LONGINT;
  177. BEGIN
  178. i := 0;
  179. REPEAT
  180. OFS.Read(rd, ch);
  181. s[i] := CAP(ch);
  182. INC(i);
  183. UNTIL (ch = 0X) OR (i = LEN(s));
  184. s[i-1] := 0X;
  185. END GetCommandName;
  186. PROCEDURE ReadParameters(VAR s: ARRAY OF CHAR);
  187. VAR i, ir, ilr: LONGINT;
  188. BEGIN
  189. ir := 0;
  190. ilr := 0;
  191. i := 0;
  192. WHILE (i < LEN(s)) & (s[i] # 0X) DO
  193. IF s[i] = 'r' THEN
  194. OFS.ReadReal(rd, singlepar[ir]);
  195. INC(ir);
  196. ELSIF s[i] = 'i' THEN
  197. OFS.ReadInt(rd, intpar);
  198. ELSIF s[i] = 'l' THEN
  199. INC(i);
  200. IF s[i] = 'r' THEN
  201. OFS.ReadBytes(rd, doublepar[ilr], 8);
  202. INC(ilr);
  203. END;
  204. END;
  205. INC(i);
  206. END;
  207. END ReadParameters;
  208. PROCEDURE ReadResult(VAR s: ARRAY OF CHAR);
  209. VAR ch: CHAR;
  210. BEGIN
  211. IF s = "r" THEN
  212. OFS.ReadReal(rd, trueres.single);
  213. ELSIF s = "b" THEN
  214. OFS.Read(rd, ch);
  215. trueres.boolean := (ch # 0X);
  216. ELSIF s = "i" THEN
  217. OFS.ReadInt(rd, trueres.int);
  218. ELSIF s = "lr" THEN
  219. OFS.ReadBytes(rd, trueres.double, 8);
  220. END;
  221. END ReadResult;
  222. PROCEDURE Run*;
  223. VAR
  224. f: OFS.File;
  225. name: ARRAY 12 OF CHAR;
  226. n, ok, i: LONGINT;
  227. cmd: Command;
  228. t, dt: LONGINT;
  229. BEGIN
  230. dt := 0;
  231. FOR i := 0 TO LEN(filenames, 0)-1 DO
  232. f := Tools.RemoteReadFile(filenames[i]);
  233. IF f # NIL THEN
  234. OFS.Set(rd, f, 0);
  235. ShowLogDate;
  236. WHILE ~rd.eof DO
  237. GetCommandName(name);
  238. IF name # "" THEN
  239. cmd := cmds;
  240. WHILE (cmd # NIL) & (name # cmd.name) DO
  241. cmd := cmd.next;
  242. END;
  243. IF cmd = NIL THEN
  244. Log.SL("Unknown Command!");
  245. ELSE
  246. INC(cmd.n);
  247. ReadParameters(cmd.partypes);
  248. ReadResult(cmd.restype);
  249. t := Kernel.GetOSTimer();
  250. cmd.calc();
  251. dt := dt + (Kernel.GetOSTimer() - t);
  252. IF cmd.compare() THEN
  253. INC(cmd.ok);
  254. ELSIF cmd.show # NIL THEN
  255. cmd.show(cmd);
  256. Kernel.MilliWait(50);
  257. END;
  258. END;
  259. END;
  260. END;
  261. OFS.Close(f);
  262. ELSE
  263. Log.S("Cannot read the file ");
  264. Log.S(filenames[i]);
  265. Log.SL(".");
  266. END;
  267. END;
  268. n := 0;
  269. ok := 0;
  270. Log.L; Log.SL("Command: ok / n");
  271. cmd := cmds;
  272. WHILE cmd # NIL DO
  273. n := n + cmd.n;
  274. ok := ok + cmd.ok;
  275. IF cmd.n > 0 THEN
  276. Log.S(cmd.name);
  277. Log.S(": ");
  278. Log.I(cmd.ok);
  279. Log.S(" / ");
  280. Log.IL(cmd.n);
  281. END;
  282. cmd := cmd.next;
  283. END;
  284. Log.L; Log.S("Number of tests: "); Log.IL(n);
  285. Log.S("Successful: "); Log.IL(ok);
  286. Log.S("Unsuccessful: "); Log.IL(n-ok); Log.L;
  287. Log.S("Calculation time [ms]: ");
  288. Log.RL(REAL(dt)/REAL(Platform.CLOCKDIVISOR)*10.0);
  289. Kernel.MilliWait(1000);
  290. Minos.Reset;
  291. END Run;
  292. PROCEDURE InitCmd(CONST name, partypes: ARRAY 12 OF CHAR; restype: ARRAY 4 OF CHAR;
  293. calc: CalcHandler; compare: CompareHandler; show: ShowHandler);
  294. VAR c: Command;
  295. BEGIN
  296. NEW(c);
  297. c.next := cmds;
  298. c.name := name;
  299. c.partypes := partypes;
  300. c.restype := restype;
  301. c.calc := calc;
  302. c.compare := compare;
  303. c.show := show;
  304. c.n := 0;
  305. c.ok := 0;
  306. cmds := c;
  307. END InitCmd;
  308. BEGIN
  309. cmds := NIL;
  310. (* single precision commands *)
  311. InitCmd("ABS", "r", "r", CalcABS, CompareR, ShowRR);
  312. InitCmd("NEG", "r", "r", CalcNEG, CompareR, ShowRR);
  313. InitCmd("ADD", "rr", "r", CalcADD, CompareRelative1eps, ShowRRR);
  314. InitCmd("SUB", "rr", "r", CalcSUB, CompareRelative1eps, ShowRRR);
  315. InitCmd("MUL", "rr", "r", CalcMUL, CompareRelative1eps, ShowRRR);
  316. InitCmd("DIV", "rr", "r", CalcDIV, CompareRelative1eps, ShowRRR);
  317. InitCmd("ENTIER", "r", "i", CalcENTIER, CompareI, NIL);
  318. InitCmd("REAL", "i", "r", CalcREAL, CompareRelative1eps, ShowIR);
  319. InitCmd("GREATER", "rr", "b", CalcGREATER, CompareB, NIL);
  320. InitCmd("LOWER", "rr", "b", CalcLOWER, CompareB, NIL);
  321. InitCmd("SIN", "r", "r", CalcSIN, CompareAbsolute4eps, ShowRR);
  322. InitCmd("COS", "r", "r", CalcCOS, CompareAbsolute4eps, ShowRR);
  323. InitCmd("SQRT", "r", "r", CalcSQRT, CompareRelative1eps, ShowRR);
  324. InitCmd("EXP", "r", "r", CalcEXP, CompareRelative31eps, ShowRR);
  325. InitCmd("LN", "r", "r", CalcLN, CompareRelative9eps, ShowRR);
  326. InitCmd("ARCTAN", "r", "r", CalcARCTAN, CompareRelative3eps, ShowRR);
  327. InitCmd("ARCTAN2", "rr", "r", CalcARCTAN2, CompareRelative3eps, ShowRRR);
  328. (* double precision commands *)
  329. InitCmd("ABSD", "lr", "lr", CalcABSD, CompareLR, NIL);
  330. InitCmd("NEGD", "lr", "lr", CalcNEGD, CompareLR, NIL);
  331. InitCmd("ADDD", "lrlr", "lr", CalcADDD, CompareRelative1epsLR, ShowLRLRLR);
  332. InitCmd("SUBD", "lrlr", "lr", CalcSUBD, CompareRelative1epsLR, ShowLRLRLR);
  333. InitCmd("MULD", "lrlr", "lr", CalcMULD, CompareRelative1epsLR, ShowLRLRLR);
  334. InitCmd("DIVD", "lrlr", "lr", CalcDIVD, CompareLR, ShowLRLRLR);
  335. InitCmd("LOWERD", "lrlr", "b", CalcLOWERD, CompareB, NIL);
  336. InitCmd("FLOATD", "i", "lr", CalcFLOATD, CompareLR, NIL);
  337. InitCmd("FIXD", "lr", "i", CalcFIXD, CompareI, NIL);
  338. InitCmd("SINGLED", "lr", "r", CalcSINGLED, CompareR, ShowLRR);
  339. InitCmd("DOUBLED", "r", "lr", CalcDOUBLED, CompareLR, ShowRLR);
  340. (* test vectors *)
  341. filenames[0] := "MathTest.val";
  342. filenames[1] := "FPE64Test.val";
  343. END TestMathLong.
  344. TestMathLong.Run
  345. TestMath
  346. PET.Open MathTest.val