È ansible definire più di una funzione per file in MATLAB e accedervi da tale file?

Quando stavo studiando per il mio corso di laurea in EE, MATLAB richiedeva che ogni funzione fosse definita nel suo file, anche se era un one-liner.

Sto studiando per una laurea ora e devo scrivere un progetto in MATLAB. Questo è ancora un requisito per le versioni più recenti di MATLAB?

Se è ansible inserire più di una funzione in un file, esistono restrizioni a questo? Ad esempio, è ansible accedere a tutte le funzioni nel file dall’esterno del file o solo alla funzione che ha lo stesso nome del file?

Nota: sto usando la versione MATLAB R2007b.

La prima funzione in un m-file (cioè la funzione principale ), viene invocata quando viene chiamato quel m-file. Non è necessario che la funzione principale abbia lo stesso nome del file m, ma per chiarezza dovrebbe . Quando la funzione e il nome del file differiscono, è necessario utilizzare il nome del file per chiamare la funzione principale.

Tutte le funzioni successive nel m-file, chiamate funzioni locali (o “sottofunzioni” nella terminologia precedente), possono essere chiamate solo dalla funzione principale e da altre funzioni locali in tale m-file. Le funzioni in altri m-file non possono chiamarle. A partire da R2016b, è ansible aggiungere anche funzioni locali agli script , sebbene il comportamento dell’ambito sia ancora lo stesso (ovvero possono essere richiamati solo dallo script).

Inoltre, è anche ansible dichiarare funzioni all’interno di altre funzioni. Queste sono chiamate funzioni annidate e possono essere richiamate solo all’interno della funzione che sono annidate. Possono anche avere accesso alle variabili nelle funzioni in cui sono annidati, il che li rende piuttosto utili anche se un po ‘complicati da usare.

Più spunti di riflessione …

Esistono alcuni modi per aggirare il normale comportamento dell’ambito della funzione descritto sopra, come il passaggio di handle di funzione come argomenti di output come menzionato nelle risposte di SCFrench e Jonas (che, a partire da R2013b, è facilitato dalla funzione localfunctions ). Tuttavia, non suggerirei di prendere l’abitudine di ricorrere a trucchi del genere, poiché ci sono probabilmente molte migliori opzioni per l’organizzazione di funzioni e file.

Ad esempio, supponiamo di avere una funzione principale A in un m-file Am , insieme alle funzioni locali D , E e F Ora diciamo che avete altre due funzioni correlate B e C nei m-file Bm e Cm , rispettivamente, che volete anche essere in grado di chiamare D , E e F Ecco alcune opzioni che hai:

  • Metti D , E ed F ciascuno nei propri m-files separati, permettendo a qualsiasi altra funzione di chiamarli. Lo svantaggio è che l’ambito di queste funzioni è ampio e non è limitato solo a A , B e C , ma il vantaggio è che questo è abbastanza semplice.

  • Crea un defineMyFunctions m defineMyFunctions (come nell’esempio di Jonas) con D , E , e F come funzioni locali e una funzione principale che restituisce semplicemente la funzione che le gestisce. Ciò consente di mantenere D , E e F nello stesso file, ma non fa nulla per quanto riguarda l’ambito di queste funzioni poiché qualsiasi funzione che può chiamare defineMyFunctions può richiamarle. Dovresti anche preoccuparti di passare i manici delle funzioni in giro come argomenti per assicurarti di averli dove ti servono.

  • Copia D , E e F in Bm e Cm come funzioni locali. Ciò limita l’ambito del loro utilizzo solo a A , B e C , ma rende l’aggiornamento e la manutenzione del tuo codice un incubo perché hai tre copie dello stesso codice in luoghi diversi.

  • Usa funzioni private ! Se hai A , B e C nella stessa directory, puoi creare una sottodirectory chiamata private e posizionare D , E e F lì, ciascuno come un m-file separato. Questo limita il loro scope in modo che possano essere richiamati solo dalle funzioni nella directory immediatamente sopra (ad esempio A , B e C ) e li tiene insieme nello stesso posto (ma ancora diversi m-files):

     myDirectory/ Am Bm Cm private/ Dm Em Fm 

Tutto questo va al di fuori della portata della tua domanda, ed è probabilmente più dettagliato del necessario, ma ho pensato che potrebbe essere utile toccare la preoccupazione più generale di organizzare tutti i tuoi m-file. 😉

Generalmente, la risposta alla tua domanda è no, non puoi definire più di una funzione visibile esternamente per file. È ansible restituire gli handle di funzione alle funzioni locali, tuttavia, e un modo conveniente per farlo è di renderli campi di una struttura. Ecco un esempio:

 function funs = makefuns [email protected]; [email protected]; end function y=fun1(x) y=x; end function z=fun2 z=1; end 

Ed ecco come potrebbe essere usato:

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

L’unico modo per avere più funzioni accessibili separatamente in un singolo file è definire METODI STATICI usando la programmazione orientata agli oggetti . Dovresti accedere alla funzione come myClass.static1() , myClass.static2() ecc.

La funzionalità OOP è ufficialmente supportata solo da R2008a, quindi, a meno che tu non voglia utilizzare la vecchia syntax OOP non documentata, la risposta per te è no, come spiegato da @gnovice .

MODIFICARE

Un altro modo per definire più funzioni all’interno di un file accessibile dall’esterno è creare una funzione che restituisca più handle di funzione . In altre parole, chiameresti la tua funzione di definizione come [fun1,fun2,fun3]=defineMyFunctions , dopodiché potresti usare out1=fun1(inputs) ecc.

Mi piace molto la risposta di SCFrench – vorrei sottolineare che può essere facilmente modificato per importare le funzioni direttamente nello spazio di lavoro utilizzando la funzione assignin. (Farlo mi ricorda molto il modo in cui Python “importa x da y” di fare le cose)

 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 

E poi usato così:

 >> makefuns ans = Done importing functions to workspace >> fun1(123) ans = 123 >> fun2() ans = 1 

Sulla stessa falsariga della risposta di SCFrench, ma con uno spin in più stile C #.

Vorrei (e spesso faccio) creare una class contenente più metodi statici. Per esempio:

 classdef Statistics methods(Static) function val = MyMean(data) val = mean(data); end function val = MyStd(data) val = std(data); end end end 

Poiché i metodi sono statici, non è necessario instradiare la class. Chiami le funzioni come segue:

 data = 1:10; mean = Statistics.MyMean(data); std = Statistics.MyStd(data); 

Definisco più funzioni in un file .m con Octave e poi utilizzo il comando dal file .m in cui ho bisogno di utilizzare le funzioni da quel file:

 source("mycode.m"); 

Non sono sicuro se questo è disponibile con 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'. 

Puoi anche raggruppare le funzioni in un file principale insieme alla funzione principale simile alla seguente:

 function [varargout] = main( subfun, varargin ) [varargout{1:nargout}] = feval( subfun, varargin{:} ); % paste your subfunctions below .... function str=subfun1 str='hello' 

Quindi chiamare subfun1 sarebbe simile a questo: str = main (‘subfun1’)

A partire da R2017b, questo non è ufficialmente ansible. La documentazione pertinente afferma che:

I file di programma possono contenere più funzioni. Se il file contiene solo definizioni di funzione, la prima funzione è la funzione principale ed è la funzione che MATLAB associa al nome del file. Le funzioni che seguono la funzione principale o il codice di script sono chiamate funzioni locali. Le funzioni locali sono disponibili solo all’interno del file.

Tuttavia, soluzioni alternative suggerite in altre risposte possono ottenere qualcosa di simile.