Когда я учился на получение степени бакалавра в EE, MATLAB требовал, чтобы каждая функция определялась в собственном файле, даже если она была однострочным.
Сейчас я учусь в аспирантуре, и мне нужно написать проект в MATLAB. Это все еще требование для более новых версий MATLAB?
Если в файл можно поместить более одной функции, существуют ли какие-либо ограничения на это? Например, могут ли доступны все функции в файле из-за пределов файла или только функция с тем же именем, что и файл?
Примечание. Я использую MATLAB release R2007b.
Первая функция в m файле (т.е. основная функция) вызывается при вызове этого m файла. Не требуется, чтобы основная функция имела то же имя, что и файл m, но для ясности это должно быть. Когда функция и имя файла различаются, имя файла должно использоваться для вызова основной функции.
Все последующие функции в m файле, называемые локальные функции (или "подфункции" в старой терминологии), могут быть вызваны только основная функция и другие локальные функции в этом m файле. Функции других m файлов не могут вызывать их.
Кроме того, вы также можете объявлять функции в рамках других функций. Они называются вложенными функциями, и их можно вызывать только внутри функции, в которую они вложены. Они также могут иметь доступ к переменным в функциях, в которых они вложены, что делает их весьма полезными, хотя и немного сложными для работы.
Больше пищи для размышлений...
Существуют способы обхода описанного выше нормального режима работы функции, такие как передача функций handles в качестве выходных аргументов, как указано в Ответ Jonas. Тем не менее, я бы не стал предлагать привычку прибегать к таким трюкам, так как есть, вероятно, гораздо лучшие варианты для организации ваших файлов.
Например, предположим, что у вас есть основная функция A
в m файле A.m
, а также локальные функции D
, E
и F
. Теперь предположим, что у вас есть две другие связанные функции B
и C
в m файлах B.m
и C.m
, соответственно, что вы также хотите иметь возможность звонить D
, E
и F
. Вот некоторые варианты, которые у вас есть:
Поместите D
, E
и F
каждый в свои собственные m файлы, позволяя любой другой функции их вызывать. Недостатком является то, что объем этих функций большой и не ограничивается только A
, B
и C
, но вверху является то, что это довольно просто.
Создайте defineMyFunctions
m файл (например, в примере Джонаса) с D
, E
и F
как локальные функции и главную функцию, которая просто возвращает к ним дескрипторы функций. Это позволяет хранить D
, E
и F
в одном файле, но ничего не делает в отношении объема этих функций, поскольку любая функция, которая может вызывать defineMyFunctions
, может вызывать их. Вы также должны беспокоиться о передаче функций в качестве аргументов, чтобы убедиться, что они есть там, где они вам нужны.
Скопируйте D
, E
и F
в B.m
и C.m
в качестве локальных функций. Это ограничивает объем их использования только A
, B
и C
, но делает обновление и обслуживание вашего кошмара кошмаром, потому что у вас есть три копии одного и того же кода в разных местах.
Используйте частные функции! Если у вас есть A
, B
и C
в том же каталоге, вы можете создать подкаталог под названием private
и поместить D
, E
и F
туда, каждый в виде отдельного m файла. Это ограничивает их область действия, поэтому их можно вызывать только из функций в каталоге непосредственно выше (т.е. A
, B
и C
) и удерживать их вместе в одном и том же месте (но все еще разные m файлы):
myDirectory/
A.m
B.m
C.m
private/
D.m
E.m
F.m
Все это выходит за рамки вашего вопроса и, вероятно, более подробно, чем вам нужно, но я подумал, что было бы полезно затронуть более общую проблему организации всех ваших m файлов.;)
Как правило, ответ на ваш вопрос - нет, вы не можете определить более чем одну внешнюю видимую функцию для каждого файла. Однако вы можете возвращать дескрипторы функций для локальных функций, и удобный способ сделать это - сделать их полями структуры. Вот пример:
function funs = makefuns
funs.fun1=@fun1;
funs.fun2=@fun2;
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
И вот как это можно использовать:
>> myfuns = makefuns;
>> myfuns.fun1(5)
ans =
5
>> myfuns.fun2()
ans =
1
Единственный способ иметь несколько, отдельно доступных функций в одном файле - это определить СТАТИЧЕСКИЕ МЕТОДЫ, используя объектно-ориентированное программирование. Вы должны получить доступ к функции как myClass.static1()
, myClass.static2()
и т.д.
Функциональность OOP официально поддерживается только с R2008a, поэтому, если вы не хотите использовать старый, недокументированный синтаксис ООП, ответ для вас - нет, как объясняется @gnovice.
EDIT
Еще один способ определить несколько функций внутри файла, которые доступны извне, - это создать функцию, которая возвращает несколько функций . Другими словами, вы бы назвали вашу определяющую функцию [fun1,fun2,fun3]=defineMyFunctions
, после которой вы могли бы использовать out1=fun1(inputs)
и т.д.
Мне очень нравится ответ SCFrench. Я хотел бы указать, что его можно легко изменить, чтобы импортировать функции напрямую в рабочую область с помощью функции assignin. (Выполнение этого, как это напоминает мне много Python "import x from y" способ делать вещи)
function message = makefuns
assignin('base','fun1',@fun1);
assignin('base','fun2',@fun2);
message='Done importing functions to workspace';
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
И затем используется таким образом:
>> makefuns
ans =
Done importing functions to workspace
>> fun1(123)
ans =
123
>> fun2()
ans =
1
В том же ключе, что и SCFrench, но с более стильным стилем С#..
Я бы (и часто делал) создавал класс, содержащий несколько статических методов. Например:
classdef Statistics
methods(Static)
function val = MyMean(data)
val = mean(data);
end
function val = MyStd(data)
val = std(data);
end
end
end
Поскольку методы статичны, вам не нужно вводить в действие класс. Вы вызываете функции следующим образом:
data = 1:10;
mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);
Я определяю несколько функций в одном файле .m с октавом, а затем использую команду из файла .m, где мне нужно использовать функции из этого файла:
source("mycode.m");
Не уверен, что это доступно с помощью Matlab.
octave:8> help source
'source' is a built-in function
-- Built-in Function: source (FILE)
Parse and execute the contents of FILE. This is equivalent to
executing commands from a script file, but without requiring the
file to be named `FILE.m'.
source
:(
Вы также можете группировать функции в один основной файл вместе с основной функцией, выглядящей так:
function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} );
% paste your subfunctions below ....
function str=subfun1
str='hello'
Тогда вызов subfun1 будет выглядеть так: ул = основная ( 'subfun1')
Как и в случае R2017b, это официально невозможно. соответствующая документация гласит, что:
Файлы программы могут содержать несколько функций. Если файл содержит только определения функций, первая функция является основной функцией и является функцией, которую MATLAB связывает с именем файла. Функции, которые следуют за основной функцией или кодом script, называются локальными функциями. Локальные функции доступны только в файле.
Однако обходные пути, предложенные в других ответах, могут достичь чего-то подобного.
^
, @idigas