Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bug when redimensioning multi-dimension arrays?
#11
(06-20-2024, 03:32 PM)SMcNeill Wrote: Your arrays are from (0 to 5, 0 to 5), which affects them as above.  You're ust printing them from (1 to 5, 1 to 5), and that makes it seem as if values are totally scrambled or even lost.
AH CRAP, I missed the second part of your post.

My original code (that led me here) has an OPTION BASE 1 and I forgot to do that in my test code. PEBCAK. Thank you sir, that explains a lot.

So now I'm wondering if it would be possible to implement the array copying routine that you and bplus both outlined (copying to a new array) into the REDIM _PRESERVE routines in the QB64 source so that it would work as people might expect. I'm sure there are more considerations here that I'm recognizing, but has that been looked at?
Reply
#12
(06-20-2024, 03:41 PM)12centuries Wrote:
(06-20-2024, 03:32 PM)SMcNeill Wrote: Your arrays are from (0 to 5, 0 to 5), which affects them as above.  You're ust printing them from (1 to 5, 1 to 5), and that makes it seem as if values are totally scrambled or even lost.
AH CRAP, I missed the second part of your post.

My original code (that led me here) has an OPTION BASE 1 and I forgot to do that in my test code. PEBCAK. Thank you sir, that explains a lot.

So now I'm wondering if it would be possible to implement the array copying routine that you and bplus both outlined (copying to a new array) into the REDIM _PRESERVE routines in the QB64 source so that it would work as people might expect. I'm sure there are more considerations here that I'm recognizing, but has that been looked at?

The problem with adding it into the source is simple:  How do you account for all possible variations of array that a user might have?

DIM x(0 to 1, 1 to 4)
REDIM x(1 to 3, 4 to 17)    <--- Now what the heck does the source look like for this??

DIM x(-1 to 3, 2 to 14, 1 to 27, 11, apple_number, cheestos, and_frogs)    <-- and what would the source look like to handle this when its redimmed?

Just try and imagine the routine you'd have to write for that, and it'd have to allow resizing of the LBOUND and the UBOUND... on one, or more, or all indexes...  while preserving data that may or may not be the original range anymore...

We've looked at it...  blinked stupidly to each other a few times... and then said, "Umm...  Yeah.    No.   Folks can write what they need for their one specific case.  It'd be just about impossible to support fully for all use cases."

At least, I know it'd be impossible for *ME* to try and support it.  I'd get completely lost in the complexity of trying to write something that expanded for any number of dimensions, and any index range, and then resized to any other index ranges...

So we do what's really simple:   Preserve the data in the old array and simply move it into the new array.  That'll handle REDIM and PRESERVE as long as you resize only by the RIGHTMOST index.

For anything more than that, we leave it for the user to have to write their own routine to handle it.   As you can see, just something as simple as OPTION BASE 1 can really change how things look/work and perform.   For us to change the source, we'd have to account for ALL those possible changes which the end user might need -- and honestly, that's just overwhelming to even think about in this case.  

That said, if someone else wants to sit down and sort out how to do it, we're an open-source project.  We'll be more than happy to add in any additions which they come up with for the problem.  I don't imagine that it's impossible to do; but honestly it's not something that I ever think the current devs will ever work on.  It's low priority, complex as heck, and unless there's some library already made out there that one can just plug into to do this type of thing for us, I certainly wouldn't hold my breath waiting for us to do it ourselves. 

