Orthogonalize []仅在应用两次时按预期工作

时间:2011-11-17 12:21:15

标签: wolfram-mathematica

应用Orthogonalize[]一次:

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]

enter image description here

现在两次:

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]

enter image description here

呃......为什么?

3 个答案:

答案 0 :(得分:6)

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

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,因此系统本身只是二维的。对我来说,这意味着Orthogonalize的第一个实例正在生成数字错误,而第二个实例正在使用平面外错误来为您提供三个向量。删除Chop条件可解决此问题,

Orthogonalize[{a, b, c} /.
    N@FindInstance[{a, b, c}.v1 == 0,{a, b, c}, Reals, 4]]

需要N才能摆脱出现的Root字词。这为您提供了一个二维系统,但您可以通过交叉产品获得第三个系统。

修改:以下是Chop引起的数字错误的进一步证据。

ChopFindInstance给我

{{64., 3.6, 335.108}, {-67., -4.3, -350.817}, {0, 176., 0}, 
 {-2., -4.3, -10.4721}}

没有Chop,我得

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

这两者之间存在显着差异。

答案 1 :(得分:4)

我还认为这是一个数字错误,但我并不完全理解为什么,所以我试着自己实现Gram-Schmidt orthogonalization,希望在途中了解问题:

(* 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]

(仅供参考,在我自己重新实施之前,我根本无法弄清楚发生了什么。)

我之前没有意识到的关键步骤是在规范化步骤之前判断我们得到的矢量是否为零(参见{ {1}}在我的代码中)。否则,我们可能会得到一些微小的东西,可能只是一个数值误差,然后将其归一化为一个较大的值。

这似乎是由Chop的{​​{1}}选项控制的,实际上,提高容差,并强制它丢弃微小的向量可以解决您描述的问题。 Tolerance只需一步即可完成。

答案 2 :(得分:1)

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

尝试:Method -> "Reorthogonalization"Method -> "Householder"