2010-05-07 10 views
6

tôi có chương trình sau đâymatlab chính xác yếu tố quyết định vấn đề

format compact; format short g; clear; clc; 
L = 140; J = 77; Jm = 10540; G = 0.8*10^8; d = L/3; 
for i=1:500000 
omegan=1.+0.0001*i; 

a(1,1) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(1,2) = 2; a(1,3) = 0; a(1,4) = 0; 
a(2,1) = 1; a(2,2) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(2,3) = 1; a(2,4) = 0; 
a(3,1) = 0; a(3,2) = 1; a(3,3) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(3,4) = 1; 
a(4,1) = 0; a(4,2) = 0; a(4,3) = 2; a(4,4) = ((omegan^2)*(Jm/(G*J))*d^2)-2; 

if(abs(det(a))<1E-10) sprintf('omegan= %8.3f det= %8.3f',omegan,det(a)) 
end   
end 

giải pháp phân tích của hệ thống trên, và cùng program written in fortran đưa ra giá trị của omegan bằng 16,3818 và 32,7636 (giá trị fortran; phân tích khác nhau một chút, nhưng họ đang ở đâu đó).

Vì vậy, bây giờ tôi tự hỏi ... tôi đang đi sai với điều này? Tại sao MATLAB không đưa ra kết quả mong đợi?

(điều này có lẽ là một cái gì đó khủng khiếp đơn giản, nhưng nó đem lại cho tôi đau đầu)

+0

Hấp dẫn. Đối với tôi, nó cũng không bao giờ dừng lại. Các giá trị tôi nhận được cho det (a) là -4E-5, và -3E-4 với omegan của bạn (nếu tôi không mắc lỗi). Chỉ để kiểm tra lỗi: Bạn có nhận được một danh sách các giá trị cho det (a) từ chương trình fortran và so sánh chúng với các giá trị từ Matlab không? – Jonas

+0

@ Jonas - Không, tôi nghĩ đó là dư thừa. Sau khi tất cả, tôi chỉ cần sao chép (sửa đổi cần thiết) chương trình fortran để MATLAB, và kể từ khi MATLAB làm việc trong chế độ dp theo mặc định, tôi tin rằng nó sẽ giải quyết nó mà không có vấn đề. Như tôi đã nói trong bình luận cho gnovice, đây chỉ là ví dụ - Tôi không phải tất cả những gì quan tâm đến kết quả, nhiều như sự khác biệt giữa fortran và MATLAB (Tôi vẫn đang thử nghiệm nếu MATLAB có thể xử lý loại vấn đề này). – Rook

+0

@Idigas: Tôi hiểu rằng bạn không đặc biệt quan tâm đến vấn đề cụ thể này. Nhưng nếu nó thực sự là một vấn đề chính xác, bạn sẽ không muốn biết trong điều kiện nào nó xảy ra? Ngoài ra, như những người khác đã lưu ý: Matlab không tìm thấy các giải pháp, nó chỉ là cutoff có thể khác nhau. – Jonas

Trả lời

2

câu trả lời mới:

Bạn có thể điều tra vấn đề này sử dụng phương trình mang tính biểu tượng, mà mang lại cho tôi câu trả lời đúng:

>> clear all    %# Clear all existing variables 
>> format long   %# Display more digits of precision 
>> syms Jm d omegan G J %# Your symbolic variables 
>> a = ((Jm*(d*omegan)^2)/(G*J)-2).*eye(4)+... %# Create the matrix a 
     diag([2 1 1],1)+... 
     diag([1 1 2],-1); 
>> solns = solve(det(a),'omegan') %# Solve for where the determinant is 0 

solns = 

           0 
           0 
      (G*J*Jm)^(1/2)/(Jm*d) 
      -(G*J*Jm)^(1/2)/(Jm*d) 
     -(2*(G*J*Jm)^(1/2))/(Jm*d) 
     (2*(G*J*Jm)^(1/2))/(Jm*d) 
    (3^(1/2)*(G*J*Jm)^(1/2))/(Jm*d) 
-(3^(1/2)*(G*J*Jm)^(1/2))/(Jm*d) 

>> solns = subs(solns,{G,J,Jm,d},{8e7,77,10540,140/3}) %# Substitute values 

solns = 

        0 
        0 
    16.381862247021893 
-16.381862247021893 
-32.763724494043785 
    32.763724494043785 
    28.374217734436371 
-28.374217734436371 

Tôi nghĩ bạn không chỉ chọn giá trị trong vòng lặp đủ gần với các giải pháp cho omegan o r ngưỡng của bạn về việc yếu tố quyết định gần bằng không quá nghiêm ngặt. Khi tôi cắm vào các giá trị cho đến a, cùng với omegan = 16.3819 (đó là giá trị gần nhất với một giải pháp vòng lặp của bạn sản xuất), tôi có được điều này:

