Position item in an array larger than 3D

General FreeBASIC programming questions.
Post Reply
lrcvs
Posts: 578
Joined: Mar 06, 2008 19:27
Location: Spain

Re: Position item in an array larger than 3D

Post by lrcvs »

Think that all these equations, the large number of Loop / next ... and they can save time, both for writing or reading multidimensional arrays.

It now remains to transform all those equations in standard functions, or one Self-adjusting function dependend the dimension of arrays.!

Congratulations to all!

Regards
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Position item in an array larger than 3D

Post by dodicat »

Hi Ircvs.
If you compile the example I gave (the 20 dimension thing), with the switch -pp, then you will see the single equation for your chosen dimension.
i.e.
fbc -pp example.bas will give you the file examplepp.bas.

If you open examplepp.bas the single equation will be shown.
Please remember to remove the -pp switch before you run it.
However, I was surprised to find out that only eight dimensions (maximum) is allowed in Freebasic, I had intended to make a 20 dimension array for the example.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Position item in an array larger than 3D

Post by fxm »

dodicat wrote:However, I was surprised to find out that only eight dimensions (maximum) is allowed in Freebasic, I had intended to make a 20 dimension array for the example.
This constraint is specified in documentation DIM
paragraph "Arrays"
Multidimensional arrays can be declared as well, and are stored in this definite order: values differing only in the last index are contiguous (row-major order).
The maximum number of dimensions of a multidimensional array is 8.


But the maximum number of dimensions is 60 in Quick Basic!
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Position item in an array larger than 3D

Post by Richard »

fxm wrote:But the maximum number of dimensions is 60 in Quick Basic!
But IIRC, QB4.5 restricted the total array size to 64k. So it would not have been able to have more than 2^16 bytes. That is equivalent to 16 dimensions, with only two elements in each.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Position item in an array larger than 3D

Post by fxm »

Richard wrote:
fxm wrote:But the maximum number of dimensions is 60 in Quick Basic!
But IIRC, QB4.5 restricted the total array size to 64k. So it would not have been able to have more than 2^16 bytes. That is equivalent to 16 dimensions, with only two elements in each.
In QB4.5, command line option "/Ah" (huge arrays) allows dynamic arrays, fixed-length strings, and numeric data to be greater than 64K each:
- 128K,
- or more if its elements is an even power of 2.
lrcvs
Posts: 578
Joined: Mar 06, 2008 19:27
Location: Spain

Re: Position item in an array larger than 3D

Post by lrcvs »

Well, here we say: All you can not have

In this issue we have learned several things:

The "formula / equation" works well.

Have you checked the maximum number of dimensions that can support FreeBasic.

(It is a reason to improve it)

Also you have worked hard to develop the application of the formula / equation.

We can apply the equation / formula in simple arrays.

Similarly, using the equation, we show that one can access an element of an array without using loops ..., direct

I think everyone has learned something new ...

... but one important thing is that the equation has a wide application in mathematics.!

We have his theory and its application.

Possibly, in other computers or with other languages, have a greater application or work better

The important thing is that we have all created a new concept in search of an array or mathematical applications.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Position item in an array larger than 3D

Post by dodicat »

I've found a strange behaviour feature with dimension 8.
I expanded the macros for dim 8, compiled with -pp, and the following formula is produced:
formula= ( ( ubound(a,8)- lbound(a,8)+1)* ( ( ubound(a,7)- lbound(a,7)+1)* ( ( ubound(a,6)- lbound(a,6)+1)* ( ( ubound(a,5)- lbound(a,5)+1)* ( ( ubound(a,4)- lbound(a,4)+1)* ( ( ubound(a,3)- lbound(a,3)+1)* ( ( ubound(a,2)- lbound(a,2)+1)* (c1- lbound(a,1))+(c2- lbound(a,2)))+(c3- lbound(a,3)))+(c4- lbound(a,4)))+(c5- lbound(a,5)))+(c6- lbound(a,6)))+(c7- lbound(a,7)))+(c8- lbound(a,8)))
This is for the offset for a(c1,c2 thru c7,c8)
In otherwords the formula is a function of the dimension bounds and the offset point required (of course).
In the style of Ircvs, I decided to substitute variables for the ubound/lbound values.
e.g ub5=ubound(a,5), where ub5 is the numerical value of ubound(a,5).
However, I get a segmentation error at the final substitution, no matter in which order I do the substitutions.
viz:

