Re: Compile Fourier (2)

*To*: mathgroup at smc.vnet.net*Subject*: [mg64916] Re: Compile Fourier (2)*From*: rknapp at wolfram.com*Date*: Tue, 7 Mar 2006 06:12:27 -0500 (EST)*References*: <duh2s0$5qg$1@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

The reason that the compiled function is slower is because when you use AppendTo[b, a], all of the individual elements of b have to be copied to a new list with longer length then the elements of a are put in at the end. This means that as you execute the loop, you copy 64*64*1 elements the first time through 64*64*2 elements the second time through ... 64*64*100 elements the last time through making a total of roughly 64*64*100^2/2 = 20 million elements that have to be copied. Thats a lot of copying. The uncompiled version use references to the expressions (effectively pointers) so it only has to copy these, not the individual elements You can avoid the excess copying by using commands like Table: cf2 = Compile[{{m, _Complex, 2}}, Module[{a = m, b}, b = Table[a = a + Fourier[Re[InverseFourier[m]]], {100}]; Re[Prepend[b, m]]], {{Fourier[_], _Complex, 2}, {InverseFourier[_], _Complex, 2}}] runs just as fast at the uncompiled version. In general, it is a good idea to avoid calling Append inside a loop. (Even for the uncompiled case -- thought it will take more iterations for it to be a problem here.) If you don't know how long the result will be ahead of time, you can use Reap and Sow as alternatives. For an example like this, there is very little advantage to compiling, since most of the time is spent computing the FFT anyway. ---- If you are interested in using pseudospectral methods for evolution equations, you can do this directly through NDSolve and there are some built in functions that will compute pseudospectral derivative approximations for you. Both are described in the advanced documentation for NDSolve: http://documents.wolfram.com/v5/Built-inFunctions/NumericalComputation/EquationSolving/AdvancedDocumentation/NDSolve.html look under the topic Pseudospectral derivatives under the heading Partial Differential Equations on that page For example, In[45]:= Timing[Block[{ L = 10},NDSolve[{D[u[t,x,y],t, t] \[Equal] D[u[ t,x,y],x,x] + D[u[t,x,y], y,y] + Sin[u[t,x,y]], u[0, x, y] \[Equal] Exp[-x^2-y^2],(D[u[ t, x, y], t] /. t\[Rule]0) \[Equal] 0, u[t, L,y] \[Equal] u[t,-L, y], u[t, x, L] \[Equal] u[t, x, -L]}, u, {t,0,L},{x,-L,L},{y,-L,L}, Method\[Rule]{"MethodOfLines", "SpatialDiscretization"\[Rule]{"TensorProductGrid", "DifferenceOrder"->"Pseudospectral"}}]]] Out[45]= {0.625 Second, {{u -> InterpolatingFunction[{{0., 10.}, {..., -10., 10., ...}, {..., -10., 10., ...}}, <>]}}} Solves the sine-Gordon equation in two spatial dimensions with periodic boundary conditions using the pseudospectal method.