创建一组正交轴

时间:2015-10-09 06:53:04

标签: matlab axes orthogonal

我需要为模拟创建一系列矢量,这些矢量给出传播方向和光的偏振(3维)。因为方向和极化需要正交,所以我需要这样的东西:

D= [dir1;     P=[pol11;
   dir1;         pol12;
   dir2;         pol21;
   dir2;         pol21;
   dir3;         pol31;
   .... ]        ...  ]

正如您所看到的,每个方向都有两个极化。这里重要的是dir1 * pol11' = 0,dir1 * pol12' = 0等等。方向应该跨越整个立体角,而极化方向并不严格,尽管如果它们彼此正交则会很好。我尝试了两种不同的方法,一种是创建基本正交基础并旋转它,另一种是创建方向矩阵并使用null()函数创建极化。在这两种情况下,我得到的是,如果我做D * P'我得到一系列的0但是有些值非零 - 非常小(例如1e-17),但仍然是非零。 代码1:

bDir=[1,0,0;1,0,0]
bPol=[0,1,0;0,0,1]
dir=bDir
pol=bPol
for phi=0:pi/5:2*pi
    for theta=0:pi/5:pi
        rotatePhi=[cos(phi) -sin(phi) 0;...
                         sin(phi) cos(phi) 0;...
                         0 0 1];
        rotateTheta=[cos(theta) 0 sin(theta);...
                              0 1 0;...
                              -sin(theta) 0 cos(theta)];
        rDir=bDir*rotateTheta*rotatePhi;
        rPol=bPol*rotateTheta*rotatePhi;

        dir=vertcat(dir,rDir);
        pol=vertcat(pol,rPol);

    end
end

代码2:

bDir=[1,0,0;1,0,0]
dir=bDir
pol=[0,1,0;0,0,1]
for phi=0:pi/5:2*pi
    for theta=0:pi/5:pi
        rotatePhi=[cos(phi) -sin(phi) 0;...
                         sin(phi) cos(phi) 0;...
                         0 0 1];
        rotateTheta=[cos(theta) 0 sin(theta);...
                              0 1 0;...
                              -sin(theta) 0 cos(theta)];
        rDir=bDir*rotateTheta*rotatePhi;
        rPol=null(rDir)';

        dir=vertcat(dir,rDir);
        pol=vertcat(pol,rPol);

    end
end

我认为问题在于matlab引入了一些精度错误,但可能是错误的。 任何人都可以告诉我,我的代码中是否有错误,或者是否有更好的方法来获取我要找的2个matricies?

1 个答案:

答案 0 :(得分:0)

我认为你对floating point arithmetic的期望有点偏差。浮点运算不精确。在MATLAB中,通常浮点算术运算仅精确到16位小数(1e-16)。任何小于此值的值通常都可以视为0

MATLAB中的eps函数可用于确定MATLAB能够表示的最小浮点数。在我的系统上它产生

>> eps
ans =

   2.2204e-16

任何小于此MATLAB的数字都无法准确表示。

除了浮点运算的准确性之外,将它们与整数值0进行比较通常也是错误的。更准确的比较是

if dir*pol < 1e-16
    fprintf(1, 'Orthogonal\n');
else
    fprintf(1, 'Not Orthogonal\n');
end

对于大多数用途,当使用浮点运算时,通常在MATLAB中,如果上面的eps输出,则任何小于2.2204e-16的值都是0

如果您确实需要变量精度算术,可以使用vpa。但是,它通常是不必要的,只要你知道它的垮台,浮点运算就足够了。