Если это действительно интерполяция радиальных функций, которая замедляет вас, вы можете рассмотреть ручное кодирование этой части, основываясь на вашем знании точек выборки.Как показано ниже, это дает значительное ускорение:
Я настроил все с помощью вашей записи.lookuprvals
- это список значений 100000 r
для поиска времени.
Сначала рассмотрим интерполяцию акций как базовую отметку
With[{interp=Interpolation[N@Transpose@{rvals,yvals}]},
Timing[interp[lookuprvals]][[1]]]
Out[259]= 2.28466
Переключение на интерполяцию 0-го порядка уже выполненона порядок быстрее (первый порядок почти такой же скорости):
With[{interp=Interpolation[N@Transpose@{rvals,yvals},InterpolationOrder->0]},
Timing[interp[lookuprvals]][[1]]]
Out[271]= 0.146486
Мы можем получить еще 1,5 порядка, рассчитав индексы напрямую:
Module[{avg=MovingAverage[yvals,2],idxfact=N[(pts-1) /Log[Rmax/Rstep]]},
Timing[res=Part[avg,Ceiling[idxfact Log[lookuprvals]]]][[1]]]
Out[272]= 0.006067
В качестве среднего уровня,выполните линейно-линейную интерполяцию вручную.Это медленнее, чем вышеупомянутое решение, но все же намного быстрее, чем стандартная интерполяция:
Module[{diffs=Differences[yvals],
idxfact=N[(pts-1) /Log[Rmax/Rstep]]},
Timing[Block[{idxraw,idxfloor,idxrel},
idxraw=1+idxfact Log[lookuprvals];
idxfloor=Floor[idxraw];
idxrel=idxraw-idxfloor;
res=Part[yvals,idxfloor]+Part[diffs,idxfloor]idxrel
]][[1]]]
Out[276]= 0.026557
Если у вас есть память для этого, я бы кэшировал сферические гармоники и радиус (или даже индекс радиуса) на полномсетка.Затем сгладьте кэши сетки, чтобы вы могли выполнить
Sum[ interpolate[yvals[lm],gridrvals] gridylmvals[lm], {lm,lmvals} ]
и воссоздайте свою сетку, как обсуждалось здесь .