How to compose functions with more than one output/input

조회 수: 78 (최근 30일)
Joan Vazquez
Joan Vazquez 2019년 6월 16일
편집: Joan Vazquez 2019년 6월 20일
How can I define a function "composeFunctions" that takes two functions as an input and returns their composition as an output, when the functions to compose have more than one output/input?
For example:
function h = composeFunctions(f, g)
h = @(x) g(f(x));
end
works well with functions , such as:
function y = add1(x)
y = x+1;
end
function y = add2(x)
y = x+2;
end
h = composeFunctions(@add1, @add2)
% it works, h(5) returns g(f(5)) = 5 + 1 + 2 = 8, as expected
but I do not know what to do e.g. with functions , , such as:
function [y1, y2] = duplicate(x)
y1 = x;
y2 = x;
end
function y = addition(x1, x2)
y = x1 + x2;
end
h = composeFunctions(@duplicate, @addition)
% h(5) throws an error because duplicate does not pass two arguments to addition
Note 1 : this is a MWE, I want to better understand how to work with functions of functions, so I am not interested in built-in solutions like the compose function in the symbolic math toolbox.
Note 2: all functions are defined in their own .m file in the working directory, I am posting it like this for simplicity. A similar single input/output implementation is given here with anonymous functions.

답변 (1개)

Walter Roberson
Walter Roberson 2019년 6월 16일
In MATLAB, in every case where you have an expression of the form F(G(inputs)), it is not possible for F to capture all of the outputs of G. There is no work-around using expression syntax.
The closest you can get is to use a real function (not anonymous) F(@g, N, inputs) with
function result = F(fun, N, varargin)
[funout{1:N}] = fun(varargin{:});
result = some_operation_on(funout{:});
end
You could define something like,
function result = compose2_1(fun1, fun2, varargin)
[out2_1, out2_2] = fun2(varargin{:});
result = fun1(out2_1, out2_2);
end
and then
ad = @(x) compose2_1(@addition, @duplicate, x)
  댓글 수: 1
Joan Vazquez
Joan Vazquez 2019년 6월 20일
편집: Joan Vazquez 2019년 6월 20일
Thanks, Walter!
Based on your answer, I wrote a function that works for the general case of dimensions
Then I wrapped your last line around another function, so the output is a function.
In case it helps anyone, here it goes:
function h = composeFunctions(f, g, varargin)
h = @(varargin) comp(f, g, varargin{:});
function [varargout] = comp(f, g, varargin)
N = nargout(f);
[funout{1:N}] = f(varargin{:});
M = nargout(g);
[varargout{1:M}] = g(funout{:});
end
end
The funny thing is that you need to specify some sort of "example input" as varargin in order to build the composite function h. I don´t see how to avoid this in Matlab! One could think of using nargin(f)...but the local function still needs to explicitely call f, so unless you know its domain, you cannot even build that "example input" inside composeFunctions. (e.g. f could be defined on strings, not numbers).
To give some context, I was self-studying Category Theory for Programmers (by Bartosz Milewski), which challenges the reader to program composition in his favourite language.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Shifting and Sorting Matrices에 대해 자세히 알아보기

제품


릴리스

R2017b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by