Octave/MATLAB: области видимости переменных и поиск имен?

Итак, у меня есть массив ячеек векторов X:

octave:149> X
X = 
{
  [1,1] =

      1   17   20

  [2,1] =

      5   20   22   27

  [3,1] =

      2   17   18   21

}

Я создаю пустой вектор Y:

octave:150> Y = []
Y = [](0x0)

Затем я вызываю анонимную функцию для каждого значения X с «Y = уникальным ([Y x])»:

octave:151> cellfun(@(x)(Y = unique([Y x])),X,'UniformOutput',false)
ans = 
{
  [1,1] =

      1   17   20

  [2,1] =

      1    5   17   20   22   27

  [3,1] =

      1    2    5   17   18   20   21   22   27

}

Хорошо, но теперь Y все еще пуст:

octave:152> Y
Y = [](0x0)
octave:153> 

Ясно, что имя Y внутри анонимной функции создало и связало новое хранилище для собственной версии Y.

Каковы правила хранения и разрешения имен в Octave/MATLAB? Когда память выделяется для переменной? Когда два одинаковых имени связаны с одной и той же переменной? (Есть ли способ повлиять на значение Y в приведенной выше анонимной функции?)


person Andrew Tomazos    schedule 01.05.2012    source источник


Ответы (1)


В Matlab функции имеют свою область видимости. Когда вы передаете переменную, если эта переменная также не находится в списке вывода, она не будет изменена вызываемой функцией; функция делает копию переменной, и эта копия — это то, что функция изменяет.

В анонимных функциях переменная копируется при объявлении функции. См. эту документацию по Matlab. Это то, что вы видите с Ю.

Кроме того, я думаю, что вы неправильно используете CellFun. Вы должны возвращать значение анонимной функции не внутри вызова cellfun, а в результате cellfun.

Итак, возможно, это ближе к тому, что вы хотите:

octave:151> Y = cellfun(@(x, y)(unique([y x])),X,Y,'UniformOutput',false)

Я не могу сказать, хотите ли вы, чтобы результат каждого вызова анонимной функции изменил Y и использовал этот результат в следующем вызове. Если это то, что вы хотите, это будет сложнее.

person Dusty Campbell    schedule 01.05.2012
comment
Я пытаюсь объединить векторы в массиве ячеек. В конце Y должен быть равен [1 2 5 17 18 20 21 22 27] - person Andrew Tomazos; 01.05.2012
comment
То есть я хочу получить набор наборов векторов в массиве ячеек. - person Andrew Tomazos; 01.05.2012
comment
Если все, что вам нужно, это set union без промежуточных шагов, вы можете использовать следующее: Y = unique([X{:}]). При этом используется тот факт, что Matlab может создавать массивы из списки, разделенные запятыми. Это решение предполагает, что все векторы внутри ячейки равны 1xn. - person AE426082; 01.05.2012