Wolfram mathematica 正交化[]仅在应用两次时按预期工作

Wolfram mathematica 正交化[]仅在应用两次时按预期工作,wolfram-mathematica,Wolfram Mathematica,应用正交化[]一次: v1 = PolyhedronData["Dodecahedron", "VertexCoordinates"][[1]]; Graphics3D[Line[{{0, 0, 0}, #}] & /@ Orthogonalize[{a, b, c} /. FindInstance[{a, b, c}.v1 == 0 && (Chop@a != 0.||Chop@b != 0.||Chop@c != 0.), {a, b, c},

应用
正交化[]
一次:

v1 = PolyhedronData["Dodecahedron", "VertexCoordinates"][[1]]; 
Graphics3D[Line[{{0, 0, 0}, #}] & /@
  Orthogonalize[{a, b, c} /.
    FindInstance[{a, b, c}.v1 == 0 && (Chop@a != 0.||Chop@b != 0.||Chop@c != 0.),
     {a, b, c}, Reals, 4]], Boxed -> False]

现在两次:

Graphics3D[Line[{{0, 0, 0}, #}] & /@
  Orthogonalize@Orthogonalize[{a, b, c} /.
    FindInstance[{a, b, c}.v1 == 0 && (Chop@a != 0.||Chop@b != 0.||Chop@c != 0.),
     {a, b, c}, Reals, 4]], Boxed -> False]


呃。。。为什么?

也许这是默认GramSchmidt方法的一个特点


尝试:
Method->“rethogonalization”
Method->“Householder”

我认为第一个结果是由于数值错误,取

sys = {a,b,c}/.FindInstance[
          {a, b, c}.v1 == 0 && (Chop@a != 0. || Chop@b != 0. || Chop@c !=0.), 
          {a, b, c}, Reals, 4];
然后
MatrixRank@sys
返回2,因此系统本身只是二维的。对我来说,这意味着正交化的第一个实例生成一个数值误差,第二个实例使用平面外误差来给出三个向量。删除
Chop
条件可修复此问题

Orthogonalize[{a, b, c} /.
    N@FindInstance[{a, b, c}.v1 == 0,{a, b, c}, Reals, 4]]
其中,
N
是清除出现的
术语所必需的。这给了你一个二维系统,但你可以通过取叉积得到第三个

编辑:这里有进一步的证据表明,它的数字错误是由于
Chop
造成的

Chop
FindInstance
给我

{{64., 3.6, 335.108}, {-67., -4.3, -350.817}, {0, 176., 0}, 
 {-2., -4.3, -10.4721}}
没有
印章
,我会

{{-16.8, 3.9, -87.9659}, {6.6, -1.7, 34.558}, {13.4, -4.3, 70.1633}, 
 {19.9, -4.3, 104.198}}

这是两者之间的一个显著区别。

我还假设这是一个数字错误,但不太明白为什么,所以我尝试自己实现,希望能够理解途中的问题:

(* projects onto a unit vector *)
proj[u_][v_] := (u.v) u

Clear[gm, gramSchmidt]

gm[finished_, {next_, rest___}] := 
 With[{v = next - Plus @@ Through[(proj /@ finished)[next]]}, 
  gm[Append[finished, Normalize@Chop[v]], {rest}]
 ]

gm[finished_, {}] := finished

gramSchmidt[vectors_] := gm[{}, vectors]
(仅用于说明,在我自己重新实现之前,我无法完全弄清楚发生了什么。)

这里的一个关键步骤,我以前没有意识到,是在标准化步骤之前决定我们得到的向量是否为零(请参见我的代码中的
Chop
)。否则,我们可能会得到一些微小的东西,可能只是一个数字误差,然后将其标准化为一个大值


这似乎是由
正交化
公差
选项控制的,事实上,提高公差并强制其丢弃微小向量可以解决您描述的问题<代码>正交化[…,公差->1*^-10]一步到位。

默认值实际上是“ModifiedGramSchmidt”。只是玩过之后的一个观察。我认为这完全是一个数字错误,因为他使用了
Chop
,因为没有它,你只能得到2个非零向量。这也可以通过在之前应用
Normalize/@
来解决orthogonalization@Szabolcs,至少在我的系统上,它没有,我在32位Windows上,8.0.4,
正交化[Normalize/@(…)]
在这里修复了它。我从FindInstance中得到的向量与您机器上的向量相同。@Szabolcs,我想我明白误解是什么了。是的,在我的机器(MacOS上的v.7.0.1)上,首先使用
Normalize
可以消除第二个
正交化的需要。但是,它仍然返回3个非零向量,这就是我所指的错误。应该只有2个非零向量,但是
Chop
引入了足够多的数值误差,从而给出了一个错误的平面外项,而
正交化
会得到该项。如果我先使用Normalize,它会返回两个零向量。我相信关键在于决定哪个向量是零,哪个不是在Gram-Schmidt过程中(见我的答案,以及正交化的容差选项),我认为你是对的。在
FindInstance
中使用带和不带
Chop
的代码可以得到两个法线相差一个符号的平面。我用
正交化
公差->10^-10
得到了同样的结果。所以,我得到了一个祝贺,但我没有DHmmm,运行了一个recalc,但结果并不像我预期的那样。再次低于5公里。@rcollyer恭喜!!:我出去吃饭;-)@Szabolcs,谢谢。老实说,我只是在开他的玩笑。