Wink
Reply
#13
it might be handy to be able to use the same array name throughout an app so redim would be needed to do that and it might be useful to convert a 2d array to bigger row size (more x's per row) and really not hard to convert the for sure code i showed into a sub for resizing x's. as stated already by steve just adding more rows wont be a problem for redim forget _preserve though.

so not so complex if restrict yourself to 2d array and i'd say drop option base to make subs and functions more portable to other apps. complexity relieved further if we can assume not switching the lbounds of the array. complexity reduced again if we are only expanding the array...

so how long would it take to rewrite my example to a sub? now i am curious to see if it's as simple as i think ;-))
b = b + ...
Reply
#14
oK redim wont let me change the array ???

Code: (Select All)
Dim Grid(1 To 5, 1 To 5) As Long
' LoadInitialValues
For y = 1 To 5
    For x = 1 To 5
        counter = counter + 1
        Grid(x, y) = counter
    Next
Next
ShowArrayValues Grid()
moreXPerRow Grid(), 10, 10

ShowArrayValues Grid()
End

Sub moreXPerRow (arr() As Long, xpr As Long, r As Long) ' xpr x per row
    Dim As Long lbx, lby, ubx, uby
    lbx = LBound(arr, 1)
    lby = LBound(arr, 2)
    ubx = UBound(arr, 1)
    uby = UBound(arr, 2)
    Dim c(lbx To ubx, lby To uby) As Long
    For y = lby To uby
        For x = lbx To uby
            c(x, y) = arr(x, y)
        Next
    Next
    'ReDim arr(xpr, r)  'nope
    'ReDim _Preserve arr(xpr, r)  'nope
    'ReDim _Preserve arr(lbx To xpr, lby To r)
    ReDim _Preserve arr(lbx To xpr, lby To r) As Long ' nope
    For y = lby To uby
        For x = lbx To uby
            arr(x, y) = c(x, y)
        Next
    Next
End Sub

Sub ShowArrayValues (arr() As Long)
    Print "Array Values:": Print
    For y = 1 To UBound(arr, 2)
        Print Using "Row ##  "; y,
        For x = 1 To UBound(arr, 1)
            Print Using " ##"; arr(x, y);
        Next
        Print
    Next
    Print
End Sub
b = b + ...
Reply
#15
(06-20-2024, 04:58 PM)bplus Wrote: oK redim wont let me change the array ???

Code: (Select All)
Dim Grid(1 To 5, 1 To 5) As Long

Why would it? That's not a REDIMable array. Tongue
Reply
#16
ok that blunder fixed, fixes code, added a second test of sub
Code: (Select All)
ReDim Grid(1 To 5, 1 To 5) As Long
' LoadInitialValues
For y = 1 To 5
    For x = 1 To 5
        counter = counter + 1
        Grid(x, y) = counter
    Next
Next
ShowArrayValues Grid()
moreXPerRow Grid(), 10, 10

ShowArrayValues Grid()
moreXPerRow Grid(), 15, 12
ShowArrayValues Grid()
End

Sub moreXPerRow (arr() As Long, xpr As Long, r As Long) ' xpr x per row
    Dim As Long lbx, lby, ubx, uby
    lbx = LBound(arr, 1)
    lby = LBound(arr, 2)
    ubx = UBound(arr, 1)
    uby = UBound(arr, 2)
    Dim c(lbx To ubx, lby To uby) As Long
    For y = lby To uby
        For x = lbx To uby
            c(x, y) = arr(x, y)
        Next
    Next
    ReDim arr(xpr, r) 'nope
    'ReDim _Preserve arr(xpr, r)  'nope
    'ReDim _Preserve arr(lbx To xpr, lby To r)
    'ReDim _Preserve arr(lbx To xpr, lby To r) As Long ' nope
    For y = lby To uby
        For x = lbx To uby
            arr(x, y) = c(x, y)
        Next
    Next
End Sub

Sub ShowArrayValues (arr() As Long)
    Print "Array Values:": Print
    For y = 1 To UBound(arr, 2)
        Print Using "Row ##  "; y,
        For x = 1 To UBound(arr, 1)
            Print Using " ##"; arr(x, y);
        Next
        Print
    Next
    Print
End Sub
b = b + ...
Reply
#17
And I's brokes it already!  

Code: (Select All)
REDIM Grid(1 TO 5, 1 TO 5) AS LONG
' LoadInitialValues
FOR y = 1 TO 5
FOR x = 1 TO 5
counter = counter + 1
Grid(x, y) = counter
NEXT
NEXT
ShowArrayValues Grid()
moreXPerRow Grid(), 4, 10

ShowArrayValues Grid()
END

SUB moreXPerRow (arr() AS LONG, xpr AS LONG, r AS LONG) ' xpr x per row
DIM AS LONG lbx, lby, ubx, uby
lbx = LBOUND(arr, 1)
lby = LBOUND(arr, 2)
ubx = UBOUND(arr, 1)
uby = UBOUND(arr, 2)
DIM c(lbx TO ubx, lby TO uby) AS LONG
FOR y = lby TO uby
FOR x = lbx TO uby
c(x, y) = arr(x, y)
NEXT
NEXT
REDIM arr(xpr, r) ' fixed
'ReDim _Preserve arr(xpr, r) 'nope
'ReDim _Preserve arr(lbx To xpr, lby To r)
'ReDim _Preserve arr(lbx To xpr, lby To r) As Long ' nope
FOR y = lby TO uby
FOR x = lbx TO uby
arr(x, y) = c(x, y)
NEXT
NEXT
END SUB

SUB ShowArrayValues (arr() AS LONG)
PRINT "Array Values:": PRINT
FOR y = 1 TO UBOUND(arr, 2)
PRINT USING "Row ## "; y,
FOR x = 1 TO UBOUND(arr, 1)
PRINT USING " ##"; arr(x, y);
NEXT
PRINT
NEXT
PRINT
END SUB


Which goes to show how complex an universal routine would be to write and toss into the core language. This is breaking now, when one array is smaller than the other.

You need to check for lbound on both, ubound on both, for all dimensions.... only copy the parts that overlap... and then expand that to work for any number of dimensions which someone might have in their array.
Reply
#18
Quote:And I's brokes it already!

reread my reply 13, expansion only
b = b + ...
Reply
#19
(06-20-2024, 05:10 PM)bplus Wrote:
Quote:And I's brokes it already! 

reread my reply 13, expansion only

Code: (Select All)
REDIM Grid(1 TO 5, 1 TO 5) AS LONG
' LoadInitialValues
FOR y = 1 TO 5
    FOR x = 1 TO 5
        counter = counter + 1
        Grid(x, y) = counter
    NEXT
NEXT
ShowArrayValues Grid()
moreXPerRow Grid(), 4, 10

ShowArrayValues Grid()
END

SUB moreXPerRow (arr() AS LONG, xpr AS LONG, r AS LONG) ' xpr x per row
    DIM AS LONG lbx, lby, ubx, uby
    lbx = LBOUND(arr, 1)
    lby = LBOUND(arr, 2)
    ubx = UBOUND(arr, 1)
    uby = UBOUND(arr, 2)
    DIM c(lbx TO ubx, lby TO uby) AS LONG
    FOR y = lby TO uby
        FOR x = lbx TO uby
            c(x, y) = arr(x, y)
        NEXT
    NEXT
    REDIM arr(xpr, r) ' fixed
    'ReDim _Preserve arr(xpr, r)  'nope
    'ReDim _Preserve arr(lbx To xpr, lby To r)
    'ReDim _Preserve arr(lbx To xpr, lby To r) As Long ' nope
    FOR y = lby TO uby
        FOR x = lbx TO uby
            IF x <= xpr THEN arr(x, y) = c(x, y)
        NEXT
    NEXT
END SUB

SUB ShowArrayValues (arr() AS LONG)
    PRINT "Array Values:": PRINT
    FOR y = 1 TO UBOUND(arr, 2)
        PRINT USING "Row ##  "; y,
        FOR x = 1 TO UBOUND(arr, 1)
            PRINT USING " ##"; arr(x, y);
        NEXT
        PRINT
    NEXT
    PRINT
END SUB

There.  I fixed it for downsizing one, while expanding on the other index.  Tongue
Reply
#20
CoPilot says it can REDim a 3 Dim array into a $ dim array and preserve the values from the original array. Here is it's suggestion. 


Certainly! To redimension a 3D array to a 4D array while preserving all values in QB64pe, you can follow these steps:
  1. Let’s assume you have a 3D array called 
    Code: (Select All)
    arr
     with the shape 
    Code: (Select All)
    (n_bands, y_pixels, x_pixels)
    .
  2. First, swap the 
    Code: (Select All)
    n_bands
     axis to the end:
    Code: (Select All)
    DIM SHARED arr(1 TO n_bands, 1 TO y_pixels, 1 TO x_pixels)
    DIM SHARED arr4d(1 TO 1, 1 TO y_pixels, 1 TO x_pixels, 1 TO n_bands)

    FOR x = 1 TO x_pixels
        FOR y = 1 TO y_pixels
            FOR z = 1 TO n_bands
                arr4d(1, y, x, z) = arr(z, y, x)
            NEXT z
        NEXT y
    NEXT x
  3. Now you have a 4D array 
    Code: (Select All)
    arr4d
     with the desired shape 
    Code: (Select All)
    (1, y_pixels, x_pixels, n_bands)
    , preserving all values. ?
Remember to adjust the array dimensions and indices according to your specific use case! 




I'll have to see if Gemini can do it.
Reply




Users browsing this thread: 3 Guest(s)