En MATLAB, ¿puedo tener un script y una definición de función en el mismo archivo?

81

Supongamos que tengo una función f()y quiero usarla my_file.m, que es un script.

  1. ¿Es posible tener la función definida en my_file.m?
  2. Si no es así, suponga que lo tengo definido en f.m. ¿Cómo lo llamo my_file.m?

Leí la documentación en línea, pero no estaba claro cuál es la mejor manera de hacerlo.

Viktor
fuente
4
Tenga en cuenta que puede poner funciones en scripts en Octave.
Jeremiah Willcock
2
Considere esta respuesta para conocer las formas de organizar su código stackoverflow.com/a/3569946/18775
Anton Daneyko
Muy recomendable echar un vistazo a stackoverflow.com/questions/17315586/…
URL87
4
La verdadera pregunta debería ser: ¿A quién en Mathworks me quejo para que arregle este ridículo error?
drysdam
3
A partir de MATLAB 2016b, las funciones se pueden definir en scripts. No estoy seguro de por qué esperaron 32 años para agregar esta característica bastante básica.
onewhaleid

Respuestas:

48

A partir de la versión R2016b, puede tener funciones locales en scripts , así:

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

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

Antes del lanzamiento de R2016b, el único tipo de función que podía definirse dentro de un script MATLAB era una función anónima . Por ejemplo:

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

Tenga en cuenta que las funciones anónimas se adaptan mejor a operaciones simples, ya que deben definirse en una sola expresión. Para funciones más complicadas, tendrá que definirlas en sus propios archivos, colocarlas en algún lugar de la ruta de MATLAB para que sean accesibles a su script y luego llamarlas desde su script como lo haría con cualquier otra función.

gnovice
fuente
37

La forma en que evito esta limitación es convertir mis scripts en funciones que no toman argumentos (si necesito variables del espacio de nombres global, las paso explícitamente en la función o uso "evalin" para tomarlas).

Luego, puede definir todas las funciones adicionales que necesita en el "script". Es un truco, pero lo he encontrado bastante poderoso en aquellos casos en los que necesito varias funciones no triviales.

EDITAR: Aquí hay un ejemplo simplista. Todo esto puede residir en un solo archivo.

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

function simg = smooth(img)
    simg = img / 5;
end
Juan
fuente
6
+1, realmente me molesta cuando veo claro todo; cierra todo; en la parte superior de un script de matlab. Si tiene tantas variables y gráficos flotando alrededor, no puede realizar un seguimiento de ellos, no está usando suficientes funciones.
Bi Rico
1
¿Puede incluir una implementación de muestra de este "truco"? Parece que no puedo entender cómo funciona esto.
James Taylor
1
Tenga en cuenta que un problema con este enfoque es que las variables nunca llegan a su espacio de trabajo cuando la función sale. Esto puede ser un problema si desea reproducir / mirar / usar esas variables al final del script.
chessofnerd
1
@chessofnerd Cuando tengo el problema, devuelvo las variables en la salida de la función o utilizo asignar.
Juan
1
@John, personalmente creo que es un poco molesto tener que devolver todas las variables individualmente en lugar de que aparezcan en el espacio de trabajo por sí mismas. Dicho eso, nunca había oído hablar de él assignin. ¡Esa es una función genial que podría estar usando más!
chessofnerd
19

Puede hacer algo como esto (asumiendo que su archivo tiene un nombre my_file.m):

function my_file
   %script here
end

function out = f(in)
   %function here
end

Si hace clic en el botón Ejecutar, la función my_filese ejecutará por defecto.

Oneiros
fuente
2
¿Es esto diferente de la respuesta de John?
sancho.s ReinstateMonicaCellio
7

1) No puede anidar una función dentro de un script.

2) Asegúrese de que fm esté en su ruta o en el directorio actual, y puede llamarlo como cualquier otra función.

Rica C
fuente
Puede anidar una función dentro de un script si sigue lo propuesto por @Oneiros. Incluso puede llamar a su función ( fen su ejemplo) desde su script ( my_fileen su ejemplo).
marcelocra
6

A partir de R2016b , puede definir funciones locales dentro de un script.

x = 1;
y = add1(x);

function z = add1(x)
    z = x + 1;
end
Suever
fuente
3

Implementé la solución de John y la encontré útil. Pero hay un par de advertencias (en Octave; Matlab posiblemente se comporte de manera similar):

  1. Si el código dentro de su función principal contiene clear allantes de usar la función auxiliar, no funcionará. En el archivo test3.m, comentar / descomentar clear allhace que el código funcione o no.

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

    Desde Parece que al ejecutar un script, hay una primera pasada donde se ejecuta el código fuera de las funciones (en este caso, no existe tal código), y las funciones definidas (en este caso, test3y myfunc) se agregan al espacio de trabajo. Una segunda pasada ejecutaría la función principal, que no encontraría myfuncsi clear allestá activa.

  2. Como lo señaló chessofnerd, las variables en su función principal no van al espacio de trabajo.

sancho.s ReinstateMonicaCellio
fuente
2

Puede tener muchas funciones en un archivo de muestra. Pero solo el primero puede actuar como función principal, cuando ejecuta el archivo. Otros se pueden utilizar simplemente en este archivo. Para alguna situación, desea definir una función grande. Puede separarlo en funciones más pequeñas y definirlo debajo.

Sin embargo, la forma más sencilla de encontrar la respuesta es intentarlo ~

Ayo dólares
fuente