gpt4 book ai didi

matlab - "Undefined"重写错误但未重新定义已定义的函数

转载 作者:行者123 更新时间:2023-12-04 11:46:37 27 4
gpt4 key购买 nike

这有效(绘制一个“空”图):

function testme
plot(1)

这有效(返回 1):
function testme
plot = @(x)x;
plot(1)

这不会(错误:“未定义的函数或变量'绘图'。”):
function testme
if 0
plot = @(x)x;
end
plot(1)

这里发生了什么?为什么重写但不重新定义已定义的函数会使函数未定义?

注 1:这不是特定于内置函数的;以下代码返回相同的错误:
function testme
if 0
myfun = @(x)x;
end
myfun(1)

function x=myfun(x)
x=x*2;

注2:错误发生在函数环境中,而不是脚本中;以下代码不会返回错误(并绘制与第一个示例中相同的空图):
if 0
plot = @(x)x;
end
plot(1)

Update: For the interested reader, here is some background information on my original problem. The above examples are just minimum working samples to illustrate the main issue (which indeed feature dead end if statements). In practice, I was trying to make a function useable for colleagues who did not have certain library/toolbox functions available, by overwriting those functions for simplified custom ones if they did not exist, as a quick fix. In particular, it concerned imdilate (and imerode). The function looked something like the following:

function [myoutputs] = myfunction(myinputs)

% if the images toolbox is not available, use the following simplified
% replacement function
if ~exist('imdilate','file')
imdilate = @(IM,SE)vecdilate(IM,SE);
end

%% The original function goes here, which uses a lot of imdilate(IM,SE).

%% local functions
function M = vecdilate(IM,SE)
% simplified version of imdilate (can only process 1-D vertical arrays)

nSE = size(SE);
nIM = size(IM);
SE = logical(SE); % make logical if it isn't yet

% copy and shift xth column x down. new border entries are 0:
M = repmat([IM;zeros(nSE)],nSE);
M = M(1:end-nSE(1));
M = reshape(M,[size(M,1)/nSE(1) nSE(1)]);

% shrink back to column by taking max of every row:
M = max(M(:,SE),[],2);
M = M(ceil(nSE(1)/2)-1+(1:nIM(1))); % clip to obtain correct size

You might see that the replacement function covers some functionality of imdilate, but not all, and it might not be as efficient. The purpose simply was to use function A if it was available, and function B if it was not. To my surprise however, the former case returned an error, which eventually resulted in this question. For your interest, I solved the practical problem by renaming the function in the original code, and by using an if/else statement:

function [myoutputs] = myfunction(myinputs)

% if the images toolbox is not available, use the following simplified
% replacement function
if ~exist('imdilate','file')
mydilate = @(IM,SE)vecdilate(IM,SE);
else
mydilate = @(IM,SE)imdilate(IM,SE);
end

%% The original function goes here, which uses a lot of mydilate(IM,SE).

%% local functions
function M = vecdilate(IM,SE)
etc. etc. etc.

最佳答案

即时编译 (JIT) 并不意味着没有编译并且每一行都单独解释,因此您仍然可以弄乱代码;)

如果您使用未定义的函数,您甚至不会期望代码运行,也会出现该错误,例如

function [] = test()
if false
a = @(x)x;
end
a(1)
end

脚本存储命令行条目,即编译器别无选择,只能单独处理每一行(您可能想将其视为键盘宏)。
相反,函数是封装的代码段。编译器(通常)不期望任何未知的东西+它认为这段封装的代码可能会被重用。因此,它确保事先将所有代码编译一次(如果编译会一直这样做,则称为提前编译)。

当您清除两者之间的变量时,这变得特别明显:
function [] = test()
if false
plot = @(x)x;
else
clear all % clear vs clear all
end
plot(1)
end

(注意 clear 清除所有变量,但 clear all 也会清除删除代码(参见 MATLAB Execution Engine ))

看看这个有趣的 blog post来自罗兰

MATLAB provides the best of both worlds by compiling MATLAB code on-the-fly, or just-in-time. MATLAB code is compiled whether it be in classes, functions, scripts, or simply at the command line. There is no explicit compile step for the user to initiate and MATLAB code can be executed in blocks as small as one line at a time. The MATLAB JIT compiler generates native machine level code that is optimized for the MATLAB code being executed and for the specific hardware platform.



无论如何,您不应在代码中编写死胡同或覆盖( native )函数。使用函数句柄来克服这个问题是很好的,但请确保为所有情况定义它
function [] = test()
if false % dead end definition
fnc = @(x)x;
else
fnc = @plot;
end
fnc(1)
end

关于matlab - "Undefined"重写错误但未重新定义已定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59197724/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com