Code Monkey home page Code Monkey logo

eigenrand's Introduction

EigenRand : The Fastest C++11-compatible random distribution generator for Eigen

EigenRand is a header-only library for Eigen, providing vectorized random number engines and vectorized random distribution generators. Since the classic Random functions of Eigen relies on an old C function rand(), there is no way to control random numbers and no guarantee for quality of generated numbers. In addition, Eigen's Random is slow because rand() is hard to vectorize.

EigenRand provides a variety of random distribution functions similar to C++11 standard's random functions, which can be vectorized and easily integrated into Eigen's expressions of Matrix and Array.

You can get 5~10 times speed by just replacing old Eigen's Random or unvectorizable c++11 random number generators with EigenRand.

Features

  • C++11-compatible Random Number Generator
  • 5~10 times faster than non-vectorized functions
  • Header-only (like Eigen)
  • Can be easily integrated with Eigen's expressions
  • Currently supports only x86, x86-64(up to AVX2), and ARM64 NEON architecture.

Requirement

  • Eigen 3.3.4 ~ 3.4.0
  • C++11-compatible compilers

Build for Test & Benchmark

You can build a test binary to verify if EigenRand is working well. First, make sure you have Eigen 3.3.4~3.4.0 installed in your compiler include folder. Also make sure you have cmake 3.9 or higher installed. After then, you can build it following:

$ git clone https://github.com/bab2min/EigenRand
$ cd EigenRand
$ git clone https://github.com/google/googletest
$ pushd googletest && git checkout v1.8.x && popd
$ mkdir build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make
$ ./test/EigenRand-test # Binary for unit test
$ ./EigenRand-accuracy # Binary for accuracy test of univariate random distributions
$ ./EigenRand-benchmark # Binary for performance test of univariate random distributions
$ ./EigenRand-benchmark-mv # Binary for performance test of multivariate random distributions

You can specify additional compiler arguments including target machine options (e.g. -mavx2, -march) like:

$ cmake -DCMAKE_BUILD_TYPE=Release -DEIGENRAND_CXX_FLAGS="-march=native" ..

Alternatively cmake preset with cmake 3.21 or later can be used to compile EigenRand which also integrates nicely in VSCode

cmake --preset default
cmake --build --preset default
ctest --preset default

Documentation

https://bab2min.github.io/eigenrand/

Functions

Random distributions for real types

Function Generator Scalar Type VoP Description Equivalent to
Eigen::Rand::balanced Eigen::Rand::BalancedGen float, double Yes generates real values in the [-1, 1] range Eigen::DenseBase<Ty>::Random for floating point types
Eigen::Rand::beta Eigen::Rand::BetaGen float, double generates real values on a beta distribution
Eigen::Rand::cauchy Eigen::Rand::CauchyGen float, double Yes generates real values on the Cauchy distribution. std::cauchy_distribution
Eigen::Rand::chiSquared Eigen::Rand::ChiSquaredGen float, double generates real values on a chi-squared distribution. std::chi_squared_distribution
Eigen::Rand::exponential Eigen::Rand::ExponentialGen float, double Yes generates real values on an exponential distribution. std::exponential_distribution
Eigen::Rand::extremeValue Eigen::Rand::ExtremeValueGen float, double Yes generates real values on an extreme value distribution. std::extreme_value_distribution
Eigen::Rand::fisherF Eigen::Rand::FisherFGen float, double generates real values on the Fisher's F distribution. std::fisher_f_distribution
Eigen::Rand::gamma Eigen::Rand::GammaGen float, double generates real values on a gamma distribution. std::gamma_distribution
Eigen::Rand::lognormal Eigen::Rand::LognormalGen float, double Yes generates real values on a lognormal distribution. std::lognormal_distribution
Eigen::Rand::normal Eigen::Rand::StdNormalGen, Eigen::Rand::NormalGen float, double Yes generates real values on a normal distribution. std::normal_distribution
Eigen::Rand::studentT Eigen::Rand::StudentTGen float, double Yes generates real values on the Student's t distribution. std::student_t_distribution
Eigen::Rand::uniformReal Eigen::Rand::UniformRealGen float, double Yes generates real values in the [0, 1) range. std::generate_canonical
Eigen::Rand::weibull Eigen::Rand::WeibullGen float, double Yes generates real values on the Weibull distribution. std::weibull_distribution
  • VoP indicates 'Vectorization over Parameters'.

Random distributions for integer types

Function Generator Scalar Type VoP Description Equivalent to
Eigen::Rand::binomial Eigen::Rand::BinomialGen int Yes generates integers on a binomial distribution. std::binomial_distribution
Eigen::Rand::discrete Eigen::Rand::DiscreteGen int generates random integers on a discrete distribution. std::discrete_distribution
Eigen::Rand::geometric Eigen::Rand::GeometricGen int generates integers on a geometric distribution. std::geometric_distribution
Eigen::Rand::negativeBinomial Eigen::Rand::NegativeBinomialGen int generates integers on a negative binomial distribution. std::negative_binomial_distribution
Eigen::Rand::poisson Eigen::Rand::PoissonGen int generates integers on the Poisson distribution. std::poisson_distribution
Eigen::Rand::randBits Eigen::Rand::RandbitsGen int generates integers with random bits. Eigen::DenseBase<Ty>::Random for integer types
Eigen::Rand::uniformInt Eigen::Rand::UniformIntGen int generates integers in the [min, max] range. std::uniform_int_distribution
  • VoP indicates 'Vectorization over Parameters'.

Multivariate distributions for real vectors and matrices

Generator Description Equivalent to
Eigen::Rand::MultinomialGen generates integer vectors on a multinomial distribution scipy.stats.multinomial in Python
Eigen::Rand::DirichletGen generates real vectors on a Dirichlet distribution scipy.stats.dirichlet in Python
Eigen::Rand::MvNormalGen generates real vectors on a multivariate normal distribution scipy.stats.multivariate_normal in Python
Eigen::Rand::WishartGen generates real matrices on a Wishart distribution scipy.stats.wishart in Python
Eigen::Rand::InvWishartGen generates real matrices on a inverse Wishart distribution scipy.stats.invwishart in Python

Random number engines

Description Equivalent to
Eigen::Rand::Vmt19937_64 a vectorized version of Mersenne Twister algorithm. It generates two 64bit random integers simultaneously with SSE2 & NEON and four integers with AVX2. std::mt19937_64
Eigen::Rand::P8_mt19937_64 a vectorized version of Mersenne Twister algorithm. Since it generates eight 64bit random integers simultaneously, the random values are the same regardless of architecture.

Performance

The following charts show the relative speed-up of EigenRand compared to references(equivalent functions of C++ std or Eigen for univariate distributions and Scipy for multivariate distributions).

  • Since there is no equivalent class to balanced in C++11 std, we used Eigen::DenseBase::Random instead.
  • Cases filled with orange are generators that are slower than reference functions.

Windows 2019, MSVC 19.29.30147, Intel(R) Xeon(R) Platinum 8171M CPU, AVX2, Eigen 3.4.0

Perf_AVX2_Win Perf_AVX2_Win_Mv1 Perf_AVX2_Win_Mv1

Ubuntu 18.04, gcc 7.5.0, Intel(R) Xeon(R) Platinum 8370C CPU, AVX2, Eigen 3.4.0

Perf_AVX2_Ubu Perf_AVX2_Ubu_Mv1 Perf_AVX2_Ubu_Mv1

macOS Monterey 12.2.1, clang 13.1.6, Apple M1 Pro, NEON, Eigen 3.4.0

Perf_NEON_mac Perf_NEON_mac_Mv1 Perf_NEON_mac_Mv1

You can see the detailed numerical values used to plot the above charts on the Action page.

Accuracy

Since vectorized mathematical functions may have a loss of precision, I measured how well the generated random number fits its actual distribution. 32768 samples were generated and Earth Mover's Distance between samples and its actual distribution was calculated for each distribution. Following table shows the average distance (and stdev.) of results performed 50 times for different seeds.

C++ std EigenRand
balanced* .0034(.0015) .0034(.0015)
chiSquared(7) .0260(.0091) .0242(.0079)
exponential(1) .0065(.0025) .0072(.0022)
extremeValue(1, 1) .0097(.0029) .0088(.0025)
gamma(0.2, 1) .0380(.0021) .0377(.0025)
gamma(1, 1) .0070(.0020) .0065(.0023)
gamma(5, 1) .0169(.0065) .0170(.0051)
lognormal(0, 1) .0072(.0029) .0067(.0022)
normal(0, 1) .0070(.0024) .0073(.0020)
uniformReal .0018(.0008) .0017(.0007)
weibull(2, 1) .0032(.0013) .0031(.0010)

