2009-11-17 16 views
6

ho generare molto lunghe e complesse espressioni analitiche della forma generale:mirata Semplificare in Mathematica

(...something not so complex...)(...ditto...)(...ditto...)...lots... 

Quando provo ad usare Simplify, Mathematica si blocca, io parto dal presupposto a causa del fatto che si cerca per espandere le parentesi e/o semplificare tra parentesi diverse. Le parentesi, pur contenendo lunghe espressioni, sono facilmente semplificate da Mathematica per conto proprio. C'è un modo per limitare l'ambito di Simplify a una singola staffa alla volta?

Modifica: Alcune informazioni aggiuntive e progressi.

Quindi, utilizzando il consiglio da voi ragazzi ora ho iniziato a utilizzare qualcosa in vena di

In[1]:= trouble = Log[(x + I y) (x - I y) + Sqrt[(a + I b) (a - I b)]]; 

In[2]:= Replace[trouble, form_ /; (Head[form] == Times) :> Simplify[form],{3}] 

Out[2]= Log[Sqrt[a^2 + b^2] + (x - I y) (x + I y)] 

Modifica Times ad una testa adeguata come Plus o Power permette di indirizzare la semplificazione molto accuratamente. Il problema/domanda che rimane, tuttavia, è la seguente: Simplify continuerà a scendere più in profondità del livello specificato su Replace, ad es.

In[3]:= Replace[trouble, form_ /; (Head[form] == Plus) :> Simplify[form], {1}] 

Out[3]= Log[Sqrt[a^2 + b^2] + x^2 + y^2] 

semplifica anche la radice quadrata.

Il mio piano era quella di utilizzare in modo iterativo Replace dal basso verso l'alto di un livello alla volta, ma questo chiaramente si tradurrà in grande quantità di lavoro ripetuto da Simplify e concludersi con la stessa identica impantanarsi di Mathematica ho sperimentato in via preliminare . C'è un modo per limitare lo Simplify a determinati livelli?

Mi rendo conto che questo tipo di restrizione potrebbe non produrre risultati ottimali, ma l'idea qui è di ottenere qualcosa che sia "abbastanza buono".

risposta

4

Ci sono diversi modi per farlo, ma può essere un po 'complicato e dipende dalla struttura della tua espressione reale.Tuttavia, di solito un prodotto di un certo numero di termini tra parentesi avrà la testa Times, ed è possibile utilizzare FullForm per verificare questo:

In[1]:= FullForm[(a+b)(c+d)] 
Out[1]= Times[Plus[a, b], Plus[c, d]] 

È possibile utilizzare la funzione di ordine superiore Map con le espressioni con la testa Times lo stesso modo di usare con espressioni con la testa List, e che può consentire di Simplify l'espressione un termine alla volta, in questo modo:

Map[Simplify, yourGinormousExpression] 

è possibile utilizzare Expand sul risultato, se avete bisogno di espandere successivamente o ut le parentesi.

Modifica per aggiungere: Se si desidera specificare le forme che si vuole semplificare, è possibile utilizzare Replace o ReplaceAll al posto di uno dei parenti di Map. Replace è particolarmente utile perché prende uno level specification, consentendo di influire solo sui fattori nel prodotto più in alto. Come semplice esempio, si consideri il seguente:

In[1]:= expr = Sqrt[(a + 1)/a] Sqrt[(b + 1)/b]; 

In[2]:= Simplify[expr] 
Out[2]= Sqrt[1 + 1/a] Sqrt[1 + 1/b] 

Se non si vuole semplificare i fattori che dipendono a. si può fare questo, invece:

In[3]:= Replace[expr, form_ /; FreeQ[form, a] :> Simplify[form], {1}] 
Out[3]= Sqrt[(1 + a)/a] Sqrt[1 + 1/b] 

il secondo termine, che dipende b, è stato cambiato solo. Una cosa da tenere presente è che alcune trasformazioni vengono eseguite automaticamente da Times o Plus; ad esempio a + a verrà convertito in 2 a anche senza l'utilizzo di Simplify.

+0

Grazie a questo (e anche alle altre risposte) ho aiutato molto. – Timo

1

Si consiglia di provare Map.
In generale, Map[foo, G[a, b, c, ...]]G[foo[a], foo[b], foo[c], ...] per qualsiasi testa G e qualsiasi espressione foo, quindi per

Map[Simplify, a b c d e] 

Simplify[a] Simplify[b] Simplify[c] Simplify[d] Simplify[e] 

Nota è possibile indicare Map[foo, expr] als foo /@ expr se si scopre che più conveniente.

2

Mi permetto di dissentire con i miei colleghi, in quanto l'utilizzo di Map per applicare Simplify a ciascuna sottoespressione potrebbe non consentire il salvataggio in qualsiasi momento poiché verrà comunque applicato a ciascuna di esse. Invece provare, MapAt, come segue:

In[1]:= MapAt[f, SomeHead[a,b,c,d], {4}] 
Out[1]:= SomeHead[a, b, c, f[d]] 

La parte difficile è determinare la specifica posizione. Anche se, se l'espressione che vuoi semplificare è al primo livello, non dovrebbe essere più difficile di ciò che ho scritto sopra.


Ora, se si desidera comunque semplificare tutto, ma si desidera conservare una certa struttura, provare a utilizzare l'opzione ExcludedForms. In passato, ho usato per prevenire questa semplificazione:

In[2]:= Simplify[d Exp[I (a + b)] Cos[c/2]] 
Out[2]:= Exp[I(a + b + c)](d + d Exp[c]) 

che Mathematica sembra piacere, così faccio

In[3]:= Simplify[d Exp[I (a + b)] Cos[c/2], ExcludedForms -> {_Cos,_Sin}] 
Out[3]:= d Exp[I (a + b)] Cos[c/2] 

Inoltre, non dimenticare che il secondo parametro per Simplify è per ipotesi, e può alleviare notevolmente le tue difficoltà nell'ottenere le tue espressioni in una forma utile.

+1

Il suggerimento ExcludeForms è carino, grazie! Ho solo voluto che Mathematica avesse un modo di includere esclusivamente i moduli per semplificare altro oltre a TransformationFunctions, che non possono essere impostati per parentesi ... – Timo