Есть ли какой-либо механизм для автоматического сжатия в Matlab / Octave

#arrays #matlab #multidimensional-array #octave

#массивы #matlab #многомерный массив #октава

Вопрос:

Для массива nD было бы неплохо иметь возможность автоматического сжатия для удаления одноэлементных измерений. Есть ли способ сделать это, о котором я не знаю? Это было бы особенно полезно для агрегированных функций (например, sum, mean и т. Д.), Где вы всегда ожидаете результата с меньшим количеством измерений.

Вот простой пример:

 >> A = ones(3,3,3);
>> B = mean(A);
>> size(B)
ans =  
   1   3   3

>> squeeze(B)
ans =
   1   1   1
   1   1   1
   1   1   1
 

Было бы неплохо, если бы Matlab / Octave автоматически выполнял сжатие для меня. Или, если бы был способ включить эту опцию (что-то похожее на hold on для графиков).

Комментарии:

1. Вы имеете в виду отображение матриц или самих матриц? Мне было бы страшно, если бы размеры произвольно исчезли из матрицы, это усложнило бы написание логики алгоритма.

2. Кроме того, тогда следует a=[1,2,3] возвращать вектор столбца? Сделайте то же самое, a=[1;2;3] что и?

3. @CrisLuengo На ваш второй вопрос уже дан ответ, я думаю, из-за необходимости совместимости с squeeze поведением: векторы строк не сжимаются в столбцы

4. Проблема в том, что одноэлементные измерения широко используются для векторизации кода. Если вы найдете решение, которое заставит matlab всегда автоматически это делать, оно также будет делать это для своего собственного кода, который часто полагается на существующие синглтоны (например, для трансляции). Вы можете просто сломать многие встроенные MATLAB.

5. Когда у меня есть свободная память, я использую много n-мерной проекции и трансляции для ускорения кода. Автоматическое сжатие нарушило бы все это.

Ответ №1:

Насколько я знаю, в Matlab этого нет. И я не думаю, что это было бы хорошей идеей. Рассмотрим модифицированную версию вашего примера:

 >> A = ones(3,1,1,3);
>> B = mean(A);
>> size(B)
ans =
     1     1     1     3
 

Что здесь должно делать «автоматическое сжатие»? Уменьшить B до размера [1 1 3] или до [1 3] ?

  • Вы можете утверждать, что он должен удалить то же измерение, которое mean превратилось в синглтон. Но тогда это должно быть сделано внутри mean функции, возможно, с дополнительным входным аргументом. Как только вы получите вывод функции, нет никакой информации о том, как она была получена.
  • Или вы можете утверждать, что он должен удалить все одноэлементные измерения, например squeeze (более или менее). Но тогда это приведет к удалению измерений, которые уже были одноэлементными во входных данных функции, что, вероятно, нежелательно.

Если вы спросите меня, наличие второго ввода в squeeze specifiyng, какие (одноэлементные) измерения для удаления, было бы хорошим дополнением (в том же духе, который вы можете использовать mean(A, 1) , чтобы принудительно применить операцию к первому измерению, даже если A это вектор строки).

Комментарии:

1. Согласен. Вы можете использовать permute для удаления определенного одноэлементного измерения.

2. Для меня я бы предпочел удалить все одноэлементные измерения. Я даже не уверен, что мне нравятся синглтоны в первых двух измерениях. Но я отвлекся. Проще всего реализовать удаление всех одноэлементных измерений. Но некоторые пользователи могут предпочесть поведение для удаления только того измерения, которое только что перешло к одному. Синтаксис может быть auto reduce on all или auto reduce on для обработки обоих этих случаев соответственно.

Ответ №2:

Я согласен с Луисом и Крисом, но я бы добавил следующее.

И Matlab, и Octave автоматически сжимают дополнительные измерения в очень специфическом сценарии: любые измерения в конце, которые были сведены к одиночным, автоматически вытесняются.

Например.

 A = ones([1,2,3,4]);
B = mean(A, 4);
size(B)
% ans = 1   2   3
 

Обратите внимание, как ответ [1,2,3] , так и нет [1,2,3,1] . Это в отличие от таких языков, как python, например, где размер (1,1) сильно отличается от размера (1,) .

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

Это становится еще более полезным, когда вы понимаете, что:

 size(A(:))       % ans =   24    1     (i.e. 24)
size(A(:,:))     % ans =    1   24
size(A(:,:,:))   % ans =    1    2   12
size(A(:,:,:,:)) % ans =    1    2    3    4
 

Это означает, что если вы упорядочиваете свои измерения иерархически, вы можете гарантировать, что любые операции, которые должны выполняться над более высокими измерениями, могут а) быть легко векторизованы и б) дать естественный результат, без необходимости тратить время на сжатие или перестановку результирующих измерений.

Комментарии:

1. Matlab тоже это делает. Однако «Официальное» представление, позволяющее взглянуть на него, — это наоборот (что, конечно, эквивалентно): можно считать, что любой массив имеет бесконечно много конечных синглетов

2. Спасибо, хороший улов, я не имел в виду, что это звучало так, что это была точка только октавы.

3. Ну, я не уверен, что это так, size(B,34) возвращает 1 :). Но я понимаю вашу точку зрения.