# Landau distribution or something similar

**URL:** <https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063>\
**Category:** Statistics\
**Created:** [August 9, 2021, 7:47am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063 "2021-08-09T07:47:18Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 9, 2021, 7:47am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/1 "2021-08-09T07:47:19Z")

</div>

Good day everyone!

I need a tiny toss in the right direction since I am stuck with some statistics problems.

I am investigating signals which are similar to a Landau distribution but I don’t have a good physical model to describe those (and also don’t really have to time to develop one, but it might be a nice master thesis candidate `;)` ). Anyways, I am trying to characterise the distribution by its “FWHM” and peak location/height (just like a simple Gaussian) and then investigate data where I have a mix of these signals, with different widths/heights and peaks – usually two or three of them.

Here is an example with a single peak:

![Screenshot 2021-08-09 at 09.16.04](https://global.discourse-cdn.com/julialang/original/3X/1/9/195176aedca18d1216d1f5b295d50b33c14d6ef5.png)

here with two peaks:

![Screenshot 2021-08-09 at 09.17.05](https://global.discourse-cdn.com/julialang/original/3X/3/c/3c1d7b20e430ef64deb09ef06bb4987c8abe2d3a.png)

and here with 3-4 peaks:

![Screenshot 2021-08-09 at 09.45.27](https://global.discourse-cdn.com/julialang/original/3X/b/5/b5e5ccb9a3f10a4472bac078e7574554c08dd355.png)

Just for reference: in the ROOT (CERN) framework, there is a Landau function (see [ROOT: Probability Density Functions (PDF)](https://root.cern.ch/doc/master/group__PdfFunc.html#ga53d01e04de833eda26560c40eb207cab) and [TMath](https://root.cern.ch/root/html524/TMath.html#TMath:Landau)) which is implemented here: [TMath - source file](https://root.cern.ch/root/html524/src/TMath.cxx.html#fsokrB) and calls the `G110 denlan` from `CERNLIB` ([https://cmd.inp.nsk.su/old/cmd2/manuals/cernlib/shortwrups/node151.html](https://cmd.inp.nsk.su/old/cmd2/manuals/cernlib/shortwrups/node151.html)). I found the Fortran source code of the `DENLAN` function in the tarball ([Index of /download/2006\_source/tar](https://cernlib.web.cern.ch/download/2006_source/tar/)).

Since I could not find any implementation of the Landau function in Julia packages (`Distributions.jl` etc.) I will probably just go ahead and reimplement it (incl. a PR to `Distributions.jl`) and then try to fit it with a mixed model and least-squares fit with `JuMP.jl` or so…

…but before I go ahead, I was wondering if there is a better approach or maybe even an existing implementation I overlooked. My first attempts with crude mixed Gaussian model fittings went horribly wrong, due to the asymmetry `;)`  
My current best attempt is using `Peaks.jl` and then fiddling around with cuts on the prominence and width of the peaks, but it’s quite messy and not stable enough. Especially when the peaks are not well separated, of course (see last example)

Sorry for this very broad question…

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [August 9, 2021, 8:03am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/2 "2021-08-09T08:03:34Z")

</div>

[`GSL.jl`](https://github.com/JuliaMath/GSL.jl) is a wrapper of the [Gnu Scientific Library](https://www.gnu.org/software/gsl/doc/html/index.html), which has the [Landau Distribution](https://www.gnu.org/software/gsl/doc/html/randist.html#the-landau-distribution).

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 9, 2021, 8:53am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/3 "2021-08-09T08:53:49Z")

</div>

Ah, I have not thought of that, thanks, I’ll check it out `:)`

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 9, 2021, 6:57pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/4 "2021-08-09T18:57:08Z")

</div>

OK, I am a bit closer but I had to reimplement the Landau function (with all the helpers) since the one in `GSL.jl` is not parametrised, it’s the one with fixed parameters. I was confused since in the ROOT source it’s stated that the implementation is taken from CERNLIB and also used in GSL, however in GSL only the simplified one is implemented: [ROOT: math/mathcore/src/PdfFuncMathCore.cxx Source File](https://root.cern/doc/master/PdfFuncMathCore_8cxx_source.html#l00021)

Anyways I’ll wrap it up and aim for a PR in `Distributions.jl`, maybe someone finds it useful.

Meanwhile, I still struggle to fit my data, so currently I am doing a mix of the Landau and a Gaussian, but at least I made progress. Thanks again `:)`

![Screenshot 2021-08-09 at 21.06.01](https://global.discourse-cdn.com/julialang/original/3X/f/7/f7d872f15942856aebe9d86e7905ef26026108eb.png)

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 9, 2021, 7:32pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/5 "2021-08-09T19:32:42Z")

</div>

Try looking through the list, & add if I missed anything useful

> [@Random variables in Julia (working list)](https://discourse.julialang.org/t/random-variables-in-julia-working-list/48762):
>
> Here is my summary of probability distributions in Julia. This is a Julia version of [CRAN Task View: Probability Distributions](https://cran.r-project.org/web/views/Distributions.html). Packages with distributions: Package Description Note [Distributions](https://github.com/JuliaStats/Distributions.jl).jl fit(), rand(), truncated(), mixture(), convolve(), product\_distribution(). 100+ distributions Maintained. 585 stars. @ johnczito @ mbesancon [StatsFuns](https://github.com/JuliaStats/StatsFuns.jl).jl Wraps R. 14 distributions, 10 properties each Maintained. [Rmath](https://github.com/JuliaStats/Rmath.jl).jl Wraps R. d-p-q-r Maintained. [GSL](https://github.com/JuliaMath/GSL.jl).jl Wraps C. [38 distributio…](https://www.gnu.org/software/gsl/doc/html/randist.html)

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [August 9, 2021, 8:29pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/6 "2021-08-09T20:29:15Z")

</div>

Hey,

if you know (can code) the function that you want to fit with, you can quickly construct the model with two, three, or several PDF using [AlgebraPDF](https://github.com/mmikhasenko/AlgebraPDF.jl)

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [August 9, 2021, 8:33pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/7 "2021-08-09T20:33:12Z")

</div>

BTW, the signals look like SiPM noise 🙂

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 9, 2021, 9:14pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/8 "2021-08-09T21:14:47Z")

</div>

[https://github.com/JuliaStats/Distributions.jl/pull/1245](https://github.com/JuliaStats/Distributions.jl/pull/1245)

for posterity and discussion regarding license

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 9, 2021, 9:17pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/9 "2021-08-09T21:17:24Z")

</div>

That’s the problem, unfortunately. I don’t have a good physical model and the Landau distribution is fairly complicated… The usable approximations use a lot of hardcoded arrays 🙈

> [@misha\_mikhasenko](#):
>
> BTW, the signals look like SiPM noise 🙂

Ha, well, it’s a PMT signal, but not primarily noise. It’s the time residual distribution of hits with respect to muon track reconstructions.

Btw. I just had a quick chat with @jling and he already made a PR to `Distributions.jl` but the license is problematic. I literally did basically the same implementation 🙈

Now it works really nicely, so I’d like to pour it into a package but not sure how – w.r.t. licensing.

![Screenshot 2021-08-09 at 23.17.13](https://global.discourse-cdn.com/julialang/original/3X/f/7/f7a1ff9ed3bd0a289d51c05e3d461b33a06caa09.png)

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [August 10, 2021, 12:33am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/10 "2021-08-10T00:33:57Z")

</div>

What’s the concern about licensing?  
If you use the ROOT code, you’ll have to use GPL. I think the easiest is to just put this in its own package. Does it need to live in Distributions.jl?

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [August 10, 2021, 7:34am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/11 "2021-08-10T07:34:14Z")

</div>

> [@tamasgal](#):
>
> Now it works really nicely

I would be curious to see how to fit mixture fractions with Distributions. When I was playing with it time ago, I did not figure out.

> [@tamasgal](#):
>
> I literally did basically the same implementation 🙈

It might well be that you find the description (that is close to implementation) is some physics book, or Wikipedia page 😆 so you can well reference them

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 10, 2021, 7:40am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/12 "2021-08-10T07:40:47Z")

</div>

> [@jstrube](#):
>
> If you use the ROOT code, you’ll have to use GPL. I think the easiest is to just put this in its own package. Does it need to live in Distributions.jl?

Yes, that’s the plan! Since @jling already got a bit further by adding the `Distributions.jl` interface, he will probably go ahead and file a new package which will depend on `Distributions.jl` but decoupled license-wise. `:)`

> [@misha\_mikhasenko](#):
>
> I would be curious to see how to fit mixture fractions with Distributions. When I was playing with it time ago, I did not figure out.

Ah, that’s just a crude chi2-approach and minimised using `Optim.jl`. I can sum it up in a blog post if you like! But it’s not groundbreaking `:)` I’ll have to jump to `JuMP.jl` since I’ll probably need a bit more control over constraints…

> [@misha\_mikhasenko](#):
>
> t might well be that you find the description (that is close to implementation) is some physics book, or Wikipedia page 😆 so you can well reference them

Yes in fact we followed the source code of ROOT, CERLIB and GSL, as there are no easy-to-implement formulas here. Everything is heavily baked-in, see [ROOT: math/mathcore/src/QuantFuncMathCore.cxx Source File](https://root.cern/doc/master/QuantFuncMathCore_8cxx_source.html#l00189) `;D`

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 10, 2021, 9:00am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/13 "2021-08-10T09:00:04Z")

</div>

> [@jstrube](#):
>
> If you use the ROOT code, you’ll have to use GPL.

ROOT seems to [use LGPL](https://root.cern/about/license/), which doesn’t have the viral property of GPL. `Distributions.jl` could say “this file is under LGPL” and that’s it, that doesn’t affect the rest of the package

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 10, 2021, 9:07am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/14 "2021-08-10T09:07:12Z")

</div>

Ah OK, interesting. I am always confused about such peculiarities of the licensing word. To be honest, I still don’t fully understand which part of the license permits the inclusion into an MIT licensed product 🙈

I found this, which kind of says the opposite if I understand correctly: [ruby - How does using a LGPL gem affect my MIT licensed application? - Software Engineering Stack Exchange](https://softwareengineering.stackexchange.com/a/141848)

There it’s stated:

> The significant difference with GPL is, that it doesn’t impose the license on software using the library. Only if you’d modify the library or directly include parts of the code in your software, then your code would have to be LGPL.

In our case, we take parts of the original code (from CERNLIB/ROOT/GSL), transpile it to Julia and then include it in the source code.  
Doesn’t that require that the target project is also `LGPL`?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 10, 2021, 9:15am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/15 "2021-08-10T09:15:42Z")

</div>

> [@tamasgal](#):
>
> Doesn’t that require that the target project is also `LGPL` ?

Not in its entirety. I understand if `Distributions.jl` don’t want complexity and would prefer a codebase which has a single license, but LGPL wouldn’t make the whole project, it’d be “mostly MIT with a single file under LGPL”.

Also Julia itself is effectively multi-license at the moment, with most of the codebase under MIT, and some bits using [different licenses](https://github.com/JuliaLang/julia/blob/cd6e67f38bc8ffcd4fbb05971452630609649a91/THIRDPARTY.md)

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 10, 2021, 10:23am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/16 "2021-08-10T10:23:10Z")

</div>

[https://github.com/SiLab-Bonn/pylandau](https://github.com/SiLab-Bonn/pylandau)

indeed it can live in a separate package with a difference license and people have done it in Python.

And here’s ours:  
[https://github.com/Moelf/LandauDistribution.jl](https://github.com/Moelf/LandauDistribution.jl)

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [August 11, 2021, 1:12pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/17 "2021-08-11T13:12:06Z")

</div>

The parameters of the Landau distribution, mu and c, are related to the shift and stretching, right?  
If so, you can use grid interpolation for the shape.

BTW, the expression for p(x;mu,c) in wikipedia does not look like (x-mu)/c can be used as an argument

> **[Landau distribution](https://en.wikipedia.org/wiki/Landau_distribution)**
>
> c
> ∈
> (
> 0
> ,
> ∞
> )
>       
>     
> {\\displaystyle c\\in (0,\\infty )}
>   
> — scale parameter 
> In probability theory, the Landau distribution is a probability distribution named after Lev Landau.
> Because of the distribution's "fat" tail, the moments of the distribution, like mean or variance, are undefined. The distribution is a particular case of stable distribution.
> The probability density function, as written originally by Landau...

a typo (t/c)? Could you check, please?

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 12, 2021, 7:53am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/18 "2021-08-12T07:53:55Z")

</div>

Thanks Jerry! Is there anything missing for the package registration? `:)`

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 12, 2021, 10:28am UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/19 "2021-08-12T10:28:31Z")

</div>

> [@misha\_mikhasenko](#):
>
> The parameters of the Landau distribution, mu and c, are related to the shift and stretching, right?  
> If so, you can use grid interpolation for the shape.

In the original code the parameters are called `xi` and `x0`. Here is a quick overview how they shape the distribution:

```julia
using PGFPlotsX
using LaTeXStrings
using Colors

push!(PGFPlotsX.CUSTOM_PREAMBLE, raw"\pgfplotsset{scale=2.0}")

xs = range(-10, 40; length=500)
@pgf axis = Axis({no_marks, ultra_thick})
xis = 1:2:10
x0s = 1:2:10
for (xi, color) ∈ zip(xis, distinguishable_colors(length(xis), [RGB(1,0,0), RGB(0,0,0)]))
    for (x0, alpha) ∈ zip(x0s, range(1, 0.2; length=length(x0s)))
        push!(axis, @pgf Plot({color = color, opacity = alpha}, Coordinates(xs, [landau_pdf(x, xi, x0) for x ∈ xs])))
        push!(axis, LegendEntry("xi = $xi, x0 = $x0"))
    end
end
axis

```

![Screenshot 2021-08-12 at 12.28.24](https://global.discourse-cdn.com/julialang/original/3X/6/e/6e1d3dbc9be4330fd50068921cc96410bc219eda.png)

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 12, 2021, 1:58pm UTC](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063/20 "2021-08-12T13:58:45Z")

</div>

Ah, @misha_mikhasenko maybe the problem you encountered was that for `x0<0` the function is completely flat… In my fit, I simply introduced an additional shift to `x`. Btw. I also fit an extra scale factor, since I am using the function outside of its context.

[Next page](https://discourse.julialang.org/t/landau-distribution-or-something-similar/66063.md?page=2)