Code: Select all

dim as integer lb1,lb2,lb3,lb4,lb5,lb6,lb7,lb8
dim as integer ub1,ub2,ub3,ub4,ub5,ub6,ub7,ub8
'lowerbounds
lb1=1  '=lbound(a,1)
lb2=3   ' etc
lb3=4
lb4=2
lb5=3
lb6=4
lb7=2
lb8=4 '= lbound(a,8)
'upperbounds
ub1=6 '=ubound(a,1)
ub2=7   'etc
ub3=8
ub4=6
ub5=7
ub6=8
ub7=5
ub8=9 '=ubound(a,8)

'somewhere in middle
dim as integer c1,c2,c3,c4,c5,c6,c7,c8
c1=2
c2=4
c3=5
c4=3
c5=5
c6=5
c7=5
c8=6

'dim shared as byte a(1 to 6,3 to 7,4 to 8,2 to 6,3 to 7,4 to 8,2 to 5,4 to 9):
' IS
dim shared as byte a(lb1 to ub1,lb2 to ub2,lb3 to ub3,lb4 to ub4,lb5 to ub5,lb6 to ub6,lb7 to ub7,lb8 to ub8)
'The formula:
'original:
print ( ( ubound(a,8)- lbound(a,8)+1)* ( ( ubound(a,7)- lbound(a,7)+1)* ( ( ubound(a,6)- lbound(a,6)+1)* ( ( ubound(a,5)- lbound(a,5)+1)* ( ( ubound(a,4)- lbound(a,4)+1)* ( ( ubound(a,3)- lbound(a,3)+1)* ( ( ubound(a,2)- lbound(a,2)+1)* (c1- lbound(a,1))+(c2- lbound(a,2)))+(c3- lbound(a,3)))+(c4- lbound(a,4)))+(c5- lbound(a,5)))+(c6- lbound(a,6)))+(c7- lbound(a,7)))+(c8- lbound(a,8)))
'now subsitute for lbounds and ubounds
'lbound(a,2) should become lb2, but segmentation fault reported                           (here)                
'                                                                                           |                                 
print ((ub8-lb8+1)*((ub7-lb7+1)*((ub6-lb6+1)*((ub5-lb5+1)*((ub4-lb4+1)*((ub3-lb3+1)*((ub2-lbound(a,2)+1)*(c1-lb1)+(c2-lb2))+(c3-lb3))+(c4-lb4))+(c5-lb5))+(c6-lb6))+(c7-lb7))+(c8-lb8))
print
print    @a(2,4,5,3,5,5,5,6)-@a(1,3,4,2,3,4,2,4)
 'SAME AS
print @a(c1,c2,c3,c4,c5,c6,c7,c8)-@a(lb1,lb2,lb3,lb4,lb5,lb6,lb7,lb8)
sleep
 
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: Position item in an array larger than 3D

Post by bluatigro »

you can use a index() function like :
[ this is non working code : its a example ]
this is whit 4 dimensions it can be more than that

Code: Select all

const as integer maxa = 4
const as integer maxb = 5
const as integer maxc = 6
const as integer maxd = 7
dim q( maxa * maxb * maxc * maxd ) as something
''etc..
declare function index( a as integer , b as integer , c as integer , d as integer ) as integer
function index( a , b , c , d ) as integer
  return a + b * maxa + c * maxa * maxb + d * maxa * maxb * maxc
end function
''use
something = q( index( 3 , 3 , 3 , 3 ) )
''or
q( index( a , b , c , d ) ) = something
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Position item in an array larger than 3D

Post by fxm »

bluatigro wrote:you can use a index() function like :
[ this is non working code : its a example ]
this is whit 4 dimensions it can be more than that

Code: Select all

const as integer maxa = 4
const as integer maxb = 5
const as integer maxc = 6
const as integer maxd = 7
dim q( maxa * maxb * maxc * maxd ) as something
''etc..
declare function index( a as integer , b as integer , c as integer , d as integer ) as integer
function index( a , b , c , d ) as integer
  return a + b * maxa + c * maxa * maxb + d * maxa * maxb * maxc
