How to save a function handle to a .m file
48 次查看(过去 30 天)
显示 更早的评论
If I create a function via inline, e.g.
myfunc = @(x,y,z) x.^2+y+z
How can I save this as a matlab file function? I can do this if I chose to make a symbolic function this way
syms x y z
myfunc(x,y,z) = x.^2 + y + z;
matlabFunction(myfunc,"File","myfunc")
But I would like to accomplish this without having to create a symbolic function.
0 个评论
采纳的回答
Rik
2023-4-23
I forgot the name of function, but a few years ago, a function was introduced to capture the output to the command window to a variable. There was a blog post about it, so you could search there.
You can use that to capture the function and the inputs. Then you can write that to an m file if you wish.
The trouble is that an anonymous function will capture variables if it needs them, so you will have to find a way to recreate those variables as well.
Is that what you mean?
6 个评论
Walter Roberson
2023-4-24
But this doesn't allow me to feed the function inputs
You need to decide: are you asking for a .m file that
- is a script that assigns an anonymous function to a known variable name?
- is a function that returns the handle to an anonmous function that can be used in place of the previous anonymous function?
- is a function that can be directly passed inputs and returns the same values that would be calculated by the original anonymous function?
Is it permissible to "cheat" by having code that saves the anonymous function to a .mat file and reloads it when you want it back? Is the idea that you want to end up with something that you can execute on a parallel worker and it will work "properly" including all captured variables? Including handling captured global variables? Or are you looking to write the resulting file content to a text field in a database?
How should shared access to persistent variables be handled?
Rik
2023-4-24
编辑:Rik
2023-4-24
You still need to parse the text to a normal function:
my_fancy_function = @(x,y,z) x.^2+y+z;
write_anon_function_to_file(my_fancy_function)
dbtype my_fancy_function.m
The name will be automatically detected, but if that doesn't work, it will revert to the name myfunc.
write_anon_function_to_file(@(x)x+2)
dbtype myfunc.m
function write_anon_function_to_file(func)
% This will write an anonymous function a an m file.
% Note that this will only work if the function does not have capture
% variables. So this will not work:
% a = 100;
% func = @(x) x+a;
% write_anon_function_to_file(func)
% But this will:
% func = @(x) x+100;
% write_anon_function_to_file(func)
% Determine the function name.
try
name = inputname(1);
if isempty(name),error('trigger catch block'),end
catch
name = 'myfunc';
end
% Extract and parse the function contents.
txt = formattedDisplayText(func); % capture the output
txt = char(txt); % convert to char
txt = strtrim(txt); % remove leading and trailing whitespace
ind = strfind(txt,')'); ind = ind(1); % find the end of the input arguments
% Compose the function and write to file.
txt = sprintf('function out = %s(%s)\nout = %s;\nend', ...
name,txt(3:(ind-1)),txt((ind+1):end));
writelines(txt,[name '.m']);
end
更多回答(1 个)
Walter Roberson
2023-4-24
myfunc = @(x,y,z) x.^2+y+z;
writelines("myfunc = " + func2str(myfunc), "myfunc.m")
%crosscheck
dbtype myfunc.m
2 个评论
Walter Roberson
2023-4-24
myfunc = @(x,y,z) x.^2+y+z;
namedfunc2file(myfunc)
%crosscheck
dbtype myfunc.m
function namedfunc2file(funhandle)
if nargin < 1; error('must provide named function handle'); end
funname = inputname(1);
assert(isa(funhandle, 'function_handle') && ~isempty(funname), 'must be function handle assigned to variable');
funs = func2str(funhandle);
writelines(funname + " = " + funs, funname + ".m");
end
This could be improved to test whether the function handle is anonymous or not using functions() . If it is not anonymous then the file field returned by functions() will be empty for built-in functions, and otherwise will indicate the file that contains the function definition. If functions() says the type is simple then either it is the handle to a built-in function (in which case file field will be empty) or else it is the handle to a function that has its own file. If functions() says the type is scopedfunction then the handle is to a function defined within the file for a script, or is defined after the initial function for a function file. If functions() says the type is "nested" then the handle is to a function defined inside another function.
The case of simple and non-empty file field would seem at first to be the easiest to deal with -- but remember the goal is to extract only the function so named, and there might be additional functions after it in the file (some of which might be essential for the function to operate)....
The other cases other than 'simple' with empty file would require locating the function definition inside the containing file.
Walter Roberson
2023-4-24
Okay, getting back to anonynmous functions:
z = rand(1,3)
myfunc = @(x,y) x.^2+y+z;
S = func2str(myfunc)
Notice that the text contains the name z, not the value associated with z inside the anonymous function:
info = functions(myfunc)
info.workspace{1}.z
so if the idea is that the generated function file should replicate the behaviour of the anonymous function, then really you need to examine the workspace and have code that assigns constant values to those variables. But... keep in mind that captured variables might themselves be anonymous functions. and that the captured anonymous functions might be variables with the same name
g = 2;
g = @(x) g * ones(size(x))
g = @(x) g(x) .* (1-g(x));
info = functions(g)
inner_g = info.workspace{1}.g
inner_info = functions(inner_g)
inner_info.workspace{1}.g
so we cannot simply (reliably) recurse and generate functions with the same name of nested anonymous functions: we would have to generate new names for each nested anonymous function and rewrite the function body to use the name name... and hope it wasn't sensitive to exact variable names.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Function Creation 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!