### Author Topic: a multi-dimensional Safearray attempt with dynamic index  (Read 1947 times)

0 Members and 1 Guest are viewing this topic.

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### a multi-dimensional Safearray attempt with dynamic index
« on: June 12, 2018, 08:34:10 PM »
complicated this,
macro also did not accept to apply the pointer in its interior
I will do a cleanup on the amount of arrays and try to add a single control macro, and also add a redim preserve

Code: [Select]
`'indexbase 0skip { arrayN( -2 to 5 , 3 to 10 ) ' 3 4 5 6 7 8 9 10 { 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7, ' -2 8 ,9 ,10 ,11 ,12 ,13 ,14 ,15,' -1 16 ,17 ,18 ,19 ,20 ,21 ,22 ,23,' 0 24 ,25 ,26 ,27 ,28 ,29 ,30 ,31,' 1 32 ,33 ,34 ,35 ,36 ,37 ,38 ,39,' 2 40 ,41 ,42 ,43 ,44 ,45 ,46 ,47,' 3 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55,' 4 56 ,57 ,58 ,59 ,60 ,61 ,62 ,63}' 5 } int n0,n1dim L, C,anL=3redim long ArrayNx_M(L)redim int LBoundNx_M(L*3)redim int UBoundNx_M(L*3)redim int TBoundNx_M(L*3)redim LONG  IBoundNx_M(L*3)int *Arr1function  CriaArray(int  ArrayNx,        int Linha_Lbound,int Linha_Ubound, int Coluna_Lbound,int Coluna_Ubound) int n= ArrayNx LBoundNx_M(N)=Linha_Lbound UBoundNx_M(N)=Linha_Ubound IBoundNx_M(N)=-Linha_Lbound TBoundNx_M(N)=abs(Linha_Lbound - Linha_Ubound)+1 LBoundNx_M(N+1)=Coluna_Lbound UBoundNx_M(N+1)=Coluna_Ubound IBoundNx_M(N+1)=-Coluna_Lbound TBoundNx_M(N+1)=abs(Coluna_Lbound - Coluna_Ubound)+1 ArrayNx_M(n)=getmemory TBoundNx_M(N)*TBoundNx_M(N+1)*sizeof int end functionMACRO ARRAYnx_C(AN , L,C) '@Arr1= ArrayNx_M(an) '<<<<<<<< int B=(L+IBoundNx_M(AN))*TBoundNx_M(AN+1)+(c+IBoundNx_M(AN+1)) Arr1(B) END MACROan=1CriaArray(an, -2,5,3,10)@Arr1= ArrayNx_M(an)     '<<<<<int n=0for L=LBoundNx_M(aN) to uBoundNx_M(aN) for  c=LBoundNx_M(aN+1) to uBoundNx_M(aN+1) ARRAYnx_C(AN, L , C)=N n=n+1 nextnextL=-1C=8PRINT ARRAYnx_C(AN, L , C)PRINT ARRAYnx_C(AN, 3 , 6)`

I have to set up a matrix cleanup function "after learning how to do it"
« Last Edit: June 13, 2018, 03:31:24 PM by Eduardo Jorge »

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #1 on: June 13, 2018, 04:36:19 PM »
Eduardo,

Got it!

There are too many state-variables here for macros. They would not provide a clean solution. You need to use an object to contain all the variables and functions associated with the array.

I suggest something like this: (you can adapt it)

Code: [Select]
`'2018-06-13T15:03:24class IntArrayYX================  '  %= si sizeof(int)  '  int lboundX 'lower limit X  int uboundX 'upper limit X  int lboundY 'lower limit Y  int uboundY 'upper limit Y  int width  sys buf    'data buffer  int bytes  'sizeof buffer  '  method constructor(int ly=0, uy=0, lx=0, ux=0)  ===============================================  'ly lbound y lines  'uy ubound y lines  'lx lbound x rows  'ux ubound x rows  lboundY=ly  uboundY=uy  lboundX=lx  uboundX=ux  width=(uboundx-lboundx+1)  bytes=si*(uboundy-lboundy+1)*width  buf=getmemory bytes  end method  '  method destructor()  ===================  freememory buf  end method  '  method vi(int i, j, int v)  ==========================  'SET  'i index  'v value  int a at buf+si*( (i-lboundy)*width+(j-lboundx) )  a=v  end method  '  method vi(int i, j) as int  ==========================  'GET  'i index  int a at buf+si*( (i-lboundy)*width+(j-lboundx) )  return a  end method  '  method ptr(int i, j) as sys  ===========================  'GET POINTER  'i index  return buf+si*( (i-lboundy)*width+(j-lboundx) )  end method  'end class''TESTS======new IntArrayYX ia(-10,20,30,40) 'lbound,ubound pairsprint ia.lboundY ", " ia.bytesia.vi(-5,31)=42print ia.vi(-5,31)del ia`

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #2 on: June 13, 2018, 05:19:41 PM »
Charles,
I'm doing this is more to learn and assimilate the workings of the O2 macros, scope and pointers,
and also the operation of the code structure.