end function
''use
something = q( index( 3 , 3 , 3 , 3 ) )
''or
q( index( a , b , c , d ) ) = something
Yes, but your index formula:
a + b * maxa + c * maxa * maxb + d * maxa * maxb * maxc
= ( (d * maxc + c) * maxb + b) * maxa + a
is just that we proposed at the previous page:
http://www.freebasic.net/forum/viewtopi ... 84#p173884
http://www.freebasic.net/forum/viewtopi ... 01#p173901
corresponding to the case k=0 (all Lbounds = 0)

The formula with parentheses has the advantage to limit the number of operations:
6 operations instead of 9 operations (with also 3 multiplications instead of 6 multiplications)
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Position item in an array larger than 3D

Post by dodicat »

I've found the bug in my previous post.
Here's an artificial set of offsets for a position in an array of up to 20 dimensions.
The #defines were generated as before by writing a .bas file, I haven't included the file writer here.
Eight is the maximum for Freebasic, beyond eight you are out of Freebasic's reach.
Probably quick basic wouldn't have enough memory.
This whole thread is based on a kind of algebra for sets of numbers obeying the rules for multi dimensional arrays.
The offset number is only one function, perhaps other properties could be developed, addition, subtraction e.t.c.
Who knows, like boolean algebra, which lay dormant for decades, a more complete analyses of something like this might be usefull some day.
I've tried a little with prime numbers so far, in as much as grabbing prime offsets and comparing to elements defining them, with absolutely no luck.

Code: Select all

#define _r(n) (ub(n)-lb(n)+1)
#define d1(n1) (n1-lb(1))
#define d2(n1,n2) (_r(2)*d1(n1)+(n2-lb(2)))
#define d3(n1,n2,n3) (_r(3)*d2(n1,n2)+(n3-lb(3)))
#define d4(n1,n2,n3,n4) (_r(4)*d3(n1,n2,n3)+(n4-lb(4)))
#define d5(n1,n2,n3,n4,n5) (_r(5)*d4(n1,n2,n3,n4)+(n5-lb(5)))
#define d6(n1,n2,n3,n4,n5,n6) (_r(6)*d5(n1,n2,n3,n4,n5)+(n6-lb(6)))
#define d7(n1,n2,n3,n4,n5,n6,n7) (_r(7)*d6(n1,n2,n3,n4,n5,n6)+(n7-lb(7)))
#define d8(n1,n2,n3,n4,n5,n6,n7,n8) (_r(8)*d7(n1,n2,n3,n4,n5,n6,n7)+(n8-lb(8)))
#define d9(n1,n2,n3,n4,n5,n6,n7,n8,n9) (_r(9)*d8(1,n2,n3,n4,n5,n6,n7,n8)+(n9-lb(9)))
#define d10(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10) (_r(10)*d9(n1,n2,n3,n4,n5,n6,n7,n8,n9)+(n10-lb(10)))
#define d11(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11) (_r(11)*d10(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10)+(n11-lb(11)))
#define d12(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12) (_r(12)*d11(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11)+(n12-lb(12)))
#define d13(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13) (_r(13)*d12(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12)+(n13-lb(13)))
#define d14(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14) (_r(14)*d13(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13)+(n14-lb(14)))
#define d15(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15) (_r(15)*d14(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14)+(n15-lb(15)))
#define d16(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16) (_r(16)*d15(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15)+(n16-lb(16)))
#define d17(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17) (_r(17)*d16(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16)+(n17-lb(17)))
#define d18(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18) (_r(18)*d17(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17)+(n18-lb(18)))
#define d19(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19) (_r(19)*d18(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18)+(n19-lb(19)))
#define d20(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20) (_r(20)*d19(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19)+(n20-lb(20)))
dim as integer d=20
dim as double lb(1 to d),ub(1 to d)
'set up lower and upper
for z as integer=1 to d
    lb(z)=1:ub(z)=5'(1 to 5) for each dimension
    next z

print "Test against an array dim 7"
dim as integer b(1 to 5,1 to 5,1 to 5,1 to 5,1 to 5,1 to 5,1 to 5)
print d7(2,2,2,2,2,2,2)
print @b(2,2,2,2,2,2,2)-@b(1,1,1,1,1,1,1)
print "_______________________________"
print

