web-dev-qa-db-ger.com

Ist es möglich, mehr als eine Funktion pro Datei in MATLAB zu definieren und von außerhalb dieser Datei darauf zuzugreifen?

Als ich für mein Grundstudium in EE studierte, musste in MATLAB jede Funktion in einer eigenen Datei definiert werden, auch wenn es sich um eine Einzeiler-Funktion handelte.

Ich studiere jetzt für ein Diplom und ich muss ein Projekt in MATLAB schreiben. Ist dies immer noch eine Voraussetzung für neuere Versionen von MATLAB?

Gibt es irgendwelche Einschränkungen, wenn es möglich ist, mehr als eine Funktion in eine Datei zu setzen? Kann beispielsweise von außerhalb der Datei auf alle Funktionen in der Datei zugegriffen werden, oder nur auf die Funktion, die denselben Namen wie die Datei hat?

Hinweis: Ich verwende MATLAB Release R2007b.

203
Nathan Fellman

Die erste Funktion in einer M-Datei (d. H. Die Hauptfunktion ) wird aufgerufen, wenn diese M-Datei aufgerufen wird. Es ist nicht erforderlich, dass die Hauptfunktion den gleichen Namen hat wie die M-Datei, aber der Übersichtlichkeit halber sollte. Wenn die Funktion und der Dateiname unterschiedlich sind, muss Dateiname zum Aufrufen der Hauptfunktion verwendet werden.

Alle nachfolgenden Funktionen in der M-Datei, genannt lokale Funktionen (oder "Unterfunktionen" in der älteren Terminologie), können nur von der Hauptfunktion und anderen lokalen Funktionen in dieser M-Datei aufgerufen werden. Funktionen in anderen M-Files können diese nicht aufrufen. Ab R2016b können Sie auch lokale Funktionen zu Skripten hinzufügen , obwohl das Gültigkeitsbereichsverhalten immer noch dasselbe ist (d. H. Sie können nur innerhalb des Skripts aufgerufen werden).

Darüber hinaus können Sie auch Funktionen innerhalb anderer Funktionen deklarieren. Diese heißen verschachtelte Funktionen und können nur innerhalb der Funktion aufgerufen werden, in der sie verschachtelt sind. Sie können auch auf Variablen in Funktionen zugreifen, in denen sie verschachtelt sind, was die Arbeit mit ihnen recht nützlich, wenn auch etwas schwierig macht.

Mehr Denkanstöße ...

Es gibt einige Möglichkeiten, um das oben beschriebene normale Funktionsumfangsverhalten zu umgehen, z. B. die Übergabe von Funktionshandles als Ausgabeargumente, wie in den Antworten von SCFrench und Jonas ​​erwähnt = (was ab R2013b durch die Funktion localfunctions erleichtert wird). Ich würde jedoch nicht empfehlen, sich solche Tricks zur Gewohnheit zu machen, da es wahrscheinlich viel bessere Möglichkeiten gibt, Ihre Funktionen und Dateien zu organisieren.

Angenommen, Sie haben eine Hauptfunktion A in einer M-Datei A.m, zusammen mit lokalen Funktionen D, E und F. Angenommen, Sie haben zwei weitere verwandte Funktionen: B und C in m-files B.m und C.m, das Sie auch D, E und F aufrufen möchten. Hier sind einige Optionen, die Sie haben:

  • Fügen Sie D, E und F jeweils in ihre eigenen M-Dateien ein, damit jede andere Funktion sie aufrufen kann. Der Nachteil ist, dass der Umfang dieser Funktionen groß ist und nicht nur auf A, B und C beschränkt ist, sondern dass dies recht einfach ist.

  • Erstellen Sie eine defineMyFunctions m-Datei (wie in Jonas 'Beispiel) mit D, E und F als lokalen Funktionen und einer Hauptfunktion, die einfach zurückgegeben wird Funktionsgriffe zu ihnen. Dies ermöglicht es Ihnen, D, E und F in derselben Datei zu belassen, hat jedoch keine Auswirkungen auf den Umfang dieser Funktionen, da jede Funktion diese Funktionen aufrufen kann defineMyFunctions kann sie aufrufen. Sie müssen sich dann auch darum kümmern, die Funktionshandles als Argumente zu übergeben, um sicherzustellen, dass Sie sie dort haben, wo Sie sie benötigen.

  • Kopieren Sie D, E und F in B.m und C.m als lokale Funktionen. Dies beschränkt den Umfang ihrer Verwendung auf nur A, B und C, macht jedoch die Aktualisierung und Pflege Ihres Codes zu einem Albtraum, da Sie drei Kopien desselben Codes haben an verschiedenen Orten.

  • Verwenden Sie private Funktionen ! Wenn Sie A, B und C Im selben Verzeichnis können Sie ein Unterverzeichnis mit dem Namen private erstellen und D, E und F als separate Verzeichnisse einfügen M-Datei. Dies schränkt ihren Gültigkeitsbereich ein, sodass sie nur von Funktionen im unmittelbar darüber liegenden Verzeichnis (dh A, B und C) aufgerufen werden können und an derselben Stelle zusammengehalten werden ( aber immer noch andere m-files):

    myDirectory/
        A.m
        B.m
        C.m
        private/
            D.m
            E.m
            F.m
    

All dies geht etwas über den Rahmen Ihrer Frage hinaus und ist wahrscheinlich detaillierter als Sie es benötigen, aber ich dachte, es wäre gut, auf das allgemeinere Problem der Organisation aller Ihrer M-Files einzugehen. ;)

