
Muchos comandos en Mathematica 8 ( Integrate
,, Simplify
etc.) parecen estar usando solo un núcleo en mi sistema. ¿Hay alguna manera de cambiar la afinidad para que utilice todos los núcleos para los cálculos?
Respuesta1
Como se mencionó en las otras preguntas y comentarios, cosas como Integrate
y Simplify
serían realmente difíciles de paralelizar, por lo que Mathematica devuelve el mensaje Parallelize::nopar1
y procede "con una evaluación secuencial".
(Aunque pensándolo bien, tal vez FullSimplify
podría establecerse un paralelismo, ya quebásicamentefunciona probando muchas reglas diferentes y contando hojas sobre ellas...)
Si tienes muchas integrales o simplificaciones que hacer, entonces puedes usar ParallelTable
o ParallelMap
etc...
Como ejemplo trivial, si tienes los integrandos
In[1]:= ints = Table[x^n, {n, 1, 10}]
Out[1]= {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10}
Puedes usarParallelTable
In[2]:= ParallelTable[Integrate[int, x], {int, ints}]
Out[2]= {x^2/2, x^3/3, x^4/4, x^5/5, x^6/6, x^7/7, x^8/8,\
x^9/9, x^10/10, x^11/11}
oParallelMap
In[3]:= ParallelMap[Integrate[#, x] &, ints]
Out[3]= {x^2/2, x^3/3, x^4/4, x^5/5, x^6/6, x^7/7, x^8/8,\
x^9/9, x^10/10, x^11/11}
Obviamente, para listas pequeñas de integrales como la anterior, la sobrecarga de paralelización probablemente sea mayor que el beneficio. Pero si tienes listas realmente grandes e integrales complejas, probablemente valga la pena.
Editar en respuesta a comentarios
Dado el integrando realmente complicado que le interesa al OP (nota: ¡realmente deberías simplificar tus resultados a medida que avanzas!), aquí hay un código que divide la integral en una suma de monomios y realiza las integrales usando ParallelDo
.
Primero importamos la integral de Pastebin.
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
extraer el dominio de integración
In[2]:= intLimits = Rest@(2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "List"]])
vars = intLimits[[All, 1]];
Out[2]= {{\[Theta]3, 0, 2*Pi}, {\[Theta]2, 0, 2*Pi},
{\[Theta]1, 0, 2*Pi}, {\[CurlyPhi]2, 0, Pi/2}, {\[CurlyPhi]1, 0, Pi/2}}
y el integrando, que viene como la suma de 21 términos monstruosos
In[4]:= integrand = First@(2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
Necesitamos dividir este horrible desastre en trozos pequeños. Primero extraemos todas las diferentes funciones de la integral.
In[7]:= (fns=Union[vars, Cases[integrand, (Cos|Sin|Tan|Sec|Csc|Cot)[x_]/;!FreeQ[x,Alternatives@@vars],Infinity]])//Timing
Out[7]= {0.1,{\[Theta]1, <snip> ,Tan[\[CurlyPhi]2]}}
Encontramos los coeficientes (13849 que no desaparecen) de monomios construidos a partir defns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
Length@coef
Out[8]= {35.63, Null}
Out[9]= 13849
Compruebe que todos los coeficientes estén libres de variables de integración.
In[10]:= FreeQ[coef[[All, 2]], Alternatives@@vars]
Out[10]= True
Tenga en cuenta que en realidad podemos limpiar los coeficientes usando Factor
o Simplify
y disminuir ByteSize
aproximadamente 5 veces... Pero como las integrales de la mayoría de los monomios son cero, también podríamos dejar las simplificaciones hasta el final.
Así es como se reconstruye un monomio, se integra y se recombina con su coeficiente; por ejemplo, el monomio número 40 da una integral que no desaparece:
In[11]:= monomialNum=40;
Times@@(fns^coef[[monomialNum,1]])
Integrate[%, Sequence@@intLimits]
coef[[monomialNum,2]] %//Factor
Out[12]= \[Theta]1 Cos[\[Theta]1]^2 Cos[\[CurlyPhi]1]^4 Cos[4 \[CurlyPhi]1] Cos[\[CurlyPhi]2]^4 Cos[2 \[CurlyPhi]2] Sin[\[Theta]1]^2
Out[13]= \[Pi]^6/256
Out[14]= -((k1^2 (k1-k2) (k1+k2) (-2+p) p^3 \[Pi]^6 \[Sigma]^4)/(131072 \[Omega]1))
Por ahora reduciré el número de términos, ya que me llevaría una eternidad hacer todas las integrales en mi portátil de doble núcleo. Elimine o comente la siguiente línea cuando desee evaluar todo el conjunto de integrales.
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
Bien, inicialice una lista vacía para los resultados de la integración monomial
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, Length@coef];
Al realizar las integrales, Print
obtenemos
num: {momento, resultado}
para cada monomio integrado. El CellLabel
de cada celda impresa te indica qué núcleo hizo la integral. La impresión puede resultar molesta; si le molesta, reemplácela Print
con PrintTempory
o ##&
. También puede monitorear el cálculo usando una variable dinámica de algún tipo: por ejemplo, unabarra de progreso.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[Times@@(fns^coef[[c,1]]), Sequence@@intLimits]]],
{c, Length@coef}]
Combinar con sus coeficientes
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
¡Y (con suerte) eso es todo!
Respuesta2
Desde elParalelizar la documentación, en Ejemplos > Posibles problemas:
Las expresiones que no se pueden paralelizar se evalúan normalmente:
Parallelize[Integrate[1/(x - 1), x]]