>> det(subs(a,{omegan,G,J,Jm,d},{16.3819,8e7,77,10540,140/3})) 

ans = 

    2.765476845475786e-005 

Đó là vẫn lớn hơn trong biên độ tuyệt đối so với 1e-10.

+0

Xin chào gnovice, tôi đã hy vọng bạn sẽ dừng lại bởi :) Không, dấu hiệu "ít hơn" là ok ở đó (trừ khi tôi đang thiếu một cái gì đó bạn đang cố gắng để ngụ ý) .Đó là một vấn đề eigenvalue trong rung động ... Tôi cần phải tìm tất cả các omegans (tự nhiên tần số) mà xác định bằng 0. Có một số lượng vô hạn, nhưng tôi chỉ tìm vài (hai hoặc ba) đầu tiên.Tuy nhiên, điều tôi không thể hiểu là tại sao chương trình fortran của tôi "nuốt" cái này mà không có vấn đề, và hàm det() không có. không có vẻ là một vấn đề chính xác đơn/đôi – Rook

+0

hoặc - chương trình fortran hiện nó trong duy nhất, và theo mặc định trong tất cả mọi thứ MATLAB là trong độ chính xác gấp đôi. Vì vậy, MATLAB nên có lợi thế từ đầu. – Rook

+0

Sprintf là thực sự thừa, nó là ở đây chỉ vì vậy những người sẽ cố gắng tìm ra điều này sẽ không phải thêm nó. Như tôi đã nói, tôi đã biết kết quả trong trường hợp này. Tôi quan tâm nhiều hơn đến lý do cho lỗi này, vì tôi không biết bây giờ nếu tôi có thể dựa vào cơ chế của MATLAB, khi giải quyết một vấn đề lớn hơn (mà tôi không biết kết quả). – Rook

3

Bạn đang tìm quá ít giá trị xác định vì Matlab đang sử dụng hàm xác định khác (hoặc một số lý do khác giống như độ chính xác của dấu phẩy động liên quan đến hai phương pháp khác nhau). Tôi sẽ cho bạn thấy rằng Matlab về cơ bản là cung cấp cho bạn các giá trị chính xác và một cách tốt hơn để tiếp cận vấn đề này nói chung.

Trước tiên, hãy lấy mã của bạn và thay đổi nó một chút.

format compact; format short g; clear; clc; 
L = 140; J = 77; Jm = 10540; G = 0.8*10^8; d = L/3; 
vals = zeros(1,500000); 
for i=1:500000 
    omegan=1.+0.0001*i; 

    a(1,1) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(1,2) = 2; a(1,3) = 0; a(1,4) = 0; 
    a(2,1) = 1; a(2,2) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(2,3) = 1; a(2,4) = 0; 
    a(3,1) = 0; a(3,2) = 1; a(3,3) = ((omegan^2)*(Jm/(G*J))*d^2)-2; a(3,4) = 1; 
    a(4,1) = 0; a(4,2) = 0; a(4,3) = 2; a(4,4) = ((omegan^2)*(Jm/(G*J))*d^2)-2; 
    vals(i) = abs(det(a)); 
    if(vals(i)<1E-10) 
     sprintf('omegan= %8.3f det= %8.3f',omegan,det(a)) 
    end 
end 
plot(1.+0.0001*(1:500000),log(vals)) 

Tất cả những gì tôi đã thực hiện thực sự được đăng nhập các giá trị của các yếu tố quyết định cho tất cả các giá trị của omegan và vẽ các bản ghi của những giá trị yếu tố quyết định là một hàm của omegan. Dưới đây là cốt truyện:

alt text

Bạn nhận thấy ba dips lớn trong đồ thị. Hai trùng với kết quả của bạn là 16.3818 và 32.7636, nhưng cũng có thêm một kết quả mà bạn bị thiếu (có thể do điều kiện của yếu tố quyết định nhỏ hơn 1e-10 quá thấp ngay cả khi mã Fortran của bạn nhận được nó). Do đó, Matlab cũng nói với bạn rằng đó là những giá trị của omegan mà bạn đang tìm kiếm, nhưng vì yếu tố quyết định được xác định theo một cách khác nhau trong Matlab, các giá trị không giống nhau - không đáng ngạc nhiên khi xử lý ma trận kém . Ngoài ra, nó có thể đã làm với Fortran bằng cách sử dụng phao chính xác đơn như người khác nói. Tôi sẽ không xem xét lý do tại sao họ không phải vì tôi không muốn lãng phí thời gian của tôi vào đó. Thay vào đó, hãy nhìn vào những gì bạn đang cố gắng làm và thử một cách tiếp cận khác.

