Oxygen Basic

Programming => Problems & Solutions => Topic started by: edcronos on May 25, 2018, 03:21:20 AM

Title: O2 Multidimensional Arrays
Post by: edcronos on May 25, 2018, 03:21:20 AM
sorry, one thing I think should be taken into account for those who write the tutorials is to separate the semantics of the syntaxes
make it clear that you can mix, but separate the syntax forms by better known types, basic, vb, C in different examples not to confuse

and something more about arrays, I ran out of the internet to search the forum and I'm not skilled enough to understand the examples I found
I'm used to using arrays type array(row, column) and use base 1
maybe something more about, array of arrays
with vba, I use something like this

dim ar1 (20)
dim arr2 (1000) as long
for c = 1 to 20
     for r = 1 to 1000
       arr2(r) = r * c
     next
   arr1(c) = arr2
next
and to use

arr1(c)(r)
How can I make use of it?
Title: Re: O2 Multidimensional Arrays
Post by: Aurel on May 26, 2018, 03:14:03 AM
array ..?
what is problem there?

int arr[100]
 and that is
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 26, 2018, 04:56:41 AM
array ..?  what is problem there?

thanks, I'll wait for the beta with something basic to follow,

Unfortunately I could not find useful content about pointers, ByRef on O2

I think I understood about array being primitive and the calculation to be applied
Resul (row * total of columns + Column)
and I can handle it
but I tried some variations of examples with pointers up to C and I could not
about [] or () I did not see any problems in O2 interleaved uses, I also did not find any difference in the examples I looked at
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on May 26, 2018, 05:28:51 AM
Hi Eduardo,

This code demonstrates how to create a basic dynamic 2D array object. The construct provides the flexibility required for adding row, coumn, and sub-table extraction. I have not considered arrays of arrays here, but once you have an array-object represented as
one pointer, it becomes feasible to build them, if necessary.

Code: [Select]
'14:08 26/05/2018
'
class ArrayObjectXY
==================
  sys pA
  int sc,sx,sy
  '
  method constructor(int x,y)
    sc=sizeof(double) : sx=x : sy=y
    pA=getmemory sc*x*y
  end method
  '
  method destructor()
    freememory pA
    sc=0 : sx=0 : sy=0
  end method
  '
  method dv(int x,y) as double
    x-- : y-- 'BASE 0
    double da at pA+sc*(x+y*sx)
    return da
  end method
  '
  method dv(int x,y,double a)
    x-- : y-- 'BASE 0
    double da at pA+sc*(x+y*sx)
    da=a
  end method
  '
end class

'TESTS:
new ArrayObjectXY ta(100,200)
ta.dv(10,20)=42
print "ok " ta.dv(10,20)
del ta
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 26, 2018, 07:17:32 AM
Thanks, Charles.
it will be useful for me to try to understand something of class
although I never remember the names of these functions
so everything I do is just basic of the basics

I use only for next, if then else, and some case, with arrays and variables, I get everything transformed into a big salad that only I understand but by some miracle it works in the vba

even conditional loops I use goto with if because I can never remember the "loop" functions
I tried something with array by reference but all the attempts caught
Code: [Select]
includepath "$/inc/"
$filename "Statistics_1.0.dll"
$dll
include "RTL32.inc"
extern export

Function  Statistics(byref Resul[] as int,  byval Cq as int,  byval Ct as int,  byval Lt as long)
',  byref Tab_Atra() as int )

'sub  Statistics( *Resul() as int, 
' byval Cq as int,
' byval Ct as int,
' byval Lt as int,
' *Tab_Atra() as int )
indexbase 0
dim Tab_Atra() as int

dim  C, L, Atr0() as int
dim n1 , n2 as double
dim int MAIOR_REPT, MAIOR_ATR

cq=cq-1
Ct=Ct-1
Lt=lt-1
Atr0(Ct)

For  c = 0 To cq
    Atr0((Resul)[L*cq+C]) = 1' Atr0(Resul(1, c)) = 1
Next

If Atr0(c) = 1 Then
Tab_Atra(L*cq+C) = 1
Atr0(c) = 0
Else
Tab_Atra(L*cq+C) = -1
End If

