Ячейка MATLAB для отдельных переменных - PullRequest
3 голосов
/ 03 ноября 2011

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

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

>> output = 

[300x300x2 double]    [300x300x2 double]    [300x300x2 double]

>> [a1,a2,a3]=deal(output{:});

Где число после а представляет идентификатор. Можно ли автоматизировать эту команду, чтобы префикс (в данном случае: a) мог быть установлен пользователем, а идентификатор был заполнен автоматически? Например, я мог бы установить переменные, как показано ниже, и использовать их в команде deal для именования моих новых переменных?

>> id =

 1     2     3

>> prefix =

a

Есть идеи? Благодаря.

Ответы [ 4 ]

2 голосов
/ 03 ноября 2011

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

function deal_output(output, id, prefix)

id     = id(:);
vars   = strcat(prefix, cellstr(num2str(id)))';
myexpr = ['[', sprintf('%s,', vars{1:end-1}), vars{end}, '] = deal(output{:})'];

evalin('caller', myexpr)
>> output = num2cell(1:3);
>> id     = 1:3;
>> prefix = 'a';
>> deal_output(output, id, prefix)

a1 =

     4


a2 =

     5


a3 =

     6

Также проверьте файл join.m в FileExchange, чтобы избежать уродливого sprintf.

2 голосов
/ 03 ноября 2011

Возможно что-то вроде:

function dealinto(prefix, cellarray)
% DEALINTO
% USAGE
%   dealinto('a', {'one', 'two', 'three'})
% Causes these variables to be set in the base workspace:
% a1: 'one'
% a2: 'two'
% a3: 'three'    
for i=1:numel(cellarray)
    assignin('base', [prefix num2str(i)], cellarray{i});
end

Если вы замените 'base' на 'caller' в приведенном выше, переменные будут записаны в рабочую область вызывающей функции. Однако я не рекомендую делать это по той же причине, по которой я бы не рекомендовал вызывать LOAD без выходных аргументов внутри функции: произвольная запись в рабочее пространство работающей функции не очень безопасна.

Если вам нужно что-то подобное для использования внутри функций, но вы не хотите просто писать переменные, вы можете сделать то же самое, что и LOAD, то есть дать вам структуру, поля которой являются переменными, которые вы бы хотели в противном случае производят.

0 голосов
/ 06 января 2012

Я не могу добавить комментарий, поэтому я добавляю ответ в виде вопроса ^ _ ^

Не лучше ли предварительно создать список имен и проверить их врабочее пространство вызывающего абонента с использованием genvarname?

Names = cell(1,numel(data))
for idx = 1:numel(data)
 Names{idx} = [Prefix, num2str(idx)]
end
Names = genvarname(Names,who)
dealinto(Names, data)

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

function dealinto(Names, Values)
for idx = 1:length(Names)
 assignin('caller', Names(idx), Values(idx))
end
0 голосов
/ 04 ноября 2011

Вы действительно должны выводить их как полностью отдельные переменные?Было бы намного эффективнее использовать динамические имена полей в структуре, поскольку это позволило бы избежать использования оператора eval().Смотрите блоги MATLAB , чтобы избежать eval ()

В этом случае

m = length(output);
[a(1:m).data] = deal(output{:});

Это вернет массив структуры, вычисление длины добавлено, так что оно будет работатьдля разных размеров выходного массива ячеек.

Каждый массив может быть доступен индивидуально с помощью номера идентификатора.

a(1).data
a(2).data
a(3).data
...