Bạn, như tôi chắc chắn rằng bạn đã biết, đang cố gắng để tìm ra giá trị riêng của ma trận

a = [[-2 2 0 0]; [1 -2 1 0]; [0 1 -2 1]; [0 0 2 -2]]; 

, cài đặt chúng bằng

-omegan^2*(Jm/(G*J)*d^2) 

và giải quyết cho omegan. Đây là cách tôi đã đi về nó:

format compact; format short g; clear; clc; 
L = 140; J = 77; Jm = 10540; G = 0.8*10^8; d = L/3; 
C1 = (Jm/(G*J)*d^2); 
a = [[-2 2 0 0]; [1 -2 1 0]; [0 1 -2 1]; [0,0,2,-2]]; 
myeigs = eig(a); 
myeigs(abs(myeigs) < eps) = 0.0; 
for i=1:4 
    sprintf('omegan= %8.3f', sqrt(-myeigs(i)/C1)) 
end 

này cung cấp cho bạn tất cả bốn giải pháp - không chỉ hai mà bạn đã tìm thấy với mã Fortran của bạn (mặc dù một trong số họ, không, là ngoài phạm vi thử nghiệm của bạn cho omegan). Nếu bạn muốn giải quyết điều này bằng cách kiểm tra yếu tố quyết định trong Matlab, như bạn đã cố gắng thực hiện, thì bạn sẽ phải chơi với giá trị mà bạn đang kiểm tra giá trị tuyệt đối của yếu tố quyết định nhỏ hơn. Tôi đã nhận nó để làm việc cho một giá trị của 1e-4 (nó đã cho 3 giải pháp: 16.382, 28.374, và 32.764).

Xin lỗi vì giải pháp dài như vậy, nhưng hy vọng nó sẽ giúp ích.

Cập nhật:

Trong khối đầu tiên của tôi về mã trên, tôi đã thay thế

vals(i) = abs(det(a)); 

với

[L,U] = lu(a); 
s = det(L); 
vals(i) = abs(s*prod(diag(U))); 

đó là thuật toán mà det được cho là sử dụng theo quy định của Matlab tài liệu. Bây giờ, tôi có thể sử dụng 1E-10 làm điều kiện và nó hoạt động. Vì vậy, có lẽ Matlab không tính toán định thức chính xác như các tài liệu nói? Đây là loại đáng lo ngại.

+0

Đó có thể là vấn đề (MATLAB sử dụng chức năng xác định khác nhau). Bạn có biết nơi người ta có thể tìm ra những gì MATLAB thuật toán được sử dụng cho điều đó? Btw, tôi đánh giá cao nỗ lực bạn đã đưa vào giải quyết hệ thống này, nhưng không may Tôi không thể sử dụng nó trong công việc của mình. Các ma trận hệ số tôi sử dụng, được lắp ráp sử dụng các chức năng đã viết và luôn phức tạp hơn (và lớn hơn) sau đó là một chùm đơn giản được chia thành 3 phần tử/4 nút). – Rook

+0

Tôi không bỏ lỡ thứ ba (hoặc thứ hai, phụ thuộc vào cách bạn nhìn vào nó) omegan. Chương trình Fortran cũng cung cấp cho chương trình đó.Đó chỉ là, đó không phải là một trong các giải pháp, mặc dù nó là số chính xác. Các freqs.phải nằm trong một số khẩu phần nhất định cho một khẩu phần khác. Tôi xin lỗi nếu tôi làm bạn bối rối với điều đó; Tôi cần có đề cập đến nó trong câu hỏi. – Rook

+0

Tôi tìm thấy btw khủng khiếp khủng khiếp này. Tôi hy vọng rằng nếu MATLAB hoạt động ở độ chính xác gấp đôi, và nếu tôi viết các chương trình fortran của tôi trong đó; Tôi sẽ có thể nhận được kết quả tương tự mà không cần viết lại nhiều (chủ yếu là các toán tử ** đến^:). Tôi không mong đợi các chức năng của MATLAB gây ra vấn đề. – Rook

1

Tôi đặt câu trả lời này là vì tôi không thể dán điều này vào nhận xét: Đây là cách Matlab tính toán determinant. Tôi giả sử các lỗi làm tròn số đến từ tính là sản phẩm của nhiều yếu tố chéo trong U.

Algorithm

Các yếu tố quyết định được tính toán từ yếu tố tam giác thu được bằng cách khử Gauss

[L,U] = lu(A) s = det(L)   
%# This is always +1 or -1 
det(A) = s*prod(diag(U))