我在 MATLAB 中进行科学图像处理,这需要解决具有许多参数的怪异优化问题,这些参数由“实验”函数使用,该函数具有许多不同的“辅助函数”,这些函数使用参数的各种子集。传递这些参数很痛苦,我想要一个优雅的可扩展解决方案。
我的首选解决方案是“相对全局”变量 - 对“主”函数的工作区以及主函数调用的任何子函数以及指定它们想要共享该变量的任何子函数都是通用的。但是相对全局变量不会存在于声明它的函数之外,并且一旦主函数返回就会消失。
代码看起来像这样,除了会有更多的 experiment_helpers,每个 experiment_helpers 都以不同的方式使用参数:
function y = experiment(p1,p2,p3,...)
% declare relative global variables.
% these will not change value within this experiment function,
% but this experiment will be reused several times in the calling function,
% each time with different parameter values.
relative global p1, p2, p3 ...
% load and process some data based on parameters
...
% call the helper + return
y = experiment_helper(y,z);
end
function y = experiment_helper(y,z)
relative global p1, p3
%% do some stuff with y, z, possibly using p1 and p3, but not changing either of them.
...
end
我意识到您可以通过其他几种方式获得所需的行为——您可以将参数传递给实验调用的子函数,您可以将参数放在参数结构中并将它们传递给子函数, 等等。第一个很糟糕,因为每次我想更改参数的使用时,我都必须更改所有子函数的参数。第二个没问题,但每次我想使用变量时都必须包含结构前缀。
我想我的问题的“正确”解决方案是使用选项结构,就像 matlab 在其自己的优化代码中所做的那样。我只是想知道是否有一种更巧妙的方法不需要我每次想使用参数“值”时都输入“paramStruct.value”。
我知道相对全局变量可能会导致各种调试噩梦,但我认为它们不一定比现有全局变量导致的更糟糕。而且它们至少会比不合格的全局变量具有更多的局部性。
那么真正的程序员是如何处理这个问题的呢?是否有针对此类问题的优雅、易于创建和维护的设计?可以在matlab中完成吗?如果没有,你会如何用另一种语言来做? (我总是对使用 matlab 感到内疚,因为它并不完全鼓励良好的设计。我总是想切换到 python 但不能证明重新学习东西和迁移代码库是合理的——除非它能让我成为一个更快更好的程序员在几周内,可以在 python 中快速+轻松地找到或复制特定于 matlab 的工具,例如小波和优化工具箱。)
最佳答案
不,我不认为 Matlab 有您正在寻找的东西。
最佳答案取决于您的主要关注点是传递参数所需的输入量,还是传递大型数据集时的内存使用情况。我采用了几种方法,它们各有利弊。
结构中的参数。你已经在你的问题中提到了这一点,但我想强调它在大多数情况下都是一个很好的答案。我通常不会调用我的参数结构
paramStruct
,而是将其称为p
。它始终局限于我正在使用的函数,然后我需要键入p.value
而不是value
。我相信额外的两个字符非常值得能够轻松传递完整的参数集。输入解析器
。在设计需要大量输入的函数时,我经常使用InputParser
类。这实际上与 (1) 非常吻合,因为可以传入参数结构,或者您可以使用“参数”/值对,并且您可以让您的函数定义默认值。非常有用。嵌套函数在有限的情况下会有帮助,但前提是您的所有函数都可以分层定义。如果您的内部函数之一足够通用以支持多个父函数,它会限制代码重用。
使用句柄类通过引用传递。如果你关心的是内存。的新形式 类实际上允许您定义一个通过引用传递的参数结构。代码看起来像这样:
classdef paramStructure < handle properties (SetAccess = public, GetAccess = public) param1 = []; param2 = []; % ... param100 = []; end end
然后你可以像这样创建一个新的引用传递结构
p = paramStructure;
并设置值
p.param1 = randn(100,1);
因为这是传递,所有传递都是通过引用,有优点(更少的内存使用,启用某些编码风格)和缺点(通常更容易犯某些类型的错误。
全局
变量。我非常努力地避免这些,但它们是一种选择。
关于matlab - "relative global"matlab或其他语言的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8183513/