【问题标题】:"relative global" variables in matlab or other languagesmatlab或其他语言中的“相对全局”变量
【发布时间】:2011-11-18 13:54:30
【问题描述】:

我在 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 中快速轻松地找到或复制。)

【问题讨论】:

  • 我觉得这里的答案应该以某种方式涉及“命名空间层次结构”这个词,但我不知道具体如何,因为我不是 csci 专家。
  • 现在我已经正确地阐明了这个问题,我开始四处寻找解决方案。 Python modules 似乎有我想要的功能,但我仍然不确定,而且我很确定它们在 matlab 中不存在。
  • 在大多数其他语言中,类变量(“成员变量”)被隐式添加到成员函数的名称搜索空间中,因此无需进一步限定即可访问它们。

标签: matlab global-variables


【解决方案1】:

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

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

  1. 结构中的参数。你已经在你的问题中提到了这一点,但我想强调它在大多数情况下都是一个很好的答案。我通常不叫我的参数结构paramStruct,而是直接叫它p。它总是在本地限定为我正在使用的函数,然后我需要输入p.value 而不是value。我相信额外的两个字符非常值得能够轻松传递完整的参数集。

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

  3. 嵌套函数可以在有限的情况下提供帮助,但前提是您的所有函数都可以分层定义。如果您的内部函数之一足够通用以支持多个父函数,则会限制代码重用。

  4. 使用句柄类通过引用传递。如果你关心的是记忆。的新形式 类实际上允许您定义一个通过引用传递的参数结构。代码如下所示:

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

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

    p = paramStructure;
    

    并设置值

    p.param1 = randn(100,1);
    

    由于这是传递的,所有传递都是通过引用进行的,具有优点(更少的内存使用,启用某些编码样式)和缺点(通常更容易犯某些错误。

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

【讨论】:

    【解决方案2】:

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

    这是一种非常优雅的编程方式,并且与全局变量相比,它引起的调试问题要少得多。最新版本的 MATLAB 甚至在编辑器中以浅蓝色突出显示共享变量,以帮助解决此问题。

    【讨论】:

    • 我知道嵌套函数,但我不认为它们正是我想要的。如果我不希望嵌套函数访问父工作区中的所有内容怎么办?给定一个子函数,我可能有三种类型的变量:从父工作区传递的变量,子函数创建和修改其本地副本;我希望子函数共享的父工作区中的参数变量;以及父工作区中的其余变量,我根本不希望子函数弄乱它们,以免引起错误。嵌套函数能正确完成所有这些吗?
    • 据此,我想我想要的是一个“安全”的嵌套函数——我可以为它指定我希望它在父工作区中访问的变量列表。我只是对让函数完全不受限制地访问父母工作区的想法感到不舒服。我想控制嵌套函数在父级中可能出现的问题——无需编写一堆 eval 语句或其他东西。我可能应该停止如此挑剔,每次我想使用 paramValue 时都写“opt.paramValue”,并将 opt 传递给所有需要它的函数......
    • 嵌套函数可以访问父工作区的所有变量。如果您需要这种控制,也许面向对象的方法会更好,您可以在其中指定变量是私有的、公共的还是受保护的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2013-05-06
    相关资源
    最近更新 更多