matlab - 访问特定工作区中的变量

2024-03-18

我需要类似的东西evalin,但是原来的evalinMatlab 不能递归使用。例如,我有函数 f0,它调用另外 2 个函数 f11 和 f12:

function f0()
    [v1, v2] = deal(1, 1);

    f11();
    f12();

    disp(v1);
end

函数 f11 和 f12 使用变量 v1,并且都调用函数 f2:

function f11()
    v1 = evalin('caller', 'v1');

    f2();

    assignin('caller', 'v1', v1);
end

function f12()
    v1 = evalin('caller', 'v1');

    f2();

    assignin('caller', 'v1', v1);
end

函数 f2 应该使用 f0 工作空间的变量 v1 和 v2:

function f2()
    v1 = evalin('caller', 'v1');    % get variable v1 from f11 or f12
                                    % since there is already a variable v1 
                                    % in f11 and f12's workspaces
    % TODO: get v2 from f0

    if v2 == 1
        v1 = v1 + 1;
    end

    assignin('caller', 'v1', v1);

end

无论如何,有没有办法使 TODO 成为可能而不使用v2 = evalin('caller', 'v2')在 f11 和 f12 中?


这可能是组织函数之间数据传输的最糟糕的方式之一。功能工作区分开是有充分理由的,以保持工作干净整洁。

您正试图绕过设计该语言(以及共享这种工作空间/范围分离的许多其他语言)的人所设置的所有安全措施。 Matlab 中提供了这些“旁路”函数,以便您在进行原型设计时能够准时使用。它们不适合大量使用或最终解决方案(其中大多数实际上无法编译)。

It is

  • 可能会非常令人困惑(稍后对您来说,但如果其他人必须使用您的代码,情况会更糟)。
  • 很难调试(你几乎have提前知道变量的值,以了解从另一个工作区导入是否正确)。

您在评论中说,由于变量的数量,将变量作为参数传递很复杂,但是每次您调用类似的东西时x = evalin('caller', 'x');无论如何,你必须编写一整行代码才能检索你的值。进而assignin('caller', 'x', x);是另一行代码将其发送回来......这太疯狂了。

难道不是更简单(也更短)吗?x在你的函数输入参数中? (输入 100 个变量仍然比使用 200 整行代码从不确定位置检索然后重新发送这些值要快).


推荐(如果可行):在参数中传递变量

为了使变量传递变得容易,您可以将它们全部收集在一个structure http://mathworks.com/help/matlab/structures.html (or a cell array http://mathworks.com/help/matlab/cell-arrays.html):

[v1, v2] = deal(1, 1);
myVars.v1 = v1 ;
myVars.v2 = v2 ;

myVars = f11(myVars); %// you only have one variable to pass into your functions
myVars = f12(myVars); %// just make sure you retrieve it in output too

disp(myVars.v1);

And then

function myVars = f11()
    myVars = f2(myVars);
end

依此类推,只要将变量传递给下一个函数,然后在输出中检索它,这将适用于任何级别的递归。


推荐(如果以上不可能):使用nested功能

如果你定义你的函数f11() inside your f0(),两个函数中具有相同名称的变量将被共享(在两个级别都可见)。阅读documentation http://uk.mathworks.com/help/matlab/matlab_prog/nested-functions.html#f4-73993了解更多详情。这样您就不需要多次致电evalin/assignin因为变量到处都是已知的。你的函数必须写成这样的形式:

function f0()
[v1, v2] = deal(1, 1);

f11();
f12();

disp(v1);

    function f11()
        f2();
        function f2()
            if v2 == 1
                v1 = v1 + 1;
            end
        end
    end %// END function F11

    function f12()
        f2();
        function f2()
            if v2 == 1
                v1 = v1 + 1;
            end
        end
    end %// END function F12

end %// END function F0

Stack Exchange 不会渲染它,但在 Matlab 编辑器中,您可能会注意到“共享”变量将以不同的颜色突出显示(以提醒您它们的范围与标准变量不同)。

如果我跑f0()我确实得到:

