Hello,

alright - FFTs are a difficult topic. We likely are seeing numerical and logical (as in: roofit has a bug) issues here.

## Bins

The first thing I want to recommend is to use a high number of bins for x. The factory uses 500, as I found out with

```
onemip = w.factory('Landau::onemip(x[0,500], mpv[40,0,100], sigma_landau[5,0,20])')
x = w.obj("x")
x.getBinning().Print()
```

Now, what you don’t see, unfortunately (because Doxygen for many RooFit classes is misconfigured **improvements coming soon**, at least in the master documentation), the numerical FFT needs a lot of bins for decent accuracy. See the comments at the top of:

https://root.cern.ch/doc/master/RooFFTConvPdf_8cxx_source.html

The factory doesn’t seem to have a way to communicate the number of bins, so you unfortunately have to

```
x = w.obj("x")
x.setBins(2000)
```

and please do this *before* evaluating anything, because this allocates the caches. I hope 2000 will do a good job.

## Periodicity

The next issue might be the cyclical nature of FFTs. Since they are analysing frequencies, they see your input data as a grid with cyclical boundary conditions. After all, frequencies only make sense if something oscillates …

If you had only 3 bins, the FFT sees the bins as follows:

```
... 0 1 2 0 1 2 ...
```

Now, if the Landau has a tail to the right (because the range of x is not large enough), the FFT sees periodic jumps. This leads to artifacts in Fourier space and might well be the cause of the non-linearity of the FFT. You could try to choose the range of x large such that the dropoff at the high end of x’s value range is small. Also, try a generous buffer zone `setBufferFraction(0.2)`

(default is 0.1), which extends the grid, on which the FFTs run. What you get is an x with an extended value range, this is FFT-ed, and artifacts due to boundary conditions should mostly affect the buffer zone. When evaluating the PDFs, the buffer zone is stripped away, so you are left with a better-behaved PDF.

## Expert-level FFT

To avoid problems with the boundary conditions, one could multiply a window function on top of the Landaus before transforming them. A proper window would pull the Landaus to zero at the boundaries, removing all problems with the periodicity.

The poor-man’s solution is the generous buffer zone. Play around with it.

Whether 2000 bins and 0.2 will do the job, isn’t clear to me. I guess that these are good starting points, maybe overdoing it a bit. You might tweak them up or down a bit.

## Speed

One more thing: FFTs like powers of 2. It would be better to use 2048 bins. However, since the buffer zone comes on top of that, you will be left with something like 245x bins. If you want to squeeze out the last bits of speed, you can play around with bin numbers around 1706.6 (2048/1.2). You might hit the magic number and get a bit more speed out of it.

## Commutativity:

That must be a bug. I will try to investigate.

Cheers,

Stephan