Forced variable evaluation in MATLAB anonymous function

MATLAB stores variables along with anonymous functions. Here's an example of how this works from the documentation .

Variables in expression :

Functional handles can store not only the expression, but also the variables that the expression is required to evaluate.

For example, create a function descriptor for an anonymous function that requires the coefficients a, b, and c.

a = 1.3;
b = .2;
c = 30;
parabola = @(x) a*x.^2 + b*x + c;

      

Since a, b and c are available when the parabola is created, the function descriptor contains these values. The values โ€‹โ€‹are kept within the limits even if you clear the variables:

clear a b c
x = 1;
y = parabola(x)
y =
   31.5000

      

Presumably the a and c values โ€‹โ€‹are saved with the function, even if it is saved and reloaded from the math file. In practice, I've found that these values โ€‹โ€‹are not saved, especially if the code originally generated by the function is edited.

Is there a way to define a function descriptor in terms of the numeric values โ€‹โ€‹of the variables? I would like something like a form

>> a = 1.3;
>> b = .2;
>> c = 30;
>> parabola = @(x) a*x.^2 + b*x + c

parabola = @(x) a*x.^2+b*x+c

>> parabola2 = forceEval(parabola)

parabola2 = @(x) 1.3*x.^2+.2x+30

      

EDIT: Perhaps my problem is with file associations, but when I edit the file in which I originally defined the anonymous function, I get the error:

Can't find function @ (ydata) nr / (na * dt) * normpdf (ydata, mu (j), s (j)) ./ normpdf (ydata, mu_a (j), s_a (j)) within C :. .. \ mfilename.m. (where i changed my mfile name to mfilename)

My usual solution for this kind of thing was to use func2str () to remove the dependency on the file, but that also removes the workspace information, including the parameter values. So I would like to force all parameters to take their numerical values โ€‹โ€‹in the function definition.

+3


source to share


3 answers


The values โ€‹โ€‹are stored in the function. As I said in various answers, you can check this with the command functions

:

>> a = 1.3; b = .2; c = 30;
>> parabola = @(x) a*x.^2 + b*x + c;
>> x = 1;
>> y = parabola(x)
y =
         31.5
>> clear a b c
>> y = parabola(x)
y =
         31.5
>> fi = functions(parabola)
fi = 
     function: '@(x)a*x.^2+b*x+c'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}
>> fi.workspace{1}
ans = 
    a: 1.3
    b: 0.2
    c: 30

      

Even when you save the descriptor to disk:

>> save parabolaFun.mat parabola
>> clear parabola a b c
>> load parabolaFun.mat parabola
>> y = parabola(x)
y =
         31.5
>> fi = functions(parabola)
fi = 
     function: '@(x)a*x.^2+b*x+c'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}
>> fi.workspace{1}
ans = 
    a: 1.3
    b: 0.2
    c: 30

      

And you can simplify the creation of the parabola descriptor like this:



function p = makeParabola(a,b,c)

p = @(x) a*x.^2 + b*x + c;

end

      

There are certain caveats :

You can save and load function descriptors in a MAT file using the MATLABยฎ save and load functions. If you load a function descriptor that you saved in a previous MATLAB session, the following conditions may cause unexpected behavior:

  • Any of the files that define the function have been moved and therefore no longer exist in the path stored in the descriptor.
  • You are loading the function descriptor into a different environment from the one in which it was saved. For example, the source for a function either does not exist or is located in a different folder than the system on which the handle was saved.

In both cases, the function descriptor is now invalid because it is no longer associated with any existing function code. Although the handle is not valid, MATLAB still loads successfully and does not display a warning. However, an attempt to call the handle results in an error.

Hence, if you create a handle from a file-aware function (not a script, that's okay) and then modify or delete the file, the handle becomes invalid.

+6


source


Anonymous functions capture the values โ€‹โ€‹of all variables involved in the expression. If you want to see the captured workspace use functions

as @chappjc showed in his answer.

Now you need to be careful about the types of variables used in the anonymous function (think value type versus descriptor type).

All native types (numeric values, logics, structures, cells, etc.) are captured by value, not by reference . Example:



x = magic(4);
f = @() x;    % captures matrix x

x(1) = 1      % modify x
xx = f()      % change not reflected here

      

Compare this to using handle-class types (for example containers.Map

):

x = containers.Map('KeyType','char', 'ValueType','double');
f = @() x;        % captures handle-class object x

x('1') = 1;       % modify map
keys(x)           % changed
keys(f())         % also changed!

f() == x          % compare handle equality, evaluates to true

      

+3


source


a = 1.3, b = 0.2, c = 30;
parabola = eval(['@(x) ', num2str(a), '*x^2 + ', num2str(b), '*x + ', num2str(c)]);

      

+1


source







All Articles