Trong MATLAB, tôi có thể có tập lệnh và định nghĩa hàm trong cùng một tệp không?


81

Giả sử tôi có một hàm f()và tôi muốn sử dụng nó my_file.m, đó là một tập lệnh.

  1. Có thể có chức năng được xác định trong my_file.m?
  2. Nếu không, giả sử tôi đã xác định nó trong f.m. Làm cách nào để gọi nó vào my_file.m?

Tôi đã đọc tài liệu trực tuyến, nhưng không rõ đâu là cách tốt nhất để thực hiện việc này.


4
Lưu ý rằng bạn có thể đặt các chức năng trong tập lệnh trong Octave.
Jeremiah Willcock

2
Hãy xem xét câu trả lời này để biết cách sắp xếp mã stackoverflow.com/a/3569946/18775
Anton Daneyko

Rất khuyên bạn nên xem qua stackoverflow.com/questions/17315586/…
URL87

4
Câu hỏi thực sự nên là: Tôi phàn nàn với ai tại Mathworks để sửa lỗi vô lý này?
drysdam

3
Kể từ MATLAB 2016b, các chức năng có thể được định nghĩa trong các tập lệnh. Tôi không chắc tại sao họ đã đợi 32 năm để thêm tính năng khá cơ bản này.
onewhaleid

Câu trả lời:


48

Kể từ phiên bản R2016b, bạn có thể có các chức năng cục bộ trong các tập lệnh , như sau:

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

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

Trước khi phát hành R2016b, loại hàm duy nhất có thể được định nghĩa bên trong tập lệnh MATLAB là một hàm ẩn danh . Ví dụ:

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

Lưu ý rằng các hàm ẩn danh phù hợp hơn với các hoạt động đơn giản, vì chúng phải được xác định trong một biểu thức duy nhất. Đối với các hàm phức tạp hơn, bạn sẽ phải xác định chúng trong các tệp của riêng chúng, đặt chúng ở đâu đó trên đường dẫn MATLAB để làm cho chúng có thể truy cập vào tập lệnh của bạn, sau đó gọi chúng từ tập lệnh của bạn như cách bạn làm với bất kỳ hàm nào khác.


37

Cách tôi khắc phục hạn chế này là biến các tập lệnh của tôi thành các hàm không có đối số (nếu tôi cần các biến từ không gian tên chung, tôi hoặc chuyển chúng một cách rõ ràng vào hàm hoặc sử dụng "evalin" để lấy chúng.)

Sau đó, bạn có thể xác định tất cả các chức năng bổ sung mà bạn cần trong "script". Đó là một bản hack, nhưng tôi thấy nó khá mạnh trong những trường hợp tôi cần một số chức năng không tầm thường.

CHỈNH SỬA: Đây là một ví dụ đơn giản. Tất cả điều này có thể nằm trong một tệp duy nhất.

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

function simg = smooth(img)
    simg = img / 5;
end

6
+1, nó thực sự làm phiền tôi khi tôi thấy rõ ràng tất cả; đóng tất cả; ở đầu tập lệnh matlab. Nếu bạn có quá nhiều biến và biểu đồ trôi nổi xung quanh, bạn không thể theo dõi chúng thì bạn đang không sử dụng đủ hàm.
Bi Rico

1
Bạn có thể vui lòng bao gồm một triển khai mẫu của "hack" này? Tôi dường như không thể tìm ra cách hoạt động của nó.
James Taylor

1
Lưu ý một vấn đề với cách tiếp cận này là các biến không bao giờ đưa nó vào không gian làm việc của bạn khi hàm thoát. Đây có thể là một vấn đề nếu bạn muốn phát / xem / sử dụng các biến đó khi kết thúc tập lệnh.
flagsofnerd

1
@chessofnerd Khi gặp sự cố, tôi trả về các biến trong đầu ra của hàm hoặc tôi sử dụng hàm gán.
John

1
@John, cá nhân tôi cảm thấy hơi phiền khi phải trả lại tất cả các biến riêng lẻ thay vì để chúng tự hiển thị trong vùng làm việc. Điều đó nói rằng, tôi chưa bao giờ nghe nói về assignin. Đó là một chức năng gọn gàng mà tôi có thể sẽ sử dụng nhiều hơn nữa!
flagsofnerd

19

Bạn có thể làm điều gì đó như sau (giả sử tệp của bạn được đặt tên my_file.m):

function my_file
   %script here
end

function out = f(in)
   %function here
end

Nếu bạn nhấp vào nút chạy, chức năng my_filesẽ được thực thi như mặc định.


2
Điều này có khác với câu trả lời của John không?
sancho.s ReinstateMonicaCellio

7

1) Bạn không thể lồng một hàm bên trong tập lệnh.

2) Đảm bảo rằng fm nằm trên đường dẫn của bạn hoặc trong thư mục hiện tại và bạn có thể gọi nó giống như bất kỳ hàm nào khác.


Bạn có thể lồng một hàm bên trong tập lệnh nếu bạn làm theo những gì được đề xuất bởi @Oneiros. Bạn thậm chí có thể gọi hàm của mình ( ftrong ví dụ của anh ấy) từ trong tập lệnh của bạn ( my_filetrong ví dụ của anh ấy).
marcelocra

6

Kể từ R2016b , bạn có thể xác định các chức năng cục bộ trong một tập lệnh.

x = 1;
y = add1(x);

function z = add1(x)
    z = x + 1;
end

3

Tôi đã triển khai giải pháp của John và tôi thấy nó hữu ích. Nhưng có một vài lưu ý (trong Octave; Matlab có thể hoạt động tương tự):

  1. Nếu mã bên trong hàm chính của bạn chứa clear alltrước khi sử dụng hàm phụ, nó sẽ không hoạt động. Trong tệp test3.m, nhận xét / bỏ ghi chú clear alllàm cho mã hoạt động / không hoạt động.

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

    Từ Có vẻ như khi chạy một tập lệnh, có một đường chuyền đầu tiên mà mã bên ngoài các hàm được thực thi (trong trường hợp này, không có mã nào như vậy) và các hàm được xác định (trong trường hợp này test3myfunc) được thêm vào không gian làm việc. Một đường chuyền thứ hai sẽ thực thi hàm chính, hàm này sẽ không tìm thấy myfuncnếu clear allđang hoạt động.

  2. Như đã chỉ ra bởi flagsofnerd, các biến trong hàm chính của bạn không được chuyển đến vùng làm việc.


2

Bạn có thể có nhiều chức năng trong một tệp mẫu. Nhưng chỉ cái đầu tiên có thể hoạt động như một chức năng chính, khi bạn chạy tệp. Những người khác chỉ có thể được sử dụng trong tệp này. Đối với một số tình huống bạn muốn xác định một hàm lớn. Bạn có thể tách nó thành các hàm nhỏ hơn và xác định bên dưới nó.

Tuy nhiên, cách đơn giản nhất để tìm câu trả lời là thử ~

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.