1

I am trying to save many float arrays in a multiple dimsensional array. Each float array belongs to a specific index in the dimensional array.

The array size of the float arrays are [128, 128].

What did I try?

(I made it simple, right now I am not using the [128, 128] size.)

multiple_array = MAKE_ARRAY(5, 3, /FLOAT)
> multiple_array
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000

float_array = FLTARR(3, 3)
;skipped setting some simple values

> float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

multiple_array[0, 0] = float_array
   1.0000000       2.0000000       3.0000000      0.00000000      0.00000000
   4.0000000       5.0000000       6.0000000      0.00000000      0.00000000
   7.0000000       8.0000000       9.0000000      0.00000000      0.00000000

And that is actually not what I want! My float_array should not overwrite the other indexes from my multiple array, but only the very first index (multiple_array[0, 0])

What do I want:

I was thinking something like this:

(Let's say this code would work like in other programming languages)

multiple_array[0, 0] = float_array
   FIRST_FLOAT_ARRAY       0.0000000       0.0000000      0.00000000      0.00000000
   0.0000000               0.0000000       0.0000000      0.00000000      0.00000000
   0.0000000               0.0000000       0.0000000      0.00000000      0.00000000

And later my multiple_array should look like this:

> multiple_array
   FIRST_FLOAT_ARRAY       SECOND_FLOAT_ARRAY       THIRD_FLOAT_ARRAY      FOURTH_FLOAT_ARRAY      FIFTH_FLOAT_ARRAY
   SIXTH_FLOAT_ARRAY       0.0000000                0.0000000              0.00000000              0.00000000
   0.0000000               0.0000000                0.0000000              0.00000000              0.00000000

... and so on

What am doing with this later?

Later I want to get these values like this:

current_float_array = multiple_array[0, 0]
> help, current_float_array
CURRENT_FLOAT_ARRAY               FLOAT     = Array[3, 3]

> current_float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

Is this even possible? For me it actually doesn't matter, if my multiple_array would end in a PTRARR or anything else, as long as I have the result like current_float_array I would be happy with it.

Thanks in advance for any help! I am looking forward for any suggestions.

asynchronos
  • 583
  • 2
  • 14
TheHeroOfTime
  • 751
  • 4
  • 9
  • 23

2 Answers2

2

You did a great job of answering your own very nicely framed question. :-) I can add some more options.

In the case where your subarrays are the same size (128x128), a common approach in IDL is to use a higher-dimensional array to contain several of them. In this case, where you want a (5x3) array of the subarrays, you could create:

multidim_array = FltArr(128, 128, 5, 3)

To access one 128x128 subarray, use, for example:

current_float_array = multidim_array[*, *, 0, 0]
help, current_float_array
CURRENT_FLOAT_ARRAY               FLOAT     = Array[128, 128]

Note that IDL drops trailing dimensions if they have length 1, so we get Array[128, 128] rather than Array[128, 128, 1, 1].

One note for efficiency: when you are loading data into this array, rather than addressing the 128x128 subarray, if you indicate the starting element only, IDL will do the assignment much more quickly. So, use:

multidim_array[0, 0, 0, 0] = float_array

rather than:

multidim_array[*, *, 0, 0] = float_array

(The general rule is that, behind the scenes, IDL takes any "*" items and expands them into a set of indices that are used to move each data element one by one. If you just give the starting element, the whole array can be copied as a block.)

Note that this is exactly what you inadvertently did in your first test above (multiple_array[0, 0] = float_array), which was not what you wanted at the time.

The multidim_array approach and your PtrArr approach will each have pros and cons when arrays are very large, where memory size and processing time may have trade-offs, but in small applications, either approach is reasonable.

Yet another way to do this (since IDL 8.1 at least) is with the LIST data type, which would allow the subarrays to have different sizes. In fact, an element of a list can be anything at all (like your subarrays), and you can access those entries (and even index into the subarrays) with simple array-indexing syntax. Here's a sample of what you can do, creating a as a list of lists:

IDL> a=list(list(indgen(2,3),indgen(3,4)), list(indgen(2,4)))
IDL> a
[
    [
        [[0, 1], [2, 3], [4, 5]],
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
    ],
    [
        [[0, 1], [2, 3], [4, 5], [6, 7]]
    ]
]
IDL> a[0]
[
    [[0, 1], [2, 3], [4, 5]],
    [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
]
IDL> a[0,1]
       0       1       2
       3       4       5
       6       7       8
       9      10      11

You would load your data into the list of lists like this, within a loop (sorry, not tested, but believed correct):

multiple_list = List()
FOR rowI = 0, 3 DO BEGIN
   row_list = List
   FOR columnI = 0, 5 DO $
      row_list.Add, GetYourFloatArrayHerePossiblyUsing(columnI, rowI)
   multiple_list.Add, row_list
ENDFOR ; rowI over all rows

and you could access the first array as:

multiple_list[0, 0]

and also:

multiple_list[0, 0, 0, 0]     ; first element of first array
multiple_list[2, 4, 127, 127] ; last element of last array

I hope this is helpful!

  • Thank you very much for your answer. I have chosen your post as answer, because I think it is way better and in my opinion easier and faster to save float array in a multidim array :D. I still have one little question: With this solution you can save **float** array in a multidim array. Is there also a similar way to save a **struct** in a multidim array? I also want first to define a multi array and then adding a struct in a certain position of the array one by one. If it is not possible to define first the multi array, would there still be a solution where I can add structs one by one? – TheHeroOfTime Aug 11 '17 at 10:26
  • Yes, a multidim structure array is easily done with `structArray = Replicate({myStruct, a:0, b:''}, [3, 4, 2])` and `structArray[2, 0, 1] = {a:42, b:'hi'}`. More info at [Harris docs site](http://www.harrisgeospatial.com/docs/Arrays_of_Structures.html). – Dick Jackson Aug 17 '17 at 17:28
1

I just found the answer somehow by myself. It is actually very easy. I also hope this helps other people.

This is what you have to do:

Instead of setting a /FLOAT, just set a /PTR in the MAKE_ARRAY function:

multiple_array = MAKE_ARRAY(5, 3, /PTR)
> multiple_array
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>

Define your float_array as always:

float_array = FLTARR(3, 3)
;skipped setting some simple values

> float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

Most important part:

Define your float array as PTR_NEW, so that you can save your float array in the first index.

multiple_array[0,0] = PTR_NEW(float_array)
> multiple_array
<PtrHeapVar1><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>

> multiple_array[0,0]
<PtrHeapVar1>

By putting a * infront of your array, you will print out the content of your float array.

> *multiple_array[0,0]
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000
TheHeroOfTime
  • 751
  • 4
  • 9
  • 23