Есть ли в Matlab быстрый способ закодировать следующее:

[SmallA41./SmallA42, SmallA51./SmallA52, SmallA61./SmallA62, ..., SmallA201./SmallA202]

Где SmallA является общим для всех переменных, "числа" находятся в диапазоне от 4 до 20, а каждое имя переменной в форме SmallA__ является вектором 101 x 1 ?

Я пытался horzcat, но не знаю, как перебирать имена переменных.

Благодарность!

2
abscissa 23 Фев 2016 в 22:14

3 ответа

Лучший ответ

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

SmallA1 = rand(100,1);
SmallA2 = rand(100,1);
SmallA3 = rand(100,1);
SmallA4 = rand(100,1);

vars = whos('SmallA*');

% Borrowing the idea from the answers below
tmp = [tempname, '.mat'];
save(tmp, vars.name);
data = load(tmp, '-mat');

indices = str2double(regexp({vars.name}, '(?<=SmallA)\d', 'match', 'once'));

A = cell(size(vars));
for k = 1:numel(vars)
    A{indices(k)} = data.(vars(k).name);
end

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

Теперь, чтобы делать то, что вы хотите, вы можете просто использовать индексирование и матричное деление.

Для простого случая, который я представил, это будет

result = cat(2, A{1:2:end}) ./ cat(2, A{2:2:end});

Для точного сценария, который вы опубликовали, это будет означать:

result = cat(2, A{41:10:end}) ./ cat(2, A{42:10:end});

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

A = cat(2, A{:});

А затем выполните нужное деление следующим образом:

result = A(:,41:10:end) ./ A(:,42:10:end);

Затем с этими изменениями вы можете сосредоточиться на фактической математике и перестать беспокоиться о том, как анализировать имена переменных и т. Д.

2
Suever 23 Фев 2016 в 20:17

Возможное не совсем элегантное решение, которое позволяет не использовать eval , может быть:

  • определить интересующие переменные
  • сохранить эти переменные в фиктивном файле .mat
  • читать переменные, хранящиеся в фиктивном файле .mat, в структуру
  • доступ к полям структуры путем динамической генерации имени самих полей

Макет .mat можно удалить в конце скрипта.

% Define the input arrays
SmallA4=randi(10,3,1);;
SmallA5=randi(10,3,1);;
SmallA6=randi(10,3,1);;
SmallA7=randi(10,3,1);;
SmallA8=randi(10,3,1);;
SmallA9=randi(10,3,1);;
SmallA10=randi(10,3,1);;
SmallA11=randi(10,3,1);;
SmallA12=randi(10,3,1);;
SmallA13=randi(10,3,1);;
Small13=randi(10,3,1);;
% Get the names of the varaibles
lv=who('SmallA*')
% Save the desired variables in a dummy ".mat" file
[pathstr,name,ext] = fileparts(tempname);
save([name '.mat'],lv{:})
% Load the varaible stored in the dummy ".mat" file in a struct
lv_s=load([name '.mat'])
% Build the target matrix by dinamically creating the names of the fields
m=[];
for i=4:2:13
   m=[m,lv_s.(['SmallA' num2str(i)])./lv_s.(['SmallA' num2str(i+1)])]
end

Надеюсь это поможет.

Капла

3
il_raffa 23 Фев 2016 в 19:48

Следующий код работает:

for kk = 4:20
    y(:,kk-3) = horzcat(eval(['SmallA' num2str(kk) '1'])./eval(['SmallA' num2str(kk) '2']));
end
0
abscissa 23 Фев 2016 в 19:34