2011-12-20 5 views
5

Considérese una situación en la que se tienen datos en una lista de la formaGenerar términos de una serie de potencias de orden m en n variables

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

Por ejemplo,

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

me gustaría ajustar los datos a un polinomio multivariante de orden, por ejemplo, 2. Por lo tanto, los valores de la función de 3 variables son:

{2, 4, 3} 

en puntos respectivos

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

diría algo así como

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

Todo esto está muy bien, pero puede que no haya sólo datos 3-variable, puede haber un número arbitrario de variables, y no sé cómo generar programáticamente todos los términos lineales, cuadráticos o incluso de orden superior, para insertarlos como el segundo argumento de Fit [].

Para la fecha 4-variable hacen de segundo orden, sería algo así como:

{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} 

¿Hay alguna manera de poder generar una lista de este tipo de n las variables, a fin m -ésimo? Términos similares (sin coeficientes) en un m -order power series series de una función n -variable.

+0

¿Deberían ser 'x y' en lugar de' xy'? – kennytm

+0

por supuesto, sry sobre eso. – vedran

Respuesta

8

¿Hace esto lo que quiere?

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

Esto hace exactamente lo que quiero. :) ¡Gracias! – vedran

+0

Me alegro de poder ayudar. –

3

Usando @ solución pura de ruebenko,

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

se puede generar a través de la lista deseada varsList[x, 4, 2].

2

Aquí es otro método que creo que vale la pena conocer:

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

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

Mientras que la solución de @ruebenko es perfectamente correcta, me gustaría mencionar que será bastante lento para potencias superiores/número mayor de variables, debido a la complejidad de Tuples y muchos duplicados para potencias superiores. He aquí un método algebraico con un rendimiento mucho mejor de los casos (tanto en tiempo de ejecución y la memoria-wise):

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

Aquí se presenta una comparación de gran número de variables:

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 

En este caso, observamos una aceleración de 1000x, pero generalmente los dos métodos tienen complejidades computacionales diferentes. El código anterior es una aplicación de un método general y agradable, llamado Programación Algebraica. Para una discusión interesante de él en el contexto de Mathematica, vea esto Mathematica Journal paper por Andrzej Kozlowski.

+1

+1, ¡cosas buenas! Pero ya sabes, si FindFit con 700 vars, los 20 seg. para los vars probablemente sea lo menos preocupante ;-) –

+0

¡buena solución optimizada! gracias :) – vedran

+0

@ruebenko Claro, esto no es para restar valor a su solución (¡la cual subí)! Conceptualmente, su método es más natural. Esto es solo para la información de fondo, y quién sabe, algunas personas pueden necesitar resolver el mismo problema para otra cosa. –

Cuestiones relacionadas