Back to Laplace-distributed random numbers
#ifndef PASTELSYS_RANDOM_LAPLACE_HPP
#define PASTELSYS_RANDOM_LAPLACE_HPP
#include "pastel/sys/random/random_laplace.h"
#include "pastel/sys/random/random_uniform.h"
#include "pastel/sys/random/random_exponential.h"
namespace Pastel
{
    template <typename Real>
    Real randomLaplace()
    {
        /*
       Laplace distribution is simply a 
       two-sided Exponential distribution.
       See the derivation for Exponential
       distribution. We could call its
       generation function, but doing it
       this way saves us generating one 
       additional random variable.
       */
        Real u = 0;
        do
        {
            u = random<Real>(-1, 1);
        }
        while(u == 0);
        if (u < 0)
        {
            // Negative side.
            return std::log(-u);
        }
        // Positive side.
        return -std::log(u);
    }
    template <typename Real>
    Real randomLaplace(
        const NoDeduction<Real>& scale)
    {
        return Pastel::randomLaplace<Real>() * scale;
    }
    template <typename Real>
    Real laplacePdf(
        const NoDeduction<Real>& x)
    {
        return exponentialPdf<Real>(std::abs(x)) / 2;
    }
    template <typename Real>
    Real laplacePdf(
        const NoDeduction<Real>& x,
        const NoDeduction<Real>& scale)
    {
        Real invScale = inverse(scale);
        return Pastel::laplacePdf<Real>(x * invScale) * invScale;
    }
}
#endif