Как распараллелить интеграцию в Mathematica 8

У кого-нибудь есть идея, как использовать все ядра для расчета интеграции? Мне нужно использовать распараллеливание или параллельную таблицу, но как?

 f[r_] := Sum[(((-1)^n*(2*r - 2*n - 7)!!)/(2^n*n!*(r - 2*n - 1)!))*
 x^(r - 2*n - 1), {n, 0, r/2}]; 


 Nw := Transpose[Table[f[j], {i, 1}, {j, 5, 200, 1}]]; 

 X1 = Integrate[Nw . Transpose[Nw], {x, -1, 1}]; 

 Y1 = Integrate[D[Nw, {x, 2}] . Transpose[D[Nw, {x, 2}]], {x, -1, 1}]; 

 X1//MatrixForm
 Y1//MatrixForm

person George Mills    schedule 05.11.2011    source источник
comment
Также на math.SE и соответствующий вопрос на суперпользователь.   -  person Simon    schedule 06.11.2011


Ответы (2)


Если кто-то немного поможет интегрировать, сначала расширив элементы матрицы, то все можно сделать, приложив немного усилий.

На четырехъядерном ноутбуке с Windows и Mathematica 8.0.4 приведенный ниже код выполняется для запрошенного DIM=200 примерно за 13 минут, для DIM=50 код выполняется за 6 секунд.


