Как элегантно игнорировать некоторые возвращаемые значения функции MATLAB? - PullRequest
114 голосов
/ 14 апреля 2009

Возможно ли получить 'nth' возвращаемое значение из функции, не создавая фиктивные переменные для всех n-1 возвращаемых значений до этого?

Допустим, у меня есть следующая функция в MATLAB:

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;

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

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;

Но я думаю, что это вроде безобразно Я думаю, что вы могли бы сделать что-то вроде одной из следующих вещей, но вы не можете:

[_, _, variableThatIWillUse, _] = func;

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

Есть ли элегантные способы сделать это, которые работают?


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

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;

Я все еще думаю, что это очень уродливый код, но если нет лучшего способа, то, я думаю, я приму ответ.

Ответы [ 8 ]

223 голосов
/ 10 сентября 2009

В MATLAB версии 7.9 (R2009b) вы можете использовать ~, например,

[~, ~, variableThatIWillUse] = myFunction();

Обратите внимание, что , не является обязательным. Просто набрать [~ ~ var] не сработает и выдает ошибку.

Подробнее см. о выпуске .

38 голосов
/ 14 апреля 2009

Это что-то вроде хака, но это работает:

Сначала быстрый пример функции:

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3

Теперь ключ в том, что если вы используете переменную дважды в левой части назначения с несколькими выражениями, более раннее назначение перекрывается более поздним назначением:

[b,b,c]=Func3();
% yields b=2, c=3

[c,c,c]=Func3();
% yields c=3

(правка: просто чтобы проверить, я также проверил, что этот метод работает с [mu,mu,mu]=polyfit(x,y,n), если все, что вам нужно из polyfit, это третий аргумент)


изменить: есть лучший подход; см. ответ ManWithSleeve .

37 голосов
/ 14 апреля 2009

Если вы хотите использовать стиль, в котором переменная будет оставлена ​​для попадания в область битов, то разумной альтернативой будет

[ans,ans,variableThatIWillUse] = myfun(inputs);

ans - это, конечно, стандартная переменная нежелательной почты для matlab, которая часто перезаписывается в ходе сеанса.

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

13 голосов
/ 14 апреля 2009

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

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

Затем вызовите функцию следующим образом:

[a{:}] = func();

Затем просто удалите элемент из a , который вы хотите, и перезапишите a :

a = a{3};  % Get the third output
9 голосов
/ 28 августа 2009

Я написал функцию kth out:


function kth = kthout(k,ffnc,varargin)
%% kthout: take the kth varargout from a func call %FOLDUP
% 
% kth = kthout(k,ffnc,varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

[outargs{1:k}]  = feval(ffnc,varargin{:});
kth                         = outargs{k};

end %function

Вы можете позвонить

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc

Вы можете также обернуть функцию как

func_i_want = @(varargin)(kthout(3,@myfunc,varargin{:}));  %assuming you want the 3rd output.

после чего вы используете

val_i_want = func_i_want(func_input_1,func_input_2);

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

4 голосов
/ 16 апреля 2010

В Matlab 2010a я нашел отличный способ сделать то, что вы просите. Просто использовать символ «~» (без кавычек, конечно) в качестве фиктивной переменной (столько, сколько вы хотите при возвращении нескольких параметров). Это также работает для входных параметров функций, если функции предназначены для обработки отсутствующих данных. Я не знаю, существовало ли это в предыдущих версиях, но я недавно сталкивался с этим.

1 голос
/ 22 марта 2012

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

select = @(a,b) a(b);

Затем вы можете вызвать свою функцию следующим образом:

select(func,2);
select(func,1:3);

Или вы можете назначить вывод переменной:

output(1,2:4) = select(func,1:3);
0 голосов
/ 24 мая 2013

Есть ли причина не использовать ans (n), например:

a=rand([5 10 20 40]);

size(a);

b=ans(2);

Дает b = 10, и не будет ли этот способ совместим со всеми версиями Matlab?

Кроме того, это работает для получения второго выходного аргумента, когда вы не знаете, сколько будет аргументов! Принимая во внимание, что если вы сделаете это:

[~, b] = size(a);

Тогда б = 8000! (Вы должны закончить с ~, чтобы поймать больше аргументов!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...