Как я могу сохранить массивы с плавающей запятой в многомерном массиве в IDL?

Я пытаюсь сохранить много массивов с плавающей запятой в массиве с несколькими размерами. Каждый массив с плавающей запятой принадлежит определенному индексу в многомерном массиве.

Размер массива массивов с плавающей запятой: [128, 128].

Что я пробовал?

(Я сделал это проще, сейчас я не использую размер [128, 128].)

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

И это на самом деле не то, что я хочу! Мой float_array не должен перезаписывать другие индексы из моего множественного массива, а только самый первый индекс (multiple_array[0, 0])

Что я хочу:

Я думал примерно так:

(Допустим, этот код будет работать как в других языках программирования)

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

И позже мой multiple_array должен выглядеть так:

> 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

... и так далее

Что я буду делать с этим позже?

Позже я хочу получить эти значения следующим образом:

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

Это вообще возможно? Для меня на самом деле не имеет значения, будет ли мой multiple_array заканчиваться на PTRARR или что-то еще, пока у меня есть результат вроде current_float_array, я буду им доволен.

Заранее благодарю за любую помощь! Я с нетерпением жду любых предложений.


person TheHeroOfTime    schedule 08.08.2017    source источник


Ответы (2)


Вы проделали большую работу, ответив на свой очень красиво сформулированный вопрос. :-) Могу добавить еще несколько вариантов.

В случае, когда ваши подмассивы имеют одинаковый размер (128x128), общий подход в IDL заключается в использовании массива большей размерности для содержания нескольких из них. В этом случае, когда вам нужен массив (5x3) подмассивов, вы можете создать:

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

Чтобы получить доступ к одному подмассиву 128x128, используйте, например:

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

Обратите внимание, что IDL отбрасывает конечные измерения, если они имеют длину 1, поэтому мы получаем Array[128, 128], а не Array[128, 128, 1, 1].

Одно замечание для эффективности: когда вы загружаете данные в этот массив, а не адресуете подмассив 128x128, если вы указываете только начальный элемент, IDL выполнит назначение гораздо быстрее. Итак, используйте:

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

скорее, чем:

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

(Общее правило заключается в том, что за кулисами IDL берет любые элементы «*» и расширяет их до набора индексов, которые используются для перемещения каждого элемента данных один за другим. Если вы просто задаете начальный элемент, весь массив может копировать как блок.)

Обратите внимание, что это именно то, что вы непреднамеренно сделали в своем первом тесте выше (multiple_array[0, 0] = float_array), что было не тем, что вы хотели в то время.

Подход multidim_array и ваш подход PtrArr будут иметь свои плюсы и минусы, когда массивы очень большие, где размер памяти и время обработки могут иметь компромиссы, но в небольших приложениях разумен любой подход.

Еще один способ сделать это (по крайней мере, начиная с IDL 8.1) — использовать тип данных LIST, который позволил бы подмассивам иметь разные размеры. На самом деле элемент списка может быть чем угодно (например, ваши подмассивы), и вы можете получить доступ к этим записям (и даже индексировать подмассивы) с помощью простого синтаксиса индексации массива. Вот пример того, что вы можете сделать, создав a как список списков:

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

Вы загрузите свои данные в список списков, подобных этому, в цикле (извините, не проверено, но считается правильным):

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

и вы можете получить доступ к первому массиву как:

multiple_list[0, 0]

а также:

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

Я надеюсь, что это полезно!

person Dick Jackson    schedule 08.08.2017
comment
Большое спасибо за ваш ответ. Я выбрал ваш пост в качестве ответа, потому что я думаю, что намного лучше и, на мой взгляд, проще и быстрее сохранить массив с плавающей запятой в многомерном массиве: D. У меня все еще есть один маленький вопрос: с помощью этого решения вы можете сохранить массив float в многомерном массиве. Есть ли аналогичный способ сохранить struct в массиве multidim? Я также хочу сначала определить множественный массив, а затем добавить структуру в определенную позицию массива один за другим. Если невозможно сначала определить множественный массив, будет ли решение, в котором я могу добавлять структуры одну за другой? - person TheHeroOfTime; 11.08.2017
comment
Да, массив многомерных структур легко создается с помощью structArray = Replicate({myStruct, a:0, b:''}, [3, 4, 2]) и structArray[2, 0, 1] = {a:42, b:'hi'}. Дополнительную информацию можно найти на сайте документации Harris. - person Dick Jackson; 17.08.2017

Я просто нашел ответ как-то сам. На самом деле это очень легко. Я также надеюсь, что это поможет другим людям.

Вот что вам нужно сделать:

Вместо установки /FLOAT просто установите /PTR в функции MAKE_ARRAY:

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

Определите свой float_array как всегда:

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

Самая важная часть:

Определите свой массив с плавающей запятой как PTR_NEW, чтобы вы могли сохранить свой массив с плавающей запятой в первом индексе.

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>

Поместив * перед вашим массивом, вы распечатаете содержимое вашего массива с плавающей запятой.

> *multiple_array[0,0]
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000
person TheHeroOfTime    schedule 08.08.2017