print "d8  = ";d8(2,2,2,2,2,2,2,2)
print "d12 = ";d12(2,2,2,2,2,2,2,2,2,2,2,2)
print "d20 = ";d20(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
sleep  
lrcvs
Posts: 578
Joined: Mar 06, 2008 19:27
Location: Spain

Re: Position item in an array larger than 3D

Post by lrcvs »

Hi, all!

The initial formula is perfect, mathematically speaking, has no limits and can be very diverse applications in computer science and mathematics.

In computer science, we saved loops, time, we can convert an array of any size, in a linear array,

In math, we can find the position / order number of an object in a set of items ordered in blocks. We can also find your posion in optro linear equivalent set.

Note:

Now I ask myself:
that instead of using memory, use the hard drive = lineal memory (no limit)?

You think you?
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Position item in an array larger than 3D

Post by Richard »

The advantage of a multidimensional array is that the indexes are different variables.
It is probable that only when the entire array is being initialised or moved can it be handled conveniently as a single linear structure.

To find out how FB handled multidimensional arrays I wrote the following code. Then I extracted and documented the assembly code that sets up the array descriptors and the evaluation of an array reference. I created an 8 dimension array with 2 elements in each dimension, except for the one dimension that has 3, it is called a(,,,,,,,). I then set up a single dimension array with 8 elements i(1 To 8) to index the 8 dimension array, a( i( ) ). Since I do not want array bound checking code to be included, and the reference can be out of bounds, I avoid using the -exx option and read the array rather than writing to an out of bounds memory address.

Here is the FB code with the emitted assembly code appended as documentation.

Code: Select all

'=======================================================================
' 8 dimensioned arrays
'=======================================================================
Dim As Integer a( 0 To 1, 0 To 2, 2 To 3, 3 To 4, 4 To 5, 5 To 6, 6 To 7, 7 To 8 )
Dim As Integer i(1 To 8)    ' this array is used to index the a() array above
Dim As Integer k
k = a( i(1), i(2), i(3), i(4), i(5), i(6), i(7), i(8) )

Print " done."
Sleep

'=======================================================================
' This is the assembly code generated
'=======================================================================
' clear the a() array data area to zero
'-----------------------------------------------
'    lea eax, [ebp-1536]    ' point to the a()
'    push eax       ' ?
'    mov edi, eax   ' address to write to
'    xor eax, eax   ' clear the eax register = data to write
'    mov ecx, 384   ' element count 3 * 2^7 = 384
'    rep stosd      ' repeat store string to clear the a() array
'    pop eax        ' ?

'-----------------------------------------------
' create the a() array descriptor
'-----------------------------------------------
'    lea eax, [ebp-1536]
'    add eax, -732
'    mov dword ptr [ebp-1652], eax  ' element(zero) address for indexing
'    lea eax, [ebp-1536]
'    mov dword ptr [ebp-1648], eax  ' base address of allocated memory
'    mov dword ptr [ebp-1644], 1536 ' total allocated memory in bytes
'    mov dword ptr [ebp-1640], 4    ' element size in bytes
'    mov dword ptr [ebp-1636], 8    ' number of dimensions
' 1'st dimension
'    mov dword ptr [ebp-1632], 2    ' number of cells in this dimension
'    mov dword ptr [ebp-1628], 0    ' lower bound
'    mov dword ptr [ebp-1624], 1    ' upper bound
' 2'nd D
'    mov dword ptr [ebp-1620], 3    ' ditto for all dimensions
'    mov dword ptr [ebp-1616], 0
'    mov dword ptr [ebp-1612], 2
' 3'rd D
'    mov dword ptr [ebp-1608], 2
'    mov dword ptr [ebp-1604], 2
'    mov dword ptr [ebp-1600], 3
' 4'th D
'    mov dword ptr [ebp-1596], 2
'    mov dword ptr [ebp-1592], 3
'    mov dword ptr [ebp-1588], 4
' 5'th D
'    mov dword ptr [ebp-1584], 2
'    mov dword ptr [ebp-1580], 4
'    mov dword ptr [ebp-1576], 5
' 6'th D
'    mov dword ptr [ebp-1572], 2
'    mov dword ptr [ebp-1568], 5
'    mov dword ptr [ebp-1564], 6
' 7'th D
'    mov dword ptr [ebp-1560], 2
'    mov dword ptr [ebp-1556], 6
'    mov dword ptr [ebp-1552], 7
' 8'th D
'    mov dword ptr [ebp-1548], 2
'    mov dword ptr [ebp-1544], 7
'    mov dword ptr [ebp-1540], 8
'
'-----------------------------------------------
' clear the i() array data area to zero
'-----------------------------------------------
'    lea eax, [ebp-1684]
'    push eax       ' ?
'    mov edi, eax   ' point to i()
'    xor eax, eax   ' clear eax
'    mov ecx, 8     ' count of dwords
'    rep stosd      ' repeated string store double word
'    pop eax        ' ?

'-----------------------------------------------
' create the i() array descriptor
'-----------------------------------------------
'    lea eax, [ebp-1684]
'    add eax, -4
'    mov dword ptr [ebp-1716], eax  ' element(zero) address for indexing
'    lea eax, [ebp-1684]
'    mov dword ptr [ebp-1712], eax  ' base address of allocated memory
'    mov dword ptr [ebp-1708], 32   ' total allocated memory in bytes = 4*8
'    mov dword ptr [ebp-1704], 4    ' data element size in bytes
'    mov dword ptr [ebp-1700], 1    ' number of dimensions

'    mov dword ptr [ebp-1696], 8    ' number of elements in the only dimensions
'    mov dword ptr [ebp-1692], 1    ' lower bound
'    mov dword ptr [ebp-1688], 8    ' upper bound

'-----------------------------------------------
'   declare k and initialise with zero
'-----------------------------------------------
'    mov dword ptr [ebp-1720], 0

'-----------------------------------------------
' evaluate the element address from the 8 indexes in i(1 to 8)
'-----------------------------------------------
'    mov eax, dword ptr [ebp-1684]  ' 1'st dimension

'    imul eax, 3                    ' 2'nd is three cells
'    add eax, dword ptr [ebp-1680]

'    sal eax, 1                     ' shift left is a fast multiply by 2
'    add eax, dword ptr [ebp-1676]  ' 3'rd D

'    sal eax, 1
'    add eax, dword ptr [ebp-1672]  ' 4'th

'    sal eax, 1
'    add eax, dword ptr [ebp-1668]  ' 5'th

'    sal eax, 1
'    add eax, dword ptr [ebp-1664]  ' 6'th

'    sal eax, 1
'    add eax, dword ptr [ebp-1660]  ' 7'th dimension

'    sal eax, 1
'    add eax, dword ptr [ebp-1656]  ' 8'th

'    mov ebx, dword ptr [ebp+eax*4-2268]    ' get the indexed element to ebx
'    mov dword ptr [ebp-1720], ebx      ' move ebx to k 
'-----------------------------------------------
 

There are a couple of interesting observations.

Firstly, that for a two element dimension the FB code avoids the slower integer multiply by two, instead using the faster shift left. The array element address evaluation code appears to be optimum.

Secondly, is the push eax and pop eax that bracket the array data initialisation code. Although it is only executed once per array creation, it seems to be redundant as eax has already been loaded with the address of the array. Why might that array address need to be left unprotected on the stack ? It is evaluated again immediately afterwards by another “lea eax, [ebp-1536]” when the array descriptor is being initialised.
My guess is that the second evaluation of “lea eax, [ebp-1536]” was added after the syntax changed to allow Dim As type var = Any, which would skip the initialisation of data to zero. Since initialisation is then omitted the “lea eax, [..” had to be inserted at the start of descriptor initialisation, but the push and pop were never removed.
lrcvs
Posts: 578
Joined: Mar 06, 2008 19:27
Location: Spain

Re: Position item in an array larger than 3D

Post by lrcvs »

Code: Select all


Formulas for calculating the number of order in the position of an element within an array.

 2D array

 Array Z origin (5,6) = (row, col)

 Position the element to search Z (4,5) = (a, b)

 Position = ((a - 1) * col) + b

 Position = ((4 - 1) * 6) + 5 = 23

 :::::::::::::::::::::::::::::::::::::::::::::::::: ::::

 3D array

 Array Z origin (5,6,7) = (row, col, level)

 Position the element to search Z (4,5,6) = (a, b, c)

 Position = ((a - 1) * col) + b + ((row * col) * (level - 1))

 Position = ((4 - 1) * 6) + 5 ((5 * 6) * (7 - 1)) =


 :::::::::::::::::::::::::::::::::::::::::::::::::: ::::

 Array > 3D

 Array Z origin (5,6,7,8) = (row, col, level, dimension)

 Position the element to search Z (4,5,7,8) = (a, b, c, d)

 Position = ((a - 1) * col) + b + ((row * col) * (level - 1)) + (row * col * level) * (dimension -1))

 Position = ((4 - 1) * 6) + 5 ((5 * 6) * (7 - 1)) + (5 * 6 * 7) * (8 - 1)) =

 :::::::::::::::::::::::::::::::::::::::::::::::::: :::

 If size > 3D:

 Array Z origin (5,6,7,8) = (row, col, level, d1)

 dx = d1
 dx = 8

 Array Z origin  (5,6,7,8,9) = (row, col, level, d1, d2)

 dx = d1 * d2
 dx = 8 * 9

 Array Z origin (5,6,7,8,9,10) = (row, col, level, d1, d2, d3)

 dx = d1 * d2 * d3
 dx = 8 * 9 * 10



fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Position item in an array larger than 3D

Post by fxm »

1) Yes, but I just corrected some typos:
  • Formulas for calculating the number of order in the position of an element within an array.

    2D array

    Array Z origin (5,6) = (row, col)

    Position the element to search Z (4,5) = (a, b)

    Position = ((a - 1) * col) + b

    Position = ((4 - 1) * 6) + 5 = 23

    :::::::::::::::::::::::::::::::::::::::::::::::::: ::::

    3D array

    Array Z origin (5,6,7) = (row, col, level)

    Position the element to search Z (4,5,6) = (a, b, c)

    Position = ((a - 1) * col) + b + ((row * col) * (c - 1))

    Position = ((4 - 1) * 6) + 5 + ((5 * 6) * (6 - 1)) =


    :::::::::::::::::::::::::::::::::::::::::::::::::: ::::

    Array > 3D

    Array Z origin (5,6,7,8) = (row, col, level, dimension)

    Position the element to search Z (4,5,7,8) = (a, b, c, d)

    Position = ((a - 1) * col) + b + ((row * col) * (c - 1)) + ((row * col * level) * (d -1))

    Position = ((4 - 1) * 6) + 5 + ((5 * 6) * (7 - 1)) + ((5 * 6 * 7) * (8 - 1)) =

    :::::::::::::::::::::::::::::::::::::::::::::::::: :::
