Recent

Author Topic: multi-dimensional open array parameter?  (Read 21038 times)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8114
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: multi-dimensional open array parameter?
« Reply #15 on: June 01, 2014, 01:23:37 pm »
Actually, if somebody wants to implement ISO level 1 compliance conformant arrays then things like this could be done. This is also the reason that triggers level 1 to appear in ISO standard (. There's a little problem though, because IMO it contradicts with this, but it could be implemented as special case just like open array.

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #16 on: June 02, 2014, 12:55:07 pm »
Thanks for all the warm replies. But it is a pity that free pascal doesn't support multi-dimensional open array parameters. To me, extending the function of one-dimensional open array parameters to the multi-dimensional case is not a big challenge to the free pascal developers.
If you think so, then implement. Welcome to open source world.
Free pascal is too huge a project for me. I completely don't know where in the source code I can edit.
Then saying it's not a big challenge is not appropriate. There are implementation details that prevent this from being implemented. Note that open array accepts ANY kind of array, static or dynamic, even partial. So how would you pass a multidimensional static and dynamic array and treat them being equal? Both have different internal representation. A static array, no matter how many dimensions, is still implemented as a flat memory data. Dynamic array, OTOH, when used with >1 dimension is an array of pointers (even as a single dimension, it's internally a pointer). Therefore, it can't be treated as flat memory data because each row is NOT adjacent. It still works for single dimension because the treatment could be equal as flat memory data.
It is a wrong direction for free pascal to accept multidimensional dynamic array by open array parameters. At least for my purpose, multidimensional static array is enough. Dynamic arrays can always be dealt with by function overloading.

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #17 on: June 02, 2014, 01:01:26 pm »
I mean using a CONSTANT matrix, say
Code: [Select]
ar2:array[0..1,0..1] of Integer=((2,-1),(-3,2));as the input of a function.

This is possible in Pascal using a user-defined type, as Juha pointed out. Such as this:
Code: [Select]
program ConstantMatrix;

type
  T2DArray = array[0..1,0..1] of integer;

const
  Array2D: T2DArray = ((2,-1),(-3,2));

  procedure SqrArray(var anArray: T2DArray);
  var
    i, j: integer;
  begin
    for i:=0 to 1 do
      for j:=0 to 1 do
        anArray[i,j]:=sqr(anArray[i,j]);
  end;

  procedure DisplayArray(anArray: T2DArray; const aTitle:string);
  var
    i, j: integer;
  begin
    WriteLn(aTitle);
    for i:=0 to 1 do begin
      for j:=0 to 1 do
        Write(anArray[i][j]:3);
      WriteLn;
    end;
  end;

var
  ar2:T2DArray;
begin
  ar2:=Array2D;
  DisplayArray(ar2,'Before:');
  SqrArray(ar2);
  DisplayArray(ar2,'After SqrArray():');
  ReadLn;
end.
Note that in my case, the function that accepts the array is in a unit for general matrix operations, which doesn't know the matrix size in advance.

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #18 on: June 02, 2014, 01:24:35 pm »
If solely the first dimension is variable it is possible:
Code: [Select]
type
 arty = array[0..1] of integer;
 
procedure test(p: array of arty);
begin
end;

const
 ar2: array[0..1] of arty = ((2,-1),(-3,2));
 
procedure test2();
begin
 test(ar2);
end;

Or use an open type parameter:

Code: [Select]
const
 ar1: array[0..1,0..1] of integer = ((2,-1),(-3,2));

procedure test3(const ar; const high1: integer; const high2: integer);
begin
end;

procedure test4();
begin
 test3(ar1,high(ar1),high(ar1[0]));
