File indexing completed on 2025-02-02 04:15:57

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_random_source.h"
0008 
0009 #include <boost/random/taus88.hpp>
0010 #include <boost/random/uniform_smallint.hpp>
0011 #include <boost/random/normal_distribution.hpp>
0012 
0013 
0014 struct KisRandomSource::Private
0015 {
0016     Private()
0017         : uniformSource(qrand()) {}
0018 
0019     Private(int seed)
0020         : uniformSource(seed) {}
0021 
0022     /**
0023      * Taus88's numbers are not too random, but it works fast and it
0024      * can be copied very quickly (three 32-bit integers only).
0025      *
0026      * Average cycle: 2^88 steps
0027      */
0028     boost::taus88 uniformSource;
0029 };
0030 
0031 
0032 KisRandomSource::KisRandomSource()
0033     : m_d(new Private)
0034 {
0035 }
0036 
0037 KisRandomSource::KisRandomSource(int seed)
0038     : m_d(new Private(seed))
0039 {
0040 }
0041 
0042 KisRandomSource::KisRandomSource(const KisRandomSource &rhs)
0043     : KisShared(),
0044       m_d(new Private(*rhs.m_d))
0045 {
0046 }
0047 
0048 KisRandomSource& KisRandomSource::operator=(const KisRandomSource &rhs)
0049 {
0050     if (this != &rhs) {
0051         *m_d = *rhs.m_d;
0052     }
0053 
0054     return *this;
0055 }
0056 
0057 KisRandomSource::~KisRandomSource()
0058 {
0059 }
0060 
0061 qint64 KisRandomSource::generate() const
0062 {
0063     return m_d->uniformSource();
0064 }
0065 
0066 int KisRandomSource::generate(int min, int max) const
0067 {
0068     boost::uniform_smallint<int> smallint(min, max);
0069     return smallint(m_d->uniformSource);
0070 }
0071 
0072 qreal KisRandomSource::generateNormalized() const
0073 {
0074     const qint64 v = m_d->uniformSource();
0075     const qint64 max = m_d->uniformSource.max();
0076     // we don't have min, because taus88 is always positive
0077 
0078     return qreal(v) / max;
0079 }
0080 
0081 qreal KisRandomSource::generateGaussian(qreal mean, qreal sigma) const
0082 {
0083     boost::normal_distribution<qreal> normal(mean, sigma);
0084     return normal(m_d->uniformSource);
0085 }