For L = 1 To lt

For c = 0 To cq
Atr0((Resul)[L*cq+C]) = 1
Next

For c = 0 To ct

n1=L*ct+C
n2=(L-1)*ct+C


If Atr0(c) = 1 Then
If Tab_Atra(n2) > 0 Then
Tab_Atra(n1) = Tab_Atra(n2) + 1
If Tab_Atra(n1) > MAIOR_REPT Then MAIOR_REPT = Tab_Atra(n1)
Else
Tab_Atra(n1) = 1
End If
Atr0(c) = 0
Else
If Tab_Atra(n2) > 0 Then
Tab_Atra(n1) = -1
Else
Tab_Atra(n1) = Tab_Atra(n2) - 1
If Tab_Atra(n1) < MAIOR_ATR Then MAIOR_ATR = Tab_Atra(n1)
End If
End If
Next
Next
end Function



but you do not have to worry about me, I'm just a curious without much ability
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 27, 2018, 01:11:51 PM
I keep thinking about how to write the O2 manual
the same thing for an IDE that can work with such polymorphism

there are so many different ways of doing the same thing that one does not need more of goto nor gosub to knot in the brain of this staff that complains when it finds a goto in a macro of 20 lines

Code: [Select]
Function  Statistics( int byref Resul , 
byval Cq as int,
byval Ct as int,
byval Lt as int,
int  byref  Tab_Atra )

'both one and the other works

Function  Statistics(int  *Resul,  Cq , byval  Ct ,Lt ,*Tab_Atra )


despite my poor ability I was able to make work with the vba array byref
the vba pecorre the array by line,
then it got row + column * total rows, I think it worked here for a two-dimensional array

I have to adjust the logic and take all the mess I made for the tests

Code: [Select]
includepath "$/inc/"
$filename "Statistics_1.0.dll"
$dll
include "RTL32.inc"
extern export

Function  Statistics(int  *Resul,int Cq ,int byval  Ct ,int Lt ,int *Tab_Atra )

indexbase 0

dim int MAIOR_REPT, MAIOR_ATR
int  aa
aa=ct-1
dim int C, L, Atr0(80)
dim n1 , n2 as double
l=0

For  c = 0 To cq-1
n1=l+c*lt
Atr0(Resul[n1]-1) = 1
Next

For c = 0 To ct-1
n1=l+c*lt
If Atr0(c) = 1 Then
Tab_Atra[n1] = 1
Atr0(c) = 0
Else
Tab_Atra[n1] = -1
End If
Next

For L = 1 To  Lt - 1
For c = 0 To cq - 1
n1=l+c*lt
Atr0(Resul[n1]-1) = 1
Next

For c = 0 To Ct - 1
n1 = L  + c * Lt
n2 = L - 1+c*lt

If Atr0(c) = 1 Then
If Tab_Atra(n2) > 0 Then
Tab_Atra(n1) = Tab_Atra(n2) + 1
'    If Tab_Atra(n1) > MAIOR_REPT Then MAIOR_REPT = Tab_Atra(n1)
Else
Tab_Atra(n1) = 1
End If
Atr0(c) = 0
Else
If Tab_Atra(n2) > 0 Then
Tab_Atra(n1) = -1
Else
Tab_Atra(n1) = Tab_Atra(n2) - 1
'    If Tab_Atra(n1) < MAIOR_ATR Then MAIOR_ATR = Tab_Atra(n1)
End If
End If
Next
Next
end Function 

Code: [Select]
Public Declare Sub Statistics Lib _
                              "D:\planilhas\Statistics_1.0.dll" _
                              (ByRef Result As Long, _
                               ByVal Cq As Long, ByVal CT As Long, ByVal Lt As Long, ByRef Tab_Atra As Long)
my excel is 32bit so I have to use the long one that is the size of the int of O2

and to use it has to put the first element of the array
Code: [Select]
Call Statistics(Sort(1, 1), cq, Ct, Lt, Tab_Atra(1, 1))
I used (1.1) because base1 use in vba, if base 0 would be (0,0)
of course you can use the
arr (Lbound (arr, 1), Lbound (arr, 2)) to automatically pick up


