From: David Romero-Antequera on
"Joseph " <don'twannapostit(a)nopers.com> wrote in message <i3c8ca$9kg$1(a)fred.mathworks.com>...
> There seems to be a mistake in this code. I don't think
> for fun = funvector
>
> does what you want.
>
>
>
>
>
> "David Romero-Antequera" <dromero_fisica(a)yahoo.es> wrote in message <i3c7i1$adm$1(a)fred.mathworks.com>...
> > Hello, everyone.
> >
> > I need some suggestion to make the following function faster.
> >
> > function psi=NLF(z,y,funvector,orig_size)
> > psi=zeros(size(y));
> > Y=ifft2(reshape(y,orig_size));
> > for fun=funvector
> > fY=feval(fun{2},z,Y);
> > kY=fun{1}.*fft2(fY);
> > kY=kY(:);
> > psi=psi+kY;
> > end
> > end
> >
> > where z is a double scalar, y is a complex matrix, funvector is a cell array with double scalars in the first column and function handles in the second, and orig_size is a 2x1 matrix.
> >
> > As you can see, I need to compute the inverse Fourier transform of the vector Y, then evaluate it into several user-provided functions and compute the Fourier transform and add all of that together. This is part of an ODE, so you might expect that this is going to be evaluated THOUSANDS of times, and every second counts.
> >
> > Any suggestions?
> > Thanks in advance.

Actually, it does. It is working, that is for sure.
However, I have just modified in order to make it easier to change it to a "parfor". Here it is:

function psi=NLF(z,y,funvector,orig_size)
psi=zeros(size(y));
Y=cifft2(reshape(y,orig_size));
for ii=1:size(funvector,2) % change for a parfor
fun=funvector(:,ii);
fY=feval(fun{2},z,Y);
kY=fun{1}.*cfft2(fY);
kY=kY(:);
psi=psi+kY;
end
end
From: David Romero-Antequera on
dpb <none(a)non.net> wrote in message <i3c8cs$gq6$3(a)news.eternal-september.org>...
> David Romero-Antequera wrote:
> ...
>
> > As you can see, I need to compute the inverse Fourier transform of the
> > vector Y, then evaluate it into several user-provided functions and
> > compute the Fourier transform and add all of that together. This is part
> > of an ODE, so you might expect that this is going to be evaluated
> > THOUSANDS of times, and every second counts.
> >
> > Any suggestions?
> ...
>
> Profile, profile, profile...
>
> For all we know from the supplied data the bulk of the time is spent in
> the user-supplied functions.
>
> Don't waste time trying to optimize until know where the ouch actually is.
>
> --

That's something that it is not in my hands. On the other hand, the user provided function, can be something that can't be optimized anymore, like

@(t,f) abs(f).^2;

I just want to make sure that there's nothing else that I can do.
From: Walter Roberson on
David Romero-Antequera wrote:

> function psi=NLF(z,y,funvector,orig_size)
> psi=zeros(size(y));
> Y=cifft2(reshape(y,orig_size));
> for ii=1:size(funvector,2) % change for a parfor
> fun=funvector(:,ii);
> fY=feval(fun{2},z,Y);
> kY=fun{1}.*cfft2(fY);
> kY=kY(:);
> psi=psi+kY;
> end
> end

feval() is relatively slow. Use function handles if possible.

I suspect the above will not automatically split well, as there is no
assurance available that the invoked functions will not alter variables in the
routine via assignin() : it is not provably parallel. I do not know if there
is any way to get around that except to use spmd instead of parfor .