Loren on the Art of MATLAB

August 31st, 2010

Combining Functions

For a lot of calculations, it makes sense to combine operations into a single expression. You can sometimes do this easily when you have function handles and you generate one final function that you can apply.

Contents

Function Composition

Suppose you want to call g(f(x)), where the output of the function f is the input for the function g.

f = @(x) sin(x);
g = @(x) cos(x);
fCompg = @(x) g(f(x));

% Test the composition.

x = 0:pi/100:pi/2;
fx = f(x);
gfx = g(fx);
gfx2 = fCompg(x);
gfsEqual = isequal(gfx,gfx2)
gfsEqual =
     1

Other Combinations.

Suppose instead you want to add some functions together under certain circumstances. Sometimes, but not always. It's messy if you don't commit to evaluating a function handle with a fixed name. So, here's a pattern you can use to achieve this effect.

myfunc = @(x) sin(x);
mn = @(x) mean(x);
three = @(x) 3+zeros(size(x));
subtractMean = false;
add3 = true;

Suppose I want to add a constant offset only.

if subtractMean
    myfunc = @(x) bsxfun(@minus, myfunc(x), mn(x));
end
if add3
    myfunc = @(x) myfunc(x) + three(x);
end

Try this on the data.

mf3mean = myfunc(x);

Now, regardless of which functions we combine with the original function, we have a function handle to evaluate. You can use this to allow users to specify additional information as you build up an appropriate function for your calculation.

Let's try a different combination. Let's suppose I want the mean value to be around 3. I can first remove the mean and then add the offset.

myfunc = @(x) sin(x);
subtractMean = true;
add3 = true;
if subtractMean
    myfunc = @(x) bsxfun(@minus, myfunc(x), mn(x));
end
if add3
    myfunc = @(x) myfunc(x) + three(x);
end
mf3nomean = myfunc(x);

Notice the order of operations matters here. If I removed the mean after adding the constant, the final mean should be 0. If I remove it before adding the offset, I have no reason to expect that.

mean(mf3nomean)
mean(mf3mean)
ans =
       2.8485
ans =
       3.6339
h = plot(mf3nomean);
hold all
h(2) = plot(mf3mean);
hold off
legend(h,{'mf3nomean', 'mf3mean'})

Do You Combine Functions?

Do you have situations in which you conditionally apply functions? Would this technique help you build up the functions you want more easily? Let me know here.


Get the MATLAB code

Published with MATLAB® 7.10

9 Responses to “Combining Functions”

  1. Peter replied on :

    Maximum crazyness! :-)
    Though definitely very interesting. Thank you for the blog postings!

  2. Brian McGill replied on :

    Your example of conditional function assignment brings up for me one of the features I miss most in Matlab a vector (and array) if statement. So I could do:
    x=if(logicalvector,truevaluesvector,falsevaluesvector)

    easy enough to write this function. My version (not including code to enforce size match, match horizontal & vertical vectors and splat out a scalr to a matching vector is just:

    function ret=myif(cond,valtrue,valfalse)
    ret=valfalse;
    ret(cond)=valtrue(cond);
    

    but there are probably a dozen other ways to do this. And so much better to have it implemented in C and make the use of it portable. I keep thinking an array oriented language like Matlab must have this feature but I’ve never found it.

    Obviously this function would simplify your example too.

  3. Loren replied on :

    Brian-

    We have designed such functionality multiple times but hit certain roadblocks (which I can’t remember off the top of my head) and couldn’t agree so far…

    –Loren

  4. Joan replied on :

    Hi,

    I was wondering how good the JIT compiler is when it comes to interpreting and optimizing this dialect?

    I am working on something that requires extensive flexibility (on the fly function definition) for the end user and I am trying to decide which is the best route, any suggestions?

    Thanks,
    Joan

  5. Loren replied on :

    Joan-

    I think it’s a mistake to focus on the JIT. What you should focus on is performance. I would suggest trying things out both ways if possible and profiling to see where the bottlenecks are. The answer will be different for different applications.

    –Loren

  6. per isakson replied on :

    I combine functions occasionally. Two examples:

    InputPreprocessor (FEX) is based on inputParser and validateattributes. That code relies on combinations of functions, see the class ValidatorFunctionCreator. The resulting function is a bit slow, however the combination of functions is crucial to that construct.

    Prior to the new OOP-support I used combination of function a few times to perform operations that needed data from several functions “spaces/scopes”. I passed functions around and added to them. CODE SMELL – too tricky. Subclassing makes that construct obsolete.

  7. Loren replied on :

    Per-

    Thanks for sharing that info. Nice FEX contribution!

    –loren

  8. Avinash replied on :

    I need to combine several functions (each having atleast one parameter different)and obtain a single expression containing all the parameters used in these expressions. Is it possible to perform such an operation in MATLAB? Please let me know.

    -Avinash

  9. Loren replied on :

    Avinash-

    The answer is almost certainly yes, but your question is too vague. I recommend you ask a more formed question with some details on MATLAB Answers: http://www.mathworks.com/matlabcentral/answers/

    –Loren


MathWorks
Loren Shure works on design of the MATLAB language at MathWorks. She writes here about once a week on MATLAB programming and related topics.

These postings are the author's and don't necessarily represent the opinions of The MathWorks.