Dr.*_*ius 8 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]
Run Code Online (Sandbox Code Playgroud)

现在两次:
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]
Run Code Online (Sandbox Code Playgroud)

呃...为什么?
我认为第一个结果是由于数值误差,所以
sys = {a,b,c}/.FindInstance[
{a, b, c}.v1 == 0 && (Chop@a != 0. || Chop@b != 0. || Chop@c !=0.),
{a, b, c}, Reals, 4];
Run Code Online (Sandbox Code Playgroud)
然后MatrixRank@sys返回2,因此系统本身只是二维的.对我来说,这意味着第一个实例Orthogonalize是生成数字错误,第二个实例是使用平面外错误来为您提供三个向量.删除Chop条件修复此问题,
Orthogonalize[{a, b, c} /.
N@FindInstance[{a, b, c}.v1 == 0,{a, b, c}, Reals, 4]]
Run Code Online (Sandbox Code Playgroud)
哪里N有必要摆脱出现的Root条款.这为您提供了一个二维系统,但您可以通过采用交叉产品获得第三个系统.
编辑:这里有进一步的证据表明它的数值误差是由于Chop.
有了Chop,FindInstance给我
{{64., 3.6, 335.108}, {-67., -4.3, -350.817}, {0, 176., 0},
{-2., -4.3, -10.4721}}
Run Code Online (Sandbox Code Playgroud)
没有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}}
Run Code Online (Sandbox Code Playgroud)
这是两者之间的显着差异.
我还假设这将是一个数值错误,但不太明白为什么,所以我尝试自己实现Gram-Schmidt 正交化,希望能够理解这个问题:
(* 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]
Run Code Online (Sandbox Code Playgroud)
(仅供说明之用,在我自己重新实现之前我根本无法弄清楚发生了什么。)
这里的一个关键步骤是在标准化步骤之前确定我们得到的向量是否为零(请参阅我的代码) ,这是我之前没有意识到的Chop。否则,我们可能会得到一些微小的东西,可能只是一个数值误差,然后将其标准化回一个大值。
这似乎是由 的Tolerance选项控制Orthogonalize的,实际上,提高容差并强制它丢弃微小的向量可以解决您所描述的问题。 Orthogonalize[ ... , Tolerance -> 1*^-10]只需一步即可完成。