matlab或其他语言中的“相对全局”变量

时间:2011-11-18 13:54:31

标签: matlab global-variables

我在MATLAB中进行科学图像处理,这需要解决许多参数的奇怪优化问题,这些参数由“实验”函数使用,该函数具有使用各种参数子集的许多不同“辅助函数”。传递这些参数很痛苦,我想要一个优雅的可扩展解决方案。

我首选的解决方案是“相对全局”变量 - 对于“主”函数的工作空间是通用的,以及主函数调用并指定他们想要共享该变量的任何子函数。但是相对全局变量不会在声明它的函数之外存在,并且一旦主函数返回就会消失。

代码看起来像这样,除了会有更多的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在其自己的优化代码中所做的那样。我只是想知道是否每次我想使用参数“value”时都没有让我输入“paramStruct.value”的方式。

我意识到相对全局变量可能导致各种调试噩梦,但我认为它们不一定比现有全局变量引起的更糟糕。并且它们至少比不合格的全局变量具有更多的局部性。

那么真正的程序员如何处理这个问题呢?是否有针对此类问题的优雅,易于创建和维护的设计?可以在matlab中完成吗?如果没有,你会用另一种语言做到这一点? (我总是对使用matlab感到内疚,因为它并不能完全鼓励好的设计。我总是想切换到python,但不能证明重新学习东西和迁移代码库 - 除非它会让我成为一个更快更好的程序员在几周之内,特定于matlab的工具,如小波和优化工具箱,可以在python中快速+轻松地找到或复制。)

2 个答案:

答案 0 :(得分:2)

不,我认为Matlab并不完全符合您的要求。

最佳答案取决于您的主要关注点是由于传递参数所需的输入量,或者您在传递大型数据集时担心内存使用情况。我采取了一些方法,它们都有利有弊。

  1. 结构中的参数。你已经在你的问题中提到了这一点,但我想在大多数情况下强化它作为一个很好的答案。我通常只称它为paramStruct,而不是调用我的参数结构p。它总是局部作用于我正在使用的函数,然后我需要键入p.value而不是value。我相信额外的两个角色非常值得轻松传递完整的参数集。

  2. InputParser。在设计需要大量输入的函数时,我经常使用InputParser类。这实际上符合(1),因为可以传入参数结构,或者你可以使用'param'/ value对,yuo可以允许你的函数定义默认值。非常有用。

  3. 嵌套函数可以在有限的情况下提供帮助,但仅限于可以按层次结构定义所有函数的情况。如果你的一个内部函数足够通用以支持多个父函数,它会限制代码的重用。

  4. 使用句柄类通过引用传递。如果你关注的是记忆。新的形式 类实际上允许您定义一个通过引用传递的paraemter结构。代码看起来像这样:

    classdef paramStructure < handle
        properties (SetAccess = public, GetAccess = public)
            param1 = [];  
            param2 = [];
            % ...
            param100 = [];
        end
    end
    

    然后你可以像这样创建一个新的传递引用结构

    p = paramStructure;
    

    并设定值

    p.param1 = randn(100,1);
    

    当这个被传递时,所有传递都是通过引用,与专业人士(较少的内存使用,启用一些编码样式)和缺点(通常更容易犯一些错误。

  5. global个变量。我非常努力地避免这些,但它们是一种选择。

答案 1 :(得分:1)

您所描述的内容在MATLAB中使用嵌套函数完全可用。它们有自己的工作空间,但是它们也可以访问嵌套它们的父函数的工作空间。因此父函数可以定义您的参数,嵌套函数将能够看到它们具有共享范围。

这是一种非常优雅的编程方式,与全局变量相比,调试问题更少。最新版本的MATLAB甚至用浅蓝色突出显示编辑器中的共享变量,以帮助解决这个问题。