but what about the index of the array?
the fact of having to put the value already calculated inside a variable to apply to the array?
this can cause problems because it accepts simple calculations and the person will be left without realizing errors by complex calculations like index

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #3 on: June 13, 2018, 06:12:42 PM »
This is an example of a macro function to access an array of pixels. It does not involve Lbound and Ubound terms, so it is a simpler situation.

Macro functions work by creating a temporary variable, which is substituted into the expression, replacing the macro invocation.

Code: [Select]
`indexbase 0int pix[800*600]'macro pix2d int* (v,x,y,  vv)=============================  'v  return pixel pointer supporting read/write  'x  horizontal coordinate  'y  vertical coodinate  'vv sink pixel  if x>=0 and x<800 and y>=0 and y<600    @v=@pix(y*800+x)  else    int vv=0xffffffff 'value when out of bounds    @v=@vv  end ifend macro''TESTpix2d(1,20)=0xaabbccddprint hex pix2d(1,20)print hex pix2d(800,10)`

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #4 on: June 13, 2018, 06:33:20 PM »
To accommodate index expressions, instead of variables or constants:

@v=@pix(y*800+x)
-->
@v=@pix((y)*800+x)

Code: [Select]
`indexbase 0int pix[800*600]'macro pix2d int* (v,x,y,  vv)=============================  'v  return pixel pointer supporting read/write  'x  horizontal coordinate  'y  vertical coodinate  'vv sink pixel  if x>=0 and x<800 and y>=0 and y<600    @v=@pix((y)*800+x)  else    int vv=0xffffffff 'value when out of bounds    @v=@vv  end ifend macro''TESTpix2d(1,20)=0xaabbccddprint hex pix2d(1,20)print hex pix2d(800,10)`
« Last Edit: June 13, 2018, 06:55:13 PM by Charles Pegge »

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #5 on: June 13, 2018, 06:37:37 PM »
Thanks, Charles.
I think I understood how MACROS work
they are a kind of pointers that can define expressions
in this case the macro would be a pointer to another pnteiro
it was stupid of me not to notice this when I returned the address instead of the value

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #6 on: June 13, 2018, 07:07:01 PM »
about index of arrays I think this has to be a first line item in the help file
can generate a lot of confusion, because as it accepts small calculations, the person can think that the internal expreções are totally solved
I took some time having error problems without understanding what was happening

on macros, what I understand is that as pointers do not work in different scopes.
in NAMESPACE for example even putting "::" the variable for which it points will not have the same treatment, the variable of work in this case would have to be public

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #7 on: June 13, 2018, 09:56:41 PM »
I went to do a performance test and I liked it a lot
array( -2 to 5 , 3 to 10 )
Code: [Select]
`int n    =0int ln   int l1   =LBoundnx(aN,1)int l2   =UBoundnx(aN,1)int c1   =LBoundnx(aN,2) int c2   = UBoundnx(aN,2)for  ln= 1 to 1000000000 for L=l1 to l2 for  c=c1 to c2 ARRAYnx_l(AN, L , C)=N n=n+1 next nextnext`
less than 30 seconds

while my vba even failed to complete, and to complete has to 2 zeros less and still takes almost 2 minutes
maybe this will encourage me to complete the things I did not do because of the processing time
« Last Edit: June 13, 2018, 10:01:50 PM by Eduardo Jorge »

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #8 on: June 14, 2018, 08:46:49 PM »
Charles
his proposal using objects took 3 minutes to run with 1 zero less, 6,400,000,000,
an acquaintance from another forum tested in delphi and took 50 seconds the 64 billion of interaction upon matrix
using macros takes 30 seconds the 64 billion interaction

only this macro is breaking my head, it's difficult to define its limits and what exactly it will return
in the attempt posted here I defined an int B and put B as the matrix index,
and it worked,
and now I try INT A = (AN) * 10 and the macro returns me the value of A

even though it is a dirty solution as you said, I still prefer to try a solution using macros

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #9 on: June 14, 2018, 11:37:03 PM »
Eduardo,