end;
It is ok that in procedure test3 you use argument 'ar' of no type to accept multidimensional arrays. Then you should perform a type conversion to a one-dimensional array to read its contents, but how large should this array be defined?

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: multi-dimensional open array parameter?
« Reply #19 on: June 02, 2014, 01:48:44 pm »
It is ok that in procedure test3 you use argument 'ar' of no type to accept multidimensional arrays. Then you should perform a type conversion to a one-dimensional array to read its contents, but how large should this array be defined?
Code: [Select]
type
  T2DIntArray = array[0..0,0..0] of integer;
  P2DIntArray = ^T2DIntArray;

  Procedure Do2ValueAverage(const inAr:P2DIntArray; Dim1,Dim2:integer);
  var
    i, j : integer;
  begin
    for i := 0 to Dim1 do
      for j := 0 to Dim2 do
       inAr^[i,j] := (inAr^[i,j]+inAr^[i+1,j]) div 2; //do no run it to the max needs more error checking.
  end;
  procedure Print(const inAr:P2DintArray; Dim1, Dim2 :integer);
  var
    i, j : integer;
  begin
    for i := 0 to Dim1 do
      for j := 0 to Dim2 do
       writeln(inAr^[i,j]);
  end;
var
  MyArray :P2DIntArray;
begin
   GetMem(MyArray, 10*20*sizeof(integer));
   FillChar(MyArray^,10*20*sizeof(integer),0);
   Do2ValueAverage(MyArray,10,19);
   Print(MyArray);
   Freemem(MyArray);
end;

and this is how dynamic arrays worked before compiler had build in support.
« Last Edit: June 02, 2014, 01:57:05 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

mse

  • Sr. Member
  • ****
  • Posts: 286
Re: multi-dimensional open array parameter?
« Reply #20 on: June 02, 2014, 05:35:31 pm »
It is ok that in procedure test3 you use argument 'ar' of no type to accept multidimensional arrays. Then you should perform a type conversion to a one-dimensional array to read its contents, but how large should this array be defined?
Use pointer arithmetic:
Code: [Select]
procedure test3(const ar; const high1: integer; const high2: integer);
var
 i,j: integer;
 po1: pinteger;
begin
 po1:= @ar;
 for i:= 0 to high1 do begin
  for j:= 0 to high2 do begin
   write(po1[i*(high1+1)+j],' ');
  end;
  writeln;
 end;
end;
Maybe there will be better performance by replacing "high" by "length".
What is the purpose of the exercise? Maybe there are better possibilities?

BeniBela

  • Hero Member
  • *****
  • Posts: 685
    • homepage
Re: multi-dimensional open array parameter?
« Reply #21 on: June 02, 2014, 10:46:46 pm »
Note that in my case, the function that accepts the array is in a unit for general matrix operations, which doesn't know the matrix size in advance.

You should never use multi dimensional arrays for  matrix operations

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: multi-dimensional open array parameter?
« Reply #22 on: June 02, 2014, 10:52:01 pm »
Note that in my case, the function that accepts the array is in a unit for general matrix operations, which doesn't know the matrix size in advance.

You should never use multi dimensional arrays for  matrix operations

tell that to svg and their 3x3 transformation matrix.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #23 on: June 03, 2014, 02:42:29 pm »
Note that in my case, the function that accepts the array is in a unit for general matrix operations, which doesn't know the matrix size in advance.