2) Comparison with FreeBASIC array mapping in memory:

From 3D array and more, FreeBASIC does not use the same order than you for the indexes:
2D: You: (row, col), FreeBASIC: (row, col)
3D: You: (row, col, level), FreeBASIC: (level, row, col)
4D: You: (row, col, level, dimension), FreeBASIC: (dimension, level, row, col)


3) Short program to compute your positions values and to verify the correspondence with the FreeBASIC indexes order:

Code: Select all

Dim array2D(1 To 5, 1 To 6) As Integer
Print "offset: "; @array2D(4, 5) - @array2D(1, 1) ' = 22
Print "position: "; ((4 - 1) * 6) + 5             ' = 23
Print

Dim array3D(1 To 7, 1 To 5, 1 To 6) As Integer
Print "offset: "; @array3D(6, 4, 5) - @array3D(1, 1, 1)     ' = 172
Print "position: "; ((4 - 1) * 6) + 5 + ((5 * 6) * (6 - 1)) ' = 173
Print

Dim array4D(1 To 8, 1 To 7, 1 To 5, 1 To 6) As Integer
Print "offset: "; @array4D(8, 7, 4, 5) - @array4D(1, 1, 1, 1)                         ' = 1672
Print "position: "; ((4 - 1) * 6) + 5 + ((5 * 6) * (7 - 1)) + ((5 * 6 * 7) * (8 - 1)) ' = 1673
Print

Sleep
lrcvs
Posts: 578
Joined: Mar 06, 2008 19:27
Location: Spain

Re: Position item in an array larger than 3D

Post by lrcvs »

@ fxm:

Thanks for your observation.

Both formulas are correct (mathematical and FreeBASIC).

Themselves to adapt my formulas to FreeBASIC.

Thanks and regards!
Post Reply