Как элегантно игнорировать некоторые возвращаемые значения функции MATLAB?

Можно ли получить возвращаемое значение "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;

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

Ответ 1

Это несколько хак, но он работает:

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

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.

Ответ 2

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

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

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

Подробнее см. примечания к выпуску.

Ответ 3

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

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

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

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

Ответ 4

Вот еще один вариант, который вы можете использовать. Сначала сделайте массив ячеек для захвата всех выходов (вы можете использовать функцию 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

Ответ 5

Я написал функцию 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);

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

Ответ 6

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

Ответ 7

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

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

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

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

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

output(1,2:4) = select(func,1:3);

Ответ 8

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

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

size(a);

b=ans(2);

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

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

[~, b] = size(a);

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

Ответ 9

Я обнаружил, что если вам нужен только один вывод, вы можете пересечь функцию с матрицей единиц измерения, соответствующую желаемому выходу. т.е. out_arg_the_third = функция (input_args) * [0; 0; 1; 0];

или усложняясь, вы можете расширить размеры своей матрицы, чтобы собрать больше результатов: out_arg_second_and_third = функция (input_args) * [0,0; 1,0; 0,1; 0,0]; но мы начинаем терять элегантность здесь.

Должны быть лучшие способы с более новыми версиями, но по причинам, которые я не понимаю, мне нужно использовать 2007b