(* Result of balanced were from Eigen::Random, not C++ std)

The smaller value means that the sample result fits its distribution better. The results of EigenRand and C++ std appear to be equivalent within the margin of error.

License

MIT License

History

0.5.0 (2023-01-31)

  • Improved the performance of MultinomialGen.
  • Implemented vectorization over parameters to some distributions.
  • Optimized the performance of double-type generators on NEON architecture.

0.4.1 (2022-08-13)

  • Fixed a bug where double-type generation with std::mt19937 fails compilation.
  • Fixed a bug where UniformIntGen in scalar mode generates numbers in the wrong range.

0.4.0 alpha (2021-09-28)

  • Now EigenRand supports ARM & ARM64 NEON architecture experimentally. Please report issues about ARM & ARM64 NEON.
  • Now EigenRand has compatibility to Eigen 3.4.0.

0.3.5 (2021-07-16)

  • Now UniformRealGen generates accurate double values.
  • Fixed a bug where non-vectorized double-type NormalGen would get stuck in an infinite loop.
  • New overloading functions balanced and balancedLike which generate values over [a, b] were added.

0.3.4 (2021-04-25)

  • Now Eigen 3.3.4 - 3.3.6 versions are additionally supported.

0.3.3 (2021-03-30)

  • A compilation failure with some RNGs in double type was fixed.
  • An internal function name plgamma conflict with one of SpecialFunctionsPacketMath.h was fixed.

0.3.2 (2021-03-26)

  • A default constructor for DiscreteGen was added.

0.3.1 (2020-11-15)

  • Compiling errors in the environment EIGEN_COMP_MINGW && __GXX_ABI_VERSION < 1004 was fixed.

0.3.0 (2020-10-17)

  • Potential cache conflict in generator was solved.
  • Generator classes were added for efficient reusability.
  • Multivariate distributions including Multinomial, Dirichlet, MvNormal, Wishart, InvWishart were added.

0.2.2 (2020-08-02)

  • Now ParallelRandomEngineAdaptor and MersenneTwister use aligned array on heap.

0.2.1 (2020-07-11)

  • A new template class ParallelRandomEngineAdaptor yielding the same random sequence regardless of SIMD ISA was added.

0.2.0 (2020-07-04)

  • New distributions including cauchy, studentT, fisherF, uniformInt, binomial, negativeBinomial, poisson and geometric were added.
  • A new member function uniform_real for PacketRandomEngine was added.

0.1.0 (2020-06-27)

  • The first version of EigenRand

eigenrand's People

Contributors

bab2min avatar jorisv avatar m-henning-toptal avatar manifoldfr avatar prudhomm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

eigenrand's Issues

Please Report Performance in ARM64 NEON architectures

From version 0.4.0 alpha onwards, EigenRand begins to support ARM64 experimentally.
If anyone report an issue or its performance on various real ARM machines here, it will be helpful for optimization.

Reporting Performance

Please report outputs from these 3 binaries below along with the details of the machine that runs them.

$ git clone https://github.com/bab2min/EigenRand
$ cd EigenRand
$ git clone https://github.com/google/googletest
$ pushd googletest && git checkout v1.8.x && popd
$ mkdir build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DEIGENRAND_CXX_FLAGS="-march=native" ..
$ make
$ ./EigenRand-accuracy # Binary for accuracy test of univariate random distributions
$ ./EigenRand-benchmark # Binary for performance test of univariate random distributions
$ ./EigenRand-benchmark-mv # Binary for performance test of multivariate random distributions

Unrealistic result of StdNormalGen.

My code:

#include <iostream>
#include <functional>

#include <Eigen/Dense>
#include <EigenRand/EigenRand>

using namespace std;
using namespace Eigen;

int main()
{
	Rand::Vmt19937_64 urng{4212};

	Rand::StdNormalGen<float> stdnorm;
	for (int i = 0; i < 10; ++i)
	{
		cout << stdnorm.generate<Matrix<float, 4, -1>>(4, 1, urng) << endl;
	};
};
``
Returning result:
  -0

-6.42001
8.3635
-6.50135
1.90169
2.42386e-38
2.94601e-38
2.49921e-38
-0
0
-0
0
0.783801
0.534232
1.48888
0.844737
4.74061
7.18897
-0
-5.66121
1.59769e-38
2.74603e-38
0.594965
2.17096e-38
-1.74388
-0
-0
3.80259
6.58371e-39
0.81791
0.762132
1.40474e-38
-0
-2.30039
-0
-12.4106
1.05125
8.62637e-39
0.706428
4.00838e-38


One can see that there are many values very close to 0. It's unlikely that these values obey normal distribution.

I'm using EigenRand in 64bit Ubuntu and my CPU has AVX and SSE flags.

Support Eigen 3.4.0

Since a new Eigen 3.4.0 has many internal changes, it isn't compatible to the current EigenRand. Thus it is need to support Eigen 3.4.0.

How to include the library

Hello,

I may sound like a nooby but I'm going for it. How to include your library? I did not understand in your documentation you just say to download it and that's all but I guess there is not that to do. I already have Eigen. I am on Linux.
Thanks!

Vectorisation over distribution parameters

Hi, fantastic work - it's making our code a lot faster! Having said that we got a bit stuck of generating an array/matrix of numbers from binomial distribution for different trials and probabilities. For example, in numpy you can run np.random.binomial(n, p) where n and p can either be a scalar (like in EigenRand) or arrays of the same dimensions. How difficult would it be to implement to implement a similar interface? Do you think it's possible to SIMD operations like this? Many thanks!

Compilation Error when using Eigen double

System: Ubuntu 20.04
Compiler: g++ 9.3.0

When trying to use double type (double, ArrayXXd or MatrixXd), the compiler throws the following error:

/usr/local/include/Eigen/src/Core/GenericPacketMath.h: In instantiation of ‘Packet Eigen::internal::plog(const Packet&) [with Packet = __vector(2) double]’:
/usr/local/include/EigenRand/Dists/NormalExp.h:74:53:   required from ‘const Packet Eigen::Rand::StdNormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/Dists/NormalExp.h:124:21:   required from ‘const Packet Eigen::Rand::NormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/RandUtils.h:417:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) double; Gen = Eigen::Rand::NormalGen<double>&; _Scalar = double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; bool _mutable = false]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:360:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) double; IndexType = long int; Scalar = double; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:505:68:   required from ‘PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 16; PacketType = __vector(2) double; IndexType = long int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>; PlainObjectType = const Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:658:5:   [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:879:31:   required from ‘static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::Dense2Dense, Weak>::run(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Array<double, -1, -1>; SrcXprType = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Functor = Eigen::internal::assign_op<double, double>; Weak = void]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Array<double, -1, -1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Func = Eigen::internal::assign_op<double, double>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:732:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/Array.h:242:29:   required from ‘Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Array(const Eigen::EigenBase<OtherDerived>&, typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1; typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type = Eigen::Array<double, -1, -1>::PrivateType]’
test_randeigen.cpp:19:59:   required from here
/usr/local/include/Eigen/src/Core/GenericPacketMath.h:406:58: error: no matching function for call to ‘log(const __vector(2) double&)’
  406 | Packet plog(const Packet& a) { using std::log; return log(a); }
      |                                                       ~~~^~~
In file included from /usr/local/include/Eigen/Core:96,
                 from /usr/local/include/Eigen/Dense:1,
                 from test_randeigen.cpp:4:
/usr/include/c++/9/complex:817:5: note: candidate: ‘template<class _Tp> std::complex<_Tp> std::log(const std::complex<_Tp>&)’
  817 |     log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); }
      |     ^~~
/usr/include/c++/9/complex:817:5: note:   template argument deduction/substitution failed:
In file included from /usr/local/include/Eigen/Core:372,
                 from /usr/local/include/Eigen/Dense:1,
                 from test_randeigen.cpp:4:
/usr/local/include/Eigen/src/Core/GenericPacketMath.h:406:58: note:   mismatched types ‘const std::complex<_Tp>’ and ‘const __vector(2) double’
  406 | Packet plog(const Packet& a) { using std::log; return log(a); }
      |                                                       ~~~^~~
In file included from /usr/include/c++/9/complex:44,
                 from /usr/local/include/Eigen/Core:96,
                 from /usr/local/include/Eigen/Dense:1,
                 from test_randeigen.cpp:4:
/usr/include/c++/9/cmath:350:5: note: candidate: ‘template<class _Tp> constexpr typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::log(_Tp)’
  350 |     log(_Tp __x)
      |     ^~~
