PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Matlab-Simulink & Labview & 20-Sim (http://www.picvietnam.com/forum/forumdisplay.php?f=47)
-   -   lệnh fsolve trong Matlab (http://www.picvietnam.com/forum/showthread.php?t=1871)

conso0 03-01-2008 12:56 AM

lệnh fsolve trong Matlab
 
Có bác nào thạo "fsolve" ko giúp em voi!Em đang làm đồ án thì gặp thằng này đang mắc.
ví dụ:có hàm vd1
function F=vd1(q)

x=-10:0.1:10;

a0=1;
b0=-2;
c0=3;

fx=a0*x.^2+ b0*x + c0;
df=diff(fx);
a=df/sqrt(df.^2+1);
l0=490;
l1=250;
l2=150;
l3=200;


F=[ x+l2-l3*sin(q(1)+q(2)-q(3))-l0*cos(q(1)+q(2))+l1*cos(q(2))];
[ fx +l3*sin(q(1)+q(2)-q(3))+l0*sin(q(1)+q(2))-l1*sin(q(2))];
[ a-cos(q(1)+q(2)-q(3))];
Trong cửa sổ Matlab :q0=[0.94910999;4.804079037;0.52999628]
options=optimset('Display','iter');
[q,fval] = fsolve(@vd1,q0,options)
Vấn đề là nghiệm ko hội tụ,Bác nào có điều kiện giúp em với nhe!Thank!

picvendor 03-01-2008 03:22 PM

Hình như cú pháp hàm F của bạn viết sai:

Trích:

F=[ x+l2-l3*sin(q(1)+q(2)-q(3))-l0*cos(q(1)+q(2))+l1*cos(q(2))];
[ fx +l3*sin(q(1)+q(2)-q(3))+l0*sin(q(1)+q(2))-l1*sin(q(2))];
[ a-cos(q(1)+q(2)-q(3))];
Viết kiểu này nghĩa là 2 dòng dưới không có giá trị gì. Hàm F ở đây được gán là một vector có cùng số cột với x: F=[ x+l2-l3*sin(q(1)+q(2)-q(3))-l0*cos(q(1)+q(2))+l1*cos(q(2))];

Như vậy lệnh fsolve giải bài toán là một hệ chừng 100 phương trình, với chỉ có 3 ẩn số -> rất dễ rơi vào tình huống vô nghiệm.
---

Tôi đoán bạn đang giải bài toán kiểu:
F = [F1; F2; F3] trong đó F1, F2, F3 đều là số scalar.

Nhưng vì trong function vd1, ngay từ đầu bạn quy định x=-10:0.1:10 nên nó đã là 1 vector, làm cho F1 biến thành vector.

Giờ bạn cần tránh việc đặt x là 1 vector trong function vd1, hoặc làm sao đó để F1, F2, F3 không còn là vector (tùy vào yêu cầu bài toán của bạn).

conso0 09-01-2008 09:31 PM

Trích:

Nguyên văn bởi picvendor (Post 13679)
Hình như cú pháp hàm F của bạn viết sai:



Viết kiểu này nghĩa là 2 dòng dưới không có giá trị gì. Hàm F ở đây được gán là một vector có cùng số cột với x: F=[ x+l2-l3*sin(q(1)+q(2)-q(3))-l0*cos(q(1)+q(2))+l1*cos(q(2))];

Như vậy lệnh fsolve giải bài toán là một hệ chừng 100 phương trình, với chỉ có 3 ẩn số -> rất dễ rơi vào tình huống vô nghiệm.
---

Tôi đoán bạn đang giải bài toán kiểu:
F = [F1; F2; F3] trong đó F1, F2, F3 đều là số scalar.

Nhưng vì trong function vd1, ngay từ đầu bạn quy định x=-10:0.1:10 nên nó đã là 1 vector, làm cho F1 biến thành vector.

Giờ bạn cần tránh việc đặt x là 1 vector trong function vd1, hoặc làm sao đó để F1, F2, F3 không còn là vector (tùy vào yêu cầu bài toán của bạn).

Cám ơn bác "picvendor" đã quan tâm trả lời.Thực chất đây là 1 bài toán động học ngược,em cho quỹ đạo trước và các thông số ban đầu:q1=0.94910999;q2=4.804079037;q3=0.52999628 để tìm ra quỹ đạo (các góc tại khớp).Em giới hạn x nằm trong khoảng [-10,10].
Nếu bác "picvendor" từng dùng fsolve rồi thì có thể nói rõ hơn về cách dùng nó cho em và anh em trong diễn đàn được ko? Em cảm ơn rất nhiều.

picvendor 10-01-2008 12:01 AM

Cách dùng fsolve thì trong Matlab Help có mô tả kỹ rồi: http://www.math.colostate.edu/manual...im/fsolve.html

Viết Matlab theo một ví dụ hướng dẫn của họ thì mình thấy nó chạy thế nào:

Trích:

First, write an M-file that computes F, the values of the equations at x:

function F = myfun(x)
F = [2*x(1) - x(2) - exp(-x(1));
-x(1) + 2*x(2) - exp(-x(2))];

Next, call an optimization routine:

x0 = [-5; -5]; % Make a starting guess at the solution
options=optimset('Display','iter'); % Option to display output
[x,fval] = fsolve('myfun',x0,options) % call optimizer
Ý nghĩa của lệnh fsolve là dùng để giải một hệ phương trình phi tuyến, bằng một giải thuật lặp nào đó. Khi bạn quy định hàm số:

function F = myfun(x)
...
F = [ F1(x); F2(x); F3(x)]

chẳng hạn là đầu ra F có 3 thành phần, thì tức là muốn giải hệ 3 phương trình:
F1(x) = 0;
F2(x) = 0;
F3(x) = 0;

mà ở đó biến x cũng có thể là nhiều chiều (ở bài toán của bạn thì ký hiệu là q, có 3 chiều).

Phải nói rằng đây là công cụ rất mạnh của bộ Optimization toolbox, đứng trên cách nhìn tối ưu hóa để giải phương trình: thực hiện giải thuật lặp để tìm nghiệm x sao cho F(x) gần 0 nhất, tức là tối ưu hóa trị tuyệt đối của F(x).
---

Trong bài toán của bạn, q là biến số, nhưng x là gì và tại sao x có thể thay đổi trong khoảng [-10; 10]? Nếu x cũng là biến số thì bạn ghép nó thành q4, nếu không thì bạn cần gán x là giá trị cụ thể trước khi chạy lệnh fsolve.

conso0 10-01-2008 05:32 PM

Trích:

Nguyên văn bởi picvendor (Post 13792)
Trong bài toán của bạn, q là biến số, nhưng x là gì và tại sao x có thể thay đổi trong khoảng [-10; 10]? Nếu x cũng là biến số thì bạn ghép nó thành q4, nếu không thì bạn cần gán x là giá trị cụ thể trước khi chạy lệnh fsolve.

Chào bác "picvendor" ! Nếu xét theo 1 khía cạnh nòa đó thì x là 1 biến nhưng lại là biến trong hàm f(x) cơ (tức là 1 đường parabol em đã phải đặt trước,nếu bác đã từng giả bài toán động học tay máy thì đây chính là quỹ đạo của tay máy).Em giới hạn x=[-10;10] 1 cách ví dụ thôi khoảng này cũng có thể thay đổi,nhưng bắt buộc phải giới hạn vì yêu cầu giới hạn không gian làm việc của tay máy. Nhưng x ko thể là 1 giá trị vì đường parabol sẽ là tập hợp của vô số cặp điểm (x[i];fx[i]).------>Đó là cái khó
Bác "picvendor" chắc đã từng làm việc với lệnh Fsolve vậy bác có thể cho em hỏi ý nghĩa của thông báo lỗi sau được ko?
Error in ==> fsolve at 180
fuser = feval(funfcn{3},x,varargin{:});
Cảm ơn rất nhiều!
Email của em:ld_canh7384@yahoo.com rất mong sự giúp đỡ của các cao thủ.

picvendor 10-01-2008 11:08 PM

Bạn gửi file mô tả bài toán động học và cách bạn giải đi, tôi chưa giải bài toán này, nhưng nghe cũng thấy thú vị. Bạn hãy trình bày kỹ các phương trình và cách giải của bạn, tôi sẽ giúp bạn giải quyết bằng chương trình Matlab.
(bạn viết ra giấy rồi chụp hình gửi lên cũng được)

Trích:

Error in ==> fsolve at 180
fuser = feval(funfcn{3},x,varargin{:});
Thông báo này chỉ có nghĩa là trong mã lệnh của fsolve có gọi lệnh feval, và có một lỗi nào đó xảy ra ở feval. Nói chung là khó debug, thường liên quan đến việc dùng nhầm syntax, hoặc tính toán các ma trận không khớp số chiều.

conso0 11-01-2008 10:35 PM

Chân thành cảm ơn sự giúp đỡ của bác "Picvendor"
 
1 Attachment(s)
Trích:

Nguyên văn bởi picvendor (Post 13810)
Bạn gửi file mô tả bài toán động học và cách bạn giải đi, tôi chưa giải bài toán này, nhưng nghe cũng thấy thú vị. Bạn hãy trình bày kỹ các phương trình và cách giải của bạn, tôi sẽ giúp bạn giải quyết bằng chương trình Matlab.
(bạn viết ra giấy rồi chụp hình gửi lên cũng được)

ok! Em tạm thời gửi bác phần bài toán động học,nếu có gì thiếu sót bác cứ nói lại với em
Thật tiếc file .avi của em bị mất rồi ko thì em gửi luôn cho Anh tham khảo

picvendor 12-01-2008 05:43 AM

Tôi tách thành 3 file:

%%%---vd1_init.m---%%%

% initialize function f(x) and calculate df/dx

x=-10:0.1:10;

a0=1;
b0=-2;
c0=3;

fx=a0*x.^2+ b0*x + c0;
df=[diff(fx) 0]; %so that df has the same length with f
a=df./sqrt(df.^2+1);
%%%---%%%

%%%---vd1.m---%%%

function F=vd1(q,t,fxt,at)

% bring the commented part out of this function
% x=-10:0.1:10;
%
a0=1;
b0=-2;
c0=3;
%
% fx=a0*x.^2+ b0*x + c0;
% df=diff(fx);
% a=df/sqrt(df.^2+1);
l0=490;
l1=250;
l2=150;
l3=200;


F=[t+l2-l3*sin(q(1)+q(2)-q(3))-l0*cos(q(1)+q(2))+l1*cos(q(2));...
fxt+l3*sin(q(1)+q(2)-q(3))+l0*sin(q(1)+q(2))-l1*sin(q(2));...
at-cos(q(1)+q(2)-q(3))];
%%%---%%%

%%% ---vd1_run.m--- %%%

% q0 should vary with x, anyway using the same initial guess is ok

vd1_init;

q0=[0.94910999;4.804079037;0.52999628]
q_matrix=[];

options=optimset('Display','iter');

for i=1:length(x)

t = x(i);
fxt = fx(i);
at = a(i);
[qt,fval] = fsolve(@vd1,q0,options,t,fxt,at);
%t,fxt,at come after "options", meaning they are parameter, fsolve doesn't optimize those parameters
q_matrix = [q_matrix qt]; %solution for each x is a column of q_matrix
end

%at x=x(i), solution is: q=q_matrix(:,i)

% Read help of fsolve: (online help contains one more syntax than Matlab help)
% http://nf.apac.edu.au/facilities/sof...im/fsolve.html
% x = fsolve(fun,x0,options,P1,P2,...) passes the problem-dependent
% parameters P1, P2, etc., directly to the function fun.

% Good study!
% conso0 & picvendor, www.picvietnam.com, 20080111.
%%%---%%%

---

Cách giải bài này là:
- Xấp xỉ hàm liên tục f(x) bằng một chuỗi, đây là bước rời rạc hóa, bạn đã làm được. Lưu ý chọn bước để xấp xỉ càng nhỏ càng tốt. (phụ thuộc vào độ phân giải bộ điều khiển của dao)
- Tính đạo hàm df/dx, do đạo hàm chỉ phụ thuộc vào hình dạng của f(x) mà không phụ thuộc vào các góc quay q_i, nên ta mang ra ngoài, tính đạo hàm một lần thôi.
- Giải hệ phương trình [F1(q); F2(q); F3(q)] = [0;0;0] bằng lện fsolve, đối với mỗi giá trị x. (mỗi giá trị x thì có giá trị fx và ax tương ứng).

---

Mã lệnh bạn gửi lúc đầu có một số lỗi về cú pháp:

+ Tính giá trị a, nếu bạn ghi a=df/sqrt(df.^2+1) thì cái dấu / có ý nghĩa là phép chia (giả) giữa 2 ma trận. Cần sửa là a=df./sqrt(df.^2+1) - từng phần tử chia cho nhau.

+ F = [...];[...];[...]; không tạo được vector 3 thành phần.

+ fx +l3*sin(q(1)+q(2)-q(3))+l0*sin(q(1)+q(2))-l1*sin(q(2)) - để ý khoảng trống ngay sau biến fx, nó tách câu lệnh này thành vector có 2 cột, đó là lý do bạn thấy lỗi ở feval (lúc mới sửa tôi cũng gặp lỗi đó, nó báo lỗi "vercat" và cho biết 3 dòng của F không có cùng số cột).

conso0 26-01-2008 09:17 AM

Vâng! Em làm thử được rồi chỉ mỗi tội là mỗi lần chạy để xem kết quả lâu quá(khi em muốn cho bước xấp xỉ lớn).Dù sao rất cảm ơn bác "picvendor" đã giúp em giải quyết vướng mắc,trong thời gian tới chắc còn phải hỏi bác nhiều vì em đang làm đồ án có liên quan đến nhiều Matlab-Simulink.Rất mong sự giúp đỡ của bác!
Chúc 1 ngày tốt lành!

nobita611 05-06-2014 12:39 AM

Mình đang mầy mò phần giải hệ phương trình phi tuyến bằng matlab và đây là ví dụ mình lấy trên trang http://www.mathworks.com/help/optim/ug/fsolve.html

function F = myfun(x)
F = [2*x(1) - x(2) - exp(-x(1));
-x(1) + 2*x(2) - exp(-x(2))];
x0 = [-5; -5]; % Make a starting guess at the solution
options=optimset('Display','iter'); % Option to display output
[x,fval] = fsolve(@myfun,x0,options) % Call optimizer

Mình chạy thử thì nó báo lỗi thế này. Tất cả mình đều để ở file myfun.m

??? Input argument "x" is undefined.

Error in ==> myfun at 2
F = [2*x(1) - x(2) - exp(-x(1));

Giờ lỗi này mình phải xử lý thế nào hả mọi người.


Múi giờ GMT. Hiện tại là 01:34 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam