typ.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. {
  2. $Id$
  3. This file is part of the Numlib package.
  4. Copyright (c) 1986-2000 by
  5. Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
  6. Computational centre of the Eindhoven University of Technology
  7. FPC port Code by Marco van de Voort ([email protected])
  8. documentation by Michael van Canneyt ([email protected])
  9. This is the most basic unit from NumLib.
  10. The most important items this unit defines are matrix types and machine
  11. constants
  12. See the file COPYING.FPC, included in this distribution,
  13. for details about the copyright.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. **********************************************************************}
  18. {
  19. In the FPC revision, instead of picking a certain floating point type,
  20. a new type "ArbFloat" is defined, which is used as floating point type
  21. throughout the entire library. If you change the floating point type, you
  22. should only have to change ArbFloat, and the machineconstants belonging to
  23. the type you want.
  24. However for IEEE Double (64bit) and Extended(80bit) these constants are
  25. already defined, and autoselected by the library. (the library tests the
  26. size of the float type in bytes for 8 and 10 and picks the appropiate
  27. constants
  28. Also some stuff had to be added to get ipf running (vector object and
  29. complex.inp and scale methods)
  30. }
  31. unit typ;
  32. {$I DIRECT.INC} {Contains "global" compilerswitches which
  33. are imported into every unit of the library }
  34. {$DEFINE ArbExtended}
  35. interface
  36. CONST numlib_version=2; {used to detect version conflicts between
  37. header unit and dll}
  38. highestelement=20000; {Maximal n x m dimensions of matrix.
  39. +/- highestelement*SIZEOF(arbfloat) is
  40. minimal size of matrix.}
  41. type {Definition of base types}
  42. {$IFDEF ArbExtended}
  43. ArbFloat = extended;
  44. {$ELSE}
  45. ArbFloat = double;
  46. {$ENDIF}
  47. ArbInt = LONGINT;
  48. Float8Arb =ARRAY[0..7] OF BYTE;
  49. Float10Arb =ARRAY[0..9] OF BYTE;
  50. CONST {Some constants for the variables below, in binary formats.}
  51. {$IFNDEF ArbExtended}
  52. {First for REAL/Double}
  53. TC1 : Float8Arb = ($00,$00,$00,$00,$00,$00,$B0,$3C);
  54. TC2 : Float8Arb = ($FF,$FF,$FF,$FF,$FF,$FF,$EF,$7F);
  55. TC3 : Float8Arb = ($00,$00,$00,$00,$01,$00,$10,$00);
  56. TC4 : Float8Arb = ($00,$00,$00,$00,$00,$00,$F0,$7F);
  57. TC5 : Float8Arb = ($EF,$39,$FA,$FE,$42,$2E,$86,$40);
  58. TC6 : Float8Arb = ($D6,$BC,$FA,$BC,$2B,$23,$86,$C0);
  59. TC7 : Float8Arb = ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF);
  60. {$ENDIF}
  61. {For Extended}
  62. {$IFDEF ArbExtended}
  63. TC1 : Float10Arb = (0,0,$00,$00,$00,$00,0,128,192,63); {Eps}
  64. TC2 : Float10Arb = ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$D6,$FE,127); {9.99188560553925115E+4931}
  65. TC3 : Float10Arb = (1,0,0,0,0,0,0,0,0,0); {3.64519953188247460E-4951}
  66. TC4 : Float10Arb = (0,0,0,0,0,0,0,$80,$FF,$7F); {Inf}
  67. TC5 : Float10Arb = (18,25,219,91,61,101,113,177,12,64); {1.13563488668777920E+0004}
  68. TC6 : Float10Arb = (108,115,3,170,182,56,27,178,12,192); {-1.13988053843083006E+0004}
  69. TC7 : Float10Arb = ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF); {NaN}
  70. {$ENDIF}
  71. { numdig is the number of useful (safe) decimal places of an "ArbFloat"
  72. for display.
  73. minform is the number of decimal places shown by the rtls
  74. write(x:ArbFloat)
  75. maxform is the maximal number of decimal positions
  76. }
  77. numdig = 25;
  78. minform = 10;
  79. maxform = 26;
  80. var
  81. macheps : ArbFloat absolute TC1; { macheps = r - 1, with r
  82. the smallest ArbFloat > 1}
  83. giant : ArbFloat absolute TC2; { the largest ArbFloat}
  84. midget : ArbFloat absolute TC3; { the smallest positive ArbFloat}
  85. infinity : ArbFloat absolute TC4; { INF as defined in IEEE-754(double)
  86. or intel (for extended)}
  87. LnGiant : ArbFloat absolute TC5; {ln of giant}
  88. LnMidget : ArbFloat absolute TC6; {ln of midget}
  89. NaN : ArbFloat absolute TC7; {Not A Number}
  90. {Copied from Det. Needs ArbExtended conditional}
  91. const { og = 8^-maxexp, ogý>=midget,
  92. bg = 8^maxexp, bgý<=giant
  93. midget and giant are defined in typ.pas}
  94. {$IFDEF ArbExtended}
  95. ogx: Float10Arb = (51,158,223,249,51,243,4,181,224,31);
  96. bgx: Float10Arb = (108,119,117,92,70,38,155,234,254,95);
  97. maxexpx : ArbInt = 2740;
  98. {$ELSE}
  99. ogx: Float8Arb= (84, 254, 32, 128, 32, 0, 0, 32);
  100. bgx: Float8Arb= (149, 255, 255, 255, 255, 255, 239, 95);
  101. maxexpx : ArbInt = 170;
  102. {$ENDIF}
  103. {Like standard EXP(), but for very small values (near lowest possible
  104. ArbFloat this version returns 0}
  105. Function exp(x: ArbFloat): ArbFloat;
  106. type
  107. Complex = object {Crude complex record. For me an example of
  108. useless OOP, specially if you have operator overloading}
  109. xreal, imag : ArbFloat;
  110. procedure Init (r, i: ArbFloat);
  111. procedure Add (c: complex);
  112. procedure Sub (c: complex);
  113. function Inp(z:complex):ArbFloat;
  114. procedure Conjugate;
  115. procedure Scale(s: ArbFloat);
  116. Function Norm : ArbFloat;
  117. Function Size : ArbFloat;
  118. Function Re : ArbFloat;
  119. procedure Unary;
  120. Function Im : ArbFloat;
  121. Function Arg : ArbFloat;
  122. procedure MinC(c: complex);
  123. procedure MaxC(c: complex);
  124. Procedure TransF(var t: complex);
  125. end;
  126. vector = object
  127. i, j, k: ArbFloat;
  128. procedure Init (vii, vjj, vkk: ArbFloat);
  129. procedure Unary;
  130. procedure Add (c: vector);
  131. procedure Sub (c: vector);
  132. function Vi : ArbFloat;
  133. function Vj : ArbFloat;
  134. function Vk : ArbFloat;
  135. function Norm : ArbFloat;
  136. Function Norm8 : ArbFloat;
  137. function Size : ArbFloat;
  138. function InProd(c: vector): ArbFloat;
  139. procedure Uitprod(c: vector; var e: vector);
  140. procedure Scale(s: ArbFloat);
  141. procedure DScale(s: ArbFloat);
  142. procedure Normalize;
  143. procedure Rotate(calfa, salfa: ArbFloat; axe: vector);
  144. procedure Show(p,q: ArbInt);
  145. end;
  146. transformorg = record offset: complex; ss, sc: real end;
  147. transform = record
  148. offsetx, offsety, scalex, scaley: ArbFloat
  149. end;
  150. {Standard Functions used in NumLib}
  151. rfunc1r = Function(x : ArbFloat): ArbFloat;
  152. rfunc2r = Function(x, y : ArbFloat): ArbFloat;
  153. {Complex version}
  154. rfunc1z = Function(z: complex): ArbFloat;
  155. {Special Functions}
  156. oderk1n = procedure(x: ArbFloat; var y, f: ArbFloat);
  157. roofnrfunc = procedure(var x, fx: ArbFloat; var deff: boolean);
  158. {Definition of matrix types in NumLib. First some vectors.
  159. The high boundery is a maximal number only. Vectors can be smaller, but
  160. not bigger. The difference is the starting number}
  161. arfloat0 = array[0..highestelement] of ArbFloat;
  162. arfloat1 = array[1..highestelement] of ArbFloat;
  163. arfloat2 = array[2..highestelement] of ArbFloat;
  164. arfloat_1 = array[-1..highestelement] of ArbFloat;
  165. {A matrix is an array of floats}
  166. ar2dr = array[0..highestelement] of ^arfloat0;
  167. ar2dr1 = array[1..highestelement] of ^arfloat1;
  168. {Matrices can get big, so we mosttimes allocate them on the heap.}
  169. par2dr1 = ^ar2dr1;
  170. {Integer vectors}
  171. arint0 = array[0..highestelement] of ArbInt;
  172. arint1 = array[1..highestelement] of ArbInt;
  173. {Boolean (true/false) vectors}
  174. arbool1 = array[1..highestelement] of boolean;
  175. {Complex vectors}
  176. arcomp0 = array[0..highestelement] of complex;
  177. arcomp1 = array[1..highestelement] of complex;
  178. arvect0 = array[0..highestelement] of vector;
  179. vectors = array[1..highestelement] of vector;
  180. parcomp = ^arcomp1;
  181. {(de) Allocate mxn matrix to A}
  182. procedure AllocateAr2dr(m, n: integer; var a: par2dr1);
  183. procedure DeAllocateAr2dr(m, n: integer; var a: par2dr1);
  184. {(de) allocate below-left triangle matrix for (de)convolution
  185. (a 3x3 matrix looks like this
  186. x
  187. x x
  188. x x x)
  189. }
  190. procedure AllocateL2dr(n: integer; var a: par2dr1);
  191. procedure DeAllocateL2dr(n: integer; var a: par2dr1);
  192. {Get the Re and Im parts of a complex type}
  193. Function Re(z: complex): ArbFloat;
  194. Function Im(z: complex): ArbFloat;
  195. { Creates a string from a floatingpoint value}
  196. Function R2S(x: ArbFloat; p, q: integer): string;
  197. {Calculate inproduct of V1 and V2, which are vectors with N elements;
  198. I1 and I2 are the SIZEOF the datatypes of V1 and V2
  199. MvdV: Change this to "V1,V2:array of ArbFloat and forget the i1 and i2
  200. parameters?}
  201. Function Inprod(var V1, V2; n, i1, i2: ArbInt): ArbFloat;
  202. {Return certain special machine constants.(macheps=1, Nan=7)}
  203. Function MachCnst(n: ArbInt): ArbFloat;
  204. function dllversion:LONGINT;
  205. implementation
  206. Function MachCnst(n: ArbInt): ArbFloat;
  207. begin
  208. case n of
  209. 1: MachCnst := macheps;
  210. 2: MachCnst := giant;
  211. 3: MachCnst := midget;
  212. 4: MachCnst := infinity;
  213. 5: MachCnst := LnGiant;
  214. 6: MachCnst := LnMidget;
  215. 7: MachCnst := Nan;
  216. end
  217. end;
  218. { Are used in many of the example programs}
  219. Function Re(z: complex): ArbFloat;
  220. begin
  221. Re := z.xreal
  222. end;
  223. Function Im(z: complex): ArbFloat;
  224. begin
  225. Im := z.imag
  226. end;
  227. {Kind of Sysutils.TrimRight and TrimLeft called after eachother}
  228. procedure Compress(var s: string);
  229. var i, j: LONGINT;
  230. begin
  231. j := length(s);
  232. while (j>0) and (s[j]=' ') do dec(j);
  233. i := 1;
  234. while (i<=j) and (s[i]=' ') do Inc(i);
  235. s := copy(s, i, j+1-i)
  236. end;
  237. Function R2S(x: ArbFloat; p, q: integer): string;
  238. var s: string;
  239. i, j, k: integer;
  240. begin
  241. if q=-1 then
  242. begin
  243. Str(x:p, s);
  244. i := Pos('E', s)-1; k := i+1;
  245. j := i+3; while (j<length(s)) and (s[j]='0') do inc(j);
  246. while s[i]='0' do dec(i); if s[i]='.' then dec(i);
  247. if s[j]='0' then s := copy(s,1,i) else
  248. if s[k]='-' then
  249. s := copy(s, 1, i)+'E-'+Copy(s, j, length(s)+1-j)
  250. else
  251. s := copy(s, 1, i)+'E'+Copy(s, j, length(s)+1-j)
  252. end
  253. else
  254. Str(x:p:q, s);
  255. Compress(s);
  256. R2S := s
  257. end;
  258. procedure AllocateAr2dr(m, n: integer; var a: par2dr1);
  259. var i: integer;
  260. begin
  261. GetMem(a, m*SizeOf(pointer));
  262. for i:=1 to m do GetMem(a^[i], n*SizeOf(ArbFloat))
  263. end;
  264. procedure DeAllocateAr2dr(m, n: integer; var a: par2dr1);
  265. var i: integer;
  266. begin
  267. for i:=m downto 1 do FreeMem(a^[i], n*SizeOf(ArbFloat));
  268. FreeMem(a, m*SizeOf(pointer));
  269. a := Nil
  270. end;
  271. procedure AllocateL2dr(n: integer; var a: par2dr1);
  272. var i: integer;
  273. begin
  274. GetMem(a, n*SizeOf(pointer));
  275. for i:=1 to n do GetMem(a^[i], i*SizeOf(ArbFloat))
  276. end;
  277. procedure DeAllocateL2dr(n: integer; var a: par2dr1);
  278. var i: integer;
  279. begin
  280. for i:=n downto 1 do FreeMem(a^[i], i*SizeOf(ArbFloat));
  281. FreeMem(a, n*SizeOf(pointer));
  282. a := Nil
  283. end;
  284. var h, r, i: ArbFloat;
  285. procedure Complex.Init(r, i: ArbFloat);
  286. begin
  287. xreal:= r;
  288. imag := i
  289. end;
  290. procedure Complex.Conjugate;
  291. begin
  292. imag := -imag
  293. end;
  294. function Complex.Inp(z:complex):ArbFloat;
  295. begin
  296. Inp := xreal*z.xreal + imag*z.imag
  297. end;
  298. procedure Complex.MinC(c: complex);
  299. begin if c.xreal<xreal then xreal := c.xreal;
  300. if c.imag<imag then imag := c.imag
  301. end;
  302. procedure Complex.Maxc(c: complex);
  303. begin if c.xreal>xreal then xreal := c.xreal;
  304. if c.imag>imag then imag := c.imag
  305. end;
  306. procedure Complex.Add(c: complex);
  307. begin
  308. xreal := xreal + c.xreal; imag := imag + c.imag
  309. end;
  310. procedure Complex.Sub(c: complex);
  311. begin
  312. xreal := xreal - c.xreal; imag := imag - c.imag
  313. end;
  314. Function Complex.Norm: ArbFloat;
  315. begin
  316. Norm := Sqr(xreal) + Sqr(imag)
  317. end;
  318. Function Complex.Size: ArbFloat;
  319. begin
  320. Size := Sqrt(Norm)
  321. end;
  322. Function Complex.Re: ArbFloat;
  323. begin
  324. Re := xreal;
  325. end;
  326. Function Complex.Im: ArbFloat;
  327. begin
  328. Im := imag
  329. end;
  330. Procedure Complex.TransF(var t: complex);
  331. var w: complex;
  332. tt: transformorg absolute t;
  333. begin
  334. w := Self; Conjugate;
  335. with tt do
  336. begin
  337. w.scale(ss);
  338. scale(sc);
  339. Add(offset)
  340. end;
  341. Add(w)
  342. end;
  343. procedure Complex.Unary;
  344. begin
  345. xreal := -xreal;
  346. imag := -imag
  347. end;
  348. procedure Complex.Scale(s:ArbFloat);
  349. begin
  350. xreal := xreal*s; imag := imag*s
  351. end;
  352. Function Complex.Arg: ArbFloat;
  353. begin
  354. if xreal=0 then
  355. if imag>0 then Arg := 0.5*pi else
  356. if imag=0 then Arg := 0 else Arg := -0.5*pi else
  357. if xReal>0 then Arg := ArcTan(imag/xReal)
  358. else if imag>=0 then Arg := ArcTan(imag/xReal) + pi
  359. else Arg := ArcTan(imag/xReal) - pi
  360. end;
  361. Function exp(x: ArbFloat): ArbFloat;
  362. begin
  363. if x<LnMidget then exp := 0 else exp := system.exp(x)
  364. end;
  365. { procedure berekent: v1 = v1 + r*v2 i1 en i2 geven de
  366. increments in bytes voor v1 en v2 }
  367. Function Inprod(var V1, V2; n, i1, i2: ArbInt): ArbFloat;
  368. VAR i: LONGINT;
  369. p1, p2: ^ArbFloat;
  370. s: ArbFloat;
  371. begin
  372. IF I1 <>SIZEOF(ArbFloat) THEN
  373. BEGIN
  374. WRITELN('1 Something went probably wrong while porting!');
  375. HALT;
  376. END;
  377. p1 := @v1; p2 := @v2; s := 0;
  378. for i:=1 to n do
  379. begin
  380. s := s + p1^*p2^;
  381. Inc(longint(p1), i1);
  382. Inc(longint(p2), i2)
  383. end;
  384. Inprod := s
  385. end;
  386. procedure Vector.Init(vii, vjj, vkk: ArbFloat);
  387. begin
  388. i := vii; j := vjj; k := vkk
  389. end;
  390. procedure Vector.Unary;
  391. begin i := -i; j := -j; k := -k end;
  392. procedure Vector.Add(c: vector);
  393. begin
  394. i := i + c.i; j := j + c.j; k := k + c.k
  395. end;
  396. procedure Vector.Sub(c: vector);
  397. begin
  398. i := i - c.i; j := j - c.j; k := k - c.k
  399. end;
  400. function Vector.Vi : ArbFloat; begin Vi := i end;
  401. function Vector.Vj : ArbFloat; begin Vj := j end;
  402. function Vector.Vk : ArbFloat; begin Vk := k end;
  403. function Vector.Norm:ArbFloat;
  404. begin
  405. Norm := Sqr(i) + Sqr(j) + Sqr(k)
  406. end;
  407. function Vector.Norm8:ArbFloat;
  408. var r: ArbFloat;
  409. begin
  410. r := abs(i);
  411. if abs(j)>r then r := abs(j);
  412. if abs(k)>r then r := abs(k);
  413. Norm8 := r
  414. end;
  415. function Vector.Size: ArbFloat;
  416. begin
  417. Size := Sqrt(Norm)
  418. end;
  419. function Vector.InProd(c: vector): ArbFloat;
  420. begin
  421. InProd := i*c.i + j*c.j + k*c.k
  422. end;
  423. procedure Vector.Uitprod(c: vector; var e: vector);
  424. begin
  425. e.i := j*c.k - k*c.j;
  426. e.j := k*c.i - i*c.k;
  427. e.k := i*c.j - j*c.i
  428. end;
  429. procedure Vector.Scale(s: ArbFloat);
  430. begin
  431. i := i*s; j := j*s; k := k*s
  432. end;
  433. procedure Vector.DScale(s: ArbFloat);
  434. begin
  435. i := i/s; j := j/s; k := k/s
  436. end;
  437. procedure Vector.Normalize;
  438. begin
  439. DScale(Size)
  440. end;
  441. procedure Vector.Show(p,q:ArbInt);
  442. begin writeln(i:p:q, 'I', j:p:q, 'J', k:p:q, 'K') end;
  443. procedure Vector.Rotate(calfa, salfa: arbfloat; axe: vector);
  444. var qv : vector;
  445. begin
  446. Uitprod(axe, qv); qv.scale(salfa);
  447. axe.scale((1-calfa)*Inprod(axe));
  448. scale(calfa); sub(qv); add(axe)
  449. end;
  450. function dllversion:LONGINT;
  451. BEGIN
  452. dllversion:=numlib_version;
  453. END;
  454. END.
  455. {
  456. $Log$
  457. Revision 1.2 2000-01-25 20:21:41 marco
  458. * small updates, crlf fix, and RTE 207 problem
  459. Revision 1.1 2000/01/24 22:08:58 marco
  460. * initial version
  461. }