You should never use multi dimensional arrays for  matrix operations
Code: [Select]
Unit matfunc;
Interface
 Type
  Vector=Array of Extended;
  Matrix=Array of Vector;
 Function Identity(Const m:Word):Matrix;
 Function Multiply(Const mat1,mat2:Matrix):Matrix;
 Function Transpose(Const mat:Matrix):Matrix;
 Operator * (Const s:Extended;Const mat:Matrix)prod:Matrix;
 Operator + (Const mat1,mat2:Matrix)sum:Matrix;
 Operator - (Const mat1,mat2:Matrix)diff:Matrix;
 Function Operate(Const mat:Matrix;Const vec:Vector):Vector;
 Function ConstVec(Const m:Word;Const c:Extended):Vector;
 Function UnitVec(Const m,j:Word):Vector;
 Function Norm(vec:Vector):Extended;
 Operator * (Const s:Extended;Const vec:Vector)prod:Vector;
 Operator + (Const vec1,vec2:Vector)sum:Vector;
 Operator - (Const vec1,vec2:Vector)diff:Vector;
 Operator - (Const vec:Vector)minus:Vector;
 Function Gauss(Const A:Matrix;Var mat:Matrix):Word;
 Function Combine(Const mat1,mat2:Matrix):Matrix;
 Function Divide(Const mat1,mat2:Matrix):Matrix;
 Function Inverse(Const mat:Matrix):Matrix;
 Function Solve(mat:Matrix;Const vec:Vector):Vector;
 Operator * (Const vec1,vec2:Vector)prod:Vector;
 Function Exp(Const vec:Vector):Vector;overload;
 Function Cos(Const vec:Vector):Vector;overload;
 Function Sin(Const vec:Vector):Vector;overload;
 Function ChebyPts(Const m:Word):Vector;
 Function ChebyDiff(Const m:Word):Matrix;

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: multi-dimensional open array parameter?
« Reply #24 on: June 03, 2014, 03:28:18 pm »
For what purpose are these matrix calculations? If it's for realtime graphics like OpenGL (or scientific calculation), you should switch to static arrays not dynamic.

Code: [Select]
Vector=Array of Extended;
Matrix=Array of Vector;
These definitions alone are enough to cripple your performance. It's fine if you draw only a couple hundred transformed cubes, but when it comes to big landscapes and joint-animated characters, you would quickly get in trouble.
« Last Edit: June 03, 2014, 03:31:01 pm by User137 »

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #25 on: June 03, 2014, 04:01:52 pm »
For what purpose are these matrix calculations? If it's for realtime graphics like OpenGL (or scientific calculation), you should switch to static arrays not dynamic.

Code: [Select]
Vector=Array of Extended;
Matrix=Array of Vector;
These definitions alone are enough to cripple your performance. It's fine if you draw only a couple hundred transformed cubes, but when it comes to big landscapes and joint-animated characters, you would quickly get in trouble.
To do scientific calculations.

photor

  • New Member
  • *
  • Posts: 49
Re: multi-dimensional open array parameter?
« Reply #26 on: June 04, 2014, 04:18:25 am »
It is ok that in procedure test3 you use argument 'ar' of no type to accept multidimensional arrays. Then you should perform a type conversion to a one-dimensional array to read its contents, but how large should this array be defined?
Use pointer arithmetic:
Code: [Select]
procedure test3(const ar; const high1: integer; const high2: integer);
var
 i,j: integer;
 po1: pinteger;
begin
 po1:= @ar;
 for i:= 0 to high1 do begin
  for j:= 0 to high2 do begin
   write(po1[i*(high1+1)+j],' ');
  end;
  writeln;
 end;
end;
Maybe there will be better performance by replacing "high" by "length".
What is the purpose of the exercise? Maybe there are better possibilities?
It works for me, though not in the most elegant way. Thanks.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: multi-dimensional open array parameter?
« Reply #27 on: June 04, 2014, 12:36:47 pm »
It works for me, though not in the most elegant way. Thanks.
Note that the above code will only work with arrays that are defined at startup, and static arrays. It will not work with dynamic arrays however.

sean_vn

  • New member
  • *
  • Posts: 8
Re: multi-dimensional open array parameter?
« Reply #28 on: July 25, 2014, 04:54:51 am »
Telling someone to go implement it themselves in the source code is quite rude and an absurdity.
I think some of the hero members here ought to cool it a little, take a back seat and restrict themselves to wise comments.  I don't think making sport of people who are learning the ins and outs of free pascal is so clever.  If you want to show off then show off among your exact peers. 

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: multi-dimensional open array parameter?
« Reply #29 on: July 25, 2014, 06:00:51 am »
Telling someone to go implement it themselves in the source code is quite rude and an absurdity.

Nobody said that. They did ask for help in implementation from a very wise developer that said that it was easy to do so though.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64