/usr/include/c++/9/cmath:350:5: note:   template argument deduction/substitution failed:
/usr/include/c++/9/cmath: In substitution of ‘template<class _Tp> constexpr typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::log(_Tp) [with _Tp = __vector(2) double]’:
/usr/local/include/Eigen/src/Core/GenericPacketMath.h:406:58:   required from ‘Packet Eigen::internal::plog(const Packet&) [with Packet = __vector(2) double]’
/usr/local/include/EigenRand/Dists/NormalExp.h:74:53:   required from ‘const Packet Eigen::Rand::StdNormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/Dists/NormalExp.h:124:21:   required from ‘const Packet Eigen::Rand::NormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/RandUtils.h:417:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) double; Gen = Eigen::Rand::NormalGen<double>&; _Scalar = double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; bool _mutable = false]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:360:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) double; IndexType = long int; Scalar = double; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:505:68:   [ skipping 4 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:879:31:   required from ‘static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::Dense2Dense, Weak>::run(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Array<double, -1, -1>; SrcXprType = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Functor = Eigen::internal::assign_op<double, double>; Weak = void]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Array<double, -1, -1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Func = Eigen::internal::assign_op<double, double>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:732:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/Array.h:242:29:   required from ‘Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Array(const Eigen::EigenBase<OtherDerived>&, typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1; typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type = Eigen::Array<double, -1, -1>::PrivateType]’
test_randeigen.cpp:19:59:   required from here
/usr/include/c++/9/cmath:350:5: error: no type named ‘__type’ in ‘struct __gnu_cxx::__enable_if<false, double>’
/usr/local/include/Eigen/src/Core/GenericPacketMath.h: In instantiation of ‘Packet Eigen::internal::plog(const Packet&) [with Packet = __vector(2) double]’:
/usr/local/include/EigenRand/Dists/NormalExp.h:74:53:   required from ‘const Packet Eigen::Rand::StdNormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/Dists/NormalExp.h:124:21:   required from ‘const Packet Eigen::Rand::NormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/RandUtils.h:417:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) double; Gen = Eigen::Rand::NormalGen<double>&; _Scalar = double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; bool _mutable = false]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:360:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) double; IndexType = long int; Scalar = double; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:505:68:   required from ‘PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 16; PacketType = __vector(2) double; IndexType = long int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>; PlainObjectType = const Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:658:5:   [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:879:31:   required from ‘static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::Dense2Dense, Weak>::run(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Array<double, -1, -1>; SrcXprType = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Functor = Eigen::internal::assign_op<double, double>; Weak = void]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Array<double, -1, -1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Func = Eigen::internal::assign_op<double, double>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:732:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/Array.h:242:29:   required from ‘Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Array(const Eigen::EigenBase<OtherDerived>&, typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1; typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type = Eigen::Array<double, -1, -1>::PrivateType]’
test_randeigen.cpp:19:59:   required from here
/usr/include/c++/9/cmath:342:3: note: candidate: ‘constexpr long double std::log(long double)’
  342 |   log(long double __x)
      |   ^~~
/usr/include/c++/9/cmath:342:19: note:   no known conversion for argument 1 from ‘const __vector(2) double’ to ‘long double’
  342 |   log(long double __x)
      |       ~~~~~~~~~~~~^~~
/usr/include/c++/9/cmath:338:3: note: candidate: ‘constexpr float std::log(float)’
  338 |   log(float __x)
      |   ^~~
/usr/include/c++/9/cmath:338:13: note:   no known conversion for argument 1 from ‘const __vector(2) double’ to ‘float’
  338 |   log(float __x)
      |       ~~~~~~^~~
In file included from /usr/include/features.h:461,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/os_defines.h:39,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h:524,
                 from /usr/include/c++/9/iostream:38,
                 from test_randeigen.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:104:1: note: candidate: ‘double log(double)’
  104 | __MATHCALL_VEC (log,, (_Mdouble_ __x));
      | ^~~~~~~~~~~~~~
In file included from /usr/include/c++/9/cmath:45,
                 from /usr/include/c++/9/complex:44,
                 from /usr/local/include/Eigen/Core:96,
                 from /usr/local/include/Eigen/Dense:1,
                 from test_randeigen.cpp:4:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:104:1: note:   no known conversion for argument 1 from ‘const __vector(2) double’ to ‘double’
  104 | __MATHCALL_VEC (log,, (_Mdouble_ __x));
      | ^
In file included from /usr/local/include/EigenRand/RandUtils.h:15,
                 from /usr/local/include/EigenRand/Core.h:16,
                 from /usr/local/include/EigenRand/EigenRand:17,
                 from test_randeigen.cpp:5:
/usr/local/include/EigenRand/MorePacketMath.h: In instantiation of ‘void Eigen::internal::psincos(Packet, Packet&, Packet&) [with Packet = __vector(2) double]’:
/usr/local/include/EigenRand/Dists/NormalExp.h:78:12:   required from ‘const Packet Eigen::Rand::StdNormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/Dists/NormalExp.h:124:21:   required from ‘const Packet Eigen::Rand::NormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(2) double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; _Scalar = double]’
/usr/local/include/EigenRand/RandUtils.h:417:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) double; Gen = Eigen::Rand::NormalGen<double>&; _Scalar = double; Rng = Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&; bool _mutable = false]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:360:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) double; IndexType = long int; Scalar = double; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>]’
/usr/local/include/Eigen/src/Core/CoreEvaluators.h:505:68:   required from ‘PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 16; PacketType = __vector(2) double; IndexType = long int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>; PlainObjectType = const Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:658:5:   [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:879:31:   required from ‘static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::Dense2Dense, Weak>::run(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Array<double, -1, -1>; SrcXprType = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Functor = Eigen::internal::assign_op<double, double>; Weak = void]’
/usr/local/include/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Array<double, -1, -1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Func = Eigen::internal::assign_op<double, double>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:732:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; Derived = Eigen::Array<double, -1, -1>]’
/usr/local/include/Eigen/src/Core/Array.h:242:29:   required from ‘Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Array(const Eigen::EigenBase<OtherDerived>&, typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::NormalGen<double>&, double, Eigen::Rand::MersenneTwister<__vector(2) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>&, false>, const Eigen::Array<double, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1; typename Eigen::internal::enable_if<Eigen::internal::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type = Eigen::Array<double, -1, -1>::PrivateType]’
test_randeigen.cpp:19:59:   required from here
/usr/local/include/EigenRand/MorePacketMath.h:91:39: error: cannot convert ‘__vector(4) float’ to ‘__vector(2) double’ in assignment
   91 |    sign_bit_sin = reinterpret_to_float(
      |                   ~~~~~~~~~~~~~~~~~~~~^
      |                                       |
      |                                       __vector(4) float
   92 |     pand(reinterpret_to_int(sign_bit_sin), pset1<IntPacket>(0x80000000))
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   93 |    );
      |    ~                                   
/usr/local/include/EigenRand/MorePacketMath.h:111:51: error: cannot convert ‘__vector(4) float’ to ‘__vector(2) double’ in initialization
  111 |    Packet swap_sign_bit_sin = reinterpret_to_float(emm0);
      |                               ~~~~~~~~~~~~~~~~~~~~^~~~~~
      |                                                   |
      |                                                   __vector(4) float
/usr/local/include/EigenRand/MorePacketMath.h:117:43: error: cannot convert ‘__vector(4) float’ to ‘__vector(2) double’ in initialization
  117 |    Packet poly_mask = reinterpret_to_float(emm2);
      |                       ~~~~~~~~~~~~~~~~~~~~^~~~~~
      |                                           |
      |                                           __vector(4) float
/usr/local/include/EigenRand/MorePacketMath.h:134:46: error: cannot convert ‘__vector(4) float’ to ‘__vector(2) double’ in initialization
  134 |    Packet sign_bit_cos = reinterpret_to_float(emm4);
      |                          ~~~~~~~~~~~~~~~~~~~~^~~~~~
      |                                              |
      |                                              __vector(4) float

Here the snippet of code:

#include <iostream>
#include <string>
#include <fstream>
#include <Eigen/Dense>
#include <EigenRand/EigenRand>
 
using namespace Eigen;
 
int main()
{

    std::ofstream outputFile;
    outputFile.open("distribution.csv");
    int n = 100000;
    // Initialize random number generator with seed=42 for following codes.
    // Or you can use C++11 RNG such as std::mt19937 or std::ranlux48.
    Rand::Vmt19937_64 urng{ 1234 };
    Rand::NormalGen<double> normal_dist{1.0,0.5};
    ArrayXXd arr = normal_dist.generate<ArrayXXd>(n,1,urng);
    std::cout << arr << std::endl;


    for(int i;i<n;i++)
    {
        outputFile << i << "," << arr(i,0) <<std::endl;
    }

    outputFile.close();
  return 0;
}

