2011-11-17 11 views
8

Applicando Orthogonalize[] una volta:ortogonalizzare [] funziona come previsto solo se applicato due volte

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

E ora due volte:

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 ... Perché ?

+0

Quindi, [Szabolcs] (http://stackoverflow.com/questions/8154079/add-text-to-faces-of-polyhedron/8155008#comment10011483_8155008) ottiene una congratulazioni, ma io non?!? : D – rcollyer

+0

Hmmm, ha eseguito un ricalcolo e non ha funzionato come mi aspettavo. Sotto 5k, di nuovo. – rcollyer

+0

@rcollyer Congratulazioni !! : D Ero fuori da pranzo ;-) – Szabolcs

risposta

4

Ho anche pensato che sarebbe un errore di numerico, ma non riusciva a capire il motivo per cui , così ho cercato di implementare Gram-Schmidt orthogonalization me stesso, sperando di capire il problema sulla strada:

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

(incluso a scopo puramente illustrativo, ho semplicemente potuto non del tutto a capire cosa sta succedendo prima di reimplementato io stesso.)

un passaggio fondamentale qui, che non mi rendevo conto prima, è decidere se un vettore che otteniamo è azzerare o meno prima del il passo di normalizzazione (vedere Chop nel mio codice). Altrimenti potremmo ottenere qualcosa di minuscolo, forse un semplice errore numerico, che viene poi normalizzato in un grande valore.

Questo sembra essere controllato dall'opzione Tolerance di Orthogonalize, e infatti, aumentando la tolleranza, e costringendolo a scartare piccoli vettori risolve il problema che si descrive. Orthogonalize[ ... , Tolerance -> 1*^-10] funziona in un unico passaggio.

+0

Penso che tu abbia ragione. Usare il tuo codice con e senza 'Chop' in' FindInstance' mi dà due piani le cui normali differiscono per un segno. Ottengo la stessa cosa usando 'Ortogonalize' con' Tolerance -> 10^-10'. – rcollyer

1

Forse è una caratteristica del metodo GramSchmidt predefinito?

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

+0

L'impostazione predefinita è in realtà "ModifiedGramSchmidt". Solo un'osservazione dopo aver giocato con esso. – Szabolcs

+0

Penso che sia strettamente un errore numerico dovuto al suo uso di 'Chop', in quanto senza di esso si ottengono solo 2 vettori diversi da zero. – rcollyer

6

ritengo il primo risultato è causa di errore numerico, prendendo

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

quindi [email protected] restituisce 2, per esso il sistema stesso è solo bidimensionale. Per me, questo implica che la prima istanza di Orthogonalize stia generando un errore numerico e che la seconda istanza stia usando l'errore fuori piano per fornire i tre vettori. Rimozione dei Chop condizioni corregge questo,

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

dove N è necessario per sbarazzarsi del Root termini che compaiono. Questo ti dà un sistema bidimensionale, ma puoi ottenerne un terzo prendendo il prodotto incrociato.

Modifica: Ecco ulteriori prove che il suo errore numerico dovuto a Chop.

Con Chop, FindInstance mi dà

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

Senza Chop, ottengo

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

che è una differenza significativa tra i due.

+0

Questo può anche essere risolto applicando 'Normalize/@' prima dell'ortogonalizzazione – Szabolcs

+0

@Szabolcs, almeno sul mio sistema, non lo fa, e non mi aspetterei che rimangano gli errori numerici. – rcollyer

+0

Sono su Windows a 32 bit, 8.0.4, 'Ortogonalizza [Normalizza/@ (...)]' lo aggiusta qui. I vettori che ottengo da FindInstance sono gli stessi della tua macchina. – Szabolcs

Problemi correlati