如何编写具有与Matlab脚本兼容的函数定义的单个Octave脚本?

时间:2019-04-20 05:44:17

标签: matlab function octave

如果我这样写:

clc
clear

close all
format long
fprintf( 1, 'Starting...\n' )

function results = do_thing()
    results = 1;
end

results = do_thing()

并使用Octave运行它,它可以正常工作:

Starting...
results =  1

但是,如果我尝试使用Matlab 2017b运行它,则会抛出此错误:

Error: File: testfile.m Line: 13 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "do_thing" function definition to before the first local function
definition.

然后,如果我按照以下步骤解决错误:

clc
clear

close all
format long
fprintf( 1, 'Starting...\n' )

results = do_thing()

function results = do_thing()
    results = 1;
end

它在Matlab上正常工作:

Starting...

results =

     1

但是现在,它停止与Octave一起使用了:

Starting...
error: 'do_thing' undefined near line 8 column 11
error: called from
    testfile at line 8 column 9

此问题在以下问题上得到了解释:Run octave script file containing a function definition

如何解决此问题而不必为功能do_thing()创建单独的专有文件?

此问题是否已在Matlab的某些较新版本中修复为2019a

2 个答案:

答案 0 :(得分:3)

答案在注释中,但为了清楚起见:

% in file `do_thing.m`
function results = do_thing()
    results = 1;
end

% in your script file
clc;   clear;   close all;   format long;
fprintf( 1, 'Starting...\n' );
results = do_thing();

随附的解释性说明:

  • 定义函数的规范和最安全的方法是在它们自己的文件中定义它们,并使该文件可以在octave / matlab的路径中访问。
  • 自八月以来,Octave一直支持“动态”功能定义(即在脚本或命令行上下文中)。但是,出于兼容性的目的,由于matlab不支持此功能,所以大多数人没有使用它,而是明智地依赖于规范方法。
  • Matlab最近也终于引入了动态函数定义,但是如上所述,它选择了以破坏八度音阶兼容性的方式显式实现它们。 (当然:这可能是一个巧合,是一个认真的设计决定,但我确实注意到,它也碰巧与之前关于嵌套函数的matlab约定背道而驰,后者可以在其封闭范围内的任何位置进行定义。)
  • 从某种意义上说,什么都没有改变。 Matlab与高级八度音阶功能不兼容,现在它已经引入了该功能的自己的实现,因此仍然不兼容。这是因祸得福。为什么?因为,如果您要使用兼容的代码,则应依靠规范的形式和良好的编程习惯,而不要使用动态功能来乱扔脚本,这是您应该做的

答案 1 :(得分:0)

Octave在脚本中对本地函数的实现与Matlab的不同。 Octave要求在脚本使用前 定义脚本中的局部函数。但是Matlab要求脚本中的局部函数都必须在文件的 end 处定义。

因此,您可以在两个应用程序的脚本中使用局部函数,但不能编写在两个应用程序上都可以使用的脚本。因此,如果您想同时在Matlab和Octave上运行的代码,请使用函数。

示例:

最后的功能

disp('Hello world')
foo(42);

function foo(x)
  disp(x);
end

在Matlab R2019a中:

>> myscript
Hello world
    42

在Octave 5.1.0中:

octave:1> myscript
Hello world
error: 'foo' undefined near line 2 column 1
error: called from
    myscript at line 2 column 1

使用前的功能

disp('Hello world')

function foo(x)
  disp(x);
end

foo(42);

在Matlab R2019a中:

>> myscript
Error: File: myscript.m Line: 7 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "foo" function definition to before the first local function definition. 

在Octave 5.1.0中:

octave:2> myscript
Hello world
 42

工作原理

请注意,从技术上讲,八度中的功能不是“本地功能”,而是“命令行功能”。它们定义了在评估function语句时就存在的全局函数,而不是定义脚本本地的函数。