gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dynamic mutidimensional arrays


From: Fischlin Andreas
Subject: Re: Dynamic mutidimensional arrays
Date: Wed, 5 Apr 2023 07:39:33 +0000

Dear Michael,

Of course

val := value(A,i,k) * value(B,k,j);

Andreas


ETH Zurich
Prof. em. Dr. Andreas Fischlin
IPCC Vice-Chair WGII
Systems Ecology - Institute of Biogeochemistry and Pollutant Dynamics
CHN E 24
Universitaetstrasse 16
8092 Zurich
SWITZERLAND


+41 44 633-6090 phone
+41 44 633-1136 fax
+41 79 595-4050 mobile

             Make it as simple as possible, but distrust it!
________________________________________________________________________









On Wed, 05.04.23, at 09:08, Michael Riedl <udo-michael.riedl@t-online.de> wrote:

Benjamin,

thanks for the detailed answer - but it still does not become clear to me.

How would I (without and "surrounding") do a simple

    val := A[i,k] * B[k,j];

just as a core _expression_. And how can you, with such an approach, interface e.g. to libraies such as Lapack or Blas,

just to name two.

Gruß

Michael

Am 05.04.23 um 01:52 schrieb Benjamin Kowarsch:

On Wed, 5 Apr 2023 at 04:43, Michael Riedl <udo-michael.riedl@t-online.de> wrote:

actually I do not see your approach to be "easy" at all.

So please can you line out how the short sample I lined out should look like ?

I'll give you the public interface to the entire library instead.

With that you can allocate, initialise, introspect and operate on arbitrarily sized matrices.

DEFINITION MODULE Matrix;

IMPORT Vector;
FROM Vector IMPORT VectorT;

TYPE Matrix; (* OPAQUE *)

TYPE MatrixT = Matrix; (* for unqualified use *)

(* allocator, passes back null matrix *)
PROCEDURE New ( VAR m : Matrix; rows, columns : CARDINAL );

(* introspection *)
PROCEDURE rowCount ( m : Matrix ) : CARDINAL;

PROCEDURE columnCount ( m : Matrix ) : CARDINAL;

PROCEDURE isInvertible ( m : Matrix ) : BOOLEAN;

(* constructors *)
PROCEDURE NewWithRows ( VAR m : Matrix; rowValues : ARRAY OF VectorT );

PROCEDURE NewWithColumns ( VAR m : Matrix; colValues : ARRAY OF VectorT );

(* mutators *)
PROCEDURE StoreValue ( m : Matrix; row, col : CARDINAL; value : REAL );

PROCEDURE StoreRow ( m : Matrix; rowIndex : CARDINAL; rowValues : ARRAY OF VectorT );

PROCEDURE StoreColumn ( m : Matrix; colIndex : CARDINAL; colValues : ARRAY OF VectorT );

(* accessors *)
PROCEDURE value ( m : Matrix; row, col : CARDINAL ) : REAL;

PROCEDURE row ( m : Matrix; rowIndex : CARDINAL ) : VectorT;

PROCEDURE column ( m : Matrix; colIndex : CARDINAL ) : Vector T;

(* operations *)
PROCEDURE eq ( m1, m2 : Matrix ) : BOOLEAN;

PROCEDURE sum ( m1, m2 : Matrix ) : Matrix;

PROCEDURE diff ( m1, m2 : Matrix ) : Matrix;

PROCEDURE prod ( m1, m2 : Matrix ) : Matrix;

PROCEDURE scalarProd ( m : Matrix; scalar : REAL ) : Matrix;

PROCEDURE vectorProd ( m : Matrix; vector : VectorT ) : VectorT;

PROCEDURE inverse ( m : Matrix ) : Matrix;

PROCEDURE transpose ( m : Matrix ) : Matrix;

(* destructor, deallocates and passes back NIL *)
PROCEDURE Release ( VAR m : Matrix );

END Matrix.

The Vector type module follows the same pattern, so I omitted it.

I believe you can do the implementation for this yourself, so I omitted that, too.

Note that you can implement this in PIM and ISO without the need for any additional features. However, since neither PIM nor ISO provide any facility to declare a record field of indeterminate size, you need to use an ADDRESS field and then use address arithmetic to access the individual values.

TYPE Matrix = RECORD
  rows, columns : CARDINAL;
  capacity : LONGCARD;
  data : ADDRESS
END; (* Matrix *)

Doing the address arithmetic will look very messy and represents plenty of opportunity for error. In this way it is even less safe than doing it in C. But it can be done and the unholy mess is hidden in the implementation module. Once you've got it working, you will only ever use the public interface.

By contrast, with the facility of records with indeterminate fields that I described does not rely on address arithmetic, it allows the use of array subscripts to address the values of the array field, clean and safe, as it should be in Modula-2.

(* type declaration in implementation module *)
TYPE Matrix = POINTER TO RECORD
  rows, columns : CARDINAL
+ data : ARRAY capacity OF REAL
END; (* Matrix *)

I hope this clarifies.

regards
benjamin

Attachment: smime.p7s
Description: S/MIME cryptographic signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]