HCubeInt.Mod 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. (* CAPO - Computational Analysis Platform for Oberon - by Alan Freed and Felix Friedrich. *)
  2. (* Version 1, Update 2 *)
  3. MODULE HCubeInt; (** AUTHOR "fof"; PURPOSE "3D matrix object of type Integer."; *)
  4. IMPORT SYSTEM, NbrInt, ArrayXdBytes, ArrayXd := ArrayXdInt, DataErrors, DataIO;
  5. CONST
  6. (** The version number used when reading/writing a hypercube to file. *)
  7. VERSION* = 1;
  8. TYPE
  9. Value* = ArrayXd.Value; Index* = LONGINT; Array* = ArrayXd.Array; Map* = ArrayXd.Map; ArrayH* = ArrayXd.Array4;
  10. (** Type HCube is DataIO registered, instances of it can therefore be made persistent. *)
  11. HCube* = OBJECT (ArrayXd.Array)
  12. VAR lenx-, leny-, lenz-, lent-: LONGINT; (* lenx = nr.Columns, leny = nr.Rows *)
  13. ox-, oy-, oz-, ot-: LONGINT;
  14. Get-: PROCEDURE {DELEGATE} ( x, y, z, t: Index ): Value;
  15. (** override *)
  16. PROCEDURE AlikeX*( ): ArrayXdBytes.Array;
  17. VAR copy: HCube;
  18. BEGIN
  19. NEW( copy, origin[0], len[0], origin[1], len[1], origin[2], len[2], origin[3], len[3] ); RETURN copy;
  20. END AlikeX;
  21. PROCEDURE NewRangeX*( neworigin, newlen: ArrayXdBytes.IndexArray; copydata: BOOLEAN );
  22. BEGIN
  23. IF LEN( newlen ) # 4 THEN HALT( 1001 ) END;
  24. NewRangeX^( neworigin, newlen, copydata );
  25. END NewRangeX;
  26. PROCEDURE ValidateCache*;
  27. BEGIN
  28. ValidateCache^;
  29. IF dim # 4 THEN HALT( 100 ) END;
  30. lenx := len[0]; leny := len[1]; lenz := len[2]; lent := len[3]; ox := origin[0]; oy := origin[1]; oz := origin[2];
  31. ot := origin[2];
  32. END ValidateCache;
  33. PROCEDURE SetBoundaryCondition*( c: SHORTINT ); (* called by new, load and directly *)
  34. BEGIN
  35. SetBoundaryCondition^( c );
  36. CASE c OF
  37. ArrayXd.StrictBoundaryC:
  38. Get := Get4;
  39. | ArrayXd.AbsorbingBoundaryC:
  40. Get := Get4BAbsorbing;
  41. | ArrayXd.PeriodicBoundaryC:
  42. Get := Get4BPeriodic;
  43. | ArrayXd.SymmetricOnBoundaryC:
  44. Get := Get4BSymmetricOnB
  45. | ArrayXd.SymmetricOffBoundaryC:
  46. Get := Get4BSymmetricOffB
  47. | ArrayXd.AntisymmetricOnBoundaryC:
  48. Get := Get4BAntisymmetricOnB
  49. | ArrayXd.AntisymmetricOffBoundaryC:
  50. Get := Get4BAntisymmetricOffB
  51. END;
  52. END SetBoundaryCondition;
  53. (** new *)
  54. PROCEDURE & New*( ox, w, oy, h, oz, d, ot, td: LONGINT );
  55. BEGIN
  56. NewXdB( ArrayXdBytes.Array4( ox, oy, oz, ot ), ArrayXdBytes.Array4( w, h, d, td ) );
  57. END New;
  58. PROCEDURE Alike*( ): HCube;
  59. VAR copy: ArrayXdBytes.Array;
  60. BEGIN
  61. copy := AlikeX(); RETURN copy( HCube );
  62. END Alike;
  63. PROCEDURE NewRange*( ox, w, oy, h, oz, d, ot, td: LONGINT; copydata: BOOLEAN );
  64. BEGIN
  65. IF (w # len[0]) OR (h # len[1]) OR (d # len[2]) OR (td # len[3]) OR (ox # origin[0]) OR (oy # origin[1]) OR
  66. (oz # origin[2]) OR (ot # origin[3]) THEN
  67. NewRangeX^( ArrayXdBytes.Array4( ox, oy, oz, ot ), ArrayXdBytes.Array4( w, h, d, td ), copydata )
  68. END;
  69. END NewRange;
  70. PROCEDURE Copy*( ): HCube;
  71. VAR res: ArrayXdBytes.Array;
  72. BEGIN
  73. res := CopyX(); RETURN res( HCube );
  74. END Copy;
  75. PROCEDURE Set*( x, y, z, t: Index; v: Value );
  76. BEGIN
  77. ArrayXdBytes.Set4( SELF, x, y, z, t, v );
  78. END Set;
  79. (** copy methods using the current boundary condition SELF.bc*)
  80. PROCEDURE CopyToVec*( dest: Array; dim: Index; srcx, srcy, srcz, srct, destx, len: Index );
  81. VAR slen: ArrayXdBytes.IndexArray;
  82. BEGIN
  83. IF (dest.dim # 1) THEN HALT( 1004 ) END;
  84. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dim] := len;
  85. CopyToArray( dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen, ArrayXdBytes.Index1( destx ),
  86. ArrayXdBytes.Index1( len ) );
  87. END CopyToVec;
  88. PROCEDURE CopyToMtx*( dest: Array; dimx, dimy: Index; srcx, srcy, srcz, srct, destx, desty, lenx, leny: Index );
  89. VAR slen: ArrayXdBytes.IndexArray;
  90. BEGIN
  91. IF (dest.dim # 2) OR (dimx >= dimy) THEN HALT( 1005 ) END;
  92. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny;
  93. CopyToArray( dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen, ArrayXdBytes.Index2( destx, desty ),
  94. ArrayXdBytes.Index2( lenx, leny ) );
  95. END CopyToMtx;
  96. PROCEDURE CopyToCube*( dest: Array; dimx, dimy, dimz: Index;
  97. srcx, srcy, srcz, srct, destx, desty, destz, lenx, leny, lenz: Index );
  98. VAR slen: ArrayXdBytes.IndexArray;
  99. BEGIN
  100. IF (dest.dim # 3) OR (dimx >= dimy) OR (dimy >= dimz) THEN HALT( 1005 ) END;
  101. slen := ArrayXdBytes.Index4( 1, 1, 1, 1 ); slen[dimx] := lenx; slen[dimy] := leny; slen[dimz] := lenz;
  102. CopyToArray( dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen, ArrayXdBytes.Index3( destx, desty, destz ),
  103. ArrayXdBytes.Index3( lenx, leny, lenz ) );
  104. END CopyToCube;
  105. PROCEDURE CopyToHCube*( dest: Array; srcx, srcy, srcz, srct, destx, desty, destz, destt, lenx, leny, lenz, lent: Index );
  106. VAR slen: ArrayXdBytes.IndexArray;
  107. BEGIN
  108. IF (dest.dim # 4) THEN HALT( 1005 ) END;
  109. slen := ArrayXdBytes.Index4( lenx, leny, lenz, lent );
  110. CopyToArray( dest, ArrayXdBytes.Index4( srcx, srcy, srcz, srct ), slen, ArrayXdBytes.Index4( destx, desty, destz, destt ),
  111. slen );
  112. END CopyToHCube;
  113. PROCEDURE CopyTo1dArray*( VAR dest: ARRAY OF Value; sx, sy, sz, st, slenx, sleny, slenz, slent: Index; dpos, dlen: LONGINT );
  114. VAR destm: ArrayXdBytes.ArrayMemoryStructure;
  115. BEGIN
  116. destm :=
  117. ArrayXdBytes.MakeMemoryStructure( 1, ArrayXdBytes.Index1( 0 ), ArrayXdBytes.Index1( LEN( dest ) ), SIZEOF( Value ),
  118. ADDRESSOF( dest[0] ) );
  119. ArrayXd.CopyArrayToArrayPartB( SELF, destm, bc, ArrayXdBytes.Index4( sx, sy, sz, st ),
  120. ArrayXdBytes.Index4( slenx, sleny, slenz, slent ), ArrayXdBytes.Index1( dpos ),
  121. ArrayXdBytes.Index1( dlen ) );
  122. END CopyTo1dArray;
  123. PROCEDURE CopyTo2dArray*( VAR dest: ARRAY OF ARRAY OF Value; sx, sy, sz, st, slenx, sleny, slenz, slent: Index;
  124. dposx, dposy, dlenx, dleny: LONGINT );
  125. VAR destm: ArrayXdBytes.ArrayMemoryStructure;
  126. BEGIN
  127. destm :=
  128. ArrayXdBytes.MakeMemoryStructure( 2, ArrayXdBytes.Index2( 0, 0 ), ArrayXdBytes.Index2( LEN( dest, 1 ), LEN( dest, 0 ) ),
  129. SIZEOF( Value ), ADDRESSOF( dest[0, 0] ) );
  130. ArrayXd.CopyArrayToArrayPartB( SELF, destm, bc, ArrayXdBytes.Index4( sx, sy, sz, st ),
  131. ArrayXdBytes.Index4( slenx, sleny, slenz, slent ),
  132. ArrayXdBytes.Index2( dposx, dposy ), ArrayXdBytes.Index2( dlenx, dleny ) );
  133. END CopyTo2dArray;
  134. PROCEDURE CopyTo3dArray*( VAR dest: ARRAY OF ARRAY OF ARRAY OF Value; sx, sy, sz, st, slenx, sleny, slenz, slent: Index;
  135. dposx, dposy, dposz, dlenx, dleny, dlenz: LONGINT );
  136. VAR destm: ArrayXdBytes.ArrayMemoryStructure;
  137. BEGIN
  138. destm :=
  139. ArrayXdBytes.MakeMemoryStructure( 3, ArrayXdBytes.Index3( 0, 0, 0 ),
  140. ArrayXdBytes.Index3( LEN( dest, 2 ), LEN( dest, 1 ), LEN( dest, 0 ) ), SIZEOF( Value ),
  141. ADDRESSOF( dest[0, 0, 0] ) );
  142. ArrayXd.CopyArrayToArrayPartB( SELF, destm, bc, ArrayXdBytes.Index4( sx, sy, sz, st ),
  143. ArrayXdBytes.Index4( slenx, sleny, slenz, slent ),
  144. ArrayXdBytes.Index3( dposx, dposy, dposz ),
  145. ArrayXdBytes.Index3( dlenx, dleny, dlenz ) );
  146. END CopyTo3dArray;
  147. PROCEDURE CopyTo4dArray*( VAR dest: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value;
  148. sx, sy, sz, st, slenx, sleny, slenz, slent: Index;
  149. dposx, dposy, dposz, dpost, dlenx, dleny, dlenz, dlent: LONGINT );
  150. VAR destm: ArrayXdBytes.ArrayMemoryStructure;
  151. BEGIN
  152. destm :=
  153. ArrayXdBytes.MakeMemoryStructure( 4, ArrayXdBytes.Index4( 0, 0, 0, 0 ),
  154. ArrayXdBytes.Index4( LEN( dest, 3 ), LEN( dest, 2 ), LEN( dest, 1 ), LEN( dest, 0 ) ), SIZEOF( Value ),
  155. ADDRESSOF( dest[0, 0, 0, 0] ) );
  156. ArrayXd.CopyArrayToArrayPartB( SELF, destm, bc, ArrayXdBytes.Index4( sx, sy, sz, st ),
  157. ArrayXdBytes.Index4( slenx, sleny, slenz, slent ),
  158. ArrayXdBytes.Index4( dposx, dposy, dposz, dpost ),
  159. ArrayXdBytes.Index4( dlenx, dleny, dlenz, dlent ) );
  160. END CopyTo4dArray;
  161. (** copy from without boundary conditions *)
  162. PROCEDURE CopyFrom1dArray*( VAR src: ARRAY OF Value; spos, slen: Index;
  163. dx, dy, dz, dt, dlenx, dleny, dlenz, dlent: Index );
  164. VAR srcm: ArrayXdBytes.ArrayMemoryStructure;
  165. BEGIN
  166. srcm :=
  167. ArrayXdBytes.MakeMemoryStructure( 1, ArrayXdBytes.Index1( 0 ), ArrayXdBytes.Index1( LEN( src ) ), SIZEOF( Value ),
  168. ADDRESSOF( src[0] ) );
  169. ArrayXdBytes.CopyArrayPartToArrayPart( srcm, SELF, ArrayXdBytes.Index1( spos ), ArrayXdBytes.Index1( slen ),
  170. ArrayXdBytes.Index4( dx, dy, dz, dt ),
  171. ArrayXdBytes.Index4( dlenx, dleny, dlenz, dlent ) );
  172. END CopyFrom1dArray;
  173. PROCEDURE CopyFrom2dArray*( VAR src: ARRAY OF ARRAY OF Value; sposx, spoxy, slenx, sleny: Index;
  174. dx, dy, dz, dt, dlenx, dleny, dlenz, dlent: Index );
  175. VAR srcm: ArrayXdBytes.ArrayMemoryStructure;
  176. BEGIN
  177. srcm :=
  178. ArrayXdBytes.MakeMemoryStructure( 2, ArrayXdBytes.Index2( 0, 0 ), ArrayXdBytes.Index2( LEN( src, 1 ), LEN( src, 0 ) ),
  179. SIZEOF( Value ), ADDRESSOF( src[0, 0] ) );
  180. ArrayXdBytes.CopyArrayPartToArrayPart( srcm, SELF, ArrayXdBytes.Index2( sposx, spoxy ),
  181. ArrayXdBytes.Index2( slenx, sleny ), ArrayXdBytes.Index4( dx, dy, dz, dt ),
  182. ArrayXdBytes.Index4( dlenx, dleny, dlenz, dlent ) );
  183. END CopyFrom2dArray;
  184. PROCEDURE CopyFrom3dArray*( VAR src: ARRAY OF ARRAY OF ARRAY OF Value; sposx, spoxy, sposz, slenx, sleny, slenz: Index;
  185. dx, dy, dz, dt, dlenx, dleny, dlenz, dlent: Index );
  186. VAR srcm: ArrayXdBytes.ArrayMemoryStructure;
  187. BEGIN
  188. srcm :=
  189. ArrayXdBytes.MakeMemoryStructure( 3, ArrayXdBytes.Index3( 0, 0, 0 ),
  190. ArrayXdBytes.Index3( LEN( src, 2 ), LEN( src, 1 ), LEN( src, 0 ) ), SIZEOF( Value ),
  191. ADDRESSOF( src[0, 0, 0] ) );
  192. ArrayXdBytes.CopyArrayPartToArrayPart( srcm, SELF, ArrayXdBytes.Index3( sposx, spoxy, sposz ),
  193. ArrayXdBytes.Index3( slenx, sleny, slenz ),
  194. ArrayXdBytes.Index4( dx, dy, dz, dt ),
  195. ArrayXdBytes.Index4( dlenx, dleny, dlenz, dlent ) );
  196. END CopyFrom3dArray;
  197. PROCEDURE CopyFrom4dArray*( VAR src: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value;
  198. sposx, spoxy, sposz, spost, slenx, sleny, slenz, slent: Index;
  199. dx, dy, dz, dt, dlenx, dleny, dlenz, dlent: Index );
  200. VAR srcm: ArrayXdBytes.ArrayMemoryStructure;
  201. BEGIN
  202. srcm :=
  203. ArrayXdBytes.MakeMemoryStructure( 4, ArrayXdBytes.Index4( 0, 0, 0, 0 ),
  204. ArrayXdBytes.Index4( LEN( src, 3 ), LEN( src, 2 ), LEN( src, 1 ), LEN( src, 0 ) ), SIZEOF( Value ),
  205. ADDRESSOF( src[0, 0, 0, 0] ) );
  206. ArrayXdBytes.CopyArrayPartToArrayPart( srcm, SELF, ArrayXdBytes.Index4( sposx, spoxy, sposz, spost ),
  207. ArrayXdBytes.Index4( slenx, sleny, slenz, slent ),
  208. ArrayXdBytes.Index4( dx, dy, dz, dt ),
  209. ArrayXdBytes.Index4( dlenx, dleny, dlenz, dlent ) );
  210. END CopyFrom4dArray;
  211. END HCube;
  212. OPERATOR ":="*( VAR l: HCube; VAR r: ARRAY OF ARRAY OF ARRAY OF ARRAY OF Value );
  213. BEGIN
  214. (* IF r = NIL THEN l := NIL; RETURN END; *)
  215. IF l = NIL THEN NEW( l, 0, LEN( r, 3 ), 0, LEN( r, 2 ), 0, LEN( r, 1 ), 0, LEN( r, 0 ) )
  216. ELSE l.NewRange( 0, LEN( r, 3 ), 0, LEN( r, 2 ), 0, LEN( r, 1 ), 0, LEN( r, 0 ), FALSE )
  217. END;
  218. ArrayXdBytes.CopyMemoryToArrayPart( ADDRESSOF( r[0, 0, 0, 0] ), l, LEN( r, 0 ) * LEN( r, 1 ) * LEN( r, 2 ) * LEN( r, 3 ), NIL , NIL );
  219. END ":=";
  220. OPERATOR ":="*( VAR l: HCube; r: Value );
  221. BEGIN
  222. IF l # NIL THEN ArrayXd.Fill( l, r ); END;
  223. END ":=";
  224. OPERATOR "+"*( l, r: HCube ): HCube;
  225. VAR res: HCube;
  226. BEGIN
  227. res := l.Alike(); ArrayXd.Add( l, r, res ); RETURN res;
  228. END "+";
  229. OPERATOR "-"*( l, r: HCube ): HCube;
  230. VAR res: HCube;
  231. BEGIN
  232. res := l.Alike(); ArrayXd.Sub( l, r, res ); RETURN res;
  233. END "-";
  234. OPERATOR "+"*( l: HCube; r: Value ): HCube;
  235. VAR res: HCube;
  236. BEGIN
  237. res := l.Alike(); ArrayXd.AddAV( l, r, res ); RETURN res;
  238. END "+";
  239. OPERATOR "+"*( l: Value; r: HCube ): HCube;
  240. BEGIN
  241. RETURN r + l
  242. END "+";
  243. OPERATOR "-"*( l: HCube; r: Value ): HCube;
  244. VAR res: HCube;
  245. BEGIN
  246. res := l.Alike(); ArrayXd.SubAV( l, r, res ); RETURN res;
  247. END "-";
  248. OPERATOR "-"*( l: Value; r: HCube ): HCube;
  249. VAR res: HCube;
  250. BEGIN
  251. res := r.Alike(); ArrayXd.SubVA( l, r, res ); RETURN res;
  252. END "-";
  253. OPERATOR "-"*( l: HCube ): HCube;
  254. BEGIN
  255. RETURN 0 - l;
  256. END "-";
  257. OPERATOR "*"*( l: HCube; r: Value ): HCube;
  258. VAR res: HCube;
  259. BEGIN
  260. res := l.Alike(); ArrayXd.MulAV( l, r, res ); RETURN res;
  261. END "*";
  262. OPERATOR "*"*( l: Value; r: HCube ): HCube;
  263. BEGIN
  264. RETURN r * l;
  265. END "*";
  266. OPERATOR "DIV"*( l: HCube; r: Value ): HCube;
  267. VAR res: HCube;
  268. BEGIN
  269. res := l.Alike(); ArrayXd.DivAV( l, r, res ); RETURN res;
  270. END "DIV";
  271. OPERATOR "DIV"*( l: Value; r: HCube ): HCube;
  272. VAR res: HCube;
  273. BEGIN
  274. res := r.Alike(); ArrayXd.DivVA( l, r, res ); RETURN res;
  275. END "DIV";
  276. OPERATOR "MOD"*( l: HCube; r: Value ): HCube;
  277. VAR res: HCube;
  278. BEGIN
  279. res := l.Alike(); ArrayXd.ModAV( l, r, res ); RETURN res;
  280. END "MOD";
  281. OPERATOR "MOD"*( l: Value; r: HCube ): HCube;
  282. VAR res: HCube;
  283. BEGIN
  284. res := r.Alike(); ArrayXd.ModVA( l, r, res ); RETURN res;
  285. END "MOD";
  286. (* The procedures needed to register type HCube so that its instances can be made persistent. *)
  287. PROCEDURE LoadHCube( R: DataIO.Reader; VAR obj: OBJECT );
  288. VAR a: HCube; version: SHORTINT; ver: NbrInt.Integer;
  289. BEGIN
  290. R.RawSInt( version );
  291. IF version = -1 THEN
  292. obj := NIL (* Version tag is -1 for NIL. *)
  293. ELSIF version = VERSION THEN NEW( a, 0, 0, 0, 0, 0, 0, 0, 0 ); a.Read( R ); obj := a
  294. ELSE ver := version; DataErrors.IntError( ver, "Alien version number encountered." ); HALT( 1000 )
  295. END
  296. END LoadHCube;
  297. PROCEDURE StoreHCube( W: DataIO.Writer; obj: OBJECT );
  298. VAR a: HCube;
  299. BEGIN
  300. IF obj = NIL THEN W.RawSInt( -1 ) ELSE W.RawSInt( VERSION ); a := obj( HCube ); a.Write( W ) END
  301. END StoreHCube;
  302. PROCEDURE Register;
  303. VAR a: HCube;
  304. BEGIN
  305. NEW( a, 0, 0, 0, 0, 0, 0, 0, 0 ); DataIO.PlugIn( a, LoadHCube, StoreHCube )
  306. END Register;
  307. (** Load and Store are procedures for external use that read/write an instance of HCube from/to a file. *)
  308. PROCEDURE Load*( R: DataIO.Reader; VAR obj: HCube );
  309. VAR ptr: OBJECT;
  310. BEGIN
  311. R.Object( ptr ); obj := ptr( HCube )
  312. END Load;
  313. PROCEDURE Store*( W: DataIO.Writer; obj: HCube );
  314. BEGIN
  315. W.Object( obj )
  316. END Store;
  317. BEGIN
  318. Register
  319. END HCubeInt.