Possible to pass a single column of an array to a function?

General FreeBASIC programming questions.
Post Reply
cbruce
Posts: 166
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Possible to pass a single column of an array to a function?

Post by cbruce »

.
Is it possible to pass a single column of a multidimensional array to a function - have the function operate on that as it would on any single dimension array - and see the results in the multidimensional array?

I have a function that I would like it to be able to handle both, single dimension arrays and single columns of multidimensional arrays.

I keep getting "error 58: Type mismatch, at parameter 1" during the compile. Can't wrap my head around the addressing...

Code: Select all

dim ary(5,5) as integer
test( ary(0,2))   ' "error 58: Type mismatch, at parameter 1"
test( @ary(0,2))   ' "error 58: Type mismatch, at parameter 1"
'
sub test( f_ary() as integer ptr)
    dim x as integer
    x = 5
    f_ary(3) = x
end sub
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Possible to pass a single column of an array to a function?

Post by SARG »

I would pass the wished index as another parameter and no need ptr

Code: Select all

sub test( f_ary() as integer,index As Long)
    dim x as integer
    x = 5
    f_ary(3,index) = x
end Sub
dim ary(5,5) as integer
test( ary(),2)
print ary(3,2)
cbruce
Posts: 166
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: Possible to pass a single column of an array to a function?

Post by cbruce »

.
But "f_ary(3,index) = x" is the problem. That won't handle a single dimension array. That's why I want to be able to pass a single column of a multidimensional array - so the code can handle either situation.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Possible to pass a single column of an array to a function?

Post by jj2007 »

Pass column -1 if it's a single dimension array.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Possible to pass a single column of an array to a function?

Post by badidea »

I got a bit sidetracked while looking into your question. So this is not an answer, but may shed some light on passing arrays as subroutine parameters in freebasic:

Code: Select all

const as integer D1 = 5
const as integer D2 = 3
const as integer D3 = 2

sub show(f_ary() as integer)
	dim as integer iDimension
	dim as integer numItems = 1
	dim as integer numDimensions = 0
	dim as integer dimensionSize
	print "f_ary";
	for iDimension = 1 to 100  '100 is probably enough
		dimensionSize = 1 + (ubound(f_ary, iDimension) - lbound(f_ary, iDimension))
		if dimensionSize = 0 then exit for
		numDimensions += 1
		numItems *= dimensionSize
		print "("; dimensionSize; " )";
	next
	print ", Dimensions:"; numDimensions; ", Items:"; numItems
	print
	for i as integer = 0 to numItems-1
		print *(@f_ary(0) + i); 'when stuck, go pointers :-)
	next
	print
	print
end sub

dim ary2d(D1-1, D2-1) as integer 'D1 * D2 integers
dim ary1d(D1-1) as integer
dim ary3d(D1-1, D2-1, D3-1) as integer

ary3d(3,1,1) = 12345

print "ary2d(): ";
show(ary2d())
print "ary1d(): ";
show(ary1d())
print "ary3d(): ";
show(ary3d())
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Possible to pass a single column of an array to a function?

Post by fxm »

You can simplify your code because:
numDimensions = ubound(f_ary, 0) '' since fbc version 0.90.0

See article How to Use the Lbound / Ubound Size information of Array in FB

(anyway, the maximum number of dimensions of a multidimensional array is 8)
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: Possible to pass a single column of an array to a function?

Post by sancho3 »

The best you are going to do is set a pointer to a location inside your matrix. From there you can offset to get the spot inside the array.
This works but probably doesn't work for all dimensions.
You will need to look into how an array is laid out in memory in FB.

Code: Select all

sub test( f_ary as integer ptr)
    dim x as integer
    x = 5
    f_ary[3] = x
end Sub
dim ary(5,5) as integer

test( @ary(0,0))   ' "error 58: Type mismatch, at parameter 1"
? ary(0,3)
sleep
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Possible to pass a single column of an array to a function?

Post by caseih »

Are arrays row-major or column-major in FB? I know that in C they are row-major, which precludes passing an arbitrary column out of an array without some kind of intermediate processing (known as a "project" operation in relational algebra).
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Possible to pass a single column of an array to a function?

Post by fxm »

It all depends on the given definition of rows and columns of an array that my vary according to the authors (often the definition is the opposite of what it is for vectors).
But FB multidimensional arrays are stored so that values differing only in the last index (right index) are contiguous.

According to Wikipedia Row- and column-major order:
Row-major order
Last edited by fxm on Jun 07, 2018 4:59, edited 1 time in total.
cbruce
Posts: 166
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: Possible to pass a single column of an array to a function?

Post by cbruce »

.
sancho3's code points me in the right direction...

In his example, f_ary[3] is the same as ary(0,3)... (because FB is row-major order)... since sancho3 passed @ary(0,0) as the starting point... +3 from there = row 0, column 3.