It compiles normally if everything is typed as float

thank you

Is there any specific reason for the version constraint?

I tried to compile my code against Eigen 3.3.4 (bundled in Ubuntu 18.04) and manually relieved the version constraint. The compilation is successful, although I haven't tested the output. So I'm curious is there any specific reason for constraint Eigen > 3.3.7? It will be convenient if I don't need to override system Eigen.

error C2466: cannot allocate an array of constant size 0

I want to random matrix using C++11 RNG such as std::mt19937 with std::random_device. Every time it randoms different numbers. Your example using Rand::P8_mt19937_64 urng{ 42 }; produces the same number if I run in a loop.

The following code is working fine (building without any errors) with matrix, vector size is 4. It can also run and return a random matrix.

        Eigen::Vector<double, 4> mu1;
        Eigen::Matrix<double, 4, 4> cov1;
        Eigen::Matrix<double, 4, -1> samples;
        Eigen::Rand::MvNormalGen<double, 4> gen_init{ mu1, cov1 };
        std::random_device rd;
        std::mt19937 genn(rd());
        samples = gen_init.generate(genn, 10);

But if I change the size to 2, 3, or 9 it has an error.
eigenrand\Dists/Basic.h(260): error C2466: cannot allocate an array of constant size 0

        Eigen::Vector<double, 3> mu1;
        Eigen::Matrix<double, 3, 3> cov1;
        Eigen::Matrix<double, 3, -1> samples;
        Eigen::Rand::MvNormalGen<double, 3> gen_init{ mu1, cov1 };
        std::random_device rd;
        std::mt19937 genn(rd());
        samples = gen_init.generate(genn, 10);

NOTE: It happens on Windows, Ubuntu has no problem

uniformReal : Access violation reading location 0xFFFFFFFFFFFFFFFF with a specific congifuration

Hi so the error occurs in GenericPacketMath.h here (line 452) (In Eigen)

/** \internal copy the packet \a from to \a *to, (un-aligned store) */
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
{  (*to) = from; }

The code I ran is this, and the error occurs when debugging the line where i define my X variable

typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> CMatrix;
using Eigen::Rand::Vmt19937_64;
using Eigen::Rand::uniformReal;
Vmt19937_64 gen_eigen;
CMatrix X = uniformReal<CMatrix>(5, 3, gen_eigen);

Any ideas?

Edit:
These work.

CMatrix X1 = uniformReal<CMatrix>(2, 3, gen_eigen);
CMatrix X1 = uniformReal<CMatrix>(5, 2, gen_eigen);
CMatrix X2 = uniformReal<CMatrix>(100, 2, gen_eigen);
CMatrix X3 = uniformReal<CMatrix>(100, 3, gen_eigen);
CMatrix X4 = uniformReal<CMatrix>(100, 10, gen_eigen);

Is there something wrong with the specific configuration of 5 rows and 3 columns?

