调试时如何使用曲线拟合工具?
How can we use the Curve Fitting Tool during debugging?
MATLAB 的曲线拟合应用程序(以前是 "tool",因此是 cftool
)是交互式曲线拟合的图形工具1。
使用此工具的一般方法是从工作区中选择变量:
但是,在调试过程中,数据选择被禁用(这个是documented):
...这很麻烦,因为我们必须将数据保存到文件中,然后退出调试或打开一个新的 MATLAB 实例,然后才能再次加载该数据并在 cftool
.
我假设禁用输入的原因是因为在调试期间我们通常有多个工作区,因此在用户体验方面迭代它们或提供用户选择工作区太麻烦了 - 所以开发人员决定禁用输入,直到只有一个工作区存在。
我的问题是:我们如何禁用 cftool
的 "debugging detection" 或以其他方式指定我们感兴趣的工作区,以便我们可以使用 cftool
在调试期间?
我做了一些挖掘,这是我发现的:
曲线拟合工具包含一种特殊类型的组合框,用于选择变量,它使用 com.mathworks.mlservices.MatlabDebugObserver
class 来检测调试模式并禁用控件.这些控件的 java class 是
MATLAB\R20###\java\jar\toolbox\curvefit.jar!
com.mathworks.toolbox.curvefit.surfacefitting.SFDataCombo
我发现的:
a) 启动 cftool
并使用
获取其 window 的句柄
hSFT = getappdata( groot, 'SurfaceFittingToolHandle' );
b) 探索 hSFT
的属性和子项以找到包含我们指定拟合数据的面板的 java 对象。
c) 使用命令 src:[= 找到包含上述 java class 的 .jar
文件21=]
jObj.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
我们可以通过访问各个组合框并调用它们的 cleanup()
方法来禁用调试侦听器,该方法会删除调试侦听器(请参阅下面代码中的注释)。这涉及访问几个对象的私有字段,为此我们将使用反射:
function unlockCftool()
% NOTES:
% 1) After unlocking cftool, it will no longer update the list of workspace variables, so
% make sure all desired variables exist in the base workspace before proceeding, or you'll
% need to restart cftool.
% 2) DO NOT execute this code while debugging, since then the variable selection fields in
% cftool will be stuck in their disabled mode until it is restarted.
hSFT = getappdata( groot, 'SurfaceFittingToolHandle' );
jEFP = hSFT.FitFigures{1}.HFittingPanel.HUIPanel.Children.java.getJavaPeer();
f = jEFP.getClass().getDeclaredField('fittingDataPanel');
f.setAccessible(true);
jFDP = f.get(jEFP);
f = jFDP.getClass().getDeclaredFields(); f = f(1:4); % <- shortcut for:
%{
f = [jFDP.getClass().getDeclaredField('fXDataCombo');
jFDP.getClass().getDeclaredField('fYDataCombo');
jFDP.getClass().getDeclaredField('fZDataCombo');
jFDP.getClass().getDeclaredField('fWDataCombo')];
%}
java.lang.reflect.AccessibleObject.setAccessible(f, true);
for ind1 = 1:numel(f)
f(ind1).get(jFDP).cleanup();
end
所以现在我们可以执行以下操作:
X = 0:9;
Y = 10:-1:1;
cftool();
% <select the X and Y variables in cftool to get a decreasing slope>.
unlockCftool();
% <enter debug mode, for example using: dbstop in unlockCftool; unlockCftool(); >
assignin('base', 'X', 5:-1:-4);
% <re-select X to update the data - resulting in a rising slope>.
MATLAB 的曲线拟合应用程序(以前是 "tool",因此是 cftool
)是交互式曲线拟合的图形工具1。
使用此工具的一般方法是从工作区中选择变量:
...这很麻烦,因为我们必须将数据保存到文件中,然后退出调试或打开一个新的 MATLAB 实例,然后才能再次加载该数据并在 cftool
.
我假设禁用输入的原因是因为在调试期间我们通常有多个工作区,因此在用户体验方面迭代它们或提供用户选择工作区太麻烦了 - 所以开发人员决定禁用输入,直到只有一个工作区存在。
我的问题是:我们如何禁用 cftool
的 "debugging detection" 或以其他方式指定我们感兴趣的工作区,以便我们可以使用 cftool
在调试期间?
我做了一些挖掘,这是我发现的:
曲线拟合工具包含一种特殊类型的组合框,用于选择变量,它使用
com.mathworks.mlservices.MatlabDebugObserver
class 来检测调试模式并禁用控件.这些控件的 java class 是MATLAB\R20###\java\jar\toolbox\curvefit.jar! com.mathworks.toolbox.curvefit.surfacefitting.SFDataCombo
我发现的:
a) 启动
获取其 window 的句柄cftool
并使用hSFT = getappdata( groot, 'SurfaceFittingToolHandle' );
b) 探索
hSFT
的属性和子项以找到包含我们指定拟合数据的面板的 java 对象。c) 使用命令 src:[= 找到包含上述 java class 的
.jar
文件21=]jObj.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
我们可以通过访问各个组合框并调用它们的
cleanup()
方法来禁用调试侦听器,该方法会删除调试侦听器(请参阅下面代码中的注释)。这涉及访问几个对象的私有字段,为此我们将使用反射:function unlockCftool() % NOTES: % 1) After unlocking cftool, it will no longer update the list of workspace variables, so % make sure all desired variables exist in the base workspace before proceeding, or you'll % need to restart cftool. % 2) DO NOT execute this code while debugging, since then the variable selection fields in % cftool will be stuck in their disabled mode until it is restarted. hSFT = getappdata( groot, 'SurfaceFittingToolHandle' ); jEFP = hSFT.FitFigures{1}.HFittingPanel.HUIPanel.Children.java.getJavaPeer(); f = jEFP.getClass().getDeclaredField('fittingDataPanel'); f.setAccessible(true); jFDP = f.get(jEFP); f = jFDP.getClass().getDeclaredFields(); f = f(1:4); % <- shortcut for: %{ f = [jFDP.getClass().getDeclaredField('fXDataCombo'); jFDP.getClass().getDeclaredField('fYDataCombo'); jFDP.getClass().getDeclaredField('fZDataCombo'); jFDP.getClass().getDeclaredField('fWDataCombo')]; %} java.lang.reflect.AccessibleObject.setAccessible(f, true); for ind1 = 1:numel(f) f(ind1).get(jFDP).cleanup(); end
所以现在我们可以执行以下操作:
X = 0:9;
Y = 10:-1:1;
cftool();
% <select the X and Y variables in cftool to get a decreasing slope>.
unlockCftool();
% <enter debug mode, for example using: dbstop in unlockCftool; unlockCftool(); >
assignin('base', 'X', 5:-1:-4);
% <re-select X to update the data - resulting in a rising slope>.