2013-02-19 36 views
5

Có thể sử dụng chức năng ẩn danh làm chức năng sự kiện trong Matlab hay không. Những gì tôi muốn làm về cơ bản làCó thể sử dụng chức năng ẩn danh làm chức năng sự kiện khi giải quyết ODE trong Matlab

opt = odeset('Events', @(t,y) (deal(y(end)-t^2,1,0))); 
[T,Y] = ode45(@odefun,[tstart tend],y0,opt); 

Tuy nhiên, điều này trả về lỗi phàn nàn rằng số lượng đầu ra cần xử lý phải khớp chính xác. Có cách nào khác để làm cho hàm ẩn danh trả về nhiều đối số không?

Trả lời

0

Ngoài ra (điều này là rất muộn trong trò chơi để được thêm vào điều này, nhưng điều này làm tôi thất vọng). Đây là giải pháp có chức năng lồng nhau:

function [ dealfunchandle ] = dealwithit(arrayfunc) 
% Takes as input an event function of (t,z) that returns a 3 array (in same order as event syntax). 

    function [a, b, c] = dealfunc(t,z) 
     output = arrayfunc(t,z); 
     a = output(:,1); 
     b = output(:,2); 
     c = output(:,3); 
    end 

dealfunchandle = @dealfunc; 
end 

Chức năng này chỉ phải được viết một lần (tiện dụng nếu bạn phải sử dụng nhiều chức năng sự kiện khác nhau). Điều này có thể được sử dụng để tạo chức năng sự kiện ẩn danh trong mã như sau:

arrayfunc = @(t,y) [y(1), 0, 1]; 
events = dealwithit(arrayfunc); 

opts = odeset('Events', events); 

Và sau đó ode45 như bình thường.

1

Không, bạn không thể làm điều đó. Các hàm ẩn danh trong Matlab chỉ trả về một giá trị.

Thay vào đó, bạn có thể định nghĩa một wrapper mỏng xung quanh deal và vượt qua wrapper của bạn như một tay cầm:

function [a b c] = wrapper(t,y) 
    [a b c] = deal('some stop condition', 1, 0); 
end 

opt = odeset('Events', @wrapper); 

[T, Y] = ode45(@odefun, [tstart tend], y0, opt); 
+1

Vấn đề là tôi muốn tránh một hàm bao bọc. Sử dụng thỏa thuận, bạn CÓ THỂ thực sự có được hàm ẩn danh để trả về ba giá trị (vì thỏa thuận chỉ trả về các đối số của nó). Tuy nhiên, bộ giải mã ODE dường như đang mong đợi một số giá trị trả về khác nhau trong khi giao dịch phải được khớp chính xác. –

+0

Bạn hoàn toàn đúng. Tôi sẽ có một cái nhìn khác khi tôi nhận được một sự thay đổi. Tôi nghi ngờ rằng nó có thể liên quan đến thực tế là 'ode45' chuyển một số biến đối số tới trình xử lý sự kiện. –

+0

Tôi nghi ngờ, đó là do chức năng được đánh giá với một đầu ra duy nhất trong 'odeevents' và với một bộ ba đầu ra trong' odezero'. Tuy nhiên, số lượng đầu ra arg của một hàm ẩn danh là một hoặc * ba, nhưng nó không thể xử lý cả hai. – embert

2

tôi nhận thấy bài này tìm kiếm câu trả lời cho những câu hỏi tương tự. Điều này có nghĩa là đối với một số người, câu hỏi có thể vẫn hợp lệ. Vì cuối cùng tôi đã tự mình tìm ra giải pháp, tôi muốn đưa ra một câu trả lời "lỗi thời".

Thực ra, có - có thể nhưng không đơn giản. Hãy thử điều này:

evnt_fun = @ (t, f) subsref ({'một số điều kiện dừng', 1, 0}, struct ('type', '{}', 'subs', {{':'} }));

Tôi không thể kiểm tra đầy đủ tính tương thích ngược của mã. Tuy nhiên, nó hoạt động với R2011 và các phiên bản MATLAB sau này.

Các vấn đề liên quan