Search code examples
matlabodefunction-handle

Multiplying two function handle and applying ode45 to the result


I have the following functions in discrete form (which means that they are arrays):

p1_1 of dim(200x1)
p1_2 of dim(200x1)
p1_3 of dim(200x1)
p2_1 of dim(200x1)
p2_2 of dim(200x1)
p2_3 of dim(200x1) 

The functions p1_1, p1_2, p1_3 have being evaluated a the points of x1 = 0:(10/199):10 and the functions p2_1, p2_2, p2_3 at the points x2 = 0:(10/199):10.

Since I have the function values and the points where the function was evaluated, I can do the following:

fun1_of_p1 = @(xq1) interp1(x1,p1_1,xq1);
fun1_of_p2 = @(xq1) interp1(x1,p1_2,xq1);
fun1_of_p3 = @(xq1) interp1(x1,p1_3,xq1);

and

fun2_of_p1 = @(xq2) interp1(x2,p2_1,xq2);
fun2_of_p2 = @(xq2) interp1(x2,p2_2,xq2);
fun2_of_p3 = @(xq2) interp1(x2,p2_3,xq2);

And then I need to be able to do the following:

new_fun1 = @(xq1,xq2) fun1_of_p1.*fun2_of_p1;
new_fun2 = @(xq1,xq2) fun1_of_p1.*fun2_of_p2;
new_fun3 = @(xq1,xq2) fun1_of_p1.*fun2_of_p3;
new_fun4 = @(xq1,xq2) fun1_of_p2.*fun2_of_p1;
new_fun5 = @(xq1,xq2) fun1_of_p2.*fun2_of_p2;
new_fun6 = @(xq1,xq2) fun1_of_p2.*fun2_of_p3;
new_fun7 = @(xq1,xq2) fun1_of_p3.*fun2_of_p1;
new_fun8 = @(xq1,xq2) fun1_of_p3.*fun2_of_p2;
new_fun9 = @(xq1,xq2) fun1_of_p3.*fun2_of_p3;

Finally

 last_fun = @(xq1,xq2) gamma1*new_fun1 + gamma2*new_fun2 +...
 gamma3*new_fun3 + gamma4*new_fun4 + gamma5*new_fun4 +...
 gamma6*new_fun6 + gamma7*new_fun7 + gamma8*new_fun8 +...
 gamma9*new_fun9;

The gamma-values are just constants (real values constants). After I have defined last_fun, I need to apply ode45 to it but I don't know how to do it, I tried:

([T,V] = ode45(@(xq1,xq2)last_fun(xq1,xq2),tspan,x0)

But it doesn't work. Actually I don't know if all I have done is correct so some feedback will be very appreciated!


Solution

  • Think the handle of a function as a tag (or address, ID etc.) that identifies that function among others. These tags are numbers alright (everything in a computer is a number), but they don't represent the values the function might take. To obtain the values, you must provide the function's ID and the function's arguments.

    Now, when you say function multiplication you mean a function that returns the multiplication of the functions' values, not functions' tags. Which leads to the correct definitions:

    new_fun1 = @(xq1,xq2) fun1_of_p1(xq1).*fun2_of_p1(xq2);
    new_fun2 = @(xq1,xq2) fun1_of_p1(xq1).*fun2_of_p2(xq2);
    new_fun3 = @(xq1,xq2) fun1_of_p1(xq1).*fun2_of_p3(xq2);
    new_fun4 = @(xq1,xq2) fun1_of_p2(xq1).*fun2_of_p1(xq2);
    new_fun5 = @(xq1,xq2) fun1_of_p2(xq1).*fun2_of_p2(xq2);
    new_fun6 = @(xq1,xq2) fun1_of_p2(xq1).*fun2_of_p3(xq2);
    new_fun7 = @(xq1,xq2) fun1_of_p3(xq1).*fun2_of_p1(xq2);
    new_fun8 = @(xq1,xq2) fun1_of_p3(xq1).*fun2_of_p2(xq2);
    new_fun9 = @(xq1,xq2) fun1_of_p3(xq1).*fun2_of_p3(xq2);
    

    Please correct also the last_fun expression in the same manner:

    last_fun = @(xq1,xq2) ...
         gamma1*new_fun1(xq1,xq2) ...
       + gamma2*new_fun2(xq1,xq2) ...
       + gamma3*new_fun3(xq1,xq2) ...
       + gamma4*new_fun4(xq1,xq2) ...
       + gamma5*new_fun4(xq1,xq2) ...
       + gamma6*new_fun6(xq1,xq2) ...
       + gamma7*new_fun7(xq1,xq2) ...
       + gamma8*new_fun8(xq1,xq2) ...
       + gamma9*new_fun9(xq1,xq2);
    

    The correct call to ode45 would be:

    [T,V] = ode45(last_fun,tspan,x0);
    

    provided that tspan and x0 are vectors, and tspan is sorted ascendingly.