|
From: | Michael Riedl |
Subject: | Re: Dynamic mutidimensional arrays |
Date: | Mon, 3 Apr 2023 23:33:23 +0200 |
User-agent: | Mozilla/5.0 (X11; Linux i686; rv:102.0) Gecko/20100101 Thunderbird/102.9.0 |
Gaius,
in a lot of cases within linear algebra routines one has a need to have intermediate multidimensional arrays (mostly 2-dimensional, but I also had more dimensions) which would only be needed within the scope of the procedure.
A simple sample might be that we need to multiply two matrices and, in the end, one is only interrested in some special aspects of this result (e.g. the lowest eigenvalues).
How would you handle such a case ?
As said, in Oberon it would work as suggested, but also in modern Fortran that is not implement too different (sample code below), gfortran can compile the code without issues.
But I just wanted to see if that would be of principal interrest - if it would reqite too much work, I can live with static allocation for the moment.
Mainly it would be a chance to make code more readable and to avoide wasting too much memory in the case you define the maximun size of a problem the code can handle with static declarations.
Michael
PROGRAM DynArray
Michael Riedl <udo-michael.riedl@t-online.de> writes:Gaius, all, I have a questions / suggest about a possible extension of GM2. Would it be possible to have dynamic multidimensional arrays implemented ? We have multidimensional open array as procedure parameter, but if we come to the main module we already need to know the (maximal) dimension of e.g. a matrix - that does not make a lot of sense in my view. Especially if you have more complex programs where you do not know upfront the dimensions of the problem you would like to handle. A small sample code illustrating the approach below - the code should work with AWD Modula, XDS M2 and the P1 compiler - it's the way Oberon addresses the issue (without the "DISPOSE"). Thanks for some feedback Michael ---------------------------------------------------------------------- MODULE DynArray; TYPE tVECTOR = ARRAY OF REAL; (* 1-dim open array *) tMATRIX = ARRAY OF tVECTOR; (* 2-dim open array *) tPtrVECTOR = POINTER TO tVECTOR; (* pointer to open 1-dim array *) tPtrMATRIX = POINTER TO tMATRIX; (* pointer to open 2-dim array *) PROCEDURE MultMatVek( M,N : CARDINAL; VAR A : ARRAY OF ARRAY OF REAL; (* in *) VAR B : ARRAY OF REAL; (* in *) VAR C : ARRAY OF REAL); (* out *) (* multiply matrix A[M,N] times vector B[N], result is vector C[M] *) VAR i,j : CARDINAL; s : REAL; BEGIN FOR i:=0 TO M-1 DO s := 0.0; FOR j:=0 TO N-1 DO s:=s + A[i,j]*B[j]; END; C[i] := s; END; (* FOR i *) END MultMatVek; VAR A : tPtrMATRIX; B,C : tPtrVECTOR; M,N,i,j : CARDINAL; BEGIN M := 4; N := 3; (* suppose M and N are read in from some (external) source ... *) NEW(A,M,N); NEW(B,N); NEW(C,M); FOR i:=0 TO M-1 DO (* some code to initialize A,B ... *) FOR j:=0 TO N-1 DO A^[i,j] := VAL(REAL,i+j); END; END; FOR i:=0 TO N-1 DO B^[i] := VAL(REAL,i); END; MultMatVek(M,N,A^,B^,C^); (* Some code to output the result C ... *) DISPOSE(A); DISPOSE(B); DISPOSE(C); END DynArray.Hello Michael, interesting - yes I see it would be useful. I'd like to implement the ISO generics, ISO OO and M2R10. But I do see implementing open array variables could be an easy win (and fit with the current implementation of open array parameters). How about: MODULE DynArray ; PROCEDURE MultMatVek (M, N: CARDINAL; VAR A: ARRAY OF ARRAY OF REAL ; (* in *) VAR B: ARRAY OF REAL; (* in *) VAR C: ARRAY OF REAL) ; (* out *) (* multiply matrix A[M,N] times vector B[N], result is vector C[M] *) VAR i, j: CARDINAL; s : REAL; BEGIN FOR i:=0 TO M-1 DO s := 0.0; FOR j:=0 TO N-1 DO s:=s + A[i,j]*B[j]; END; C[i] := s; END; (* FOR i *) END MultMatVek; PROCEDURE Init (M, N: CARDINAL) ; VAR (* A, B and C are created at runtime via alloca and are internally implemented in the same way as procedure parameters. *) A : ARRAY <0..M-1> OF ARRAY <0..N-1> OF REAL ; B, C: ARRAY <0..N-1> OF REAL ; BEGIN FOR i:=0 TO M-1 DO (* some code to initialize A,B ... *) FOR j:=0 TO N-1 DO A[i,j] := VAL (REAL,i+j) END; END; FOR i:=0 TO N-1 DO B[i] := VAL(REAL,i); END; MultMatVek (M, N, A, B, C); (* Some code to output the result C ... *) END END Init ; VAR M, N: CARDINAL ; BEGIN M := ReadCard () ; N := ReadCard () ; Init (M, N) END DynArray. as a suggestion? Although it requires further thought to re-examine the ebnf and change it to restrict the use of open array variables to procedures (although I guess one could provide some form of alloca (similar to your NEW example)) for the global variables regards, Gaius
[Prev in Thread] | Current Thread | [Next in Thread] |