anonymous function in matlab executable

2019-08-10 08:16发布

问题:

I have a three files that work perfectly before I compile them. However when I compile them matlab behaves as if I didn't include one of the files even though it is included in the deployment.

function testMain

kuzu = zeros(5,1);
anonymousFunction = testClass.anonymousFunction;
kuzu2 = anonymousFunction(kuzu)

end

classdef testClass
    properties (Constant)
        anonymousFunction = @(x) replaceZeroWithNaN2(x)
    end
end

function output = replaceZeroWithNaN2(input)

input(input==0) = NaN;
output = input;

end

All the files are in the same directory. After compilation I get the following error:

Undefined function 'replaceZeroWithNaN2' for input arguments of type 'double'

回答1:

The following is from MATLAB's guide on code generation (from ver. 2011b):

Clearly your use of the anonymous function is causing issues.

It's possible that this has changed in the time since this guide was published, but I would be a bit surprised. Try reworking your code to avoid anonymous function calls; you'll probably save a bit of overhead anyway.

Edit:

After a bit more digging I found here that MATLAB now supports objects, however, anonymous functions are still unsupported.



回答2:

When MATLAB Compiler packages your code into an executable, it needs to include all the files that your main function depends on. It does this using dependency analysis, i.e. walking through the code to see which things it depends on, and which things those things depend on.

Sometimes the dependency analysis can fail and it misses some dependencies. For example, if your code calls something like eval('myfunction'), it won't find myfunction as a dependency.

It looks like, for whatever reason, the dependency analysis is not finding replaceZeroWithNaN2, and it's not getting included in your executable, so you're getting the error you see. You can check this yourself by running depfun('testMain.m') - depfun is the command MATLAB uses to find dependencies, and the output shows that it's finding the dependency on testClass, but not replaceZeroWithNaN2.

In cases like this you can explicitly tell the dependency analysis to include a function.

Put the following comment at the top of testClass.m:

%#function replaceZeroWithNaN2

The %#function is a pragma that explicitly tells the dependency analysis that the code below depends on the function replaceZeroWithNaN2. When I do that, the output of depfun now includes replaceZeroWithNaN2.

MATLAB Compiler should then include replaceZeroWithNaN2 and your executable should work.

You might also like to report the issue to MathWorks: it feels to me like the dependency analysis really should be picking up replaceZeroWithNaN2 already, and it's maybe a bug.