Is it possible to have an array of function handles?

288 vues (au cours des 30 derniers jours)
Jared Joselowitz
Jared Joselowitz le 1 Juin 2020
I am trying to make an array of function handles so that, for example, I can create a function that looks like this:
[x,y]= RK4system(f ,xspan, y0, N);
Instead of this:
[x,y]= RK4system(y1prime,y2prime ,xspan, y0, N);
Therefore, I want a function handle 'f' that contains y1prime and y2prime, where :
y1prime = @(x,y1,y2) y2;
y2prime = @(x,y1,y2) -2*x^2*y1 - 3*x*y2;
Here is the actual function if you need it:
function [x,y]= RK4system(y1prime, y2prime ,xspan, y0, N)
x(1) = xspan(1);
xf = xspan(2);
y1(1) = y0(1);
y2(1) = y0(2);
h=xf/N;
for i=1:N
x(i+1) = x(i)+h;
k1y1 = y1prime(x(i),y1(i),y2(i));
k1y2 = y2prime(x(i),y1(i),y2(i));
k2y1 = y1prime(x(i)+h/2, y1(i)+h/2*k1y1, y2(i)+h/2*k1y2);
k2y2 = y2prime(x(i)+h/2, y1(i)+h/2*k1y1, y2(i)+h/2*k1y2);
k3y1 = y1prime(x(i)+h/2, y1(i)+h/2*k2y1, y2(i)+h/2*k2y2);
k3y2 = y2prime(x(i)+h/2, y1(i)+h/2*k2y1, y2(i)+h/2*k2y2);
k4y1 = y1prime(x(i)+h, y1(i)+h*k3y1, y2(i)+h*k3y2);
k4y2 = y2prime(x(i)+h, y1(i)+h*k3y1, y2(i)+h*k3y2);
y1(i+1) = y1(i)+h/6*(k1y1 + 2*k2y1 + 2*k3y1 + k4y1);
y2(i+1) = y2(i)+h/6*(k1y2 + 2*k2y2 + 2*k3y2 + k4y2);
end
x=x';
y1=y1';
y2=y2';
y=[y1 y2];
end
When calling the function:
N = 4;
y1prime = @(x,y1,y2) y2;
y2prime = @(x,y1,y2) -2*x^2*y1 - 3*x*y2;
xspan = [0 0.4];
y0 = [3 1];
[x,y]= RK4system(y1prime,y2prime ,xspan, y0, N);
[x y]

Réponse acceptée

per isakson
per isakson le 1 Juin 2020
The short answer is no. However, it's possible to store function handles in a cell array.
f = cell(2,1);
f{1} = y1prime;
f{2} = y2prime;

Plus de réponses (1)

tri stan
tri stan le 6 Avr 2021
In modern versions of Matlab, there exist a better solution for this problem than proposed by @per isakson.
Instead of using a cell array you can define those two functions as:
f = @(x,y1,y2) [y2, -2*x^2*y1 - 3*x*y2]
Than you can use it as followis:
f(1,0,1)
which returns the values of both functions as the elements of a vector:
ans = 1 -3
  2 commentaires
Barbara Margolius
Barbara Margolius le 4 Mar 2022
how would I access just the first function or just the second if say I wanted to plot just one of these?
Walter Roberson
Walter Roberson le 4 Mar 2022
There are two possibilities involved.
  1. The anonymous function has no "captured" variables. In this case, the route is to use formula() on the handle to extract the code as a character vector, then parse the code to figure out where the pieces end, pull out the character subset, and put it together with a new header, and use str2func() to create a new handle
  2. The anonymous function does have captured variables. In this case you need to use functions() and some indexing to extract the captured variables as a struct. Then you take an approach similar to the above to extract the character vector that contains the code subset you want. Now, carefully replace references to the captured variables in the code with references to the struct of extracted captured variables. This is tricky because you have to figure out whether any particular apparent reference is within a quoted string or is within its own @() that shadows the meaning of the name. If the code uses eval() or evalc() or some other tricks, then you have a problem.
So... it might be possible to do what you ask, at least unless there is character string evaluation, but there is no easy way to do that.
It is much easier to write a small wrapper that just executes the original function and then extracts the desired portion of the result.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by