2011-12-20 10 views
5

consideri una situazione in cui si dispone di dati in un elenco di formaGenera termini di una serie di potenze m-ordine in n variabili

data = {{x1, x2, x3, ..., xn, y}, {...}, ..., {...}} 

Per esempio,

data = {{0, 2, 3, 2}, {0, 0, 1, 4}, {7, 6, 8, 3}} 

mi piacerebbe adattare i dati ad un polinomio multivariato di ordine, diciamo, 2. Quindi, i valori della funzione 3-variabili sono:

{2, 4, 3} 

in rispettivi punti

{{0, 2, 3}, {0, 0, 1}, {7, 6, 8}} 

Mi piacerebbe dire qualcosa come

Fit[data, {1, x, y, z, x^2, y^2, z^2, x y , x z, y z}, {x, y, z}] 

Questo è tutto molto bello, ma non può avere solo i dati 3-variata, ci può essere un numero arbitrario di variabili, e non so come generare a livello di codice tutti i termini lineari, quadratici o anche di ordine superiore, per inserirli come secondo argomento di Adatta [].

Per data 4-variata fare secondo ordine, sarebbe qualcosa di simile:

{1, x1, x2, x3, x4, x1^2, x2^2, x3^2, x4^2, x1 x2, x1 x3, x1 x4, x2 x3, x2 x4, x3 x4} 

v'è un modo per generare tale lista per n variabili, a m ordine esimo? Termini simili (senza coefficienti) in una espansione serie m - ordine di una funzione variabile n.

+0

Se questi sono 'x y' invece di' xy'? – kennytm

+0

ovviamente, sry su questo. – vedran

risposta

8

Fa questo ciò che vuoi?

Union[Times @@@ Tuples[{1, x, y, z}, 2]] 
+0

Questo fa esattamente quello che voglio. :) Grazie! – vedran

+0

Contento di aver potuto aiutare. –

3

Utilizzando @ soluzione chiara di ruebenko,

varsList[y_, n_?IntegerQ, k_?IntegerQ] := 
Union[Times @@@ 
Tuples[Prepend[Table[Subscript[y, i], {i, 1, n}], 1], k]] 

è possibile generare lista desiderata tramite varsList[x, 4, 2].

2

Ecco un altro metodo che ritengo vale la pena conoscere:

set = {1, x, y, z}; 

Union @@ Outer[Times, set, set] 
6

Mentre la soluzione di @ruebenko è perfettamente corretta, vorrei ricordare che sarà piuttosto lento per potenze superiori/numero maggiore di variabili, a causa della complessità di Tuples e di molti duplicati per potenze superiori. Ecco un metodo algebrico con una prestazione molto migliore per i casi (sia in fase di esecuzione e la memoria-saggio):

List @@ Expand[(1 + x + y + z + t)^2] /. a_Integer*b_ :> b 

Ecco un confronto per gran numero di variabili:

In[257]:= (res1=Union[[email protected]@@Tuples[{1,x,y,z,t},9]])//Short//Timing 
Out[257]= {19.345,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7, 
     t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}} 

In[259]:= ([email protected]@Expand[(1+x+y+z+t)^9]/. a_Integer*b_:>b)//Short//Timing 
Out[259]= {0.016,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7, 
     t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}} 

In[260]:= res1===res2 
Out[260]= True 

In questo caso, osserviamo un aumento di velocità 1000x, ma generalmente i due metodi hanno solo complessità computazionali differenti. Il codice sopra è un'applicazione di un metodo generale e piacevole, chiamato Programmazione algebrica. Per un'interessante discussione nel contesto di Mathematica, vedi questo Mathematica Journal paper di Andrzej Kozlowski.

+1

+1, roba buona! Ma sai, se trovi FindFit con 700 vars, i 20 sec. per i vars sono molto probabilmente le meno preoccupanti ;-) –

+0

bella soluzione ottimizzata! grazie :) – vedran

+0

@ruebenko Certo, questo non è per sminuire la tua soluzione (che ho svalutato)! Concettualmente, il tuo metodo è più naturale. Questo è solo per le informazioni di base - e chissà, alcune persone potrebbero aver bisogno di risolvere lo stesso problema per qualcos'altro. –

Problemi correlati