home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / pascal / 4607 < prev    next >
Encoding:
Internet Message Format  |  1992-07-29  |  4.2 KB

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!rpi!usenet.coe.montana.edu!news.u.washington.edu!ogicse!reed!orpheus
  2. From: orpheus@reed.edu (P. Hawthorne)
  3. Newsgroups: comp.lang.pascal
  4. Subject: Re: Matrix routines in pascal
  5. Message-ID: <1992Jul30.010006.19073@reed.edu>
  6. Date: 30 Jul 92 01:00:06 GMT
  7. Article-I.D.: reed.1992Jul30.010006.19073
  8. References: <1992Jul29.162918.13707@csi.jpl.nasa.gov> <Bs5wKs.3pE@knot.ccs.queensu.ca>
  9. Distribution: usa
  10. Organization: Reed College, Portland, OR
  11. Lines: 97
  12.  
  13.  
  14.   eldred@rrunner.jpl.nasa.gov (Dan Eldred) writes:
  15. : If you have a pascal compiler that allows conformant arrays, this is pretty
  16. : easy--either do Fortran style calls in which the dimensions are passed as
  17. : parameters, or pass a record structure which has the dimensions embedded.
  18. : But I'm having trouble coming up with a satisfactory strategy for ANS
  19. : pascal (i.e. Think Pascal 4.0 on the Mac). Suggestions?
  20.  
  21.   dmurdoch@QueensU.CA (Duncan Murdoch) writes:
  22. : Think Pascal includes OOP extensions, doesn't it? If so, making a matrix
  23. : object is probably the best way to go. That's how I handle matrices in
  24. : Turbo Pascal. The big problem there is the 64K limit on size; that means I
  25. : have to go through all sorts of gyrations to handle large matrices, since
  26. : 90 by 90 is the biggest matrix of doubles that fits in 64K.
  27.  
  28.   Yeah, this sounds right to me, as far as it goes. Make a matrix class
  29. that knows it's own dimensions. Give it methods for the desired matrix
  30. operations. It's a textbook case for OOP. There are some other concerns...
  31.  
  32.   In Object Pascal, objects are relocatable memory blocks unless you get
  33. around that requirement somehow. This can mean that they can relocate on
  34. you at many points during code execution, which can really confuse the
  35. things. So, in general, you would want to keep that object moved high in
  36. the heap and locked down when it is in use. You can do that with the
  37. HLock, HUnlock and MoveHHi traps.
  38.  
  39.   Another thing is that the 68000 series have a 16 bit address register
  40. indirect addressing mode. This means it can only do array references the
  41. easy way up to a limit of 32k. (Well, you could use negative array indexes
  42. and get that other 32k, but that's somewhat beside the point.) So, if you
  43. have a matrix which grows beyond 32K, you want to calculate the addresses
  44. of each element on your own.
  45.  
  46.   All of that being said, here's some code for a simple matrix. It expects
  47. the topmost leftmost corner to be at 1,1, but you can easily change that.
  48. It also adjusts to handle elements of arbitrary size, which could be the
  49. size of the extended format. If you're going to use a Mac, you might as
  50. well benefit from the keen numeric environment it sports... :-)
  51.  
  52.  QMatrix = object(QContent)
  53.    EntrySize: Longint;
  54.    EntriesAcross: Longint;
  55.    EntriesDown: Longint;
  56.    Entries: EntryArray;
  57.  
  58.    function QMatrix.Construct: Boolean;
  59.    override;
  60.  
  61.    procedure QMatrix.SetEntry (x, y: Longint; aPtr: univ Ptr);
  62.    procedure QMatrix.GetEntry (x, y: Longint; aPtr: univ Ptr);
  63.   end;
  64.  
  65. {Clean is essentially the same as Think Pascal's ORD4, but it also does
  66. the equivalent of a call to StripAddress. There's not much reason to worry
  67. about doing that unless you need to be 32 and 24 bit clean.}
  68.  
  69. function QMatrix.Construct: Boolean;
  70.  begin
  71.  Construct := false;
  72.  Lock;
  73.  if EntrySize = 0 then
  74.   EntrySize := 4;
  75.  if Grow(Clean(@Entries) - Clean(Handle(Self)^) + (EntriesAcross * EntriesDown
  76. * EntrySize)) <> noErr then
  77.   Exit(Construct);
  78.  Construct := true;
  79.  end;
  80.  
  81. procedure QMatrix.SetEntry (x, y: Longint; aPtr: univ Ptr);
  82.  begin
  83.  BlockMove(aPtr, Ptr(Clean(@Entries) + (x - 1 + (y - 1) * EntriesAcross) *
  84. EntrySize), EntrySize);
  85.  end;
  86.  
  87. procedure QMatrix.GetEntry (x, y: Longint; aPtr: univ Ptr);
  88.  begin
  89.  BlockMove(Ptr(Clean(@Entries) + (x - 1 + (y - 1) * EntriesAcross) *
  90. EntrySize), aPtr, EntrySize);
  91.  end;
  92.  
  93. {The Grow method is inherited. It adjusts the size of the handle that
  94. contains the object, making it the intended size. Here's that:}
  95.  
  96. function Abstract.Grow (intended: Longint): OSErr;
  97.  var
  98.   state: SignedByte;
  99.  begin
  100.  state := HGetState(Handle(Self));
  101.  HUnlock(Handle(Self));
  102.  SetHandleSize(Handle(Self), intended);
  103.  Grow := MemError;
  104.  if state = -128 then
  105.   MoveHHi(Handle(Self)); {Skanky little hack, but harmless}
  106.  HSetState(Handle(Self), state);
  107.  end;
  108.  
  109.   Theus (orpheus@reed.edu)
  110.