【问题标题】:Matlab/Octave function handlers and narginMatlab/Octave 函数处理程序和 nargin
【发布时间】:2011-11-20 15:01:23
【问题描述】:

我正在用 Octave 编写程序,但遇到了一个问题,我实现了 Gauss-Legandre Quadrature,我将几个参数传递给我的 Gauss-Legandre 函数,我传递了要在单元立方体中集成的函数,所以我可以通过一次有几个功能。我有这段代码:

    for weight=1:length(w)
        temp=1; 
        for fun=1:length(c)
            %liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
            f=c{fun};
            nargin(func2str(c{fun}))
            if (nargin (func2str(c{fun})) == 1)
                disp('a');
                temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
            else
                    (b-a)/2 * x(weight) + (a+b)/2;  
                temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
            end
        end
        %mnozenie wyniku przez odpowiedni wspolczynnik - wage
        temp*=w(weight);
        result+=temp;
    end

在单元格数组中,有我想要集成的函数的函数处理程序。根据函数需要的参数数量,我想对函数使用两个不同的调用。如果在单元格数组中有一个函数的处理程序,该函数写在与我的 Octave 工作目录相同的目录中的 .m 文件中,一切正常,但是当我在 Octave 运行时定义函数时,例如:

    function result=a(x)
    result=x*x
    end

类型

    c{1}=@a

并将这个单元格数组传递给我的函数 Kwadratury 存在 nargin 错误

    error: nargin: invalid function
    error: called from:

为什么会这样,我该如何解决,所以我不仅可以在 .m 文件中定义函数,还可以在 Octave 中定义函数。

【问题讨论】:

    标签: function matlab octave handlers


    【解决方案1】:

    我怀疑我有一个解决方案,但由于这是 Octave 特有的,而且我主要习惯于 MATLAB,所以你的情况可能会有所不同。

    您通过提供字符串参数调用nargin 函数,这意味着nargin 将必须解析该函数​​并检查参数的数量。当您内联声明一个函数时,该函数是在该范围内定义的(即您的基本范围),因此解析函数名称将无法在任何函数内工作(或者它可能解析为内置函数,甚至更糟糕的行为)。

    最好的解决方案是使用nargin(c{fun}) 而不是nargin(func2str(c{fun}))。这样您就可以传递实际的函数句柄,并且无需将函数名称解析为实际函数,因此不会产生歧义。

    一般来说,我建议不要使用字符串来传递函数:为什么函数句柄包含在 MATLAB 中,所以任何阅读您的代码(或静态代码分析工具)的人都将能够理解您正在使用函数。使用字符串时,一切都变得模棱两可:字符串'a' 是指函数a 还是指字母表中的第一个字母?

    关于使用内联函数,我不知道Octave是否支持这个,但是如果你的函数很简单,定义一个匿名函数会更容易,比如你的例子,a = @(x)(x*x);。这是 MATLAB 支持的构造,因此可以使您的代码更易于移植到其他环境(好吧,您仍然需要将 X *= A 替换为 X = X * A; 以与 MATLAB 兼容)。

    编辑: 另一种可能性是只尝试具有多个参数的表单是否有效,并在必要时回退到一个参数表单:

    try
       (b-a)/2 * x(weight) + (a+b)/2;  
       temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
    catch ME
       try
           disp('a');
           temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
       catch ME
       end
    end
    

    您可能想检查返回的错误ME 是否确实表明使用了错误数量的参数来允许其他错误通过。我承认这是一个丑陋的解决方法,但由于 Octave 显然不支持 nargin 的函数句柄,它可能是您获得内联函数所需的唯一方法。

    【讨论】:

    • 我开始使用 func2str 是因为在 Octave nargin 中只接受一个字符串,但无论如何我通过让我的单元格也有其他参数来解决我的问题,所以当我知道我的函数接受 3 个变量时,我只是得到它们来自 c{fun,2} 和其他,我将所有函数放在单独的文件中,因此不用担心范围。
    • 正如我之前所说,我通过将每个函数都放在它自己的文件中解决了我的问题,需要这些内联函数来加快我对自己代码的测试,但我没有但是,但感谢你的帮助:)。
    猜你喜欢
    • 2020-12-10
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多