1

I'm trying to generate .bmp graphics in MATLAB and I'm having trouble summing functions together. I'm designing my function such that given an arbitrary set of inputs, my function will add an arbitrary number of functions together and output a function handle. The inputs are coefficients to my general function so I can specify any number of functions (that only differ due to their coefficients) and then add them together into a function handle. What I've tried to do is create each function as a string and then concatenate them and then write them as a function handle. The main problem is that because x and y aren't defined (because I'm trying to create a function handle) MATLAB can't add them regularly. My current attempt:

    function HGHG = anyHGadd(multi) %my array of inputs
    m=length(multi);
    for k=3:3:m;
    m1=multi(k-2); %these three are the coefficients that I'd like to specify
    n1=multi(k-1);
    w1=multi(k);
    HGarrm1=hermite(m1); %these generate arrays
    HGarrn1=hermite(n1);
    arrm1=[length(HGarrm1)-1:-1:0];%these generate arrays with the same length
    arrn1=[length(HGarrn1)-1:-1:0];%the function below is the general form of my equation
    t{k/3}=num2str(((sum(((sqrt(2)*x/w1).^arrm1).*HGarrm1))*(sum(((sqrt(2)*y/w1).^arrn1).*HGarrn1))*exp(-(x^2+y^2)/(w1^2))));
    end
    a=cell2mat(t(1:length(t)));
    str2func(x,y)(a);

Any help would be much appreciated. I haven't seen much on here about this, and I'm not even sure this is entirely possible. If my question isn't clear, please say so and I'll try again.

Edit: The fourth from last line shouldn't produce a number because x and y aren't defined. They can't be because I need them to be preserved as a part of my function handle. As for a stripped down version of my code, hopefully this gets the point across:

    function HGHG = anyHGadd(multi) %my array of inputs
    m=length(multi);
    for k=3:3:m;
    m1=multi(k-2); %these three are the coefficients that I'd like to specify
    n1=multi(k-1);
    w1=multi(k);
    t{k/3}=num2str(genericfunction(x,y,n1,m1,n1,w1); %where x and y are unspecified
    end
    a=cell2mat(t(1:length(t)));
    str2func(x,y)(a);

Edit I am expecting this to output a single function handle that is the sum of an arbitrary number of my functions. However, I'm not sure if using strings would be the best method or not.

Amro
  • 123,847
  • 25
  • 243
  • 454
Nick M
  • 11
  • 3
  • Could you post a stripped down version of your code? Also as far as I can see the 4th last line `t{k/3} = ...` produces a number... how can this be a general form of an equation? – jmetz Jul 24 '12 at 19:17
  • What kind of output do you expect from the multiple handles? – Jonas Jul 24 '12 at 19:59
  • Have you tried [symbolic variables](http://www.mathworks.com/help/toolbox/symbolic/syms.html)? – Squazic Jul 24 '12 at 20:03
  • You can't call `genericfunction` if `x` and `y` aren't defined! It seems to me that really your 4th to last line should read something like `t{k/3} = @(x,y)genericfunction(x,y,n1, m1, n1, w1);` – jmetz Jul 24 '12 at 20:08

2 Answers2

3

Your question is not very clear to me, but I think you are trying to create a function that generate output functions parametrized by some input.

One way is to use closures (nested function that access its parent function workspace). Let me illustrate with an example:

function fh = combineFunctions(funcHandles)
    %# return a function handle
    fh = @myGeneralFunction;

    %# nested function. Implements the formula:
    %# f(x) = cos( f1(x) + f2(x) + ... + fN(x) )
    %# where f1,..,fN are the passed function handles 
    function y = myGeneralFunction(x)
        %# evaluate all functions on the input x
        y = cellfun(@(fcn) fcn(x), funcHandles);

        %# apply cos(.) to the sum of all the previous results
        %# (you can make this any formula you want)
        y = cos( sum(y) );
    end
end

Now say we wanted to create the function @(x) cos(sin(x)+sin(2x)+sin(5x)), we would call the above generator function, and give it three function handles as follows:

f = combineFunctions({@(x) sin(x), @(x) sin(2*x), @(x) sin(5*x)});

Now we can evaluate this created function given any input:

>> f(2*pi/5)         %# evaluate f(x) at x=2*pi/5
ans =
     0.031949

Note: The function returned will work on scalars and return a scalar value. If you want it vectorized (so that you can apply it on whole vector at once f(1:100)), you'll have to set UniformOutput to false in cellfun, then combine the vectors into a matrix, sum them along the correct dimension, and apply your formula to get a vector result.

Amro
  • 123,847
  • 25
  • 243
  • 454
  • in your case, you could also make `makeFunc` accept function handles and write the nested function to evaluate each and return their sum – Amro Jul 24 '12 at 20:15
  • Unfortunately, your 'makeFunc' doesn't generate an arbitrary number of functions to add together. Though I imagine that wouldn't be a tough fix. – Nick M Jul 24 '12 at 20:29
  • @NickM: see my updated example, you can pass any number of function handles stored in a cell array, and it will create a new function as the sum of all applied – Amro Jul 24 '12 at 20:42
  • @NickM: I omitted parameters to keep it simple, but you can add them again if you want to do a weighted sum for example – Amro Jul 24 '12 at 20:50
  • The problem I am seeing with this method is that I can't operate on the summation. One of the reasons I need to sum this way is that I need to operate on the summation as a whole, and not its components. – Nick M Jul 24 '12 at 21:14
  • @NickM: The truth is I still don't get exactly what you are trying to do.. Perhaps you can edit your code and simplify it a bit (remove all unnecessary stuff). It would help if you give an example and state what you expect the result to be... – Amro Jul 24 '12 at 21:21
  • If you see the answer below, it explains the direction I am trying to head. Say my general function is @sin, I want to sum sin(x), sin(2x), sin(5x), but I also want to operate on it so that my end result would be @(x)cos(sin(x)+sin(2x)+sin(5x)). I hope that makes sense, I'm still trying to work it out in my head too. – Nick M Jul 24 '12 at 21:40
  • @NickM: I revised my example, please have a look. – Amro Jul 24 '12 at 22:05
0

If your goal is to create a function handle that sums the output of an arbitrary number functions, you can do the following:

n = 3; %# number of function handles
parameters = [1 2 4];
store = cell(2,3);

for i=1:n
  store{1,i} = sprintf('sin(t/%i)',parameters(i));
  store{2,i} = '+'; %# operator
end

%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = ['@(t)',store{1:end-1}]; %# ignore last operator

functionHandle = str2func(funStr)

functionHandle = 

    @(t)sin(t/1)+sin(t/2)+sin(t/4)
Jonas
  • 74,690
  • 10
  • 137
  • 177
  • In your 'funStr' line where you cat the cell elements together, I'm having an issue such that the elements of the array don't get written as strings at all, and that part is overlooked entirely. E.g. I'm getting '@(x,y)' but not '@(x,y)(cell elements)' – Nick M Jul 24 '12 at 21:17
  • @NickM: When I run my example, it works perfectly fine. Is your issue with the examlple, or with your function? In case it's the latter: Make sure that the `sprintf` statement correctly returns a string representation of your summands (with the parameters filled in properly - you may need to use %f as format string!) – Jonas Jul 24 '12 at 21:32