2011-11-17 12 views
8

Aplicando Orthogonalize[] vez:Ortogonalizar [] funciona como se esperaba solamente cuando se aplica dos veces

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

enter image description here

Y ahora dos veces:

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

enter image description here

Errr ... ¿Por qué ?

+0

Entonces, [Szabolcs] (http://stackoverflow.com/questions/8154079/add-text-to-faces-of-polyhedron/8155008#comment10011483_8155008) recibe una felicitación, pero yo no? : D – rcollyer

+0

Hmmm, ejecuté un recalc y no funcionó como esperaba. Por debajo de 5k, de nuevo. – rcollyer

+0

@rcollyer ¡Felicidades! : D Estaba fuera cenando ;-) – Szabolcs

Respuesta

4

También asumí que sería un error numérico, pero no comprendía por qué , por lo que trató de implementar Gram-Schmidt orthogonalization a mí mismo, con la esperanza de comprender el problema en el camino:

(* 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, [email protected][v]], {rest}] 
] 

gm[finished_, {}] := finished 

gramSchmidt[vectors_] := gm[{}, vectors] 

(incluido con fines ilustrativos únicamente, simplemente no podía bastante entender lo que está pasando antes de que yo reimplementado yo mismo.)

un paso crítico en este caso, que no me di cuenta antes, es decidir si un vector que obtenemos es cero o no antes de el paso de normalización (vea Chop en mi código). De lo contrario, podríamos obtener algo pequeño, posiblemente un mero error numérico, que luego se normalizará en un valor grande.

Esto parece estar controlado por la opción Tolerance de Orthogonalize, y, de hecho, aumentar la tolerancia y forzarla a descartar pequeños vectores corrige el problema que describe. Orthogonalize[ ... , Tolerance -> 1*^-10] funciona en un solo paso.

+0

Creo que tienes razón. Usar tu código con y sin 'Chop' en' FindInstance' me da dos planos cuyas normales se diferencian por un signo. Obtengo lo mismo usando 'Orthogonalize' con' Tolerance -> 10^-10'. – rcollyer

1

¿Quizás es una característica del método GramSchmidt predeterminado?

Probar: Method -> "Reorthogonalization" o Method -> "Householder".

+0

El valor predeterminado es en realidad "ModifiedGramSchmidt". Solo una observación después de jugar con ella. – Szabolcs

+0

Creo que es estrictamente un error numérico debido a su uso de 'Chop', ya que sin él, obtienes solo 2 vectores distintos de cero. – rcollyer

6

creo que el primer resultado es debido a un error numérico, tomando

sys = {a,b,c}/.FindInstance[ 
      {a, b, c}.v1 == 0 && ([email protected] != 0. || [email protected] != 0. || [email protected] !=0.), 
      {a, b, c}, Reals, 4]; 

luego vuelve [email protected] 2, para ello el sistema en sí es sólo dos dimensiones. Para mí, esto implica que la primera instancia de Orthogonalize está generando un error numérico, y la segunda instancia está utilizando el error fuera del plano para darle sus tres vectores. La eliminación de las condiciones Chop corrige esto,

Orthogonalize[{a, b, c} /. 
    [email protected][{a, b, c}.v1 == 0,{a, b, c}, Reals, 4]] 

donde N es necesario deshacerse de los términos que aparecen Root. Esto le da un sistema bidimensional, pero puede obtener un tercero tomando el producto cruzado.

Editar: Aquí hay más evidencia de que es un error numérico debido a Chop.

Con Chop, FindInstance me da

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

Sin Chop, consigo

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

que es una diferencia significativa entre los dos.

+0

Esto también se puede curar aplicando 'Normalize/@' antes de la ortogonalización – Szabolcs

+0

@Szabolcs, al menos en mi sistema, no es así, y no lo esperaría ya que los errores numéricos permanecen. – rcollyer

+0

Estoy en Windows de 32 bits, 8.0.4, 'Orthogonalize [Normalize/@ (...)]' lo arregla aquí. Los vectores que obtengo de FindInstance son los mismos que en su máquina. – Szabolcs

Cuestiones relacionadas