There is no problem, if you are comfortable using macros, and customising them. The important thing is to ensure that your code is readable, and that you will still be able to understand it six months from now

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #10 on: June 18, 2018, 01:14:37 AM »
charles
would probably be just a dumb question, but could not create an internal macro in the compiler to recognize matrices indexes?

the macros are called by name,
then it would have to have one for each array, but if called by a set 1 only "[] []" "(,)" could serve for all arrays
well, I do not know if it would be viable or possible
I do not like to have something controlled as an object since they are very slow

EDIT========================
I really said bullshit
I forgot the dimensional control of the array
each created matrix would have to have control variables or use elements of the matrix itself for that purpose
after all how are they done in C and Delphi for example?
« Last Edit: June 18, 2018, 02:52:33 AM by Eduardo Jorge »

#### Mike Lobanovsky

• Jr. Member
• Posts: 93
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #11 on: June 18, 2018, 04:44:13 PM »

indexbase 0
int pix[800*600]
'
macro pix2d int* (v,x,y,  vv)
=============================
'v  return pixel pointer supporting read/write
'x  horizontal coordinate
'y  vertical coodinate

'vv sink pixel
if x>=0 and x<800 and y>=0 and y<600
@v=@pix(y*800+x)
else
int vv=0xffffffff 'value when out of bounds
@v=@vv
end if
end macro
'
'TEST
pix2d(1,20)=0xaabbccdd
print hex pix2d(1,20)
print hex pix2d(800,10)

Hi Charles,

Please note well that the solution you've suggested implements O2 multidimesional dynamic arrays as row-major entities while since the times of Dartmouth, BASIC arrays and matrices have been stored in memory in a column-major order. Row-major is rather how the C language and its derivatives would store their arrays and matrices, which makes them element-by-element (pointer) incompatible with their genuine BASIC equivalents without prior transposition.

It is of course irrelevant for the O2 user as long as all access to the array contents is done via the array indices. But it makes the O2 arrays and matrices binary incompatible with the modules generated by other BASIC compilers, e.g. an O2 project main code and a PB/FB DLL or vice versa.
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #12 on: June 18, 2018, 06:40:24 PM »
Hi Mike,

Yes, that example is for accessing pixels in x,y order, conforming to the original hardware layout of pixels in a video controller, and scan-lines in a TV set.

FreeBasic is Row-Major, like C. PowerBasic is Column-Major. But these terms are very confusing, so I have dodged the whole issue and left it to the programmer to decide how they like to arrange their arrays.

For general tabular layouts, Row then Column, with each row holding contiguous data, makes more intuitive sense. Each row is a record, and each column is a field.

This is the example I was about to provide for Eduardo:

Code: [Select]
`'2D ARRAY USING A TYPEuses consoletype RowType  int c[16] 'columnsend typedim RowType r[100]int i,jfor i=1 to 100  for j=1 to 16    r[i].c[j]=i*10+j  nextnext'for i=1 to 10  for j=1 to 8    print r[i].c[j] tab  next  print crnextwait`
« Last Edit: June 18, 2018, 08:38:20 PM by Charles Pegge »

#### Eduardo Jorge

• Jr. Member
• Posts: 50
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #13 on: June 18, 2018, 08:34:29 PM »
I think that this concern with the current type of array of O2 is unnecessary, since it is a visible implementation for the programmer

I myself was ignorant on the subject, and with this knowledge I have been able to improve some routines that I have in Vba

the same solution can be changed with simple change in the calculation of the index.
when this is something internal of the compiler, and transparent to the programmer, then Chales has to decide the course that will take.

Charles, thanks for the example,
this gives a greater margin of examples
I still prefer to implement the macros because they are faster, even though
more work

#### Charles Pegge

• Global Moderator
• Hero Member
• Posts: 677
##### Re: a multi-dimensional Safearray attempt with dynamic index
« Reply #14 on: June 18, 2018, 09:18:24 PM »
When traversing an array, you can use a pointer as an alternative to a macro. The pointer is moved instead of recalculating the array index every time an element is accessed. It should be significantly faster!

Code: [Select]
`'TRAVERSING 2D ARRAY USING A POINTER'INSTEAD OF A MACROuses consoledim int ar(100*16)'macro arr(r,c)'  ar((r)*16+c)'end macroint i,jint *afor i=1 to 100  @a=@ar(i*16) 'set pointer address  for j=1 to 16    'arr(i,j)=i*10+j    a=i*10+j    @a+=sizeof int 'ptr next element  nextnext'for i=1 to 10  @a=@ar(i*16) 'set pointer address  for j=1 to 8    'print arr(i,j) tab    print a tab    @a+=sizeof int 'ptr next element  next  print crnextwait`