Como fazer com que comandos no Mathematica 8 usem todos os núcleos?

Como fazer com que comandos no Mathematica 8 usem todos os núcleos?

Muitos comandos no Mathematica 8 ( Integrate, Simplify, etc.) parecem estar usando apenas um único núcleo no meu sistema. Existe alguma maneira de alterar a afinidade para que ela utilize todos os núcleos para cálculos?

Responder1

Conforme mencionado nas outras perguntas e comentários, coisas como Integratee Simplifyseriam realmente difíceis de paralelizar, então o Mathematica retorna a mensagem Parallelize::nopar1e prossegue "com a avaliação sequencial".

(Embora refletindo, talvez FullSimplifypossa ser paralelizado, uma vez quebasicamentefunciona tentando muitas regras diferentes e contando folhas com elas...)

Se você tiver muitas integrais ou simplificações para fazer, poderá usar ParallelTableou ParallelMapetc...

Como exemplo trivial, se você tiver os 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}

Você pode 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}

ouParallelMap

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 pequenas listas de integrais como a acima, a sobrecarga de paralelização é provavelmente maior que o benefício. Mas se você tiver listas muito grandes e integrais complexas, provavelmente valerá a pena.


Editar em resposta aos comentários

Dado o integrando realmente confuso no qual o OP está interessado (nota: você realmente deve simplificar seus resultados à medida que avança!), aqui está um código que divide a integral em uma soma de monômios e executa as integrais usando ParallelDo.

Primeiro importamos a integral do pastebin

In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];

extrair o domínio de integração

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

e o integrando, que vem como a soma de 21 termos monstruosos

In[4]:= integrand = First@(2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
        Length[integrand]
        LeafCount[integrand]

Out[5]= 21
Out[6]= 48111

Precisamos quebrar a bagunça horrível em pedaços pequenos. Primeiro extraímos todas as diferentes funções da 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 os coeficientes (13849 não-desaparecidos) de monômios construídos a partir defns

In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
         Length@coef

Out[8]= {35.63, Null}
Out[9]= 13849

Verifique se todos os coeficientes estão livres de quaisquer variáveis ​​de integração

In[10]:= FreeQ[coef[[All, 2]], Alternatives@@vars]
Out[10]= True

Observe que podemos limpar os coeficientes usando Factorou Simplifye diminuir ByteSizecerca de 5 vezes... Mas como as integrais da maioria dos monômios são zero, podemos muito bem deixar as simplificações para o final.

É assim que você reconstrói um monômio, integra-o e recombina com seu coeficiente, por exemplo, o 40º monômio dá uma integral que não 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 enquanto vou reduzir o número de termos, já que levaria uma eternidade para fazer todas as integrais no meu laptop dual-core. Exclua ou comente a linha a seguir quando quiser calcular todo o conjunto de integrais

In[15]:= coef = RandomChoice[coef, 100];  (* Delete me!! *)

OK, inicialize uma lista vazia para os resultados da integração monomial

In[16]:= SetSharedVariable[ints]
         ints = ConstantArray[Null, Length@coef];

À medida que realizamos as integrais, Printobtemos num: {tempo, resultado} para cada monômio integrado. O CellLabelde cada célula impressa informa qual núcleo fez a integral. A impressão pode ser irritante - se incomodar, substitua Printpor PrintTemporyou ##&. Você também pode monitorar o cálculo usando algum tipo de variável dinâmica: por exemplo, umBarra de progresso.

ParallelDo[Print[c, ": ", Timing[
            ints[[c]] = Integrate[Times@@(fns^coef[[c,1]]), Sequence@@intLimits]]], 
           {c, Length@coef}]

Combine com seus coeficientes

1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]

E (espero) é isso!

Responder2

DeParalelizar documentação, em Exemplos > Possíveis problemas:

Expressões que não podem ser paralelizadas são avaliadas normalmente:

Parallelize[Integrate[1/(x - 1), x]]

insira a descrição da imagem aqui

informação relacionada