Im using:
Eigen 3.3.9 specifically (https://gitlab.com/libeigen/eigen/-/tree/5f25bcf7d6918f5c6091fb4e961e5607e13b7324)

"fatal error: 'Eigen/Dense' file not found" when using Eigen in header-only mode

hello Bab2min, I am a novice at C++ and Eigen. I found your EigenRand library yesterday and I think it is awesome. However, I came across 2 issues.

  1. I use eigen with header-only mode, and I put the Eigen library under ./libs. Since EigenRand is also header only, I put EigenRand under ./libs, too. The file structure is shown in the picture.
    image

Then I use the code below to test EigenRand, and compile the eigen_demo.cpp with
clang++ eigen_demo.cpp -I libs/Eigen/ -I libs/EigenRand/ -o ./output/eigen_demo -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core -lgomp -lpthread -lm -ldl -I /usr/include/mkl

However, it raised an error. I am not sure how to solve it. Is there something wrong in the compile command?

"In file included from eigen_demo.cpp:10:
./libs/EigenRand/EigenRand:15:10: fatal error: 'Eigen/Dense' file not found
#include <Eigen/Dense>
^~~~~~~~~~~~~
1 error generated."

#define EIGEN_USE_BLAS
#define EIGEN_USE_LAPACK
#define EIGEN_USE_MKL_ALL

#include <iostream>
#include <chrono>
#include <ctime>
#include <random>
#include "libs/Eigen/Dense"
#include "libs/EigenRand/EigenRand"

void RunTest(int size=100, size_t loops=10)
{
    for (size_t i = 0; i <= loops; ++i)
    {
        std::srand((unsigned)time(NULL));
        int urng  = std::rand();
        Eigen::Rand::NormalGen<double> norm_gen{ 0.0, 1.0 };
        Eigen::MatrixXd A = norm_gen.template generate<Eigen::MatrixXd>(size, size, urng);
        Eigen::MatrixXd B = A * A;
        std::cout << urng << std::endl;
    }
}

int main(){
    RunTest();
    return 0;
}
  1. The other issue is that if I want to change the random seed in every loop, what is the proper way to achieve the goal. I use the srand function, but I did't try because the code can't be compiled.😂

Because I am quite new to C++, I have to ask you for solutions. Hope I claimed the questions clearly and thank you for your great work.

Compilation errors at MinGW64 + Eigen3.4.0 + AVX512

E:\AddInclude/EigenRand/Dists/NormalExp.h:79:12: error: no matching function for call to 'psincos(__vector(16) float&, __vector(16) float&, __vector(16) float&)'
   79 |     psincos(theta, sintheta, costheta);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from E:\AddInclude/EigenRand/RandUtils.h:15,
                 from E:\AddInclude/EigenRand/Core.h:16,
                 from E:\AddInclude/EigenRand/EigenRand:20,
                 from E:\CppRepo\EigenRand\tuto.cpp:3:
E:\AddInclude/EigenRand/MorePacketMath.h:273:11: note: candidate: 'template<class Packet> typename std::enable_if<Eigen::internal::IsFloatPacket<Ty>::value>::type Eigen::internal::psincos(Packet, Packet&, Packet&)'
  273 |   >::type psincos(Packet x, Packet& s, Packet& c)
      |           ^~~~~~~
E:\AddInclude/EigenRand/MorePacketMath.h:273:11: note:   template argument deduction/substitution failed:
E:\AddInclude/EigenRand/MorePacketMath.h: In substitution of 'template<class Packet> typename std::enable_if<Eigen::internal::IsFloatPacket<Ty>::value>::type Eigen::internal::psincos(Packet, Packet&, Packet&) [with Packet = __vector(16) float]':
E:\AddInclude/EigenRand/Dists/NormalExp.h:79:12:   required from 'const Packet Eigen::Rand::StdNormalGen<_Scalar>::packetOp(Rng&&) [with Packet = __vector(16) float; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&; _Scalar = float]'
E:\AddInclude/EigenRand/RandUtils.h:130:45:   required from 'const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, true>::packetOp() const [with Packet = __vector(16) float; Gen = Eigen::Rand::StdNormalGen<float>; _Scalar = float; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&]'
E:\AddInclude/Eigen/src/Core/CoreEvaluators.h:402:180:   required from 'T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(16) float; IndexType = int; Scalar = float; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>]'
E:\AddInclude/Eigen/src/Core/CoreEvaluators.h:547:68:   required from 'PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 64; PacketType = __vector(16) float; IndexType = int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>; PlainObjectType = const Eigen::Array<float, -1, -1>]'
E:\AddInclude/Eigen/src/Core/AssignEvaluator.h:681:5:   required from 'void Eigen::internal::generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>::assignPacket(Eigen::Index) [with int StoreMode = 64; int LoadMode = 64; PacketType = __vector(16) float; DstEvaluatorTypeT = Eigen::internal::evaluator<Eigen::Array<float, -1, -1> >; SrcEvaluatorTypeT = Eigen::internal::evaluator<Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> > >; Functor = Eigen::internal::assign_op<float, float>; int Version = 0; Eigen::Index = int]'
E:\AddInclude/Eigen/src/Core/AssignEvaluator.h:437:7:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
E:\AddInclude/Eigen/src/Core/AssignEvaluator.h:944:31:   required from 'static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::Dense2Dense, Weak>::run(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Array<float, -1, -1>; SrcXprType = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> >; Functor = Eigen::internal::assign_op<float, float>; Weak = void]'
E:\AddInclude/Eigen/src/Core/AssignEvaluator.h:880:49:   required from 'void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Array<float, -1, -1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> >; Func = Eigen::internal::assign_op<float, float>]'
E:\AddInclude/Eigen/src/Core/PlainObjectBase.h:797:41:   required from 'Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> >; Derived = Eigen::Array<float, -1, -1>]'
E:\AddInclude/Eigen/src/Core/PlainObjectBase.h:594:7:   required from 'Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> >; Derived = Eigen::Array<float, -1, -1>]'
E:\AddInclude/Eigen/src/Core/Array.h:288:29:   required from 'Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Array(const Eigen::EigenBase<OtherDerived>&, typename Eigen::internal::enable_if<std::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::StdNormalGen<float>, float, Eigen::Rand::ParallelRandomEngineAdaptor<long long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, true>, const Eigen::Array<float, -1, -1> >; _Scalar = float; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1; typename Eigen::internal::enable_if<std::is_convertible<typename OtherDerived::Scalar, typename Eigen::internal::traits<Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >::Scalar>::value, Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::PrivateType>::type = Eigen::Array<float, -1, -1>::PrivateType]'

Automatic detection of CPU capabilities.

Is there a way the CPU capabilites can automatically being detected?
Since today EigenRand is used in all of the optmization algorithms of fcmaes
currently by hardcoding SSE2 support. Would be better if AVX support would be automatically detected
since fcmaes is used from Python and I cannot predict on which CPUs it is deployed.

But I already see a significant speedup, specially with machine learning tasks ( EvoJax uses some of my algos) which require up to a million random variable generations each iteration (lasting a few seconds).
Thks for this great project!

merge this project to Eigen?

I find Eigen's built-in RNG super slow and thank you for this great project. Have you contacted Eigen's developers to get it merged into Eigen?

Adding multivariate distribution

It is more useful to provide RNGs for multivariate distributions such as

  • multivariate normal distribution
  • Wishart / inverse-Wishart distribution
  • other distributions listed on scipy.stats

Is it thread safe?

Hi! Thanks for the great library. I haven't seen this being mentioned in the docs or issues, so I just wanna ask to see if this library is thread safe, and more importantly, would the random number generator seeded uniquely across different threads?

Say if I have spawned multiple threads, and each of them constructed their own instances of Eigen::Rand::Vmt19937_64{}(i.e. Without fixed random seed). Would different thread guarantees to produce different random numbers?

I know some libraries (e.g. Eigen's own Rand) doesn't work across threads as they are not re-entrant

note that all functions generating random matrices are not re-entrant nor thread-safe. Those include DenseBase::Random(), and DenseBase::setRandom() despite a call to Eigen::initParallel(). This is because these functions are based on std::rand which is not re-entrant.

https://eigen.tuxfamily.org/dox/TopicMultiThreading.html

A different scenario would be a master thread constructs a Eigen::Rand::Vmt19937_64{}and each slave threads holds a reference to the same instance. I would assume it will not be thread safe in this case?

About the compilation warnings

Thanks for your efforts again! I get compilation warnings every time I build the packages, it there any plan to fix them? Or is it safe to ignore them?

In file included from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:15,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/Core.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/EigenRand:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/include/semantic_bki/bkioctomap.h:9,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/src/semantickitti_node.cpp:5:
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:52:30: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
   52 |   struct IsIntPacket<Packet4i> : std::true_type {};
      |                              ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:55:32: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4f’ {aka ‘__vector(4) float’} [-Wignored-attributes]
   55 |   struct IsFloatPacket<Packet4f> : std::true_type {};
      |                                ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:58:33: warning: ignoring attributes on template argument ‘Eigen::internal::Packet2d’ {aka ‘__vector(2) double’} [-Wignored-attributes]
   58 |   struct IsDoublePacket<Packet2d> : std::true_type {};
      |                                 ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:61:29: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
   61 |   struct HalfPacket<Packet4i>
      |                             ^
In file included from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:15,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/Core.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/EigenRand:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/include/semantic_bki/bkioctomap.h:9,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/src/semantickitti_node.cpp:5:
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:1129:32: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
 1129 |   struct reinterpreter<Packet4i>
      |                                ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:1148:32: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4f’ {aka ‘__vector(4) float’} [-Wignored-attributes]
 1148 |   struct reinterpreter<Packet4f>
      |                                ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/MorePacketMath.h:1167:32: warning: ignoring attributes on template argument ‘Eigen::internal::Packet2d’ {aka ‘__vector(2) double’} [-Wignored-attributes]
 1167 |   struct reinterpreter<Packet2d>
      |                                ^
In file included from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/Core.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/EigenRand:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/include/semantic_bki/bkioctomap.h:9,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/src/semantickitti_node.cpp:5:
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/PacketFilter.h:178:37: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4f’ {aka ‘__vector(4) float’} [-Wignored-attributes]
  178 |     std::array<internal::Packet4f, 4> selector;
      |                                     ^
In file included from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/Core.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/EigenRand:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/include/semantic_bki/bkioctomap.h:9,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/src/semantickitti_node.cpp:5:
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/PacketRandomEngine.h:573:53: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
  573 |   using Vmt19937_64 = Pmt19937_64<internal::Packet4i>;
      |                                                     ^
In file included from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/Core.h:16,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/EigenRand:17,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/include/semantic_bki/bkioctomap.h:9,
                 from /home/jacobz/Mapping/ws/src/BKISemanticMapping/src/semantickitti_node.cpp:5:
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:279:79: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
  279 |   struct RawbitsMaker<Packet4i, Rng, RngResult, Rand::RandomEngineType::scalar>
      |                                                                               ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:328:78: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
  328 |   struct RawbitsMaker<Packet4i, Rng, Packet4i, Rand::RandomEngineType::packet>
      |                                                                              ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:328:78: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:347:40: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4f’ {aka ‘__vector(4) float’} [-Wignored-attributes]
  347 |   struct UniformRealUtils<Packet4f, Rng> : public RawbitsMaker<Packet4i, Rng>
      |                                        ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:347:77: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
  347 |   struct UniformRealUtils<Packet4f, Rng> : public RawbitsMaker<Packet4i, Rng>
      |                                                                             ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:362:40: warning: ignoring attributes on template argument ‘Eigen::internal::Packet2d’ {aka ‘__vector(2) double’} [-Wignored-attributes]
  362 |   struct UniformRealUtils<Packet2d, Rng> : public RawbitsMaker<Packet4i, Rng>
      |                                        ^
/home/jacobz/Mapping/ws/src/BKISemanticMapping/thirdparty/EigenRand/EigenRand/RandUtils.h:362:77: warning: ignoring attributes on template argument ‘Eigen::internal::Packet4i’ {aka ‘__vector(2) long long int’} [-Wignored-attributes]
  362 |   struct UniformRealUtils<Packet2d, Rng> : public RawbitsMaker<Packet4i, Rng>
      |                                                                             ^

Compilation error with Apple Silicon

I am trying to compile EigenRand on a Homebrewed macbook Pro with a M1 processor. Using the "Simple Random Generator Matrix Example" from https://bab2min.github.io/eigenrand/v0.3.3/en/getting_started.html, I have:

> g++ -I/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/ -I./EigenRand/ -std=c++11 test.cpp
In file included from test.cpp:3:
In file included from ./EigenRand/EigenRand/EigenRand:17:
In file included from ./EigenRand/EigenRand/Core.h:16:
In file included from ./EigenRand/EigenRand/RandUtils.h:17:
./EigenRand/EigenRand/PacketRandomEngine.h:321:15: error: no member named 'split_two' in namespace 'Eigen::internal'
                                internal::split_two(operator()(), a, cache);
                                ~~~~~~~~~~^
In file included from test.cpp:3:
In file included from ./EigenRand/EigenRand/EigenRand:17:
In file included from ./EigenRand/EigenRand/Core.h:16:
./EigenRand/EigenRand/RandUtils.h:34:29: error: implicit instantiation of undefined template
      'Eigen::internal::UniformRealUtils<__attribute__((neon_vector_type(4))) float, std::__1::mersenne_twister_engine<unsigned long long, 64,
      312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>
      &>'
                struct RandUtils : public UniformRealUtils<PacketType, Rng>
                                          ^
./EigenRand/EigenRand/Dists/Basic.h:295:12: note: in instantiation of template class
      'Eigen::internal::RandUtils<__attribute__((neon_vector_type(4))) float, std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156,
      31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &>'
      requested here
                                return RUtils{}.balanced(std::forward<Rng>(rng));
                                       ^
./EigenRand/EigenRand/RandUtils.h:455:25: note: in instantiation of function template specialization
      'Eigen::Rand::BalancedGen<float>::packetOp<__attribute__((neon_vector_type(4))) float, std::__1::mersenne_twister_engine<unsigned long
      long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43,
      6364136223846793005> &>' requested here
                                return gen.template packetOp<Packet>(rng);
                                                    ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/CoreEvaluators.h:360:168: note: in instantiation of function template
      specialization 'Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float, std::__1::mersenne_twister_engine<unsigned long
      long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43,
      6364136223846793005> &, true>::packetOp<__attribute__((neon_vector_type(4))) float>' requested here
  ...EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType=0, IndexType=0) const { return op.template packetOp<T>(); }
                                                                                                                                ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/CoreEvaluators.h:505:31: note: in instantiation of function template
      specialization 'Eigen::internal::nullary_wrapper<float, Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, true, false,
      false>::packetOp<__attribute__((neon_vector_type(4))) float, long>' requested here
    return m_wrapper.template packetOp<PacketType>(m_functor, index);
                              ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/AssignEvaluator.h:658:87: note: in instantiation of function template
      specialization 'Eigen::internal::evaluator<Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>,
      float, std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> >
      >::packet<16, __attribute__((neon_vector_type(4))) float, long>' requested here
    m_functor.template assignPacket<StoreMode>(&m_dst.coeffRef(index), m_src.template packet<LoadMode,PacketType>(index));
                                                                                      ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/AssignEvaluator.h:416:23: note: (skipping 4 contexts in backtrace; use
      -ftemplate-backtrace-limit=0 to see all)
      kernel.template assignPacket<dstAlignment, srcAlignment, PacketType>(index);
                      ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/AssignEvaluator.h:804:3: note: in instantiation of function template
      specialization 'Eigen::internal::call_assignment_no_alias<Eigen::Matrix<float, -1, -1, 0, -1, -1>,
      Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> >,
      Eigen::internal::assign_op<float, float> >' requested here
  call_assignment_no_alias(dst, src, func);
  ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/AssignEvaluator.h:782:3: note: in instantiation of function template
      specialization 'Eigen::internal::call_assignment<Eigen::Matrix<float, -1, -1, 0, -1, -1>,
      Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> >,
      Eigen::internal::assign_op<float, float> >' requested here
  call_assignment(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
  ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/PlainObjectBase.h:714:17: note: in instantiation of function template
      specialization 'Eigen::internal::call_assignment<Eigen::Matrix<float, -1, -1, 0, -1, -1>,
      Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> > >'
      requested here
      internal::call_assignment(this->derived(), other.derived());
                ^
/opt/homebrew/Cellar/eigen/3.3.9/include/eigen3/Eigen/src/Core/Matrix.h:225:20: note: in instantiation of function template specialization
      'Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1>
      >::_set<Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> > >'
      requested here
      return Base::_set(other);
                   ^
test.cpp:17:7: note: in instantiation of function template specialization 'Eigen::Matrix<float, -1, -1, 0, -1,
      -1>::operator=<Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BalancedGen<float>, float,
      std::__1::mersenne_twister_engine<unsigned long long, 64, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17,
      8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005> &, true>, const Eigen::Matrix<float, -1, -1, 0, -1, -1> > >'
      requested here
  mat = Rand::balancedLike(mat, urng);
      ^
./EigenRand/EigenRand/RandUtils.h:31:10: note: template is declared here
                struct UniformRealUtils;
                       ^
2 errors generated.

This is what cpuinfo reports:

§ cpuinfo
Python Version: 3.9.2.final.0 (64 bit)
Cpuinfo Version: 8.0.0
Vendor ID Raw:
Hardware Raw:
Brand Raw: Apple M1
Hz Advertised Friendly:
Hz Actual Friendly:
Hz Advertised:
Hz Actual:
Arch: ARM_8
Bits: 64
Count: 8
Arch String Raw: arm64
L1 Data Cache Size:
L1 Instruction Cache Size:
L2 Cache Size:
L2 Cache Line Size:
L2 Cache Associativity:
L3 Cache Size:
Stepping:
Model:
Family:
Processor Type:
Flags:

§ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: arm64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

uniformIntLike creates values outside [min,max]

EigenRand Version: 0.4.0

When trying to create uniform random values between -1 and 1 with Eigen::Rand::uniformIntLike I get also values equal 2.

I used the following code to create this bug:

#include <iostream>
#include <eigen3/Eigen/Dense>
#include <EigenRand/EigenRand>

int main(){
  uint64_t seed = std::random_device{}();
  Eigen::Rand::P8_mt19937_64 generator{seed};

  Eigen::VectorXi p;
  p.resize(2);
  
  for (uint i = 0; i<100; i++){
    auto x = Eigen::Rand::uniformIntLike(p, generator,-1,1);
    std::cout << "x :" << x << std::endl;
    
  }
}

In the output I one should see that there are values equal 2 though the range of the distribution is defined to be [-1,1].

For the range [0,1] the function works as described in the documentation.

modernize cmake

The cmake configuration can be improved in various ways:

  • add install statements
  • simplify executable generation and maintenance
  • add packaging configuration
  • remove include_directory and replace with target_link_libraries that allows to pass the necessary flags automatically

see eg here https://cliutils.gitlab.io/modern-cmake/

Conflict with other Eigen Dependents Template Libraries

I noticed conflict happens when RandEigen is used alongside another library which also uses eigen.
The conflict only happens with the definition of plgamma

<command-line>: note: this is the location of the previous definition
In file included from /usr/include/eigen3/unsupported/Eigen/SpecialFunctions:47,
                 from /usr/include/eigen3/unsupported/Eigen/CXX11/Tensor:30,
                 from /opt/ros/noetic/include/pinocchio/fwd.hpp:31,
                 [...]
/usr/include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h:19:8: error: redefinition of ‘template<class Packet> Packet Eigen::internal::plgamma(const Packet&)’
   19 | Packet plgamma(const Packet& a) { using numext::lgamma; return lgamma(a); }
      |        ^~~~~~~
In file included from /usr/local/include/EigenRand/RandUtils.h:15,
                 from /usr/local/include/EigenRand/Core.h:16,
                 from /usr/local/include/EigenRand/EigenRand:17,
                 [...]
/usr/local/include/EigenRand/MorePacketMath.h:181:30: note: ‘template<class Packet> Packet Eigen::internal::plgamma(const Packet&)’ previously declared here
  181 |   EIGEN_STRONG_INLINE Packet plgamma(const Packet& x)
      |                              ^~~~~~~

Once plgamma is commented, it compiles just fine. (Also removing the comments and compiling a second time does not
raise any error. The error comes for the first build or after a make clean).

I tried to avoid circular declaration in my own code, it might be an error from my side but I reported it just in case.

CXX compiler: GNU 9.3.0
cmake version 3.16.3
Eigen 3.3.7
RandEigen version 0.3.2

How to generate different randomized matrices with min and max values?

I use the library to generate randomized arrays. I had 2 questions:
Why when I do
MatrixXd m{rows,cols}; Rand::Vmt19937_64 urng{ 42 }; Rand::balancedLike(m, urng); m = Rand::balancedLike(m, urng);
it always returns the same matrix with the same values.

And my other question: is it possible to choose min and max values to generate random numbers?

Rand::normal does not finish

Hello

I just tried the following line of codes:

#include <Eigen/Dense>
#include <EigenRand/EigenRand>

Eigen::Rand::Vmt19937_64 gen{ 42 };
Eigen::MatrixXd test = Eigen::Rand::normal<Eigen::MatrixXd>(3,3,gen,0,1);
std::cout << test << std::endl;`

I have no compilation issue (just warnings but I think it is normal according to another discussion issue on gitlab). However, I can wait 10 mins and I have absolutely no results.
I compile with g++ (C++ 17 or 11) and I have the Eigen version 3.7.7.

Thanks in advance

Performance comparison with a written eigenmvn

Thanks for this useful random module.

If I want to sample from Multivariate Normal Distribution, Could you please tell me the performance difference between EigenRand and this Github module, eigenmvn? Which one is faster or does it have the same sampling speed?

In EigenRand, I can do

Rand::P8_mt19937_64 urng{ 42 };
Rand::MvNormalGen<double, 4> gen_init{ mu, cov };
Matrix<double, 4, -1> samples = gen_init.generate(urng, 10);

In eigenmvn, I can do

EigenMultivariateNormal<double> norm_init(mu, cov);
norm_init.samples(10);

Cannot compile with `-march=native`

Hi,

I am trying to compile using -march=native to activate avx-stuff. However, I get some issue that I am not sure how to work around.

Example application

#include <iostream>
#include <random>

#include "EigenRand/EigenRand"
#include "Eigen/Dense"

template<typename Scalar, int Rows, int Cols>
inline void resample(Eigen::Matrix<Scalar, Rows, Cols> &mat, int i)
{
    static Eigen::Rand::BinomialGen<int> bin_gen{1, 0.5};
    static std::random_device seeder{};
    static Eigen::Rand::P8_mt19937_64 uurg{seeder()};
    
    Eigen::Matrix<int, Rows, 1> r = bin_gen.template generate<Eigen::Matrix<int, Rows, 1>>(mat.rows(), 1, uurg);
    Eigen::Matrix<Scalar, Rows, 1> r_float = r.template cast<Scalar>();
    mat.col(i) = 2.0 / mat.rows() * (r_float.array() - 0.5);
}


int main()
{
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat{10, 2};
    mat.setOnes();
    resample(mat, 1);

    std::cout << mat << "\n";
}

Compile command

g++ test.cc -I libs/EigenRand/ -I ~/.local/include/eigen3 -march=native

Compilation error

In file included from /home/jakkes/.local/include/eigen3/Eigen/Core:372,
                 from /home/jakkes/.local/include/eigen3/Eigen/Dense:1,
                 from libs/EigenRand/EigenRand/EigenRand:15,
                 from test.cc:4:
/home/jakkes/.local/include/eigen3/Eigen/src/Core/GenericPacketMath.h: In instantiation of ‘TgtPacket Eigen::internal::pcast(const SrcPacket&) [with SrcPacket = __vector(4) float; TgtPacket = __vector(2) long long int]’:
libs/EigenRand/EigenRand/Dists/Discrete.h:991:39:   required from ‘const Packet Eigen::Rand::BinomialGen< <template-parameter-1-1> >::packetOp(Rng&&) [with Packet = __vector(2) long long int; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&; _Scalar = int]’
libs/EigenRand/EigenRand/RandUtils.h:90:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) long long int; Gen = Eigen::Rand::BinomialGen<int>&; _Scalar = int; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&; bool _mutable = false]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/CoreEvaluators.h:388:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) long long int; IndexType = long int; Scalar = int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/CoreEvaluators.h:533:68:   required from ‘PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 32; PacketType = __vector(2) long long int; IndexType = long int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>; PlainObjectType = const Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:658:5:   required from ‘void Eigen::internal::generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>::assignPacket(Eigen::Index) [with int StoreMode = 16; int LoadMode = 32; PacketType = __vector(2) long long int; DstEvaluatorTypeT = Eigen::internal::evaluator<Eigen::Matrix<int, -1, 1> >; SrcEvaluatorTypeT = Eigen::internal::evaluator<Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> > >; Functor = Eigen::internal::assign_op<int, int>; int Version = 0; Eigen::Index = long int]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:416:7:   [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/home/jakkes/.local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Matrix<int, -1, 1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Func = Eigen::internal::assign_op<int, int>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:728:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Derived = Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Derived = Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/Matrix.h:379:29:   required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; _Scalar = int; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
test.cc:14:33:   required from ‘void resample(Eigen::Matrix<Scalar, Rows, Cols>&, int) [with Scalar = double; int Rows = -1; int Cols = -1]’
test.cc:24:20:   required from here
/home/jakkes/.local/include/eigen3/Eigen/src/Core/GenericPacketMath.h:136:10: error: invalid static_cast from type ‘const __vector(4) float’ to type ‘__vector(2) long long int’
  136 |   return static_cast<TgtPacket>(a);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/jakkes/.local/include/eigen3/Eigen/src/Core/GenericPacketMath.h: In instantiation of ‘TgtPacket Eigen::internal::pcast(const SrcPacket&) [with SrcPacket = __vector(2) long long int; TgtPacket = __vector(4) float]’:
libs/EigenRand/EigenRand/MorePacketMath.h:294:32:   required from ‘typename std::enable_if<Eigen::internal::IsFloatPacket<Ty>::value>::type Eigen::internal::psincos(Packet, Packet&, Packet&) [with Packet = __vector(4) float; typename std::enable_if<Eigen::internal::IsFloatPacket<Ty>::value>::type = void]’
libs/EigenRand/EigenRand/Dists/Discrete.h:970:14:   required from ‘const Packet Eigen::Rand::BinomialGen< <template-parameter-1-1> >::packetOp(Rng&&) [with Packet = __vector(2) long long int; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&; _Scalar = int]’
libs/EigenRand/EigenRand/RandUtils.h:90:45:   required from ‘const Packet Eigen::internal::scalar_rng_adaptor<Gen, _Scalar, Rng, _mutable>::packetOp() const [with Packet = __vector(2) long long int; Gen = Eigen::Rand::BinomialGen<int>&; _Scalar = int; Rng = Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&; bool _mutable = false]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/CoreEvaluators.h:388:180:   required from ‘T Eigen::internal::nullary_wrapper<Scalar, NullaryOp, true, false, false>::packetOp(const NullaryOp&, IndexType, IndexType) const [with T = __vector(2) long long int; IndexType = long int; Scalar = int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/CoreEvaluators.h:533:68:   required from ‘PacketType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::packet(IndexType) const [with int LoadMode = 32; PacketType = __vector(2) long long int; IndexType = long int; NullaryOp = Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>; PlainObjectType = const Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:658:5:   [ skipping 4 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/home/jakkes/.local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:836:49:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Matrix<int, -1, 1>; Src = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Func = Eigen::internal::assign_op<int, int>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:728:41:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Derived = Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:537:7:   required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; Derived = Eigen::Matrix<int, -1, 1>]’
/home/jakkes/.local/include/eigen3/Eigen/src/Core/Matrix.h:379:29:   required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Eigen::internal::scalar_rng_adaptor<Eigen::Rand::BinomialGen<int>&, int, Eigen::Rand::ParallelRandomEngineAdaptor<long unsigned int, Eigen::Rand::MersenneTwister<__vector(4) long long int, 312, 156, 31, 13043109905998158313, 29, 6148914691236517205, 17, 8202884508482404352, 37, 18444473444759240704, 43, 6364136223846793005>, 8>&, false>, const Eigen::Matrix<int, -1, 1> >; _Scalar = int; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
test.cc:14:33:   required from ‘void resample(Eigen::Matrix<Scalar, Rows, Cols>&, int) [with Scalar = double; int Rows = -1; int Cols = -1]’
test.cc:24:20:   required from here
/home/jakkes/.local/include/eigen3/Eigen/src/Core/GenericPacketMath.h:136:10: error: invalid static_cast from type ‘const __vector(2) long long int’ to type ‘__vector(4) float'

I have had no issue compiling Eigen with -march=native previously, before adding EigenRand to my application.

Thankful for any insight into how I could resolve this.

I am running AMD Ryzen 7 5800X, and g++-9 version 9.3.0

Getting template errors when including EigenRand

I am using MinGW64/GCC 10.2.0. When trying to include EigenRand like following:

#include <Eigen/Dense>
#include <EigenRand/EigenRand>

I get lots of template errors(have not tried to initialize anything with EigenRand yet):

[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:15,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:709:32: warning: ignoring attributes on template argument 'Eigen::internal::Packet4f' {aka '__m128'} [-Wignored-attributes]
[build]   709 |   struct reinterpreter<Packet4f>
[build]       |                                ^
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:728:32: warning: ignoring attributes on template argument 'Eigen::internal::Packet2d' {aka '__m128d'} [-Wignored-attributes]
[build]   728 |   struct reinterpreter<Packet2d>
[build]       |                                ^
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h: In function 'Packet Eigen::internal::pgather(const int*, const Packet&) [with Packet = Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>]':
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:872:21: error: cannot convert 'Eigen::internal::Packet4i*' {aka 'Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*'} to '__m128i_u*'
[build]   872 |    _mm_storeu_si128((Packet4i*)u, index);
[build]       |                     ^~~~~~~~~~~~
[build]       |                     |
[build]       |                     Eigen::internal::Packet4i* {aka Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*}
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/src/Core/util/ConfigureVectorization.h:345,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Core:22,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Dense:1,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:3:
[build] C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/10.2.0/include/emmintrin.h:725:30: note:   initializing argument 1 of 'void _mm_storeu_si128(__m128i_u*, __m128i)'
[build]   725 | _mm_storeu_si128 (__m128i_u *__P, __m128i __B)
[build]       |                   ~~~~~~~~~~~^~~
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:15,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h: In function 'decltype (Eigen::internal::reinterpret_to_float(declval<Packet>())) Eigen::internal::pgather(const float*, const Packet&) [with Packet = Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>; decltype (Eigen::internal::reinterpret_to_float(declval<Packet>())) = __vector(4) float]':
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:884:21: error: cannot convert 'Eigen::internal::Packet4i*' {aka 'Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*'} to '__m128i_u*'
[build]   884 |    _mm_storeu_si128((Packet4i*)u, index);
[build]       |                     ^~~~~~~~~~~~
[build]       |                     |
[build]       |                     Eigen::internal::Packet4i* {aka Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*}
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/src/Core/util/ConfigureVectorization.h:345,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Core:22,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Dense:1,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:3:
[build] C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/10.2.0/include/emmintrin.h:725:30: note:   initializing argument 1 of 'void _mm_storeu_si128(__m128i_u*, __m128i)'
[build]   725 | _mm_storeu_si128 (__m128i_u *__P, __m128i __B)
[build]       |                   ~~~~~~~~~~~^~~
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:15,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h: In function 'decltype (Eigen::internal::reinterpret_to_double(declval<Packet>())) Eigen::internal::pgather(const double*, const Packet&, bool) [with Packet = Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>; decltype (Eigen::internal::reinterpret_to_double(declval<Packet>())) = __vector(2) double]':
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:896:21: error: cannot convert 'Eigen::internal::Packet4i*' {aka 'Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*'} to '__m128i_u*'
[build]   896 |    _mm_storeu_si128((Packet4i*)u, index);
[build]       |                     ^~~~~~~~~~~~
[build]       |                     |
[build]       |                     Eigen::internal::Packet4i* {aka Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>*}
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/src/Core/util/ConfigureVectorization.h:345,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Core:22,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Dense:1,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:3:
[build] C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/10.2.0/include/emmintrin.h:725:30: note:   initializing argument 1 of 'void _mm_storeu_si128(__m128i_u*, __m128i)'
[build]   725 | _mm_storeu_si128 (__m128i_u *__P, __m128i __B)
[build]       |                   ~~~~~~~~~~~^~~
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:15,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h: In function 'Packet Eigen::internal::pcmpeq64(const Packet&, const Packet&) [with Packet = Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>]':
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:961:64: error: no matching function for call to 'pand(Eigen::internal::Packet4i&, __m128i)'
[build]   961 |    return pand(c, _mm_shuffle_epi32(c, _MM_SHUFFLE(2, 3, 0, 1)));
[build]       |                                                                ^
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Core:165,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/Dense:1,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:3:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/src/Core/GenericPacketMath.h:272:1: note: candidate: 'template<class Packet> Packet Eigen::internal::pand(const Packet&, const Packet&)'
[build]   272 | pand(const Packet& a, const Packet& b) {
[build]       | ^~~~
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/eigen/Eigen/src/Core/GenericPacketMath.h:272:1: note:   template argument deduction/substitution failed:
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:15,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/MorePacketMath.h:961:64: note:   deduced conflicting types for parameter 'const Packet' ('Eigen::internal::eigen_packet_wrapper<__vector(2) long long int, 0>' and '__m128i')
[build]   961 |    return pand(c, _mm_shuffle_epi32(c, _MM_SHUFFLE(2, 3, 0, 1)));
[build]       |                                                                ^
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/PacketFilter.h: At global scope:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/PacketFilter.h:178:37: warning: ignoring attributes on template argument 'Eigen::internal::Packet4f' {aka '__m128'} [-Wignored-attributes]
[build]   178 |     std::array<internal::Packet4f, 4> selector;
[build]       |                                     ^
[build] In file included from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/Core.h:16,
[build]                  from C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/EigenRand:17,
[build]                  from C:\Users\the_s\Documents\coding\my-first-nn\src\Network.cpp:4:
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:347:40: warning: ignoring attributes on template argument 'Eigen::internal::Packet4f' {aka '__m128'} [-Wignored-attributes]
[build]   347 |   struct UniformRealUtils<Packet4f, Rng> : public RawbitsMaker<Packet4i, Rng>
[build]       |                                        ^
[build] C:/Users/the_s/Documents/coding/my-first-nn/deps/EigenRand/EigenRand/RandUtils.h:362:40: warning: ignoring attributes on template argument 'Eigen::internal::Packet2d' {aka '__m128d'} [-Wignored-attributes]
[build]   362 |   struct UniformRealUtils<Packet2d, Rng> : public RawbitsMaker<Packet4i, Rng>
[build]       |                                        ^
[build] mingw32-make[2]: *** [src\CMakeFiles\my_first_nn.dir\build.make:110: src/CMakeFiles/my_first_nn.dir/Network.cpp.obj] Error 1
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:112: src/CMakeFiles/my_first_nn.dir/all] Error 2
[build] mingw32-make: *** [Makefile:102: all] Error 2

Adding PDFs/CDFs to the main library

Hi @bab2min ! Thanks for the great work you've done on this library. I'm using it for a purpose (importance sampling) where I need to compute the probability density or cumulative distribution functions of what I'm sampling.

I noticed some benchmarks implement some 1D pdfs and cdfs. Would you be interested in having those be part of the main library, as well as multivariate densities e.g. the multivariate normal density? For now what I've implemented is in my own client library, but I could make a PR if there's interest.

Large (scale) samples with MvNormalGen

Hi, apologies in advance as this may look long winded but to reproduce the issue simply just copy-paste the following piece of code

#include <Eigen/Dense>
#include <EigenRand/EigenRand>

typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> TMatrix;
typedef Eigen::VectorXd TVector;
using Eigen::Rand::Vmt19937_64;
Vmt19937_64 gen_eigen;

void cdist(const TMatrix& X1, const TMatrix& X2, TMatrix& D, bool squared = false) {
    // |X1(i) - X2(j)^T|^2 = |X1(i)|^2 + |X2(j)|^2 - (2 * X1(i)^T X2(j))
    D = ((-2.0 * (X1 * X2.transpose())).colwise()
        + X1.rowwise().squaredNorm()).rowwise()
        + X2.rowwise().squaredNorm().transpose();
    if (!squared) { D = (D.array().sqrt()).matrix(); }
}

const TMatrix Matern52(const TMatrix& X1, const TMatrix& X2, TVector& length_scale) {
    TMatrix R(X1.rows(), X2.rows());
    const TMatrix X1sc = X1.array().rowwise() / length_scale.transpose().array();
    const TMatrix X2sc = X2.array().rowwise() / length_scale.transpose().array();
    cdist(X1sc, X2sc, R, false);
    R *= sqrt(5);
    return ((1 + R.array() + square(R.array()) / 3) * (exp(-R.array()))).matrix();
}

void xiong1d(const Eigen::Ref<const TMatrix>& X, Eigen::Ref<TMatrix> Y) {
    Y = -0.5 * (sin((40 * pow((X.array() - 0.85), 4)).array()) * cos((2.5 * (X.array() - 0.95)).array()) + 0.5 * (X.array() - 0.9) + 1);
}

TMatrix sample_mvn(const TVector& mean, const TMatrix& K) {
    MvNormalGen sampler = makeMvNormalGen(mean, K);
    return sampler.generate(gen_eigen);
}

void test_mvn_sample() {
    TVector x_range = TVector::LinSpaced(10, 0, 1);
    TMatrix X = Eigen::Map<TVector>(x_range.data(), 10);
    TMatrix Y(X.rows(), 1);
    xiong1d(X, Y);
    TVector length_scale = TVector::Ones(1);
    TMatrix K = Matern52(X, X, length_scale);
    std::cout << "K =\n" << K << std::endl;
    TVector mean = TVector::Zero(X.rows());
    TMatrix mvn_samples = sample_mvn(mean, K);
    std::cout << "MVN_SAMPLE =\n" << mvn_samples << std::endl;
}

int main() {
   test_mvn_sample();
   return 0;
}

This should give out

K =
       1 0.989851 0.960808 0.916168 0.859902 0.795934 0.727763 0.658294 0.589808 0.523994
0.989851        1 0.989851 0.960808 0.916168 0.859902 0.795934 0.727763 0.658294 0.589808
0.960808 0.989851        1 0.989851 0.960808 0.916168 0.859902 0.795934 0.727763 0.658294
0.916168 0.960808 0.989851        1 0.989851 0.960808 0.916168 0.859902 0.795934 0.727763
0.859902 0.916168 0.960808 0.989851        1 0.989851 0.960808 0.916168 0.859902 0.795934
0.795934 0.859902 0.916168 0.960808 0.989851        1 0.989851 0.960808 0.916168 0.859902
0.727763 0.795934 0.859902 0.916168 0.960808 0.989851        1 0.989851 0.960808 0.916168
0.658294 0.727763 0.795934 0.859902 0.916168 0.960808 0.989851        1 0.989851 0.960808
0.589808 0.658294 0.727763 0.795934 0.859902 0.916168 0.960808 0.989851        1 0.989851
0.523994 0.589808 0.658294 0.727763 0.795934 0.859902 0.916168 0.960808 0.989851        1

MVN_SAMPLE =
-8.07388
-7.99194
-7.75746
-7.41463
-6.69153
 -5.8611
-5.10573
-4.42873
-3.50118
-2.69687

As you can see the MVN samples look out of range, reproducing this issue (same mean and K value) in python with numpy.random.default_rng().multivariate_normal(mean=mean, cov=K, check_valid='ignore') would (consistently) give me a max MVN range of around (-2, 2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.