>> f0
     3

这是预期的结果。正如您所看到的,唯一的缺点是如果您打电话f2()从内部f11() and f12(), 功能f2()必须写在每个文件中(因此需要进行一些复制/粘贴)。除非在这个递归级别,您没有太多变量需要传递,所以您可以考虑编写f2()在侧面并使用标准变量传递方案。


可以工作,但不推荐

现在,如果您仍然热衷于编写大量代码来传递单个变量,那么仍然有 2 个选择:

  • use global http://mathworks.com/help/matlab/ref/global.html变量
  • use setappdata http://uk.mathworks.com/help/matlab/ref/setappdata.html and getappdata http://uk.mathworks.com/help/matlab/ref/getappdata.html

我不喜欢用global所以我这里就不详细说了。只要记住变量真的是global它必须声明为global in every函数在使用的地方。

For the appdata方法,您需要一个“容器”,您的所有功能都可以访问它。您可以使用“根”对象(标识符: 0).

例如,当你想存储一个变量时,你可以使用:

setappdata( 0 , 'v2' , v2 ) %// store the value of `v2` in a field named `'v2'` in the root object.

然后在您的任何函数中,获取值,对其进行处理,然后将其存储回来:

function f2()
    v1 = getappdata(0,'v1')     %// get the value of v1
    v2 = getappdata(0,'v2')     %// get the value of v2
    if v2 == 1
        v1 = v1 + 1;            %// modify the value of v1
    end
    v1 = setappdata(0,'v1',v1)  %// store the value of v1
end

