home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!rpi!usenet.coe.montana.edu!news.u.washington.edu!ogicse!reed!orpheus
- From: orpheus@reed.edu (P. Hawthorne)
- Newsgroups: comp.lang.pascal
- Subject: Re: Matrix routines in pascal
- Message-ID: <1992Jul30.010006.19073@reed.edu>
- Date: 30 Jul 92 01:00:06 GMT
- Article-I.D.: reed.1992Jul30.010006.19073
- References: <1992Jul29.162918.13707@csi.jpl.nasa.gov> <Bs5wKs.3pE@knot.ccs.queensu.ca>
- Distribution: usa
- Organization: Reed College, Portland, OR
- Lines: 97
-
-
- eldred@rrunner.jpl.nasa.gov (Dan Eldred) writes:
- : If you have a pascal compiler that allows conformant arrays, this is pretty
- : easy--either do Fortran style calls in which the dimensions are passed as
- : parameters, or pass a record structure which has the dimensions embedded.
- : But I'm having trouble coming up with a satisfactory strategy for ANS
- : pascal (i.e. Think Pascal 4.0 on the Mac). Suggestions?
-
- dmurdoch@QueensU.CA (Duncan Murdoch) writes:
- : Think Pascal includes OOP extensions, doesn't it? If so, making a matrix
- : object is probably the best way to go. That's how I handle matrices in
- : Turbo Pascal. The big problem there is the 64K limit on size; that means I
- : have to go through all sorts of gyrations to handle large matrices, since
- : 90 by 90 is the biggest matrix of doubles that fits in 64K.
-
- Yeah, this sounds right to me, as far as it goes. Make a matrix class
- that knows it's own dimensions. Give it methods for the desired matrix
- operations. It's a textbook case for OOP. There are some other concerns...
-
- In Object Pascal, objects are relocatable memory blocks unless you get
- around that requirement somehow. This can mean that they can relocate on
- you at many points during code execution, which can really confuse the
- things. So, in general, you would want to keep that object moved high in
- the heap and locked down when it is in use. You can do that with the
- HLock, HUnlock and MoveHHi traps.
-
- Another thing is that the 68000 series have a 16 bit address register
- indirect addressing mode. This means it can only do array references the
- easy way up to a limit of 32k. (Well, you could use negative array indexes
- and get that other 32k, but that's somewhat beside the point.) So, if you
- have a matrix which grows beyond 32K, you want to calculate the addresses
- of each element on your own.
-
- All of that being said, here's some code for a simple matrix. It expects
- the topmost leftmost corner to be at 1,1, but you can easily change that.
- It also adjusts to handle elements of arbitrary size, which could be the
- size of the extended format. If you're going to use a Mac, you might as
- well benefit from the keen numeric environment it sports... :-)
-
- QMatrix = object(QContent)
- EntrySize: Longint;
- EntriesAcross: Longint;
- EntriesDown: Longint;
- Entries: EntryArray;
-
- function QMatrix.Construct: Boolean;
- override;
-
- procedure QMatrix.SetEntry (x, y: Longint; aPtr: univ Ptr);
- procedure QMatrix.GetEntry (x, y: Longint; aPtr: univ Ptr);
- end;
-
- {Clean is essentially the same as Think Pascal's ORD4, but it also does
- the equivalent of a call to StripAddress. There's not much reason to worry
- about doing that unless you need to be 32 and 24 bit clean.}
-
- function QMatrix.Construct: Boolean;
- begin
- Construct := false;
- Lock;
- if EntrySize = 0 then
- EntrySize := 4;
- if Grow(Clean(@Entries) - Clean(Handle(Self)^) + (EntriesAcross * EntriesDown
- * EntrySize)) <> noErr then
- Exit(Construct);
- Construct := true;
- end;
-
- procedure QMatrix.SetEntry (x, y: Longint; aPtr: univ Ptr);
- begin
- BlockMove(aPtr, Ptr(Clean(@Entries) + (x - 1 + (y - 1) * EntriesAcross) *
- EntrySize), EntrySize);
- end;
-
- procedure QMatrix.GetEntry (x, y: Longint; aPtr: univ Ptr);
- begin
- BlockMove(Ptr(Clean(@Entries) + (x - 1 + (y - 1) * EntriesAcross) *
- EntrySize), aPtr, EntrySize);
- end;
-
- {The Grow method is inherited. It adjusts the size of the handle that
- contains the object, making it the intended size. Here's that:}
-
- function Abstract.Grow (intended: Longint): OSErr;
- var
- state: SignedByte;
- begin
- state := HGetState(Handle(Self));
- HUnlock(Handle(Self));
- SetHandleSize(Handle(Self), intended);
- Grow := MemError;
- if state = -128 then
- MoveHHi(Handle(Self)); {Skanky little hack, but harmless}
- HSetState(Handle(Self), state);
- end;
-
- Theus (orpheus@reed.edu)
-