6

我有以下程序

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

上述系统的解析解,以及用 fortran 编写的同一程序给出的 omegan 值等于 16.3818 和 32.7636(fortran 值;解析略有不同,但它们在某处)。

所以,现在我想知道......我哪里错了?为什么 matlab 没有给出预期的结果?

(这可能是非常简单的事情,但它让我头疼)

4

3 回答 3

3

您正在寻找的行列式值太小,因为 Matlab 正在使用不同的行列式函数(或其他一些原因,例如与两种不同方法中涉及的浮点精度有关)。我将向您展示 Matlab 本质上为您提供了正确的值和更好的方法来解决这个问题。

首先,让我们对您的代码稍作修改。

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))

我所做的只是记录所有 omegan 值的行列式值,并将这些行列式值的对数绘制为 omegan 的函数。这是情节:

替代文字

您注意到图表中的三个主要下降。两个与您的 16.3818 和 32.7636 的结果一致,但还有一个您丢失了(可能是因为您的行列式小于 1e-10 的条件太低,即使您的 Fortran 代码也无法获取它)。因此,Matlab 还告诉您,这些是您正在寻找的 omegan 的值,但是由于在 Matlab 中以不同的方式确定了行列式,因此这些值并不相同 - 在处理不良条件矩阵时并不奇怪. 此外,正如其他人所说,它可能与使用单精度浮点数的 Fortran 有关。我不打算研究他们为什么不这样做,因为我不想在这上面浪费时间。相反,让我们看看您正在尝试做什么并尝试不同的方法。

你,我相信你知道,正试图找到矩阵的特征值

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

, 设置它们等于

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

并解决欧米茄。这就是我的做法:

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

这为您提供了所有四种解决方案 - 不仅仅是您在 Fortran 代码中找到的两种解决方案(尽管其中之一,零,超出了 omegan 的测试范围)。如果您想通过检查Matlab中的行列式来解决这个问题,就像您一直在尝试做的那样,那么您将不得不使用您正在检查的行列式绝对值小于的值。我让它以 1e-4 的值工作(它提供了 3 个解决方案:16.382、28.374 和 32.764)。

抱歉这么长的解决方案,但希望它有所帮助。

更新:

在我上面的第一个代码块中,我替换了

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

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

根据 Matlab 文档,这是 det 应该使用的算法。现在,我可以使用 1E-10 作为条件并且它可以工作。所以也许Matlab没有像文档所说的那样计算行列式?这有点令人不安。

于 2010-05-07T15:06:45.890 回答
2

新答案:

你可以使用符号方程来研究这个问题,它给了我正确的答案:

>> 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

我认为您要么只是没有在循环中选择足够接近解决方案的值,omegan要么您的行列式与零的接近程度的阈值太严格了。当我将给定的值a连同omegan = 16.3819(这是与您的循环产生的一种解决方案最接近的值)一起插入时,我得到了这个:

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

ans =

    2.765476845475786e-005

其绝对幅度仍大于 1e-10。

于 2010-05-07T14:19:34.493 回答
1

我将其作为答案,因为我无法将其粘贴到评论中:这是 Matlab 计算行列式的方式。我假设舍入误差来自计算 U 中多个对角线元素的乘积。

算法

行列式是根据通过高斯消元法获得的三角因子计算的

[L,U] = lu(A) s =  det(L)        
%# This is always +1 or -1  
det(A) = s*prod(diag(U))
于 2010-05-07T15:58:15.037 回答