Как написать один скрипт Octave с определениями функций, совместимыми со скриптами Matlab? - PullRequest
3 голосов
/ 20 апреля 2019

Если я напишу это:

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

Эта проблема была объяснена по этому вопросу: Запуск файла сценария октавы, содержащего определение функции

Как это исправить, не создавая отдельный и эксклюзивный файл для функции do_thing()?

Исправлена ​​ли эта проблема в более новой версии Matlab как 2019a?

Ответы [ 2 ]

3 голосов
/ 23 апреля 2019

Ответ в комментариях, но для ясности:

% 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();

Сопровождающая пояснительная речь:

  • Канонический и самый безопасный способ определения функций - определить их в своем собственном файле и сделать этот файл доступным по пути октавы / matlab.
  • Octave поддерживает определения «динамических» функций (т. Е. В контексте скрипта или командной строки) практически навсегда. Тем не менее, в целях совместимости, поскольку matlab не поддерживал это, большинство людей не использовали его и вполне разумно полагались на канонический способ.
  • Matlab недавно наконец-то также ввел определения динамических функций, но решил реализовать их явно таким образом, чтобы нарушить совместимость с октавой, как вы описали выше. (rant: это может быть совпадением и серьезным дизайнерским решением, но я отмечаю, что оно также идет вразрез с предыдущими соглашениями matlab, касающимися вложенных функций, которые разрешалось определять в любом месте в пределах их объема).
  • В каком-то смысле ничего не изменилось. Matlab был несовместим с расширенной октавной функциональностью, и теперь, когда он представил собственную реализацию этой функциональности, он все еще несовместим. Это замаскированное благословение. Зачем? Потому что, если вы хотите совместимый код, вы должны полагаться на каноническую форму и хорошие методы программирования, а не засорять ваши скрипты динамическими функциями, , что вы должны делать в любом случае .
0 голосов
/ 21 апреля 2019

Реализация локальных функций в скриптах в Octave отличается от реализации Matlab. Octave требует, чтобы локальные функции в скриптах были определены до их использования. Но Matlab требует, чтобы все локальные функции в сценариях были определены на конце файла.

Таким образом, вы можете использовать локальные функции в сценариях обоих приложений, но вы не можете написать сценарий, который будет работать в обоих приложениях. Так что просто используйте функции, если вам нужен код, который будет работать как в Matlab, так и в Octave.

Примеры:

Функции в конце

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

function foo(x)
  disp(x);
end

В Matlab R2019a:

>> myscript
Hello world
    42

В октябре 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. 

В октаве 5.1.0:

octave:2> myscript
Hello world
 42

Как это работает

Обратите внимание, что технически функции здесь, в Octave, являются не "локальными функциями", а "функциями командной строки". Вместо того, чтобы определять функцию, которая является локальной для сценария, они определяют глобальные функции, которые возникают при оценке оператора function.

...