2009-04-28 39 views
7

Tôi có một chức năng trong MATLAB có chức năng khác như một đối số. Tôi muốn bằng cách nào đó xác định một chức năng nội tuyến piecewise có thể được thông qua nhập Có phải bằng cách nào đó có thể trong MATLAB?Làm thế nào tôi có thể tạo một hàm nội tuyến theo thứ tự trong MATLAB?

Chỉnh sửa: Các chức năng tôi muốn đại diện là:

f(x) = { 1.0, 0.0 <= x <= 0.5, 
     -1.0, 0.5 < x <= 1.0 

where 0.0 <= x <= 1.0 

Trả lời

12

Bạn thực sự đã định nghĩa một hàm piecewise với ba điểm ngắt, tức là tại [0, 0.5, 1]. Tuy nhiên, bạn chưa xác định giá trị của hàm bên ngoài các ngắt. (Bằng cách này, tôi đã sử dụng thuật ngữ "break" ở đây, bởi vì chúng tôi đang thực sự xác định một dạng spline đơn giản, một spline hằng số. Tôi cũng có thể sử dụng cụm từ, một từ phổ biến khác trong thế giới của splines.)

Nếu bạn hoàn toàn biết rằng bạn sẽ không bao giờ đánh giá hàm bên ngoài [0,1], thì không có vấn đề gì. Vì vậy, sau đó chỉ cần xác định một chức năng piecewise với ONE điểm break, tại x = 0,5. Cách đơn giản để định nghĩa một hàm hằng số piecewise như của bạn là sử dụng toán tử logic. Do đó phép thử (x> 0.5) trả về một hằng số, bằng 0 hoặc 1. Bằng cách mở rộng và dịch kết quả đó, thật dễ dàng để tạo ra một hàm thực hiện những gì bạn muốn.

constfun = @(x) (x > 0.5)*2 - 1; 

Chức năng nội tuyến thực hiện tương tự nhưng chức năng nội tuyến rất chậm so với chức năng ẩn danh. Tôi thực sự khuyên bạn nên sử dụng biểu mẫu ẩn danh. Để kiểm tra, hãy thử cách này:

infun = inline('(x > 0.5)*2 - 1','x'); 
x = 0:.001:1; 

tic,y = constfun(x);toc 
Elapsed time is 0.002192 seconds. 

tic,y = infun(x);toc 
Elapsed time is 0.136311 seconds. 

Có, hàm nội tuyến mất nhiều thời gian hơn để thực thi hơn biểu mẫu ẩn danh.

Một vấn đề với dạng hằng số piecewise đơn giản mà tôi đã sử dụng ở đây là khó mở rộng khi bạn có nhiều điểm ngắt hơn. Ví dụ, giả sử bạn muốn định nghĩa một hàm có ba giá trị khác nhau tùy thuộc vào khoảng thời gian mà điểm rơi vào? Trong khi điều này có thể được thực hiện quá với việc sử dụng sáng tạo các bài kiểm tra, cẩn thận chuyển và mở rộng chúng, nó có thể trở nên khó chịu. Ví dụ: cách xác định hàm piecewise trả về

-1 when x < 0, 
2 when 0 <= x < 1, 
1 when 1 <= x 

Một giải pháp là sử dụng đơn vị Heaviside chức năng. Đầu tiên, hãy định nghĩa một hàm Heaviside đơn vị cơ bản.

H = @(x) (x >= 0); 

Hàm piecewise của chúng tôi bây giờ có nguồn gốc từ H (x).

P = @(x) -1 + H(x)*3 + H(x-1)*(-1); 

Thấy rằng có ba phần với P (x). Thuật ngữ đầu tiên là điều xảy ra cho x bên dưới điểm ngắt đầu tiên. Sau đó, chúng tôi thêm vào một phần có hiệu lực trên không. Cuối cùng, mảnh thứ ba thêm vào trong một bù đắp khác ở trên x == 1. Nó có thể dễ dàng đủ âm mưu.

ezplot(P,[-3,3]) 

Có thể dễ dàng tạo ra các splines phức tạp hơn từ đầu. Se rằng tôi đã gọi nó là xây dựng một spline một lần nữa. Thực sự, đây là nơi chúng tôi có thể dẫn đầu. Trong thực tế, đây là nơi mà điều này dẫn đến. Một spline là một chức năng piecewise, cẩn thận gắn với nhau tại một danh sách các hải lý hoặc phá vỡ điểm. Splines nói riêng thường có các đơn đặt hàng được chỉ định về tính liên tục, ví dụ, một spline khối sẽ có hai lần khác nhau (C2) trong các lần ngắt. Ngoài ra còn có các hàm khối piecewise chỉ có các hàm C1. Quan điểm của tôi trong tất cả những điều này là tôi đã mô tả một điểm khởi đầu đơn giản để tạo thành bất kỳ chức năng tham chiếu nào. Nó hoạt động khá tốt cho các spline đa thức, mặc dù có thể có một chút wee toán học cần thiết để chọn các hệ số của các hàm này.

Một cách khác để tạo hàm này là một đa thức riêng biệt rõ ràng. Trong MATLAB, chúng ta có hàm mkpp ít được biết đến. Hãy dùng thử ...

pp = mkpp([0 .5 1],[1;-1]); 

Nếu bạn có hộp công cụ splines, thì fnplt sẽ vẽ trực tiếp cho bạn. Giả sử bạn không có TB đó, hãy thực hiện việc này:

ppfun = @(x) ppval(pp,x); 
ezplot(ppfun,[0 1]) 

Nhìn lại cuộc gọi mkpp, nó khá đơn giản sau khi tất cả. Đối số đầu tiên là danh sách các điểm ngắt trong đường cong (dưới dạng vectơ ROW). Đối số thứ hai là một vector COLUMN, với giá trị hằng số piecewise đường cong sẽ tiếp tục trong hai khoảng thời gian được xác định giữa các khoảng ngắt.

Một vài năm trước, tôi đã đăng một tùy chọn khác, piecewise_eval. Nó có thể được tải xuống từ trao đổi tập tin MATLAB Central. Đây là một hàm cho phép người dùng chỉ định một hàm piecewise thuần túy như một danh sách các điểm ngắt, cùng với các phần chức năng giữa các lần ngắt đó. Như vậy, đối với một chức năng với một break duy nhất tại x = 0,5, chúng tôi sẽ làm điều này:

fun = @(x) piecewise_eval(x,0.5,{1,-1}); 

Xem rằng số thứ ba cung cấp giá trị sử dụng trong mỗi phân đoạn, mặc dù những mảnh không cần phải là chức năng hoàn toàn không thay đổi. Nếu bạn muốn hàm trả về có lẽ là một NaN nằm ngoài khoảng thời gian quan tâm, điều này cũng dễ thực hiện.

fun = @(x) piecewise_eval(x,[0 0.5 1],{NaN,1,-1,NaN}); 

Điểm của tôi trong tất cả chuyến tham quan khá dài này là hiểu hàm piecewise là gì và một số cách để tạo một hàm trong MATLAB.

+0

Thank bạn! Tôi có một số kinh nghiệm với các phép đa thức và đa thức. Tôi không biết có một chức năng để làm cho họ trong Matlab (tôi khá mới với nó.), cũng như tôi đã không nghĩ đến chức năng của tôi như một cột sống với đa thức ở mức độ không. Cảm ơn tất cả điều này! Tôi nên chỉ ra rằng chức năng ẩn danh của bạn flip flops các giá trị được đăng trong ví dụ của tôi, nhưng tôi hiểu logic tuy nhiên. Cảm ơn! – Scott

4

Nếu bạn thực sự muốn thực hiện một chức năng nội tuyến (như trái ngược với một anonymous function), thì sau đây có lẽ sẽ là cách đơn giản nhất:

f = inline('2.*(x <= 0.5)-1'); 

Tuy nhiên, như đã chỉ ra trong các câu trả lời khác, chức năng ẩn danh được thường được sử dụng và có hiệu quả hơn:

f = @(x) (2.*(x <= 0.5)-1); 
5

Thật không may, MATLAB không có một nhà điều hành ternary mà sẽ làm cho các loại điều này dễ dàng hơn, nhưng để mở rộng một chút về cách tiếp cận gnovice, bạn có thể tạo ra một chức năng vô danh như vậy:

fh = @(x) (2 .* (x <= 0.5) - 1) 

Nói chung, vô danh các chức năng mạnh hơn các đối tượng hàm nội tuyến, và cho phép bạn tạo các bao đóng, vv ..

1

Tôi chỉ phải giải quyết vấn đề đó và tôi nghĩ điều dễ nhất cần làm là sử dụng các chức năng ẩn danh. Giả sử rằng bạn có một chức năng piecewise:

when x<0 : x^2 + 3x 
when 0<=x<=4: e^x 
when x>4 : log(x) 

lần đầu tiên tôi muốn xác định mặt nạ hợp lý cho từng vùng piecewise:

PIECE1 = @(x) x<0 
PIECE2 = @(x) x>=0 & x<=4 
PIECE3 = @(x) x>4 

Sau đó, tôi muốn đưa tất cả chúng với nhau:

f = @(x) PIECE1(x).*(x.^2+3*x) + PIECE2(x).*exp(x) + PIECE3(x).*log(x) 

x = -10:.1:10 
figure; 
plot(x,f(x)) 
Các vấn đề liên quan