So, if I passed @ary(0,4) as the starting point (PTR to column 4)... f_ary[3] would be the same as ary(1,1)...
  • ary(0,4) + 3 ==> ary(0,5) ... ary(1,0) ... ary(1,1)
Is there anyway for me to refer to the array itself, from inside the SUB, when I am passed a PTR to one of the array's columns like this ???

If I can do a ubound(array,0) from inside the SUB, then, whether I get a PTR to a single-dimension array or a PTR to a single column of a multi-dimensional array... I can calculate the offset which will let me address the elements of the column.
  • ary(0,4) + 6 ==> ary(1,4)
    ary(0,4) + 12 ==> ary(2,4)
    etc.
.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Possible to pass a single column of an array to a function?

Post by fxm »

But the most important question not addressed is why do you want to do that?
Do you know how arrays are really passed to procedures?

I wrote a topic around that:
How accessing to the array's descriptor structure?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Possible to pass a single column of an array to a function?

Post by jj2007 »

fxm wrote:But the most important question not addressed is why do you want to do that?
Indeed
Very useful indeed. Is the structure officially documented and guaranteed not to change?
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Possible to pass a single column of an array to a function?

Post by dodicat »

Perhaps I would do this task by a pedantic slog.
Pass the whole array to the sub and select the column of your choice and give those elemrnts a value of your choice.

Code: Select all

 

Sub test(ary() As Long,column As Long,value As Long)
   Dim As Long d=Ubound(ary,0)'GET_DIMENSION(array)
Select Case d
Case 1
   For a As Long=Lbound(ary,1) To Ubound(ary,1)
       If a=column Then ary(a)=value
Next 
Case 2
  For a As Long=Lbound(ary,1) To Ubound(ary,1)
    For b As Long=Lbound(ary,2) To Ubound(ary,2)
      If b =column Then ary(a,b)=value
 Next:Next
Case 3
For a As Long=Lbound(ary,1) To Ubound(ary,1)
    For b As Long=Lbound(ary,2) To Ubound(ary,2)
        For c As Long=Lbound(ary,3) To Ubound(ary,3)
        If c =column Then ary(a,b,c)=value
    Next:Next:Next
Case 4
 For a As Long=Lbound(ary,1) To Ubound(ary,1)
    For b As Long=Lbound(ary,2) To Ubound(ary,2)
        For c As Long=Lbound(ary,3) To Ubound(ary,3)
            For d As Long=Lbound(ary,4) To Ubound(ary,4)
        If d =column Then ary(a,b,c,d)=value
    Next:Next:Next :Next 
case 5
    'to be continued
case 6
    
case 7
    
case 8
    
End Select
End Sub

'example 1
Dim ary(2 To 4,0 To 6,2 To 4) As long

test(ary(),3,5)
For a As Long=Lbound(ary,1) To Ubound(ary,1)
    For b As Long=Lbound(ary,2) To Ubound(ary,2)
        For c As Long=Lbound(ary,3) To Ubound(ary,3)
            Print ary(a,b,c);

    Next:Print:Next:Print:Next
  '============ 
  'example 2
  Dim array(1 To 5,1 To 5) As long
  'set some values
  For a As Long=Lbound(array,1) To Ubound(array,1)
    For b As Long=Lbound(array,2) To Ubound(array,2)
        array(a,b)=Rnd*100
 Next:Next
  
  test(array(),2,9)
  For a As Long=Lbound(array,1) To Ubound(array,1)
    For b As Long=Lbound(array,2) To Ubound(array,2)
        Print array(a,b);
 Next:Print:Next
Sleep

 
It does bypass the headache of memcpy or descriptors.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Possible to pass a single column of an array to a function?

Post by fxm »

jj2007 wrote:
fxm wrote:I wrote a topic around that:
How accessing to the array's descriptor structure?
Very useful indeed. Is the structure officially documented and guaranteed not to change?
fxm wrote:The descriptors (for the var-len strings and for the arrays) are internal structures from compiler which allow an easily interfacing of a user with strings/arrays.
Similarly, for virtuality and polymorphism, the Vptr/Vtable/RTTinfo structures are only described in the forum topic "Abstract/Virtual destructor/method behaviour" (last diagram and use-cases at viewtopic.php?p=214677#p214677).

But all these internal structures from compiler must not normally be described in the User Manual (they are subject to change from one revision to the next).
Their knowledge allows only better understanding of the user program implementation, and also are useful for hacking but this is not the aim of the documentation!
cbruce
Posts: 166
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: Possible to pass a single column of an array to a function?

Post by cbruce »

Tested a couple of things and it looks like it could be done, but I wouldn't like getting it all working correctly, and I would *NEVER* want to try and maintain it.

Just went old-school: If they give me a multi-dimension array, I'll just create a temp single-dimension array for each part that I need to work on and then copy each of those temp S-D arrays back into their M-D array as I go along.

Thanks everyone.
Post Reply