在您的基本函数中应用相同的原则并f11(), f12()等等...只要记住在修改后始终将任何值存储回来,以便它可用于下一个需要它的函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab - 访问特定工作区中的变量 的相关文章

  • Matlab中转换数据类型的有效方法(double vs. im2double)

    我想将真彩色图像转换为双精度 据我所知有两种方法可以做到这一点 double rgb img im2double rgb img 哪一种效率更高 谢谢 他们都是不同的 im2double将图像的范围转换为0 1如果数据类型是uint8 or
  • MATLAB 中最有效的矩阵求逆

    在 MATLAB 中计算某个方阵 A 的逆矩阵时 使用 Ai inv A should be the same as Ai A 1 MATLAB 通常会通知我这不是最有效的求逆方法 那么什么是更有效率的呢 如果我有一个方程系统 可能会使用
  • Python 函数句柄 ala Matlab

    在 MATLAB 中可以创建function handles http www mathworks co uk help techdoc ref function handle html与类似的东西 myfun arglist body 这
  • MATLAB 中的多个捕获组

    我有一个包含数字或字母的字符串a 可能紧随其后的是r or l 在 MATLAB 中 以下正则表达式返回为 gt gt regexp 10r 0 9 a l r match ans 10r 我希望10 and r分开 因为我有两个捕获组 有
  • MATLAB - 如何将子图一起缩放?

    我在一张图中有多个子图 每个图的 X 轴是相同的变量 时间 每个图上的 Y 轴都不同 无论是它所代表的内容还是数据的大小 我想要一种同时放大所有图的时间尺度的方法 理想情况下 可以在其中一张图上使用矩形缩放工具 并让其他图相应地更改其 X
  • e:B, f:(B,A)=>B) : B 是什么意思

    我对这意味着什么感到困惑 我理解柯里化 但我似乎无法完全阅读代码 def foldLeft A B xs List A e B f B A gt B B 只是几个建议 顺便说一句 里面没有柯里化 def foldLeft A B xs Li
  • 用于将字符串与通配符模式进行匹配的递归函数

    所以我一整天都在试图解决这个作业 只是无法完成 以下函数接受 2 个字符串 第二个 不是第一个 可能包含 的 星号 An 是字符串的替换 空 1个字符或更多 它可以出现 仅在s2中 一次 两次 更多或根本不出现 它不能与另一个相邻 ab c
  • Matlab 字段名索引[重复]

    这个问题在这里已经有答案了 所以我有一个包含多个表的元胞数组 我试图访问表的第一个列名称 c table1 table2 table3 以下两行都给了我错误 fieldnames c 1 1 fieldnames c 1 1 Error i
  • 有没有办法在matlab中进行隐式微分

    我经常使用 matlab 来帮助我解决数学问题 现在我正在寻找一种在 matlab 中进行隐式微分的方法 例如 我想区分y 3 sin x cos y exp x 0关于dy dx 我知道如何使用数学方法通常做到这一点 但我一直在努力寻找使
  • 为什么haskell中的递归列表这么慢?

    我对 Haskell 很陌生 我在 Haskell 中定义了一个函数 febs Integral a gt a gt a febs n n lt 0 0 n 1 1 n 2 1 otherwise febs n 1 febs n 2 但是
  • 在 Matlab 中将 datenum 转换为 datetime 的最快方法

    我在 Matlab 中将 datenum 转换为 datetime 时遇到问题 Given dnum floor now floor now 1 我尝试了以下方法 datenum dnum 但这没有用 我发现有效的方法是 datetime
  • 从原点开始在离散 2D 网格上迭代向外螺旋的算法

    例如 这是预期螺旋的形状 以及迭代的每个步骤 y 16 15 14 13 12 17 4 3 2 11 18 5 0 1 10 x 19 6 7 8 9 20 21 22 23 24 其中线条是 x 轴和 y 轴 以下是算法每次迭代 返回
  • 如何找到平面和 3d 矩阵之间的交平面

    如果我有一堆图像并且尺寸如下 size M 256 256 124 我有 3 个点 它们的坐标是 coor a 100 100 124 coor b 256 156 0 coor c 156 256 0 如何创建 M 与这 3 个点定义的平
  • Java-使用递归压平数组

    我一直在练习算法 递归一直是我的弱项 该问题要求将嵌套数组展平为单个数组 如果使用给出 O n 3 给定相同大小的 3d 数组 解决方案的循环 这将很简单 然而 通过递归 我已经挣扎了几个小时 这就是我所拥有的 请注意 我已经尝试过使用我的
  • 使用 Python 的“哈密尔顿”路径

    我正在尝试使用 Python 实现遍历所有图顶点的任意路径 不一定是循环 的递归搜索 这是我的代码 def hamilton G size pt path if pt not in set path path append pt if le
  • 如何使用 MATLAB 的 substruct 函数创建表示使用“end”的引用的结构?

    我想使用substruct http www mathworks com help matlab ref substruct html函数创建一个结构体以供使用subsref 目的是使用索引字符串subsref而不是通常的 符号 因为我正在
  • 理解高斯混合模型的概念

    我试图通过阅读在线资源来理解 GMM 我已经使用 K 均值实现了聚类 并且正在了解 GMM 与 K 均值的比较 以下是我的理解 如有错误请指出 GMM 类似于 KNN 在这两种情况下都实现了聚类 但在 GMM 中 每个簇都有自己独立的均值和
  • 求 3D 棋盘中水体积的技巧

    所以我有一个任务 我必须重新创建一个 3D 棋盘 它是一个 RxC 方块网格 每个方块的高度都不同 如果棋盘是不透水的 有人把水倒在棋盘上 直到棋盘无法容纳更多的水 那么它就会容纳固定数量的水 如果板已经容纳了最大体积的水 则倒入板上的任何
  • 如何在 MATLAB 中绘制 3D 曲面图?

    我有一个像这样的数据集 0 1 0 2 0 3 0 4 1 10 11 12 13 2 11 12 13 14 3 12 13 14 15 4 13 14 15 16 我想在 matlab 中绘制 3D 曲面图 使列标题位于 y 轴 行标题
  • 如何在文本集中创建所有字符组合?

    例如 我有这样的文本集 第 1 栏 a b 第 2 栏 l m n 第 3 栏 v w x y 我想将它们组合起来以获得如下输出 alv alw alx aly amv amw amx amy 这将输出 24 种文本组合 如果我只使用前两列

随机推荐