263
gnovice

Im Allgemeinen lautet die Antwort auf Ihre Frage "Nein". Sie können nur eine extern sichtbare Funktion pro Datei definieren. Sie können Funktionshandles jedoch an lokale Funktionen zurückgeben, und eine bequeme Möglichkeit besteht darin, sie zu Feldern einer Struktur zu machen. Hier ist ein Beispiel:

function funs = makefuns
  [email protected];
  [email protected];
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

Und so könnte es verwendet werden:

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1
76
SCFrench

Die einzige Möglichkeit, mehrere, separat zugängliche Funktionen in einer einzigen Datei zu haben, besteht darin, STATISCHE METHODEN mit objektorientierte Programmierung zu definieren. Sie würden die Funktion als myClass.static1(), myClass.static2() usw. aufrufen.

Die OOP-Funktionalität wird erst seit R2008a offiziell unterstützt. Wenn Sie also nicht die alte, undokumentierte Syntax OOP) verwenden möchten, lautet die Antwort für Sie Nein, wie durch @ gnovice erläutert .

[~ # ~] edit [~ # ~]

Eine weitere Möglichkeit, mehrere Funktionen in einer Datei zu definieren, auf die von außen zugegriffen werden kann, besteht darin, eine Funktion zu erstellen, die mehrere Funktionshandles zurückgibt. Mit anderen Worten, Sie würden Ihre definierende Funktion als [fun1,fun2,fun3]=defineMyFunctions Aufrufen, wonach Sie out1=fun1(inputs) usw. verwenden könnten.

36
Jonas

Die Antwort von SCFrench gefällt mir sehr gut - ich möchte darauf hinweisen, dass sie leicht geändert werden kann, um die Funktionen direkt mit der Funktion assignin in den Arbeitsbereich zu importieren. (Wenn ich das so mache, erinnere ich mich sehr an Pythons "import x from y" -Methode.)

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

Und dann so verwendet:

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1
23
Ru Hasha

In der gleichen Richtung wie die Antwort von SCFrench, aber mit einem eher C # -ähnlichen Dreh.

Ich würde (und mache es oft) eine Klasse mit mehreren statischen Methoden. Beispielsweise:

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end

Da die Methoden statisch sind, müssen Sie die Klasse nicht instanziieren. Sie rufen die Funktionen folgendermaßen auf:

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     
9
SmallJoeMan

Ich definiere mit Octave mehrere Funktionen in einer .m-Datei und benutze dann den Befehl in der .m-Datei, in der ich die Funktionen aus dieser Datei verwenden muss:

source("mycode.m");

Nicht sicher, ob dies mit Matlab verfügbar ist.

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'.
4
J.D.

Sie können Funktionen auch in einer Hauptdatei gruppieren, wobei die Hauptfunktion folgendermaßen aussieht:

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

% paste your subfunctions below ....
function str=subfun1
str='hello'

Dann würde der Aufruf von subfun1 so aussehen: str = main ('subfun1')

3
Thierry Dalon

Ab R2017b ist dies offiziell nicht möglich. Die relevante Dokumentation besagt, dass:

Programmdateien können mehrere Funktionen enthalten. Wenn die Datei nur Funktionsdefinitionen enthält, ist die erste Funktion die Hauptfunktion und die Funktion, die MATLAB mit dem Dateinamen verknüpft. Funktionen, die auf die Hauptfunktion oder den Skriptcode folgen, werden als lokale Funktionen bezeichnet. Lokale Funktionen sind nur in der Datei verfügbar.

Problemumgehungen, die in anderen Antworten vorgeschlagen wurden, können jedoch zu ähnlichen Ergebnissen führen.

0
Dev-iL