ArrayXdRe.Mod 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231
  1. (* CAPO - Computational Analysis Platform for Oberon - by Alan Freed and Felix Friedrich. *)
  2. (* Version 1, Update 2 *)
  3. MODULE ArrayXdRe; (** AUTHOR "fof"; PURPOSE "Basic operations on an X-dimensional array of Real"; *)
  4. (** any item containing the string "dbg" is for debugging purposes only and will be removed from this module, do NOT use *)
  5. IMPORT SYSTEM, NbrInt, NbrRe, ArrayXdBytes, Array1d := Array1dRe, dbgOut := KernelLog, DataErrors, Array1dInt,
  6. ArrayXdRat, DataIO;
  7. CONST
  8. generic* = 0; vector* = 1; matrix* = 2; cube* = 3; hcube* = 4;
  9. (** The version used when reading/writing an arbitrary dimensional array to file. *)
  10. VERSION* = 1;
  11. StrictBoundaryC* = 0; (* data beyond limit -> TRAP *)
  12. AbsorbingBoundaryC* = 1; (* data beyond limit = zero*)
  13. PeriodicBoundaryC* = 2; (* data[x] =data[x MOD LEN(data)], torus *)
  14. SymmetricOnBoundaryC* = 3; (* mirror boundaries, using border point once; W= reflection centered on point N *)
  15. SymmetricOffBoundaryC* = 4; (* mirror boundaries, using border point twice; reflection centered between point N and point N+1 *)
  16. AntisymmetricOnBoundaryC* = 5; (* like SymmetricOnBoundaryC but with additional change of sign if out of bounds *)
  17. AntisymmetricOffBoundaryC* = 6; (* like SymmetricOffBoundaryC but with additional change of sign if out of bounds *)
  18. TYPE
  19. Value* = Array1d.Value; Index* = LONGINT; Array1* = Array1d.Array; IntValue* = Array1dInt.Value;
  20. Array2* = POINTER TO ARRAY OF ARRAY OF Value;
  21. Array3* = POINTER TO ARRAY OF ARRAY OF ARRAY OF Value;
  22. Array4* = POINTER TO ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value;
  23. Map* = Array1d.Map;
  24. (** Class Array has been DataIO registered, and therefore, any instance of it can be made persistent
  25. by using the DataIO Reader and Writer, or more simply, by calling procedures Load and Store below. *)
  26. Array* = OBJECT (ArrayXdBytes.Array)
  27. VAR data-: Array1; (*! will probably be removed, do not use ! *)
  28. (** override *)
  29. PROCEDURE Allocate*( size: LONGINT; VAR adr: Index; VAR ptr: ANY );
  30. BEGIN
  31. NEW( data, size ); adr := ADDRESSOF( data[0] ); ptr := data;
  32. END Allocate;
  33. PROCEDURE GetInfo*( VAR elementsize: Index );
  34. BEGIN
  35. elementsize := SIZEOF( Value );
  36. END GetInfo;
  37. PROCEDURE AlikeX*( ): ArrayXdBytes.Array;
  38. VAR copy: Array;
  39. BEGIN
  40. NEW( copy, origin, len ); RETURN copy;
  41. END AlikeX;
  42. (** new *)
  43. (** Read and Write are for internal use only.
  44. Exporting them permits extensible, persistent, data types to be constructed. *)
  45. PROCEDURE Read*( R: DataIO.Reader );
  46. BEGIN {EXCLUSIVE}
  47. LoadXd( R )
  48. END Read;
  49. PROCEDURE Write*( W: DataIO.Writer );
  50. BEGIN
  51. StoreXd( W, TRUE )
  52. END Write;
  53. PROCEDURE Type*( ): SHORTINT;
  54. (* generic, vector, matrix, cube, hcube *)
  55. BEGIN
  56. IF dim < 5 THEN RETURN SHORT( SHORT( dim ) ) ELSE RETURN 0 END;
  57. END Type;
  58. PROCEDURE Get1*( x: Index ): Value;
  59. VAR v: Value;
  60. BEGIN
  61. ArrayXdBytes.Get1( SELF, x, v ); RETURN v;
  62. END Get1;
  63. PROCEDURE Set1*( x: Index; v: Value );
  64. BEGIN
  65. ArrayXdBytes.Set1( SELF, x, v );
  66. END Set1;
  67. PROCEDURE Get2*( x, y: Index ): Value;
  68. VAR v: Value;
  69. BEGIN
  70. ArrayXdBytes.Get2( SELF, x, y, v ); RETURN v;
  71. END Get2;
  72. PROCEDURE Set2*( x, y: Index; v: Value );
  73. BEGIN
  74. ArrayXdBytes.Set2( SELF, x, y, v );
  75. END Set2;
  76. PROCEDURE Get3*( x, y, z: Index ): Value;
  77. VAR v: Value;
  78. BEGIN
  79. ArrayXdBytes.Get3( SELF, x, y, z, v ); RETURN v;
  80. END Get3;
  81. PROCEDURE Set3*( x, y, z: Index; v: Value );
  82. BEGIN
  83. ArrayXdBytes.Set3( SELF, x, y, z, v );
  84. END Set3;
  85. PROCEDURE Get4*( x, y, z, t: Index ): Value;
  86. VAR v: Value;
  87. BEGIN
  88. ArrayXdBytes.Get4( SELF, x, y, z, t, v ); RETURN v;
  89. END Get4;
  90. PROCEDURE Set4*( x, y, z, t: Index; v: Value );
  91. BEGIN
  92. ArrayXdBytes.Set4( SELF, x, y, z, t, v );
  93. END Set4;
  94. PROCEDURE GetX*( VAR x: ARRAY OF Index; dim: Index ): Value;
  95. VAR v: Value;
  96. BEGIN
  97. ArrayXdBytes.GetX( SELF, x, dim, v ); RETURN v;
  98. END GetX;
  99. PROCEDURE SetX*( VAR x: ARRAY OF Index; dim: Index; v: Value );
  100. BEGIN
  101. ArrayXdBytes.SetX( SELF, x, dim, v );
  102. END SetX;
  103. (*** Get with boundary conditions *)
  104. (** absorbing: data beyond limit = zero *)
  105. PROCEDURE Get1BAbsorbing*( x: Index ): Value;
  106. VAR v: Value;
  107. BEGIN
  108. IF ArrayXdBytes.InBounds( o0, l0, x ) THEN ArrayXdBytes.Get1( SELF, x, v ); RETURN v ELSE RETURN 0 END;
  109. END Get1BAbsorbing;
  110. PROCEDURE Get2BAbsorbing*( x, y: Index ): Value;
  111. VAR v: Value;
  112. BEGIN
  113. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) THEN
  114. ArrayXdBytes.Get2( SELF, x, y, v ); RETURN v
  115. ELSE RETURN 0
  116. END;
  117. END Get2BAbsorbing;
  118. PROCEDURE Get3BAbsorbing*( x, y, z: Index ): Value;
  119. VAR v: Value;
  120. BEGIN
  121. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) THEN
  122. ArrayXdBytes.Get3( SELF, x, y, z, v ); RETURN v
  123. ELSE RETURN 0
  124. END;
  125. END Get3BAbsorbing;
  126. PROCEDURE Get4BAbsorbing*( x, y, z, t: Index ): Value;
  127. VAR v: Value;
  128. BEGIN
  129. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) &
  130. ArrayXdBytes.InBounds( o3, l3, t ) THEN
  131. ArrayXdBytes.Get4( SELF, x, y, z, t, v ); RETURN v
  132. ELSE RETURN 0
  133. END;
  134. END Get4BAbsorbing;
  135. PROCEDURE GetXBAbsorbing*( b: ARRAY OF Index; dim: Index ): Value;
  136. VAR v: Value; i: Index;
  137. BEGIN
  138. i := 0;
  139. WHILE (i < dim) DO
  140. IF ~ArrayXdBytes.InBounds( origin[i], len[i], b[i] ) THEN RETURN 0 END;
  141. INC( i );
  142. END;
  143. ArrayXdBytes.GetX( SELF, b, dim, v ); RETURN v
  144. END GetXBAbsorbing;
  145. (** periodic: data[x] =data[x MOD LEN(data)] *)
  146. PROCEDURE Get1BPeriodic*( x: Index ): Value;
  147. VAR v: Value;
  148. BEGIN
  149. ArrayXdBytes.Get1( SELF, ArrayXdBytes.PeriodicBounds( o0, l0, x ), v ); RETURN v
  150. END Get1BPeriodic;
  151. PROCEDURE Get2BPeriodic*( x, y: Index ): Value;
  152. VAR v: Value;
  153. BEGIN
  154. ArrayXdBytes.Get2( SELF, ArrayXdBytes.PeriodicBounds( o0, l0, x ), ArrayXdBytes.PeriodicBounds( o1, l1, y ), v );
  155. RETURN v
  156. END Get2BPeriodic;
  157. PROCEDURE Get3BPeriodic*( x, y, z: Index ): Value;
  158. VAR v: Value;
  159. BEGIN
  160. ArrayXdBytes.Get3( SELF, ArrayXdBytes.PeriodicBounds( o0, l0, x ), ArrayXdBytes.PeriodicBounds( o1, l1, y ),
  161. ArrayXdBytes.PeriodicBounds( o2, l2, z ), v );
  162. RETURN v
  163. END Get3BPeriodic;
  164. PROCEDURE Get4BPeriodic*( x, y, z, t: Index ): Value;
  165. VAR v: Value;
  166. BEGIN
  167. ArrayXdBytes.Get4( SELF, ArrayXdBytes.PeriodicBounds( o0, l0, x ), ArrayXdBytes.PeriodicBounds( o1, l1, y ),
  168. ArrayXdBytes.PeriodicBounds( o2, l2, z ), ArrayXdBytes.PeriodicBounds( o3, l3, z ), v );
  169. RETURN v
  170. END Get4BPeriodic;
  171. PROCEDURE GetXBPeriodic*( b: ARRAY OF Index; dim: Index ): Value;
  172. VAR v: Value; i: Index;
  173. BEGIN
  174. i := 0;
  175. WHILE (i < dim) DO b[i] := ArrayXdBytes.PeriodicBounds( origin[i], len[i], b[i] ); INC( i ) END;
  176. ArrayXdBytes.GetX( SELF, b, dim, v ); RETURN v
  177. END GetXBPeriodic;
  178. (** mirror boundaries, using border point twice; reflection centered between point N and point N+1 *)
  179. PROCEDURE Get1BSymmetricOffB*( x: Index ): Value;
  180. VAR v: Value;
  181. BEGIN
  182. ArrayXdBytes.Get1( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), v ); RETURN v
  183. END Get1BSymmetricOffB;
  184. PROCEDURE Get2BSymmetricOffB*( x, y: Index ): Value;
  185. VAR v: Value;
  186. BEGIN
  187. ArrayXdBytes.Get2( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ), v ); RETURN v
  188. END Get2BSymmetricOffB;
  189. PROCEDURE Get3BSymmetricOffB*( x, y, z: Index ): Value;
  190. VAR v: Value;
  191. BEGIN
  192. ArrayXdBytes.Get3( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ),
  193. ArrayXdBytes.MirrorOffB( o2, l2, z ), v );
  194. RETURN v
  195. END Get3BSymmetricOffB;
  196. PROCEDURE Get4BSymmetricOffB*( x, y, z, t: Index ): Value;
  197. VAR v: Value;
  198. BEGIN
  199. ArrayXdBytes.Get4( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ),
  200. ArrayXdBytes.MirrorOffB( o2, l2, z ), ArrayXdBytes.MirrorOffB( o3, l3, z ), v );
  201. RETURN v
  202. END Get4BSymmetricOffB;
  203. PROCEDURE GetXBSymmetricOffB*( b: ARRAY OF Index; dim: Index ): Value;
  204. VAR v: Value; i: Index;
  205. BEGIN
  206. i := 0;
  207. WHILE (i < dim) DO b[i] := ArrayXdBytes.MirrorOffB( origin[i], len[i], b[i] ); INC( i ) END;
  208. ArrayXdBytes.GetX( SELF, b, dim, v ); RETURN v
  209. END GetXBSymmetricOffB;
  210. (** mirror boundaries, using border point once; reflection centered on point N*)
  211. PROCEDURE Get1BSymmetricOnB*( x: Index ): Value;
  212. VAR v: Value;
  213. BEGIN
  214. x := ArrayXdBytes.MirrorOnB( o0, l0, x ); ArrayXdBytes.Get1( SELF, x, v ); RETURN v
  215. END Get1BSymmetricOnB;
  216. PROCEDURE Get2BSymmetricOnB*( x, y: Index ): Value;
  217. VAR v: Value;
  218. BEGIN
  219. x := ArrayXdBytes.MirrorOnB( o0, l0, x ); y := ArrayXdBytes.MirrorOnB( o1, l1, y );
  220. ArrayXdBytes.Get2( SELF, x, y, v ); RETURN v
  221. END Get2BSymmetricOnB;
  222. PROCEDURE Get3BSymmetricOnB*( x, y, z: Index ): Value;
  223. VAR v: Value;
  224. BEGIN
  225. x := ArrayXdBytes.MirrorOnB( o0, l0, x ); y := ArrayXdBytes.MirrorOnB( o1, l1, y );
  226. z := ArrayXdBytes.MirrorOnB( o2, l2, z ); ArrayXdBytes.Get3( SELF, x, y, z, v ); RETURN v
  227. END Get3BSymmetricOnB;
  228. PROCEDURE Get4BSymmetricOnB*( x, y, z, t: Index ): Value;
  229. VAR v: Value;
  230. BEGIN
  231. x := ArrayXdBytes.MirrorOnB( o0, l0, x ); y := ArrayXdBytes.MirrorOnB( o1, l1, y );
  232. z := ArrayXdBytes.MirrorOnB( o2, l2, z ); t := ArrayXdBytes.MirrorOnB( o3, l3, z );
  233. ArrayXdBytes.Get4( SELF, x, y, z, t, v ); RETURN v
  234. END Get4BSymmetricOnB;
  235. PROCEDURE GetXBSymmetricOnB*( b: ARRAY OF Index; dim: Index ): Value;
  236. VAR v: Value; i: Index;
  237. BEGIN
  238. i := 0;
  239. WHILE (i < dim) DO b[i] := ArrayXdBytes.MirrorOnB( origin[i], len[i], b[i] ); INC( i ) END;
  240. ArrayXdBytes.GetX( SELF, b, dim, v ); RETURN v
  241. END GetXBSymmetricOnB;
  242. (* like SymmetricOffB but with change of sign if not in range *)
  243. PROCEDURE Get1BAntisymmetricOffB*( x: Index ): Value;
  244. VAR v: Value;
  245. BEGIN
  246. IF ArrayXdBytes.InBounds( o0, l0, x ) THEN ArrayXdBytes.Get1( SELF, x, v ); RETURN v
  247. ELSE ArrayXdBytes.Get1( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), v ); RETURN -v;
  248. END;
  249. END Get1BAntisymmetricOffB;
  250. PROCEDURE Get2BAntisymmetricOffB*( x, y: Index ): Value;
  251. VAR v: Value;
  252. BEGIN
  253. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) THEN
  254. ArrayXdBytes.Get2( SELF, x, y, v ); RETURN v
  255. ELSE
  256. ArrayXdBytes.Get2( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ), v ); RETURN -v
  257. END;
  258. END Get2BAntisymmetricOffB;
  259. PROCEDURE Get3BAntisymmetricOffB*( x, y, z: Index ): Value;
  260. VAR v: Value;
  261. BEGIN
  262. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) THEN
  263. ArrayXdBytes.Get3( SELF, x, y, z, v ); RETURN v
  264. ELSE
  265. ArrayXdBytes.Get3( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ),
  266. ArrayXdBytes.MirrorOffB( o2, l2, z ), v );
  267. RETURN -v
  268. END;
  269. END Get3BAntisymmetricOffB;
  270. PROCEDURE Get4BAntisymmetricOffB*( x, y, z, t: Index ): Value;
  271. VAR v: Value;
  272. BEGIN
  273. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) &
  274. ArrayXdBytes.InBounds( o3, l3, t ) THEN
  275. ArrayXdBytes.Get4( SELF, x, y, z, t, v ); RETURN v
  276. ELSE
  277. ArrayXdBytes.Get4( SELF, ArrayXdBytes.MirrorOffB( o0, l0, x ), ArrayXdBytes.MirrorOffB( o1, l1, y ),
  278. ArrayXdBytes.MirrorOffB( o2, l2, z ), ArrayXdBytes.MirrorOffB( o3, l3, t ), v );
  279. RETURN -v
  280. END;
  281. END Get4BAntisymmetricOffB;
  282. PROCEDURE GetXBAntisymmetricOffB*( b: ARRAY OF Index; dim: Index ): Value;
  283. VAR v: Value; i: Index; inv: BOOLEAN;
  284. BEGIN
  285. i := 0; inv := FALSE;
  286. WHILE (i < dim) DO
  287. inv := inv OR (~ArrayXdBytes.InBounds( origin[i], len[i], b[i] ));
  288. b[i] := ArrayXdBytes.MirrorOffB( origin[i], len[i], b[i] ); INC( i );
  289. END;
  290. ArrayXdBytes.GetX( SELF, b, dim, v );
  291. IF inv THEN RETURN -v ELSE RETURN v END;
  292. END GetXBAntisymmetricOffB;
  293. (** like SymmetricOnB but with change of sign if not in range *)
  294. PROCEDURE Get1BAntisymmetricOnB*( x: Index ): Value;
  295. VAR v: Value;
  296. BEGIN
  297. IF ArrayXdBytes.InBounds( o0, l0, x ) THEN ArrayXdBytes.Get1( SELF, x, v ); RETURN v
  298. ELSE ArrayXdBytes.Get1( SELF, ArrayXdBytes.MirrorOnB( o0, l0, x ), v ); RETURN -v;
  299. END;
  300. END Get1BAntisymmetricOnB;
  301. PROCEDURE Get2BAntisymmetricOnB*( x, y: Index ): Value;
  302. VAR v: Value;
  303. BEGIN
  304. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) THEN
  305. ArrayXdBytes.Get2( SELF, x, y, v ); RETURN v
  306. ELSE
  307. ArrayXdBytes.Get2( SELF, ArrayXdBytes.MirrorOnB( o0, l0, x ), ArrayXdBytes.MirrorOnB( o1, l1, y ), v ); RETURN -v
  308. END;
  309. END Get2BAntisymmetricOnB;
  310. PROCEDURE Get3BAntisymmetricOnB*( x, y, z: Index ): Value;
  311. VAR v: Value;
  312. BEGIN
  313. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) THEN
  314. ArrayXdBytes.Get3( SELF, x, y, z, v ); RETURN v
  315. ELSE
  316. ArrayXdBytes.Get3( SELF, ArrayXdBytes.MirrorOnB( o0, l0, x ), ArrayXdBytes.MirrorOnB( o1, l1, y ),
  317. ArrayXdBytes.MirrorOnB( o2, l2, z ), v );
  318. RETURN -v
  319. END;
  320. END Get3BAntisymmetricOnB;
  321. PROCEDURE Get4BAntisymmetricOnB*( x, y, z, t: Index ): Value;
  322. VAR v: Value;
  323. BEGIN
  324. IF ArrayXdBytes.InBounds( o0, l0, x ) & ArrayXdBytes.InBounds( o1, l1, y ) & ArrayXdBytes.InBounds( o2, l2, z ) &
  325. ArrayXdBytes.InBounds( o3, l3, t ) THEN
  326. ArrayXdBytes.Get4( SELF, x, y, z, t, v ); RETURN v
  327. ELSE
  328. ArrayXdBytes.Get4( SELF, ArrayXdBytes.MirrorOnB( o0, l0, x ), ArrayXdBytes.MirrorOnB( o1, l1, y ),
  329. ArrayXdBytes.MirrorOnB( o2, l2, z ), ArrayXdBytes.MirrorOnB( o3, l3, t ), v );
  330. RETURN -v
  331. END;
  332. END Get4BAntisymmetricOnB;
  333. PROCEDURE GetXBAntisymmetricOnB*( b: ARRAY OF Index; dim: Index ): Value;
  334. VAR v: Value; i: Index; inv: BOOLEAN;
  335. BEGIN
  336. i := 0; inv := FALSE;
  337. WHILE (i < dim) DO
  338. inv := inv OR (~ArrayXdBytes.InBounds( origin[i], len[i], b[i] ));
  339. b[i] := ArrayXdBytes.MirrorOnB( origin[i], len[i], b[i] ); INC( i );
  340. END;
  341. ArrayXdBytes.GetX( SELF, b, dim, v );
  342. IF inv THEN RETURN -v ELSE RETURN v END;
  343. END GetXBAntisymmetricOnB;
  344. (** copy using the current boundary condition SELF:bc*)
  345. PROCEDURE CopyToArray*( dest: Array; srcpos, srclen, destpos, destlen: ArrayXdBytes.IndexArray );
  346. BEGIN
  347. CopyArrayToArrayPartB( SELF, dest, bc, srcpos, srclen, destpos, destlen );
  348. END CopyToArray;
  349. (** apply map m to all entries, dimension ordering is not necessarily preserved! *)
  350. PROCEDURE MapAll*( m: Array1d.Map );
  351. BEGIN
  352. IF m # NIL THEN Array1d.ApplyMap( m, data^, 0, LEN( data ) ); ELSE DataErrors.Error( "A NIL mapping function was supplied." ) END
  353. END MapAll;
  354. PROCEDURE Negate*;
  355. BEGIN {EXCLUSIVE}
  356. Array1d.Negate( data^, 0, LEN( data ) );
  357. (*
  358. FOR i := 0 TO len - 1 DO vec[i] := -vec[i] END
  359. *)
  360. END Negate;
  361. (** arr := arr+x *)
  362. PROCEDURE Add*( x: Array );
  363. BEGIN
  364. IF x # NIL THEN
  365. IF LEN( data ) = LEN( x.data ) THEN
  366. BEGIN {EXCLUSIVE}
  367. (*FOR i := 0 TO len - 1 DO vec[i] := vec[i] - x.vec[i] END*)
  368. Array1d.AddAA( data^, x.data^, data^, 0, len[0] );
  369. END
  370. ELSE DataErrors.Error( "Lengths of the two arrays were not equal." )
  371. END
  372. ELSE DataErrors.Error( "The supplied array to be subtracted was NIL." )
  373. END
  374. END Add;
  375. (** arr := arr-x *)
  376. PROCEDURE Subtract*( x: Array );
  377. BEGIN
  378. IF x # NIL THEN
  379. IF LEN( data ) = LEN( x.data ) THEN
  380. BEGIN {EXCLUSIVE}
  381. (*FOR i := 0 TO len - 1 DO vec[i] := vec[i] - x.vec[i] END*)
  382. Array1d.SubtractAA( data^, x.data^, data^, 0, len[0] );
  383. END
  384. ELSE DataErrors.Error( "Lengths of the two arrays were not equal." )
  385. END
  386. ELSE DataErrors.Error( "The supplied array to be subtracted was NIL." )
  387. END
  388. END Subtract;
  389. (* arr[i] := a*arr[i] forall i*)
  390. PROCEDURE Multiply*( a: Value );
  391. VAR i: Index;
  392. BEGIN {EXCLUSIVE}
  393. FOR i := 0 TO LEN( data ) - 1 DO data[i] := a * data[i] END
  394. END Multiply;
  395. (** arr[i] :=arr[i] / a forall i *)
  396. PROCEDURE Divide*( a: Value );
  397. VAR i: Index;
  398. BEGIN
  399. IF a # 0 THEN
  400. BEGIN {EXCLUSIVE}
  401. FOR i := 0 TO LEN( data ) - 1 DO data[i] := data[i] / a; END
  402. END;
  403. ELSE DataErrors.Error( "Division by zero." )
  404. END
  405. END Divide;
  406. PROCEDURE dbgWrite*;
  407. VAR x, y, z: LONGINT;
  408. BEGIN
  409. IF Type() = vector THEN
  410. FOR x := origin[0] TO origin[0] + len[0] - 1 DO (*dbgOut.LongReal( Get1( x ), 12 ); *)dbgOut.String( "|" ); END;
  411. dbgOut.Ln;
  412. ELSIF Type() = matrix THEN
  413. FOR y := origin[1] TO origin[1] + len[1] - 1 DO
  414. FOR x := origin[0] TO origin[0] + len[0] - 1 DO (*dbgOut.LongReal( Get2( x, y ), 12 ); *)dbgOut.String( "|" ); END;
  415. dbgOut.Ln;
  416. END;
  417. dbgOut.Ln;
  418. ELSIF Type() = cube THEN
  419. FOR z := origin[2] TO origin[2] + len[2] - 1 DO
  420. FOR y := origin[1] TO origin[1] + len[1] - 1 DO
  421. FOR x := origin[0] TO origin[0] + len[0] - 1 DO (*dbgOut.LongReal( Get2( x, y ), 12 ); *)dbgOut.String( "|" ); END;
  422. dbgOut.Ln;
  423. END;
  424. dbgOut.Ln;
  425. END;
  426. END;
  427. END dbgWrite;
  428. END Array;
  429. PROCEDURE New1d*( ox, w: Index ): Array;
  430. VAR res: Array;
  431. BEGIN
  432. NEW( res, ArrayXdBytes.Array1( ox ), ArrayXdBytes.Array1( w ) ); RETURN res;
  433. END New1d;
  434. PROCEDURE New2d*( ox, w, oy, h: Index ): Array;
  435. VAR res: Array;
  436. BEGIN
  437. NEW( res, ArrayXdBytes.Array2( ox, oy ), ArrayXdBytes.Array2( w, h ) ); RETURN res;
  438. END New2d;
  439. PROCEDURE New3d*( ox, w, oy, h, oz, d: Index ): Array;
  440. VAR res: Array;
  441. BEGIN
  442. NEW( res, ArrayXdBytes.Array3( ox, oy, oz ), ArrayXdBytes.Array3( w, h, d ) ); RETURN res;
  443. END New3d;
  444. PROCEDURE New4d*( ox, w, oy, h, oz, d, ot, dt: Index ): Array;
  445. VAR res: Array;
  446. BEGIN
  447. NEW( res, ArrayXdBytes.Array4( ox, oy, oz, ot ), ArrayXdBytes.Array4( w, h, d, dt ) ); RETURN res;
  448. END New4d;
  449. PROCEDURE CopyVecToVec*( src, dest: Array; srcx, destx, len: Index );
  450. BEGIN
  451. IF (src.dim # 1) OR (dest.dim # 1) THEN HALT( 1001 ) END;
  452. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index1( srcx ), ArrayXdBytes.Index1( len ),
  453. ArrayXdBytes.Index1( destx ), ArrayXdBytes.Index1( len ) );
  454. END CopyVecToVec;
  455. PROCEDURE CopyMtxToVec*( src, dest: Array; dim: Index; srcx, srcy, destx, len: Index );
  456. VAR slen: ArrayXdBytes.IndexArray;
  457. BEGIN
  458. IF (src.dim # 2) OR (dest.dim # 1) THEN HALT( 1002 ) END;
  459. slen := ArrayXdBytes.Index2( 1, 1 ); slen[dim] := len;
  460. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index2( srcx, srcy ), slen,
  461. ArrayXdBytes.Index1( destx ), ArrayXdBytes.Index1( len ) );
  462. END CopyMtxToVec;
  463. PROCEDURE CopyVecToMtx*( src, dest: Array; dim: Index; srcx, destx, desty, len: Index );
  464. VAR slen: ArrayXdBytes.IndexArray;
  465. BEGIN
  466. IF (src.dim # 1) OR (dest.dim # 2) THEN HALT( 1002 ) END;
  467. slen := ArrayXdBytes.Index2( 1, 1 ); slen[dim] := len;
  468. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index1( srcx ), ArrayXdBytes.Index1( len ),
  469. ArrayXdBytes.Index2( destx, desty ), slen );
  470. END CopyVecToMtx;
  471. PROCEDURE CopyCubeToVec*( src, dest: Array; dim: Index; srcx, srcy, srcz, destx, len: Index );
  472. VAR slen: ArrayXdBytes.IndexArray;
  473. BEGIN
  474. IF (src.dim # 3) OR (dest.dim # 1) THEN HALT( 1003 ) END;
  475. slen := ArrayXdBytes.Index3( 1, 1, 1 ); slen[dim] := len;
  476. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index3( srcx, srcy, srcz ), slen,
  477. ArrayXdBytes.Index1( destx ), ArrayXdBytes.Index1( len ) );
  478. END CopyCubeToVec;
  479. PROCEDURE CopyVecToCube*( src, dest: Array; dim: Index; srcx, destx, desty, destz, len: Index );
  480. VAR slen: ArrayXdBytes.IndexArray;
  481. BEGIN
  482. IF (src.dim # 1) OR (dest.dim # 3) THEN HALT( 1002 ) END;
  483. slen := ArrayXdBytes.Index3( 1, 1, 1 ); slen[dim] := len;
  484. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index1( srcx ), ArrayXdBytes.Index1( len ),
  485. ArrayXdBytes.Index3( destx, desty, destz ), slen );
  486. END CopyVecToCube;
  487. PROCEDURE CopyHCubeToVec*( src, dest: Array; dim: Index; srcx, srcy, srcz, srct, destx, len: Index );
  488. VAR slen: ArrayXdBytes.IndexArray;
  489. BEGIN
  490. IF (src.dim # 4) OR (dest.dim # 1) THEN HALT( 1004 ) END;
  491. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dim] := len;
  492. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen,
  493. ArrayXdBytes.Index1( destx ), ArrayXdBytes.Index1( len ) );
  494. END CopyHCubeToVec;
  495. PROCEDURE CopyVecToHCube*( src, dest: Array; dim: Index; srcx, destx, desty, destz, destt, len: Index );
  496. VAR slen: ArrayXdBytes.IndexArray;
  497. BEGIN
  498. IF (src.dim # 1) OR (dest.dim # 4) THEN HALT( 1002 ) END;
  499. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dim] := len;
  500. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index1( srcx ), ArrayXdBytes.Index1( len ),
  501. ArrayXdBytes.Index4( destx, desty, destz, destt ), slen );
  502. END CopyVecToHCube;
  503. PROCEDURE CopyMtxToMtx*( src, dest: Array; srcx, srcy, destx, desty, lenx, leny: Index );
  504. VAR slen: ArrayXdBytes.IndexArray;
  505. BEGIN
  506. IF (src.dim # 2) OR (dest.dim # 2) THEN HALT( 1005 ) END;
  507. slen := ArrayXdBytes.Index2( lenx, leny );
  508. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index2( srcx, srcy ), slen,
  509. ArrayXdBytes.Index2( destx, desty ), slen );
  510. END CopyMtxToMtx;
  511. PROCEDURE CopyCubeToMtx*( src, dest: Array; dimx, dimy: Index; srcx, srcy, srcz, destx, desty, lenx, leny: Index );
  512. VAR slen: ArrayXdBytes.IndexArray;
  513. BEGIN
  514. IF (src.dim # 3) OR (dest.dim # 2) THEN HALT( 1005 ) END;
  515. slen := ArrayXdBytes.Index3( 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny;
  516. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index3( srcx, srcy, srcz ), slen,
  517. ArrayXdBytes.Index2( destx, desty ), ArrayXdBytes.Index2( lenx, leny ) );
  518. END CopyCubeToMtx;
  519. PROCEDURE CopyMtxToCube*( src, dest: Array; dimx, dimy: Index; srcx, srcy, destx, desty, destz, lenx, leny: Index );
  520. VAR slen: ArrayXdBytes.IndexArray;
  521. BEGIN
  522. IF (src.dim # 2) OR (dest.dim # 3) THEN HALT( 1005 ) END;
  523. slen := ArrayXdBytes.Index3( 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny;
  524. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index2( srcx, srcy ), ArrayXdBytes.Index2( lenx, leny ),
  525. ArrayXdBytes.Index3( destx, desty, destz ), slen );
  526. END CopyMtxToCube;
  527. PROCEDURE CopyHCubeToMtx*( src, dest: Array; dimx, dimy: Index; srcx, srcy, srcz, srct, destx, desty, lenx, leny: Index );
  528. VAR slen: ArrayXdBytes.IndexArray;
  529. BEGIN
  530. IF (src.dim # 4) OR (dest.dim # 2) THEN HALT( 1005 ) END;
  531. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny;
  532. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen,
  533. ArrayXdBytes.Index2( destx, desty ), ArrayXdBytes.Index2( lenx, leny ) );
  534. END CopyHCubeToMtx;
  535. PROCEDURE CopyMtxToHCube*( src, dest: Array; dimx, dimy: Index;
  536. srcx, srcy, destx, desty, destz, destt, lenx, leny: Index );
  537. VAR slen: ArrayXdBytes.IndexArray;
  538. BEGIN
  539. IF (src.dim # 2) OR (dest.dim # 4) THEN HALT( 1005 ) END;
  540. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny;
  541. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index2( srcx, srcy ), ArrayXdBytes.Index2( lenx, leny ),
  542. ArrayXdBytes.Index4( destx, desty, destz, destt ), slen );
  543. END CopyMtxToHCube;
  544. PROCEDURE CopyCubeToCube*( src, dest: Array; srcx, srcy, srcz, destx, desty, destz, lenx, leny, lenz: Index );
  545. VAR slen: ArrayXdBytes.IndexArray;
  546. BEGIN
  547. IF (src.dim # 3) OR (dest.dim # 3) THEN HALT( 1005 ) END;
  548. slen := ArrayXdBytes.Index3( lenx, leny, lenz );
  549. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index3( srcx, srcy, srcz ), slen,
  550. ArrayXdBytes.Index3( destx, desty, destz ), slen );
  551. END CopyCubeToCube;
  552. PROCEDURE CopyHCubeToCube*( src, dest: Array; dimx, dimy, dimz: Index;
  553. srcx, srcy, srcz, srct, destx, desty, destz, lenx, leny, lenz: Index );
  554. VAR slen: ArrayXdBytes.IndexArray;
  555. BEGIN
  556. IF (src.dim # 4) OR (dest.dim # 3) THEN HALT( 1005 ) END;
  557. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny; slen[dimz] := lenz;
  558. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen,
  559. ArrayXdBytes.Index3( destx, desty, destz ),
  560. ArrayXdBytes.Index3( lenx, leny, lenz ) );
  561. END CopyHCubeToCube;
  562. PROCEDURE CopyCubeToHCube*( src, dest: Array; dimx, dimy, dimz: Index;
  563. srcx, srcy, srcz, destx, desty, destz, destt, lenx, leny, lenz: Index );
  564. VAR slen: ArrayXdBytes.IndexArray;
  565. BEGIN
  566. IF (src.dim # 3) OR (dest.dim # 4) THEN HALT( 1005 ) END;
  567. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny; slen[dimz] := lenz;
  568. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index3( srcx, srcy, srcz ),
  569. ArrayXdBytes.Index3( lenx, leny, lenz ),
  570. ArrayXdBytes.Index4( destx, desty, destz, destt ), slen );
  571. END CopyCubeToHCube;
  572. PROCEDURE CopyHCubeToHCube*( src, dest: Array;
  573. srcx, srcy, srcz, srct, destx, desty, destz, destt, lenx, leny, lenz, lent: Index );
  574. VAR slen: ArrayXdBytes.IndexArray;
  575. BEGIN
  576. IF (src.dim # 4) OR (dest.dim # 4) THEN HALT( 1005 ) END;
  577. slen := ArrayXdBytes.Index4( lenx, leny, lenz, lent );
  578. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen,
  579. ArrayXdBytes.Index4( destx, desty, destz, destt ), slen );
  580. END CopyHCubeToHCube;
  581. PROCEDURE CopyArrayToVec*( VAR src: ARRAY OF Value; dest: Array; srcx, destx, len: Index );
  582. BEGIN
  583. IF dest.dim # 1 THEN HALT( 1005 ) END;
  584. ArrayXdBytes.CheckLEQ( 0, srcx ); ArrayXdBytes.CheckLE( srcx + len, LEN( src ) );
  585. ArrayXdBytes.CopyMemoryToArrayPart( ADDRESSOF( src[srcx] ), dest, len, ArrayXdBytes.Index1( destx ),
  586. ArrayXdBytes.Index1( len ) );
  587. END CopyArrayToVec;
  588. PROCEDURE CopyVecToArray*( src: Array; VAR dest: ARRAY OF Value; srcx, destx, len: Index );
  589. BEGIN
  590. IF src.dim # 1 THEN HALT( 1005 ) END;
  591. ArrayXdBytes.CheckLEQ( 0, destx ); ArrayXdBytes.CheckLE( destx + len, LEN( dest ) );
  592. ArrayXdBytes.CopyArrayPartToMemory( src, ADDRESSOF( dest[destx] ), ArrayXdBytes.Index1( srcx ),
  593. ArrayXdBytes.Index1( len ), len );
  594. END CopyVecToArray;
  595. PROCEDURE CopyArrayToMtx*( VAR src: ARRAY OF ARRAY OF Value; dest: Array; srcx, srcy, destx, desty, lenx, leny: Index );
  596. VAR srcmem: ArrayXdBytes.ArrayMemoryStructure;
  597. BEGIN
  598. IF dest.dim # 2 THEN HALT( 1005 ) END;
  599. srcmem :=
  600. ArrayXdBytes.MakeMemoryStructure( 2, ArrayXdBytes.Index2( 0, 0 ), ArrayXdBytes.Index2( LEN( src, 1 ), LEN( src, 0 ) ),
  601. SIZEOF( Value ), ADDRESSOF( src[0, 0] ) );
  602. ArrayXdBytes.CopyArrayPartToArrayPart( srcmem, dest, ArrayXdBytes.Index2( srcx, srcy ),
  603. ArrayXdBytes.Index2( lenx, leny ), ArrayXdBytes.Index2( destx, desty ),
  604. ArrayXdBytes.Index2( lenx, leny ) );
  605. END CopyArrayToMtx;
  606. PROCEDURE CopyMtxToArray*( src: Array; VAR dest: ARRAY OF ARRAY OF Value; srcx, srcy, destx, desty, lenx, leny: Index );
  607. VAR destmem: ArrayXdBytes.ArrayMemoryStructure;
  608. BEGIN
  609. IF src.dim # 2 THEN HALT( 1005 ) END;
  610. destmem :=
  611. ArrayXdBytes.MakeMemoryStructure( 2, ArrayXdBytes.Index2( 0, 0 ), ArrayXdBytes.Index2( LEN( dest, 1 ), LEN( dest, 0 ) ),
  612. SIZEOF( Value ), ADDRESSOF( dest[0, 0] ) );
  613. ArrayXdBytes.CopyArrayPartToArrayPart( src, destmem, ArrayXdBytes.Index2( srcx, srcy ),
  614. ArrayXdBytes.Index2( lenx, leny ), ArrayXdBytes.Index2( destx, desty ),
  615. ArrayXdBytes.Index2( lenx, leny ) );
  616. END CopyMtxToArray;
  617. PROCEDURE CopyArrayToCube*( VAR src: ARRAY OF ARRAY OF ARRAY OF Value; dest: Array;
  618. srcx, srcy, srcz, destx, desty, destz, lenx, leny, lenz: Index );
  619. VAR srcmem: ArrayXdBytes.ArrayMemoryStructure;
  620. BEGIN
  621. IF dest.dim # 3 THEN HALT( 1005 ) END;
  622. srcmem :=
  623. ArrayXdBytes.MakeMemoryStructure( 3, ArrayXdBytes.Index3( 0, 0, 0 ),
  624. ArrayXdBytes.Index3( LEN( src, 2 ), LEN( src, 1 ), LEN( src, 0 ) ), SIZEOF( Value ),
  625. ADDRESSOF( src[0, 0, 0] ) );
  626. ArrayXdBytes.CopyArrayPartToArrayPart( srcmem, dest, ArrayXdBytes.Index3( srcx, srcy, srcz ),
  627. ArrayXdBytes.Index3( lenx, leny, lenz ),
  628. ArrayXdBytes.Index3( destx, desty, destz ),
  629. ArrayXdBytes.Index3( lenx, leny, lenz ) );
  630. END CopyArrayToCube;
  631. PROCEDURE CopyCubeToArray*( src: Array; VAR dest: ARRAY OF ARRAY OF ARRAY OF Value;
  632. srcx, srcy, srcz, destx, desty, destz, lenx, leny, lenz: Index );
  633. VAR destmem: ArrayXdBytes.ArrayMemoryStructure;
  634. BEGIN
  635. IF src.dim # 3 THEN HALT( 1005 ) END;
  636. destmem :=
  637. ArrayXdBytes.MakeMemoryStructure( 3, ArrayXdBytes.Index3( 0, 0, 0 ),
  638. ArrayXdBytes.Index3( LEN( dest, 2 ), LEN( dest, 1 ), LEN( dest, 0 ) ), SIZEOF( Value ),
  639. ADDRESSOF( dest[0, 0, 0] ) );
  640. ArrayXdBytes.CopyArrayPartToArrayPart( src, destmem, ArrayXdBytes.Index3( srcx, srcy, srcz ),
  641. ArrayXdBytes.Index3( lenx, leny, lenz ),
  642. ArrayXdBytes.Index3( destx, desty, destz ),
  643. ArrayXdBytes.Index3( lenx, leny, lenz ) );
  644. END CopyCubeToArray;
  645. PROCEDURE CopyArrayToHCube*( VAR src: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value; dest: Array;
  646. srcx, srcy, srcz, srct, destx, desty, destz, destt, lenx, leny, lenz, lent: Index );
  647. VAR srcmem: ArrayXdBytes.ArrayMemoryStructure;
  648. BEGIN
  649. IF dest.dim # 4 THEN HALT( 1005 ) END;
  650. srcmem :=
  651. ArrayXdBytes.MakeMemoryStructure( 4, ArrayXdBytes.Index4( 0, 0, 0, 0 ),
  652. ArrayXdBytes.Index4( LEN( src, 3 ), LEN( src, 2 ), LEN( src, 1 ), LEN( src, 0 ) ), SIZEOF( Value ),
  653. ADDRESSOF( src[0, 0, 0] ) );
  654. ArrayXdBytes.CopyArrayPartToArrayPart( srcmem, dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ),
  655. ArrayXdBytes.Index4( lenx, leny, lenz, lent ),
  656. ArrayXdBytes.Index4( destx, desty, destz, destt ),
  657. ArrayXdBytes.Index4( lenx, leny, lenz, lent ) );
  658. END CopyArrayToHCube;
  659. PROCEDURE CopyHCubeToArray*( src: Array; VAR dest: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value;
  660. srcx, srcy, srcz, srct, destx, desty, destz, destt, lenx, leny, lenz, lent: Index );
  661. VAR destmem: ArrayXdBytes.ArrayMemoryStructure;
  662. BEGIN
  663. IF src.dim # 4 THEN HALT( 1005 ) END;
  664. destmem :=
  665. ArrayXdBytes.MakeMemoryStructure( 4, ArrayXdBytes.Index4( 0, 0, 0, 0 ),
  666. ArrayXdBytes.Index4( LEN( dest, 3 ), LEN( dest, 2 ), LEN( dest, 1 ), LEN( dest, 0 ) ), SIZEOF( Value ),
  667. ADDRESSOF( dest[0, 0, 0] ) );
  668. ArrayXdBytes.CopyArrayPartToArrayPart( src, destmem, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ),
  669. ArrayXdBytes.Index4( lenx, leny, lenz, lent ),
  670. ArrayXdBytes.Index4( destx, desty, destz, destt ),
  671. ArrayXdBytes.Index4( lenx, leny, lenz, lent ) );
  672. END CopyHCubeToArray;
  673. PROCEDURE CopyArrayToArrayPartB*( src: Array; dest: ArrayXdBytes.ArrayMemoryStructure; boundaryCondition: SHORTINT;
  674. srcpos, srclen, destpos, destlen: ArrayXdBytes.IndexArray );
  675. VAR temp: ArrayXdBytes.ArrayMemoryStructure;
  676. spos, dpos, last, borigin, blen, srcposcut, srclencut, destoffset: ArrayXdBytes.IndexArray; i, dim: LONGINT;
  677. val: Value; temp2: Array; enumB: ArrayXdBytes.BoundaryEnum;
  678. Get: PROCEDURE {DELEGATE} ( x: ARRAY OF Index;
  679. dim: Index ): Value;
  680. noinbound: BOOLEAN; v: Value;
  681. (* for debugging
  682. PROCEDURE OutIndex( idx: ArrayXdBytes.IndexArray; name: ARRAY OF CHAR );
  683. VAR i: LONGINT;
  684. BEGIN
  685. dbgOut.String( name );
  686. FOR i := 0 TO LEN( idx ) - 1 DO dbgOut.Int( idx[i], 1 ); dbgOut.String( "," ); END;
  687. dbgOut.Ln;
  688. END OutIndex;
  689. *)
  690. PROCEDURE Same( a, b: ArrayXdBytes.IndexArray ): BOOLEAN;
  691. BEGIN
  692. IF LEN( a ) # LEN( b ) THEN RETURN FALSE END;
  693. FOR i := 0 TO LEN( a ) - 1 DO
  694. IF a[i] # b[i] THEN RETURN FALSE END;
  695. END;
  696. RETURN TRUE;
  697. END Same;
  698. BEGIN
  699. dim := src.dim;
  700. IF boundaryCondition = StrictBoundaryC THEN
  701. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, srcpos, srclen, destpos, destlen ); (* checks are done there *)
  702. ELSE
  703. srcposcut := ArrayXdBytes.IndexCpy( srcpos ); srclencut := ArrayXdBytes.IndexCpy( srclen );
  704. NEW( enumB, src, srcposcut, srclencut );
  705. IF (Same( srcposcut, srcpos )) & (Same( srclencut, srclen )) THEN (* no boundaries *)
  706. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, srcpos, srclen, destpos, destlen ); RETURN;
  707. ELSE
  708. CASE boundaryCondition OF
  709. PeriodicBoundaryC:
  710. Get := src.GetXBPeriodic;
  711. | SymmetricOnBoundaryC:
  712. Get := src.GetXBSymmetricOnB;
  713. | SymmetricOffBoundaryC:
  714. Get := src.GetXBSymmetricOffB;
  715. | AntisymmetricOnBoundaryC:
  716. Get := src.GetXBAntisymmetricOnB;
  717. | AntisymmetricOffBoundaryC:
  718. Get := src.GetXBAntisymmetricOffB;
  719. | AbsorbingBoundaryC:
  720. ArrayXdBytes.FillArrayPart( dest, destpos, destlen, val ); (* fill with 0 first *)
  721. Get := NIL;
  722. END;
  723. NEW( destoffset, dim ); noinbound := FALSE;
  724. IF Same( srclen, destlen ) THEN (* same geometry, direct copy to boundary rects can be used*)
  725. FOR i := 0 TO dim - 1 DO
  726. destoffset[i] := destpos[i] + srcposcut[i] - srcpos[i];
  727. IF srclencut[i] = 0 THEN noinbound := TRUE END;
  728. END;
  729. IF ~noinbound THEN
  730. ArrayXdBytes.CopyArrayPartToArrayPart( src, dest, srcposcut, srclencut, destoffset, srclencut );
  731. END;
  732. FOR i := 0 TO dim - 1 DO destoffset[i] := destpos[i] - srcpos[i]; END;
  733. temp := dest;
  734. ELSE (* not the same geometry, direct copy using rectangles cannot be used *)
  735. NEW( temp2, srcpos, srclen ); temp := temp2;
  736. FOR i := 0 TO dim - 1 DO
  737. destoffset[i] := 0;
  738. IF srclencut[i] = 0 THEN noinbound := TRUE END;
  739. END;
  740. IF ~noinbound THEN
  741. ArrayXdBytes.CopyArrayPartToArrayPart( src, temp, srcposcut, srclencut, srcposcut, srclencut );
  742. END;
  743. END;
  744. IF Get # NIL THEN
  745. NEW( spos, dim ); NEW( dpos, dim ); NEW( last, dim );
  746. WHILE (enumB.Get( borigin, blen )) DO (* enumeration of rects describing the region out of range *)
  747. FOR i := 0 TO dim - 1 DO spos[i] := borigin[i]; last[i] := spos[i] + blen[i]; dpos[i] := spos[i] + destoffset[i] END;
  748. REPEAT
  749. v := Get( spos^, dim );
  750. SYSTEM.MOVE( ADDRESSOF( v ), ArrayXdBytes.AdrX( temp, dpos^, dim ), SIZEOF( Value ) ); (* optimize adress handling of destination, compute here ! *)
  751. (*temp.SetX( dpos^, dim, Get( spos^, dim ) );*) i := 0; INC( spos[i] ); INC( dpos[i] );
  752. WHILE (i < dim - 1) & (spos[i] = last[i]) DO
  753. spos[i] := borigin[i]; dpos[i] := destoffset[i] + borigin[i]; INC( i ); INC( spos[i] ); INC( dpos[i] );
  754. END;
  755. UNTIL spos[i] = last[i];
  756. END;
  757. END;
  758. IF temp # dest THEN ArrayXdBytes.CopyArrayPartToArrayPart( temp, dest, srcpos, srclen, destpos, destlen );
  759. END;
  760. END;
  761. END;
  762. END CopyArrayToArrayPartB;
  763. OPERATOR ":="*( VAR l: Array; VAR r: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value );
  764. BEGIN
  765. (* IF r = NIL THEN l := NIL; RETURN END; *)
  766. IF l = NIL THEN l := New4d( 0, LEN( r, 3 ), 0, LEN( r, 2 ), 0, LEN( r, 1 ), 0, LEN( r, 0 ) );
  767. ELSE l.NewRangeX( ArrayXdBytes.Array4( 0, 0, 0, 0 ), ArrayXdBytes.Array4( LEN( r, 3 ), LEN( r, 2 ), LEN( r, 1 ), LEN( r, 0 ) ), FALSE )
  768. END;
  769. ArrayXdBytes.CopyMemoryToArray( ADDRESSOF( r[0, 0, 0, 0] ), l, LEN( r, 0 ) * LEN( r, 1 ) * LEN( r, 2 ) * LEN( r, 3 ) );
  770. END ":=";
  771. OPERATOR ":="*( VAR l: Array; VAR r: ARRAY OF ARRAY OF ARRAY OF Value );
  772. BEGIN
  773. (* IF r = NIL THEN l := NIL; RETURN END; *)
  774. IF l = NIL THEN l := New3d( 0, LEN( r, 2 ), 0, LEN( r, 1 ), 0, LEN( r, 0 ) );
  775. ELSE l.NewRangeX( ArrayXdBytes.Array3( 0, 0, 0 ), ArrayXdBytes.Array3( LEN( r, 2 ), LEN( r, 1 ), LEN( r, 0 ) ), FALSE );
  776. END;
  777. ArrayXdBytes.CopyMemoryToArray( ADDRESSOF( r[0, 0, 0] ), l, LEN( r, 0 ) * LEN( r, 1 ) * LEN( r, 2 ) );
  778. END ":=";
  779. (*
  780. OPERATOR ":="( VAR l: Array; VAR r: ARRAY OF ARRAY OF Value );
  781. BEGIN
  782. (* IF r = NIL THEN l := NIL; RETURN END; *)
  783. IF l = NIL THEN l := New2d( 0, LEN( r, 1 ), 0, LEN( r, 0 ) )
  784. ELSE l.NewRangeX( ArrayXdBytes.Array2( 0, 0 ), ArrayXdBytes.Array2( LEN( r, 1 ), LEN( r, 0 ) ), FALSE );
  785. END;
  786. ArrayXdBytes.CopyMemoryToArray( ADDRESSOF( r[0, 0] ), l, LEN( r, 0 ) * LEN( r, 1 ) );
  787. END ":=";
  788. OPERATOR ":="( VAR l: Array; VAR r: ARRAY OF Value );
  789. BEGIN
  790. (* IF r = NIL THEN l := NIL; RETURN END; *)
  791. IF l = NIL THEN l := New1d( 0, LEN( r, 0 ) )
  792. ELSE l.NewRangeX( ArrayXdBytes.Array1( 0 ), ArrayXdBytes.Array1( LEN( r, 0 ) ), FALSE );
  793. END;
  794. ArrayXdBytes.CopyMemoryToArray( ADDRESSOF( r[0] ), l, LEN( r, 0 ) );
  795. END ":=";
  796. OPERATOR ":="( VAR l: Array; r: ArrayXdInt.Array );
  797. VAR i, last: LONGINT;
  798. BEGIN
  799. IF r = NIL THEN l := NIL ELSE
  800. IF l = NIL THEN NEW( l, r.origin^, r.len^ ); END;
  801. last := LEN( r.data ) - 1;
  802. FOR i := 0 TO last DO l.data[i] := r.data[i]; END;
  803. END;
  804. END ":=";
  805. OPERATOR ":="( VAR l: Array; r: ArrayXdRat.Array );
  806. VAR i, last: LONGINT;
  807. BEGIN
  808. IF r = NIL THEN l := NIL ELSE
  809. IF l = NIL THEN NEW( l, r.origin^, r.len^ ); END;
  810. last := LEN( r.data ) - 1;
  811. FOR i := 0 TO last DO l.data[i] := r.data[i]; END;
  812. END;
  813. END ":=";
  814. *)
  815. (***!never do this : *
  816. OPERATOR ":="( VAR l: Array; r: Vector );
  817. BEGIN
  818. IF r = NIL THEN l := NIL; RETURN END;
  819. IF l = NIL THEN NEW( l, r.origin^, r.len^ ) ELSE l.NewRangeX( r.origin^, r.len^, TRUE ); END;
  820. r.CopyElements( r.origin^, r.len^, l, l.origin^, l.len^ );
  821. END ":=";
  822. *)
  823. OPERATOR ":="*( VAR l: Array1; r: Array );
  824. BEGIN
  825. IF r = NIL THEN l := NIL; RETURN END;
  826. ArrayXdBytes.CheckEQ( 1, r.dim ); (*ArrayXdBytes.CheckEQ( r.origin[0], 0 ); *)
  827. IF (l = NIL ) OR (LEN( l ) # r.len[0]) THEN NEW( l, r.len[0] ); END;
  828. ArrayXdBytes.CopyArrayToMemory( r, ADDRESSOF( l[0] ), LEN( l, 0 ) );
  829. END ":=";
  830. OPERATOR ":="*( VAR l: Array2; r: Array );
  831. BEGIN
  832. IF r = NIL THEN l := NIL; RETURN END;
  833. ArrayXdBytes.CheckEQ( 2, r.dim ); (*ArrayXdBytes.CheckEQ( r.origin[0], 0 ); ArrayXdBytes.CheckEQ( r.origin[1], 0 ); *)
  834. IF (l = NIL ) OR (LEN( l, 1 ) # r.len[0]) OR (LEN( l, 0 ) # r.len[1]) THEN NEW( l, r.len[1], r.len[0] ); END;
  835. ArrayXdBytes.CopyArrayToMemory( r, ADDRESSOF( l[0, 0] ), LEN( l, 0 ) * LEN( l, 1 ) );
  836. END ":=";
  837. OPERATOR ":="*( VAR l: Array3; r: Array );
  838. BEGIN
  839. IF r = NIL THEN l := NIL; RETURN END;
  840. ArrayXdBytes.CheckEQ( 3, r.dim ); (*ArrayXdBytes.CheckEQ( r.origin[0], 0 ); ArrayXdBytes.CheckEQ( r.origin[1], 0 ); ArrayXdBytes.CheckEQ( r.origin[2], 0 ); *)
  841. IF (l = NIL ) OR (LEN( l, 2 ) # r.len[0]) OR (LEN( l, 1 ) # r.len[1]) OR (LEN( l, 0 ) # r.len[2]) THEN NEW( l, r.len[2], r.len[1], r.len[0] ); END;
  842. ArrayXdBytes.CopyArrayToMemory( r, ADDRESSOF( l[0, 0, 0] ), LEN( l, 0 ) * LEN( l, 1 ) * LEN( l, 2 ) );
  843. END ":=";
  844. (*
  845. OPERATOR ":="( VAR l: Array4; r: Array );
  846. BEGIN
  847. IF r = NIL THEN l := NIL; RETURN END;
  848. ArrayXdBytes.CheckEQ( 4, r.dim ); (* ArrayXdBytes.CheckEQ( r.origin[0], 0 ); ArrayXdBytes.CheckEQ( r.origin[1], 0 ); ArrayXdBytes.CheckEQ( r.origin[2], 0 );
  849. ArrayXdBytes.CheckEQ( r.origin[3], 0 ); *)
  850. IF (l = NIL ) OR (LEN( l, 3 ) # r.len[0]) OR (LEN( l, 2 ) # r.len[1]) OR (LEN( l, 1 ) # r.len[2]) OR (LEN( l, 0 ) # r.len[3]) THEN
  851. NEW( l, r.len[3], r.len[2], r.len[1], r.len[0] );
  852. END;
  853. ArrayXdBytes.CopyArrayToMemory( r, ADDRESSOF( l[0, 0, 0, 0] ), LEN( l, 0 ) * LEN( l, 1 ) * LEN( l, 2 ) * LEN( l, 3 ) );
  854. END ":=";
  855. *)
  856. PROCEDURE Fill*( l: Array; r: Value );
  857. BEGIN
  858. Array1d.Fill( r, l.data^, 0, LEN( l.data ) );
  859. END Fill;
  860. OPERATOR ":="*( VAR l: Array; r: Value );
  861. BEGIN
  862. IF l # NIL THEN Fill( l, r ) END;
  863. END ":=";
  864. OPERATOR ":="*( VAR l: Array; r: ArrayXdRat.Value );
  865. VAR r1: Value;
  866. BEGIN
  867. r1 := r; l := r1;
  868. END ":=";
  869. OPERATOR ":="*( VAR l: Array; r: IntValue );
  870. VAR r1: Value;
  871. BEGIN
  872. r1 := r; l := r1;
  873. END ":=";
  874. PROCEDURE Add*( l, r, res: Array );
  875. BEGIN
  876. ArrayXdBytes.CheckEqDimensions( l, r ); Array1d.AddAA( l.data^, r.data^, res.data^, 0, LEN( res.data ) );
  877. END Add;
  878. OPERATOR "+"*( l, r: Array ): Array;
  879. VAR res: Array;
  880. BEGIN
  881. NEW( res, l.origin, l.len ); Add( l, r, res ); RETURN res;
  882. END "+";
  883. PROCEDURE Sub*( l, r, res: Array );
  884. BEGIN
  885. ArrayXdBytes.CheckEqDimensions( l, r ); Array1d.SubtractAA( l.data^, r.data^, res.data^, 0, LEN( res.data ) );
  886. END Sub;
  887. OPERATOR "-"*( l, r: Array ): Array;
  888. VAR res: Array;
  889. BEGIN
  890. NEW( res, l.origin, l.len ); Sub( l, r, res ); RETURN res;
  891. END "-";
  892. PROCEDURE Mul*( l, r, res: Array );
  893. BEGIN
  894. ArrayXdBytes.CheckEqDimensions( l, r ); Array1d.MultAA( l.data^, r.data^, res.data^, 0, LEN( res.data ) );
  895. END Mul;
  896. PROCEDURE Div*( l, r, res: Array );
  897. BEGIN
  898. ArrayXdBytes.CheckEqDimensions( l, r ); Array1d.DivAA( l.data^, r.data^, res.data^, 0, LEN( res.data ) );
  899. END Div;
  900. (*
  901. PROCEDURE Mod*( l, r, res: Array );
  902. BEGIN
  903. ArrayXdBytes.CheckEqDimensions( l, r ); Array1d.ModAA( l.data^, r.data^, res.data^, 0, LEN( res.data ) );
  904. END Mod;
  905. *)
  906. PROCEDURE AddAV*( l: Array; r: Value; res: Array );
  907. BEGIN
  908. Array1d.AddAV( l.data^, r, res.data^, 0, LEN( res.data ) );
  909. END AddAV;
  910. OPERATOR "+"( l: Array; r: Value ): Array;
  911. VAR res: Array;
  912. BEGIN
  913. NEW( res, l.origin, l.len ); AddAV( l, r, res ); RETURN res;
  914. END "+";
  915. (*
  916. OPERATOR "+"( l: Array; r: IntValue ): Array;
  917. VAR res: Array;
  918. BEGIN
  919. NEW( res, l.origin^, l.len^ ); AddAV( l, r, res ); RETURN res;
  920. END "+";
  921. *)
  922. OPERATOR "+"( l: Value; r: Array ): Array;
  923. BEGIN
  924. RETURN r + l
  925. END "+";
  926. (*
  927. OPERATOR "+"( l: IntValue; r: Array ): Array;
  928. BEGIN
  929. RETURN r + l
  930. END "+";
  931. *)
  932. PROCEDURE MulAV*( l: Array; r: Value; res: Array );
  933. BEGIN
  934. Array1d.MultAV( l.data^, r, res.data^, 0, LEN( res.data ) );
  935. END MulAV;
  936. OPERATOR "*"( l: Array; r: Value ): Array;
  937. VAR res: Array;
  938. BEGIN
  939. NEW( res, l.origin, l.len ); MulAV( l, r, res ); RETURN res;
  940. END "*";
  941. OPERATOR "*"( l: Value; r: Array ): Array;
  942. BEGIN
  943. RETURN r * l
  944. END "*";
  945. (*
  946. OPERATOR "*"( l: Array; r: IntValue ): Array;
  947. VAR res: Array;
  948. BEGIN
  949. NEW( res, l.origin^, l.len^ ); MulAV( l, r, res ); RETURN res;
  950. END "*";
  951. OPERATOR "*"( l: IntValue; r: Array ): Array;
  952. BEGIN
  953. RETURN r * l
  954. END "*";
  955. *)
  956. PROCEDURE DivAV*( l: Array; r: Value; res: Array );
  957. BEGIN
  958. Array1d.DivAV( l.data^, r, res.data^, 0, LEN( res.data ) );
  959. END DivAV;
  960. (*
  961. OPERATOR "/"( l: Array; r: Value ): Array;
  962. VAR res: Array;
  963. BEGIN
  964. NEW( res, l.origin^, l.len^ ); DivAV( l, r, res ); RETURN res;
  965. END "/";
  966. OPERATOR "/"( l: Array; r: IntValue ): Array;
  967. VAR res: Array;
  968. BEGIN
  969. NEW( res, l.origin^, l.len^ ); DivAV( l, r, res ); RETURN res;
  970. END "/";
  971. *)
  972. PROCEDURE DivVA*( l: Value; r: Array; res: Array );
  973. BEGIN
  974. Array1d.DivVA( l, r.data^, res.data^, 0, LEN( res.data ) );
  975. END DivVA;
  976. (*
  977. OPERATOR "/"( l: Value; r: Array ): Array;
  978. VAR res: Array;
  979. BEGIN
  980. NEW( res, r.origin^, r.len^ ); DivVA( l, r, res ); RETURN res;
  981. END "/";
  982. OPERATOR "/"( l: IntValue; r: Array ): Array;
  983. VAR res: Array;
  984. BEGIN
  985. NEW( res, r.origin^, r.len^ ); DivVA( l, r, res ); RETURN res;
  986. END "/";
  987. *)
  988. (*
  989. PROCEDURE ModAV*( l: Array; r: Value; res: Array );
  990. BEGIN
  991. Array1d.ModAV( l.data^, r, res.data^, 0, LEN( res.data ) );
  992. END ModAV;
  993. OPERATOR "MOD"( l: Array; r: Value ): Array;
  994. VAR res: Array;
  995. BEGIN
  996. NEW( res, l.origin^, l.len^ ); ModAV( l, r, res ); RETURN res;
  997. END "MOD";
  998. PROCEDURE ModVA*( l: Value; r: Array; res: Array );
  999. BEGIN
  1000. Array1d.ModVA( l, r.data^, res.data^, 0, LEN( res.data ) );
  1001. END ModVA;
  1002. OPERATOR "MOD"( l: Value; r: Array ): Array;
  1003. VAR res: Array;
  1004. BEGIN
  1005. NEW( res, r.origin^, r.len^ ); ModVA( l, r, res ); RETURN res;
  1006. END "MOD";
  1007. *)
  1008. PROCEDURE SubAV*( l: Array; r: Value; res: Array );
  1009. BEGIN
  1010. Array1d.SubtractAV( l.data^, r, res.data^, 0, LEN( res.data ) );
  1011. END SubAV;
  1012. (*
  1013. OPERATOR "-"( l: Array; r: Value ): Array;
  1014. VAR res: Array;
  1015. BEGIN
  1016. NEW( res, l.origin^, l.len^ ); SubAV( l, r, res ); RETURN res;
  1017. END "-";
  1018. OPERATOR "-"( l: Array; r: IntValue ): Array;
  1019. VAR res: Array;
  1020. BEGIN
  1021. NEW( res, l.origin^, l.len^ ); SubAV( l, r, res ); RETURN res;
  1022. END "-";
  1023. *)
  1024. PROCEDURE SubVA*( l: Value; r: Array; res: Array );
  1025. BEGIN
  1026. Array1d.SubtractVA( l, r.data^, res.data^, 0, LEN( res.data ) );
  1027. END SubVA;
  1028. OPERATOR "-"*( l: Value; r: Array ): Array;
  1029. VAR res: Array;
  1030. BEGIN
  1031. NEW( res, r.origin, r.len ); SubVA( l, r, res ); RETURN res;
  1032. END "-";
  1033. OPERATOR "-"*( l: IntValue; r: Array ): Array;
  1034. VAR res: Array;
  1035. BEGIN
  1036. NEW( res, r.origin, r.len ); SubVA( l, r, res ); RETURN res;
  1037. END "-";
  1038. (* The procedures needed to register an arbitrary Array so that its instances can be made persistent. *)
  1039. PROCEDURE LoadArray( R: DataIO.Reader; VAR obj: OBJECT );
  1040. VAR a: Array; version: SHORTINT; ver: NbrInt.Integer;
  1041. BEGIN
  1042. R.RawSInt( version );
  1043. IF version = -1 THEN
  1044. obj := NIL (* Version tag is -1 for NIL. *)
  1045. ELSE
  1046. IF version = VERSION THEN NEW( a, ArrayXdBytes.Array1( 0 ), ArrayXdBytes.Array1( 0 ) ); a.LoadXd( R ); obj := a
  1047. ELSE (* Encountered an unknown version number. *)
  1048. ver := version; DataErrors.IntError( ver, "Alien version number encountered." ); HALT( 1000 )
  1049. END
  1050. END
  1051. END LoadArray;
  1052. PROCEDURE StoreArray( W: DataIO.Writer; obj: OBJECT );
  1053. VAR old: Array;
  1054. BEGIN
  1055. IF obj = NIL THEN W.RawSInt( -1 ) ELSE W.RawSInt( VERSION ); old := obj( Array ); old.StoreXd( W, TRUE ) END
  1056. END StoreArray;
  1057. PROCEDURE Register;
  1058. VAR a: Array;
  1059. BEGIN
  1060. NEW( a, ArrayXdBytes.Array1( 0 ), ArrayXdBytes.Array1( 0 ) ); DataIO.PlugIn( a, LoadArray, StoreArray )
  1061. END Register;
  1062. (** Load and Store are procedures for external use that read/write an instance of an arbitrary array from/to a file. *)
  1063. PROCEDURE Load*( R: DataIO.Reader; VAR obj: Array );
  1064. VAR ptr: OBJECT;
  1065. BEGIN
  1066. R.Object( ptr ); obj := ptr( Array )
  1067. END Load;
  1068. PROCEDURE Store*( W: DataIO.Writer; obj: Array );
  1069. BEGIN
  1070. W.Object( obj )
  1071. END Store;
  1072. BEGIN
  1073. Register
  1074. END ArrayXdRe.