Czy w programie MATLAB mogę mieć skrypt i definicję funkcji w tym samym pliku?

82

Załóżmy, że mam funkcję f()i chcę jej użyć my_file.m, czyli skrypt.

  1. Czy można mieć funkcję zdefiniowaną w my_file.m?
  2. Jeśli nie, załóżmy, że mam to zdefiniowane w f.m. Jak mam to zgłosić my_file.m?

Przeczytałem dokumentację online, ale nie było jasne, jaki jest najlepszy sposób, aby to zrobić.

Viktor
źródło
4
Zauważ, że możesz umieścić funkcje w skryptach w Octave.
Jeremiah Willcock
2
Rozważ tę odpowiedź, aby
dowiedzieć
Bardzo polecam zajrzeć na stackoverflow.com/questions/17315586/ ...
URL87
4
Prawdziwe pytanie powinno brzmieć: komu w Mathworks mam się skarżyć, żeby naprawić ten śmieszny błąd?
drysdam
3
Od MATLAB 2016b funkcje można definiować w skryptach. Nie jestem pewien, dlaczego czekali 32 lata, aby dodać tę dość podstawową funkcję.
onewhaleid

Odpowiedzi:

49

Od wersji R2016b możesz mieć lokalne funkcje w skryptach , na przykład:

data = 1:10;            % A vector of data
squaredData = f(data);  % Invoke the local function

function y = f(x)
  y = x.^2;
end

Przed wydaniem R2016b jedynym typem funkcji, który można było zdefiniować w skrypcie MATLAB, była funkcja anonimowa . Na przykład:

data = 1:10;            % A vector of data
f = @(x) x.^2;          % An anonymous function
squaredData = f(data);  % Invoke the anonymous function

Zwróć uwagę, że funkcje anonimowe lepiej nadają się do prostych operacji, ponieważ muszą być zdefiniowane w jednym wyrażeniu. W przypadku bardziej skomplikowanych funkcji będziesz musiał zdefiniować je we własnych plikach, umieścić je gdzieś na ścieżce MATLAB, aby były dostępne dla twojego skryptu, a następnie wywołać je ze swojego skryptu, tak jak każdą inną funkcję.

gnovice
źródło
37

Sposobem na obejście tego ograniczenia jest przekształcenie moich skryptów w funkcje, które nie pobierają żadnych argumentów (jeśli potrzebuję zmiennych z globalnej przestrzeni nazw, albo jawnie przekazuję je w funkcji, albo używam „evalin”, aby je pobrać).

Następnie możesz zdefiniować wszystkie dodatkowe funkcje, których potrzebujesz w „skrypcie”. To hack, ale odkryłem, że jest dość potężny w przypadkach, w których potrzebuję kilku nietrywialnych funkcji.

EDYCJA: Oto uproszczony przykład. Wszystko to może znajdować się w jednym pliku.

function [] = myScriptAsAFunction()
   img = randn(200);
   img = smooth(img);
   figure(1);
   imagesc(img);
   axis image;
   colorbar;
end

function simg = smooth(img)
    simg = img / 5;
end
Jan
źródło
6
+1, naprawdę mnie denerwuje, gdy widzę wszystko jasne; zamknij wszystko; u góry skryptu Matlab. Jeśli masz tak wiele zmiennych i wykresów krążących wokół, nie możesz ich śledzić, nie używasz wystarczającej liczby funkcji.
Bi Rico,
1
Czy możesz dołączyć przykładową implementację tego „hackowania”? Nie wiem, jak to działa.
James Taylor
1
Zauważ jeden problem z tym podejściem, że zmienne nigdy nie trafiają do twojego obszaru roboczego, gdy funkcja kończy działanie. Może to stanowić problem, jeśli chcesz odtwarzać / przeglądać / używać tych zmiennych na końcu skryptu.
chessofnerd
1
@chessofnerd Kiedy mam problem, zwracam zmienne w danych wyjściowych funkcji lub używam assignin.
Jan
1
@John, osobiście uważam, że to trochę uciążliwe, gdy muszę zwracać wszystkie zmienne indywidualnie, zamiast pokazywać je samodzielnie w miejscu pracy. To powiedziawszy, nigdy o tym nie słyszałem assignin. To fajna funkcja, której mogę używać częściej!
chessofnerd
19

Możesz zrobić coś takiego (zakładając, że twój plik ma nazwę my_file.m):

function my_file
   %script here
end

function out = f(in)
   %function here
end

Jeśli klikniesz przycisk Uruchom, funkcja my_filezostanie wykonana domyślnie.

Oneiros
źródło
2
Czy różni się to od odpowiedzi Johna?
sancho.s ReinstateMonicaCellio
7

1) Nie możesz zagnieździć funkcji wewnątrz skryptu.

2) Upewnij się, że fm znajduje się na Twojej ścieżce lub w bieżącym katalogu i możesz go wywołać jak każdą inną funkcję.

Bogaty C.
źródło
Możesz zagnieździć funkcję wewnątrz skryptu, jeśli zastosujesz się do tego, co proponuje @Oneiros. Możesz nawet wywołać swoją funkcję ( fw jego przykładzie) z poziomu skryptu ( my_filew jego przykładzie).
marcelocra
7

Od R2016b można definiować funkcje lokalne.

x = 1;
y = add1(x);

function z = add1(x)
    z = x + 1;
end
Suever
źródło
3

Wdrożyłem rozwiązanie autorstwa Johna i uznałem je za przydatne. Ale jest kilka zastrzeżeń (w Octave; Matlab prawdopodobnie zachowuje się podobnie):

  1. Jeśli kod wewnątrz funkcji głównej zawiera clear allprzed użyciem funkcji pomocniczej, nie zadziała. test3.mKomentowanie / usuwanie komentarzy w pliku clear allpowoduje, że kod działa / nie działa.

    function [] = test3()
      %clear all
      a = myfunc( 1 );
      a
    endfunction;
    
    %---------------------------------
    % Auxiliary functions
    
    function retval = myfunc( a )
      retval = 2 * a;
    endfunction;
    

    Z Wydaje się, że po uruchomieniu skryptu jest pierwsze przejście, w którym wykonywany jest kod poza funkcjami (w tym przypadku nie ma takiego kodu), a funkcje zdefiniowane (w tym przypadku test3i myfunc) są dodawane do obszaru roboczego. Drugi przebieg wykonywałby główną funkcję, która nie znajdowałaby, myfuncgdyby clear allbyła aktywna.

  2. Jak wskazał chessofnerd, po wyjęciu z pudełka zmienne w twojej głównej funkcji nie trafiają do obszaru roboczego.

sancho.s ReinstateMonicaCellio
źródło
2

Przykładowy plik może zawierać wiele funkcji. Ale tylko pierwsza z nich może działać jako główna funkcja podczas uruchamiania pliku. Inne mogą być używane tylko w tym pliku. W niektórych sytuacjach chcesz zdefiniować dużą funkcję. Możesz podzielić go na mniejsze funkcje i zdefiniować poniżej.

Jednak najprostszym sposobem znalezienia odpowiedzi jest wypróbowanie ~

Ayo Dollars
źródło