Как я могу индексировать массив MATLAB, возвращаемый функцией, не назначая его сначала локальной переменной?
например, если я хочу прочитать среднее значение из magic(5)
, Я могу сделать это так:
M = magic(5);
value = M(3,3);
и value == 13
. Я хотел бы иметь возможность сделать что-то вроде одного из них:
value = magic(5)(3,3);
value = (magic(5))(3,3);
чтобы обойтись без промежуточной переменной. Однако MATLAB жалуется на Unbalanced or unexpected parenthesis or bracket
в первой скобке перед 3
.
можно ли считывать значения из массива / матрицы без предварительного присвоения его переменной?
9 ответов:
Это на самом деле и можно делать то, что вы хотите, но вы должны использовать функциональную форму оператора индексирования. При выполнении операции индексирования с помощью
()
, вы на самом деле делает вызовsubsref
там был просто хороший пост в блоге on Лорен об искусстве Matlab пару дней назад с парой камней, которые могли бы помочь. В частности, с помощью вспомогательных функций, таких как:
paren = @(x, varargin) x(varargin{:}); curly = @(x, varargin) x{varargin{:}};
здесь
paren()
можно использовать какparen(magic(5), 3, 3);
вернутся
ans = 16
Я бы также предположил, что это будет быстрее, чем ответ gnovice, но я не проверял (используйте профилировщик!!!). Это, как говорится, вы также должны включить эти функции определения где-то есть. Я лично сделал их независимыми функциями на своем пути, потому что они очень полезны.
эти и другие функции теперь доступны в Конструкции Функционального Программирования надстройка, которая доступна через Matlab Add-On Explorer или на Обмен.
как вы относитесь к использованию недокументированных функций:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3) ans = 13
или для массивов ячеек:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3} ans = 13
Так же, как магия:)
обновление:
плохие новости, выше Хак больше не работает в R2015b! Это нормально, это была недокументированная функциональность, и мы не можем полагаться на нее как на поддерживаемую функцию :)
для тех, кто задается вопросом, Где найти этот тип вещи, посмотрите в папке
fullfile(matlabroot,'bin','registry')
. Там есть куча XML файлы там, которые перечисляют все виды вкусностей. Имейте в виду, что вызов некоторых из этих функций напрямую может легко привести к сбою сеанса MATLAB.
по крайней мере, в MATLAB 2013a вы можете использовать
getfield
как:a=rand(5); getfield(a,{1,2}) % etc
чтобы получить элемент (1,2)
к сожалению следующий синтаксис
magic(5)(3,3)
Не поддерживается matlab. вы должны использовать временные промежуточные переменные. вы можете освободить память после использования, например,tmp = magic(3); myVar = tmp(3,3); clear tmp
обратите внимание, что если вы сравниваете время выполнения со стандартным способом (asign результат, а затем доступ к записям), они точно такие же.
subs=@(M,i,j) M(i,j); >> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap) ans = 0.0103 >> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap) ans = 0.0101
на мой взгляд, суть в том, что MATLAB не имеет указателей, вы должны жить с ним.
это может быть проще, если вы сделаете новую функцию:
function [ element ] = getElem( matrix, index1, index2 ) element = matrix(index1, index2); end
и затем использовать его:
value = getElem(magic(5), 3, 3);
ваша начальная нотация-самый краткий способ сделать это:
M = magic(5); %create value = M(3,3); % extract useful data clear M; %free memory
Если вы делаете это в цикле, вы можете просто переназначить M каждый раз и игнорировать четкое утверждение.
чтобы дополнить ответ Амро, вы можете использовать
feval
вместоbuiltin
. Нет никакой разницы, действительно, если вы не пытаетесь перегрузить функцию оператора:BUILTIN(...) то же самое, что и ФЕВАЛЬ(...) кроме того, что он будет называть оригинальная встроенная версия функции, даже если она перегружена существует (для этого, чтобы работать, вы не должны перегружать ВСТРОЕННЫЙ.)
>> feval('_paren', magic(5), 3, 3) % M(3,3) ans = 13 >> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3} ans = 13
вот что интересно
feval
Кажется, совсем чуть-чуть быстрее, чемbuiltin
(на ~3,5%), по крайней мере, в Matlab 2013b, что странно, учитывая, чтоfeval
нужно проверить, если функция перегружена, в отличие отbuiltin
:>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc; Elapsed time is 49.904117 seconds. >> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc; Elapsed time is 51.485339 seconds.