a point of importance is that I could not in any way size an array by a variable
dim int ARRAY (variable) ???
and I had to use a numerical value to work
how do you adjust the size of the array by a variable in O2 ???
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on May 27, 2018, 06:38:52 PM
Hi Eduardo,

You can create a dynamic array by using "redim". It will allow you to dimension the array with a variable or an expression.

redim int Atr0(myVariable)

o2 also understands "long" as well as "int"
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on May 30, 2018, 10:53:06 AM
I personally would like to see Basic evolve from C style arrays ( please, give me slicing or cross section of arrays..

Hi Jalih,

Welcome to our forum!

o2 static arrays are very primitive but more sophisticated array facilities, such as array sections, can be handled quite easily with OOP. There are so many potential operations and state variables associated with arrays that they are best handled outside the core compiler.

I think we need separate classes for managing 1D and 2D arrays.
Title: Re: O2 Multidimensional Arrays
Post by: JRS on May 30, 2018, 11:20:56 AM
Another reason ScriptO2 makes sense. Build them with SB and use them with O2 / DLLC.

Script BASIC Arrays (http://www.scriptbasic.org/forum/index.php/topic,355.0.html)
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 30, 2018, 11:23:14 AM
Is there any example implementation and usage of array inside array in O2?
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on May 30, 2018, 02:30:58 PM
An array of strings is the only example I can think of. Essentially, it is an array of arrays of characters.
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 30, 2018, 09:38:54 PM
is there any way to use something like this in a practical way without having to do @ Arr1 = Arr2 (L)?
in case that would be an array of pointers right, I know I'm all wrong in the assembly, but I have no idea how to explain

Code: [Select]
int n0,n1
dim L, C
L=3
c=4
redim int Arr2(L)
redim int Arr1(c)

for  n0=1 to l
    Arr2(n0)=getmemory c*sizeof int
next

for  n0=1 to 3

  @Arr1= Arr2(n0)

  for  n1=1 to c
   Arr1(n1)=n1+n0*10
  next
next
 
@Arr1=arr2(2)
print arr1(1)
how would this array of arrays of characters ?
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on May 31, 2018, 03:50:01 AM
Hi Eduardo,

Here is an example of Array-of-Arrays using strings as buffers. It has interesting possibilities. However I would not recommend this technique as a solution for regular 2D arrays.

Code: [Select]
'11:10 31/05/2018
'ARRAY OF ARRAYS USING STRINGS

'CREATE ARRAY FOR INTs
======================
string sy[100] 'STRING BUFFERS
int i
for i=1 to 100
  sy[i]=nuls 50*sizeof int 'dim int sx[50]
next
'
'ACCESS ARRAY (USING INDEXBASE 1)
=================================
macro aa int* (va,ix,iy)
  @va=strptr sy(iy)+(ix)*4-4
end macro

'TESTS:
=======
aa(2,3)=42
aa(20,30)=100
print aa(2,3)*aa(20,30)
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 31, 2018, 06:35:15 AM
this is very complex arrays
I was accustomed to, simply use
now encountering the O2 array and researching about safearray constructors I see that internally there is a lot of process running

probably for large amounts of data or many accesses the primitive type is much faster, but more difficult dynamics

I do not know if there is an operator to work directly with memory address and word size
value = int (address + (10 * sizeof int))
in case I would get the value of the memory in the size of 1 int from the calculated address, but surely that is a reason half asshole on my part

I have to research more on the subject so I was able to define my reason well, which would certainly have to be cleaned at the end
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on May 31, 2018, 05:35:26 PM
I'll leave that aside, I'm going to use the normal O2 array
there are other things to adapt and ... adapt me
Title: Re: O2 Multidimensional Arrays
Post by: Charles Pegge on June 01, 2018, 03:18:55 AM
A regular 2D dynamic array is simpler:

Code: [Select]
'11:10 31/05/2018
'DYNAMIC 2D array

int sy=100, sx=50
redim int a(sy*sx)
'
'ACCESS ARRAY (USING INDEXBASE 1)
=================================
macro aa(iy,ix)
  a( ( (iy)-1)*sx + (ix) )
end macro

'TESTS:
=======
#show aa(2,3)=42
aa(20,30)=100
print aa(2,3)*aa(20,30)
Title: Re: O2 Multidimensional Arrays
Post by: edcronos on June 01, 2018, 04:22:05 AM
Thank you Charles,

I have no problem working with the array calculation inside the routines, for those who only loop and if gives even a more complex appearance

I wanted to know more about array of pointers, or array inside array to see if it facilitated the use of dynamic indexes, so I would do the whole process in the sub array of the array instead of using, index within the index, of the array in each sub

but you do not have to give me so much attention, I'm just a curious, nor programmer I am,
  Anyway, I always go the way that I adjust
Title: Re: O2 Multidimensional Arrays
Post by: jalih on June 01, 2018, 08:07:34 AM
A regular 2D dynamic array is simpler:

Code: [Select]
'11:10 31/05/2018
'DYNAMIC 2D array

int sy=100, sx=50
redim int a(sy*sx)
'
'ACCESS ARRAY (USING INDEXBASE 1)
=================================
macro aa(iy,ix)
  a( ( (iy)-1)*sx + (ix) )
end macro

'TESTS:
=======
#show aa(2,3)=42
aa(20,30)=100
print aa(2,3)*aa(20,30)

Seems like O2 can do some things via macros, that PL/I can do with declaration:

To use 1D array as 2D array:
Code: [Select]
   dcl a(100) fixed bin(31);
   dcl b(10,10) fixed bin(31) defined(a((1sub-1) * hbound(b,1) + 2sub));
Now you can just use array b to refer to array a as 2D array (like your macro, but compiler can do error checking).

PL/I supports multidimensional arrays, so easier would be to use:
Code: [Select]
   dcl a(100) fixed bin(31);
   dcl c(10,10) fixed bin(31) based(addr(a));

And if you need to allocate 2D array, just:
Code: [Select]
   dcl p ptr;
   dcl e(10,10) fixed bin(31) based(p);

   allocate e;
I like the concept of a based variable. It removes the need for ugly C-style casting and let compiler do the math.

With a little creativity one can do some fun stuff with O2 macros. Something like this would be possible with O2 macro:
Code: [Select]
   dcl a(11) float init(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0);
   dcl b(10,10) defined a(1sub*(1sub=2sub) + (1sub^=2sub)*hbound(a)) float;
Guess what it does?
Title: Re: O2 Multidimensional Arrays
Post by: Arnold on June 01, 2018, 10:27:30 AM
Hi Charles,

maybe it is time to put together the many possibilites to manage multidimensional arrays. I know there is examples\Basics\Arrays.o2bas, but in the meantime you demonstrated more ways.

Btw - Nehe tutorial 11:
http://www.oxygenbasic.org/forum/index.php?topic=1550.msg18193#msg18193 (http://www.oxygenbasic.org/forum/index.php?topic=1550.msg18193#msg18193)

applies a macro for three dimensions (line 65-69), with indexbase 0 which is also based on your solution.

Roland
Title: Re: O2 Multidimensional Arrays
Post by: JRS on June 11, 2018, 10:11:59 PM
Quote from: CC@JRS
Unfortunately Eduardo,  i only use indices from 0 upwards,  i have never encounter
or use arrays with negative indices.  What is the purpose of your usage ?

What fields of work that would use negative indices in arrays?

Best that you ask Charles on this matter.

Code: Script BASIC
  1. array[-1000000] = "Negative One Million"
  2. array[1000000]  = "Positive One Million"
  3. PRINT "[",LBOUND(array),"] - ",array[-1000000],"\n"
  4. PRINT "[",UBOUND(array),"] - ",array[1000000],"\n"
  5.  


jrs@jrs-laptop:~/sb/examples/test$ scriba negarray.sb
[-1000000] - Negative One Million
[1000000] - Positive One Million
jrs@jrs-laptop:~/sb/examples/test$


With ScriptO2 you will be able to define dynamically any array indices you like without limitations. You can also use associative arrays or a combination of both. The low level access of O2 to these array / matrix structures is hidden from the user by ScriptO2.

Another benefit of ScriptO2 is that it uses the thread safe MyAlloc memory manager with a variant style variable structure.