$starttime = AbsoluteTime[]; Quiet[LaunchKernels[]]; 
DIM = 200; 
Print["$Version = ", $Version, "  |||  ", "Number of Kernels : ", Length[Kernels[]]]; 
f[r_] := f[r] = Sum[(((-1)^n*(-(2*n) + 2*r - 7)!!)*x^(-(2*n) + r - 1))/(2^n*n!*(-(2*n) + r - 1)!), {n, 0, r/2}]; 
Nw = Transpose[Table[f[j], {i, 1}, {j, 5, DIM, 1}]]; 
nw2 = Nw . Transpose[Nw]; 
Print["Seconds for expanding Nw.Transpose[Nm] ", Round[First[AbsoluteTiming[nw3 = ParallelMap[Expand, nw2]; ]]]]; 
Print["do the integral once: ", Integrate[x^n, {x, -1, 1}, Assumptions -> n > -1]]; 
Print["the integration can be written as a simple rule: ", intrule = (pol_Plus)?(PolynomialQ[#1, x] & ) :> 
     (Select[pol,  !FreeQ[#1, x] & ] /. x^(n_.) /; n > -1 :> ((-1)^n + 1)/(n + 1)) + 2*(pol /. x -> 0)]; 
Print["Seconds for integrating Nw.Transpose[Nw] : ", Round[First[AbsoluteTiming[X1 = ParallelTable[row /. intrule, {row, nw3}]; ]]]]; 
Print["expanding: ", Round[First[AbsoluteTiming[preY1 = ParallelMap[Expand, D[Nw, {x, 2}] . Transpose[D[Nw, {x, 2}]]]; ]]]]; 
Print["Seconds for integrating : ", Round[First[AbsoluteTiming[Y1 = ParallelTable[py /. intrule, {py, preY1}]; ]]]]; 
Print["X1 = ", (Shallow[#1, {4, 4}] & )[X1]]; 
Print["Y1 = ", (Shallow[#1, {4, 4}] & )[Y1]]; 
Print["seq Y1 : ", Simplify[FindSequenceFunction[Diagonal[Y1], n]]]; 
Print["seq X1 0 : ",Simplify[FindSequenceFunction[Diagonal[X1, 0], n]]]; 
Print["seq X1 2: ",Simplify[FindSequenceFunction[Diagonal[X1, 2], n]]]; 
Print["seq X1 4: ",Simplify[FindSequenceFunction[Diagonal[X1, 4], n]]]; 
Print["overall time needed in seconds: ", Round[AbsoluteTime[] - $starttime]]; 
person Rolf Mertig    schedule 08.11.2011
comment
Уважаемый мистер Рольф, как преобразовать этот код, если мне нужны два интеграла от X1 = aIntegrate[Nw . Транспонировать[Nw], {x, -1, 0,3}]+b Интегрировать[Nw . Транспонировать[Nw], {x, 0,3, 1}]; константы а и b. Большое спасибо за этот тип подробностей. Люди должны учиться у вас, как давать решение. Большое Вам спасибо. - person George Mills; 29.11.2011

Я изменил интеграцию списка в список интеграций, чтобы можно было использовать ParallelTable:

X1par=ParallelTable[Integrate[i, {x, -1, 1}], {i, Nw.Transpose[Nw]}];

X1par==X1

(* ===> True *)

Y1par = ParallelTable[Integrate[i,{x,-1,1}],{i,D[Nw,{x,2}].Transpose[D[Nw,{x,2}]]}]

Y1 == Y1par

(* ===> True *)

В моих таймингах с {j, 5, 30, 1} вместо {j, 5, 200, 1} для ограничения используемого времени это примерно в 3,4 раза быстрее на моем четырехъядерном процессоре. Но это можно сделать еще быстрее, если:

X2par = Parallelize[Integrate[#, {x, -1, 1}] & /@ (Nw.Transpose[Nw])]

X2par == X1par == X1

(* ===> True *)

Это примерно в 6,8 раза быстрее, в 2,3 раза больше из-за Parallelize.

Timing и AbsoluteTiming не очень заслуживают доверия, когда речь идет о параллельном выполнении. Я использовал AbsoluteTime до и после каждой строки и взял разницу.


ИЗМЕНИТЬ

Мы не должны забывать ParallelMap:

На самом грубом уровне списка (1):

ParallelMap[Integrate[#, {x, -1, 1}] &, Nw.Transpose[Nw], {1}]  

На самом глубоком уровне списка (наиболее тонкое распараллеливание):

ParallelMap[Integrate[#, {x, -1, 1}] &, Nw.Transpose[Nw], {2}]
person Sjoerd C. de Vries    schedule 05.11.2011
comment
Можно ли быть быстрее, используя упрощенную форму формулы f[r_] = FullSimplify[ Sum[(((-1)^n*(2*r - 2*n - 7)!!)/(2^nn!*(r - 2*n - 1)!)) x^(r - 2*n - 1), {n, 0, r/2}], r › 0 && r [Элемент ] Целые числа] упрощается до $$ f(r)=-\frac{\sqrt{\pi } (-1)^r 2^{r-3} x^{r-1} \, 2\tilde {F}_1\left(\frac{1-r}{2},1-\frac{r}{2};\frac{7}{2}-r;\frac{1}{x^2} \справа)}{\Гамма (г)}. $$ Но это не работает с этой формулой f[r] := -(1/Gamma[r]) (-1)^r 2^(-3 + r) Sqrt[[Pi]] [Xi]^(-1 + r) Гипергеометрический2F1Регуляризованный[(1 - r)/2, 1 - r/2, 7/2 - r, 1/[Xi]^2]; - person George Mills; 06.11.2011
comment
@Sjoerd, твоя 10-тысячная вечеринка приближается! Вы купили достаточно пива? - person Dr. belisarius; 06.11.2011
comment
@George В функции, упомянутой в вашем комментарии, Sqrt[[Pi]] должен быть Sqrt[Pi], а [Xi] должен быть [Xi]. Также это ускоряет работу, если вы определяете Xi. В этом случае кажется, что только накладные расходы на распараллеливание перевешивают любые выгоды от распараллеливания. Не уверен, почему это так - person Sjoerd C. de Vries; 06.11.2011
comment
@belisarius Я чувствую, что это произойдет, когда я буду спать, к сожалению, то есть через пару минут. Звонит моя вторая половинка (на самом деле она пишет ;-)) - person Sjoerd C. de Vries; 06.11.2011
comment
@Sjoerd Так что я буду пить пиво один :) Заранее поздравляю! - person Dr. belisarius; 06.11.2011
comment
@mr.wizard Спасибо, что подтолкнули меня к краю! Вау, теперь я чувствую себя совсем иначе. - person Sjoerd C. de Vries; 06.11.2011
comment
Надеюсь, вам нравится видеть все удаленные ответы. Если нет, взгляните на meta.stackexchange.com/questions/110535. - person Mr.Wizard; 06.11.2011
comment
@George Джордж, я забыл о тенденции комментария StackOverflow опускать обратную косую черту. В любом случае, возможно, нам следует продолжить изучение неустойчивой работы инструментов распараллеливания. Возможно, вы могли бы опубликовать свой последний комментарий как новый вопрос? - person Sjoerd C. de Vries; 07.11.2011