I would like to generate Pascal pyramid data from a given data set that looks like this
Pyramid(1,2,3,4,5,6,7,8,9);
This is what I have been doing but it reaches only the second layer while I want it to recursively loop till the top.
template<typename T>
const T Pyramid(T a, T b)
{
return a + b;
}
template<typename T, typename ...A>
const T Pyramid(T t1, T t2, A...a)
{
return Pyramid(t1, t2) + Pyramid(t2, a...);
}
Could you help me fill up the next layers ? ;)
C++17
Here is the C++17 solution (using fold expressions):
#include <iostream>
#include <stdexcept>
#include <utility>
using Integer = std::uint64_t;
constexpr auto Factorial(const Integer n)
{
Integer factorial = 1;
for (Integer i = 2; i <= n; ++i)
{
factorial *= i;
}
return factorial;
}
constexpr auto Binom(const Integer n, const Integer m)
{
if (n < m)
{
throw std::invalid_argument("Binom: n should not be less than m");
}
return Factorial(n) / Factorial(m) / Factorial(n - m);
}
template <Integer... indices, typename... Types>
constexpr auto PyramidImplementation(std::integer_sequence<Integer, indices...>, Types... values)
{
return ((Binom(sizeof...(values), indices) * values) + ...);
}
template <typename... Types>
constexpr auto Pyramid(Types... values)
{
return PyramidImplementation(std::make_integer_sequence<Integer, sizeof...(values)>{}, values...);
}
// ...
constexpr auto pyramid = Pyramid(1, 2, 3, 4, 5, 6, 7, 8, 9);
std::cout << "Pyramid = " << pyramid << std::endl;
Live demo
This solution doesn't use the recursion, because the needed result for a[i] (i = 0 ... n - 1) can be calculated as a sum of binom(n, i) * a[i] (for i = 0 ... n - 1), where binom(n, m) is the binomial coefficient. The Binom function is implemented in the simplest way, so it will work only for small values of n.
C++14
The code can be made C++14-compatible via the following PyramidImplementation function implementation:
#include <type_traits>
template <Integer... indices, typename... Types>
constexpr auto PyramidImplementation(std::integer_sequence<Integer, indices...>, Types... values)
{
using Do = int[];
std::common_type_t<Types...> pyramid{};
(void)Do{0, (pyramid += Binom(sizeof...(values), indices) * values, 0)...};
return pyramid;
}
Live demo
Related
I am interested in how you can generate an array of prime numbers at compile time (I believe that the only way is using metaprogramming (in C++, not sure how this works in other languages)).
Quick note, I don't want to just say int primes[x] = {2, 3, 5, 7, 11, ...};, since I want to use this method in competitive programming, where source files cannot be larger than 10KB. So this rules out any pregenerated arrays of more than a few thousand elements.
I know that you can generate the fibonacci sequence at compile time for example, but that is rather easy, since you just add the 2 last elements. For prime numbers, I don't really know how to do this without loops (I believe it is possible, but I don't know how, using recursion I guess), and I don't know how loops could be evaluated at compile-time.
So I'm looking for an idea (at least) on how to approach this problem, maybe even a short example
We can do a compile time pre calculation of some prime numbers and put them in a compile time generated array. And then use a simple look up mechanism to get the value. This will work only to a small count of prime numbers. But it should show you the basic mechanism.
We will first define some default approach for the calculation a prime number as a constexpr function:
constexpr bool isPrime(size_t n) noexcept {
if (n <= 1) return false;
for (size_t i = 2; i*i < n; i++) if (n % i == 0) return false;
return true;
}
constexpr unsigned int primeAtIndex(size_t i) noexcept {
size_t k{3};
for (size_t counter{}; counter < i; ++k)
if (isPrime(k)) ++counter;
return k-1;
}
With that, prime numbers can easily be calculated at compile time. Then, we fill a std::array with all prime numbers. We use also a constexpr function and make it a template with a variadic parameter pack.
We use std::index_sequence to create a prime number for indices 0,1,2,3,4,5, ....
That is straigtforward and not complicated:
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
This function will be fed with an index sequence 0,1,2,3,4,... and a generator function and return a std::array<return type of generator function, ...> with the corresponding numbers, calculated by the generator.
We make a next function, that will call the above with the index sequence 1,2,3,4,...Max, like so:
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
And now, finally,
constexpr auto Primes = generateArray<100>(primeAtIndex);
will give us a compile-time std::array<unsigned int, 100> with the name Primes containing all 100 prime numbers. And if we need the i'th prime number, then we can simply write Primes [i]. There will be no calculation at runtime.
I do not think that there is a faster way to calculate the n'th prime number.
Please see the complete program below:
#include <iostream>
#include <utility>
#include <array>
// All done during compile time -------------------------------------------------------------------
constexpr bool isPrime(size_t n) noexcept {
if (n <= 1) return false;
for (size_t i = 2; i*i < n; i++) if (n % i == 0) return false;
return true;
}
constexpr unsigned int primeAtIndex(size_t i) noexcept {
size_t k{3};
for (size_t counter{}; counter < i; ++k)
if (isPrime(k)) ++counter;
return k-1;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
// This is the definition of a std::array<unsigned int, 100> with prime numbers in it
constexpr auto Primes = generateArray<100>(primeAtIndex);
// End of: All done during compile time -----------------------------------------------------------
// Some debug test driver code
int main() {
for (const auto p : Primes) std::cout << p << ' '; std::cout << '\n';
return 0;
}
By the way. The generateArray fucntionality will of course also work with other generator functions.
If you need for example triangle numbers, then you could use:
constexpr size_t getTriangleNumber(size_t row) noexcept {
size_t sum{};
for (size_t i{ 1u }; i <= row; i++) sum += i;
return sum;
}
and
constexpr auto TriangleNumber = generateArray<100>(getTriangleNumber);
would give you a compile time calculated constexpr std::array<size_t, 100> with triangle numbers.
For fibonacci numbers your could use
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
unsigned long long f1{ 0ull }, f2{ 1ull }, f3{};
while (index--) { f3 = f2 + f1; f1 = f2; f2 = f3; }
return f2;
}
and
constexpr auto FibonacciNumber = generateArray<93>(getFibonacciNumber);
to get ALL Fibonacci numbers that fit in a 64 bit value.
So, a rather flexible helper.
Caveat
Big array sizes will create a compiler out of heap error.
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2.
Additionally compiled and tested with clang11.0 and gcc10.2
Language: C++17
The following is just to give you something to start with. It heavily relies on recursively instantiating types, which isn't quite efficient and I would not want to see in the next iteration of the implementation.
div is a divisor of x iff x%div == false:
template <int div,int x>
struct is_divisor_of : std::conditional< x%div, std::false_type, std::true_type>::type {};
A number x is not prime, if there is a p < x that is a divisor of x:
template <int x,int p=x-2>
struct has_divisor : std::conditional< is_divisor_of<p,x>::value, std::true_type, has_divisor<x,p-1>>::type {};
If no 1 < p < x divides x then x has no divisor (and thus is prime):
template <int x>
struct has_divisor<x,1> : std::false_type {};
A main to test it:
int main()
{
std::cout << is_divisor_of<3,12>::value;
std::cout << is_divisor_of<5,12>::value;
std::cout << has_divisor<12>::value;
std::cout << has_divisor<13>::value;
}
Output:
1010
Live Demo.
PS: You probably better take the constexpr function route, as suggested in a comment. The above is just as useful as recursive templates to calculate the fibonacci numbers (ie not really useful other than for demonstration ;).
With "simple" constexpr, you might do:
template <std::size_t N>
constexpr void fill_next_primes(std::array<std::size_t, N>& a, std::size_t n)
{
std::size_t i = (a[n - 1] & ~0x1) + 1;
while (!std::all_of(a.begin(), a.begin() + n, [&i](int e){ return i % e != 0; })) {
i += 2;
}
a[n] = i;
}
template <std::size_t N>
constexpr std::array<std::size_t, N> make_primes_array()
{
// use constexpr result
// to ensure to compute at compile time,
// even if `make_primes_array` is not called in constexpr context
constexpr auto res = [](){
std::array<std::size_t, N> res{2};
for (std::size_t i = 1; i != N; ++i) {
fill_next_primes(res, i);
}
return res;
}();
return res;
}
Demo
I'm coding a function that calculates the pmf of multinomial distribution(https://en.wikipedia.org/wiki/Multinomial_distribution).
I've coded a function of multinomial coefficients successfully, and want to use this in calculating multinomial distribution, but compiling is failing.
My current attempt:
#include <algorithm>
#include <cmath>
#include <cassert>
#include <utility>
#include <initializer_list>
#include <numeric>
template <typename N>
concept Unsigned = std::is_unsigned_v<N>;
template <typename N>
concept Integral = std::is_integral_v<N>;
template <typename R>
concept Floating = std::is_floating_point_v<R>;
template <Unsigned U>
constexpr U binom(U N, U K) {
assert(N >= K);
U result {1};
for (U i = U {1}; i <= N - K; i++) {
result *= i + K;
result /= i;
}
return result;
}
template <Unsigned U, Integral I>
constexpr U multinom (U N, I K) {
assert(N == K);
return U {1};
}
template <Unsigned U, Integral I, Integral... Is>
constexpr U multinom (U N, I K1, Is... Ks) {
assert(N >= static_cast<U>(K1));
return binom(N, static_cast<U>(K1)) * multinom(N - static_cast<U>(K1), Ks...);
}
template <Floating F1, Floating F2>
constexpr bool almost_equal(F1 f1, F2 f2) {
return std::fabs(f1 - f2) < std::min({1.0e-4, f1 * 1.0e-3, f2 * 1.0e-3});
}
/*template <Unsigned U, Integral I, Floating F>
constexpr F multinom_pmf(U N, std::initializer_list<std::pair<I, F>> args) {
assert(almost_equal(1.0, std::accumulate(args.begin(), args.end(), 0.0, [](auto& a, auto& b) {return a + b.second;})));
}*/
template <Unsigned U, Integral I, Floating F>
constexpr F multinom_pmf (U N, std::pair<I, F>... args) {
assert(almost_equal(1.0, std::accumulate(args.begin(), args.end(), 0.0, [](auto& a, auto& b) {return a + b.second;})));
// ???
}
int main() {
static_assert(multinom<size_t>(5, 5) == 1);
static_assert(multinom<size_t>(5, 3, 2) == 10);
static_assert(multinom<size_t>(6, 2, 2, 2) == 90);
}
Desired interface:
multinom_pmf<>(N, pair<I, F>... args) = multinom<>(N, /* first of args */) * std::pow(/* second of args */, /* first of args */) * ...
ex)
multinom_pmf<>(5, {3, 0.6}, {2, 0.4}) = multinom<>(5, 3, 2) * std::pow(0.6, 3) * std::pow(0.4, 2) = 0.3456
multinom_pmf<>(6, {2, 0.4}, {2, 0.35}, {2, 0.25}) = multinom<>(6, 2, 2, 2) * pow(0.4, 2) * pow(0.35, 2) * pow(0.25, 2) = 0.11025
I want the function to be able to check that
N == sum of first of args (which would be done inside multinom() call)
1.0 == sum of second of args
How can I improve my attempts? Thanks in advance.
Self-answering: My solution ended up with discarding std::pair things. Hacky, but works.
Still have no idea about how to check whether the sum of probability is 1.
template <Unsigned U, Integral I, Floating F, typename... Ts>
constexpr F multinom_pmf (U N, I K1, F theta1, Ts... args) {
F prob_value = std::pow(theta1, K1) * binom(N, static_cast<U>(K1));
if constexpr(sizeof...(args) > 0)
return prob_value * multinom_pmf(N - static_cast<U>(K1), args...);
else
return prob_value;
}
int main() {
static_assert(multinom<size_t>(5, 5) == 1);
static_assert(multinom<size_t>(5, 3, 2) == 10);
static_assert(multinom<size_t>(6, 2, 2, 2) == 90);
assert(almost_equal(multinom_pmf<size_t>(5, 3, 0.4, 2, 0.6), 0.2304));
}
I was trying to use enable_if to avoid duplicating code. It works fine as long as placed in the return type, but not if it's in the parameters. Before this gets closed as a dup of this, the error I'm getting is not a redefinition, but a "no matching function for call." Here's my MCVE (not so "C", or so "M" for that matter) using VS2015 and g++ 7.2.0 (mingw):
#include <cmath>
#include <array>
#include <algorithm>
template <typename T, size_t M, size_t N>
class Matrix
{
public:
static const size_t ROWS = M;
static const size_t COLS = N;
typedef T SCALAR;
SCALAR operator[](const size_t index) const
{
static_assert((COLS == 1 || ROWS == 1), "operator[] is only for vectors (single row or column).");
return m_elements.at(index);
}
SCALAR& operator[](const size_t index)
{
static_assert((COLS == 1 || ROWS == 1), "operator[] is only for vectors (single row or column).");
return m_elements.at(index);
}
std::array<T, M * N> m_elements;
};
template <typename T, size_t N, size_t M>
static inline T Length(
const Matrix<typename std::enable_if<(M == 1 || N == 1), T>::type, N, M> & input)
{
T value = 0;
for (size_t i = 0; i < std::max(N, M); ++i)
{
value += (input[i] * input[i]);
}
return std::sqrt(value);
}
template <typename T, size_t M, size_t N>
static inline
Matrix<typename std::enable_if<(M == 3 && N == 1) || (M == 1 && N == 3), T>::type , M, N>
CrossProduct(const Matrix<T, M, N> & a, const Matrix<T, M, N> & b)
{
Matrix<T, M, N> result;
result[0] = a[1] * b[2] - a[2] * b[1];
result[1] = a[2] * b[0] - a[0] * b[2];
result[2] = a[0] * b[1] - a[1] * b[0];
return result;
}
Matrix<double, 1, 1> m11;
Matrix<double, 3, 1> m31;
Matrix<double, 1, 3> m13;
Matrix<double, 3, 3> m33;
auto l0 = Length(m11); // Should work, but doesn't: no matching function for call to 'Length(Matrix<double, 1, 1>&)'
auto l1 = Length(m31); // Should work, but doesn't: no matching function for call to 'Length(Matrix<double, 3, 1>&)'
auto l2 = Length(m13); // Should work, but doesn't: no matching function for call to 'Length(Matrix<double, 1, 3>&)'
//auto l3 = Length(m33); // Shouldn't work, and doesn't: no matching function for call to 'Length(Matrix<double, 3, 3>&)'
auto v1 = CrossProduct(m13, m13); //Works, as expected
//auto v2 = CrossProduct(m11, m11); // As expected: enable_if.cpp:71:32: error: no matching function for
// call to 'CrossProduct(Matrix<double, 1, 1>&, Matrix<double, 1, 1>&)'
If I change the signature of Length to
static inline typename std::enable_if<(M == 1 || N == 1), T>::type \
Length(const math::Matrix<T, N, M> & input)
it works fine. But the error it gives me seems to indicate that it was able to determine the correct signature (e.g. Length(Matrix<double, 3, 1>&)).
Why is the compiler unable to find a matching function if the enable_if is in the parameter list, but is able to if it's in the return type?
std::enable_if<..., T>::type is a nested name, and as such cannot be deduced:
See [temp.deduct.type]/5:
The non-deduced contexts are:
—
The nested-name-specifier of a type that was specified using a qualified-id.
. . .
As a workaround, move the enable_if to a separate template argument:
template <typename T, size_t N, size_t M, typename std::enable_if<(M == 1 || N == 1), int>::type = 0>
static inline T Length(
const Matrix<T, N, M> & input)
I have N numbers n_1, n_2, ...n_N and associated probabilities p_1, p_2, ..., p_N.
function should return number n_i with probability p_i, where i =1, ..., N.
How model it in c++?
I know it is not a hard problem. But I am new to c++, want to know what function will you use.
Will you generate uniform random number between 0 and 1 like this:
((double) rand() / (RAND_MAX+1))
This is very similar to the answer I gave for this question:
changing probability of getting a random number
You can do it like this:
double val = (double)rand() / RAND_MAX;
int random;
if (val < p_1)
random = n_1;
else if (val < p_1 + p_2)
random = n_2;
else if (val < p_1 + p_2 + p_3)
random = n_3;
else
random = n_4;
Of course, this approach only makes sense if p_1 + p_2 + p_3 + p_4 == 1.0.
This can easily be generalized to a variable number of outputs and probabilities with a couple of arrays and a simple loop.
If you know the probabilities compile-time you can use this variadic template version I decided to create. Although in actuality, I don't recommend using this due to how horribly incomprehensible the source is :P.
Usage
NumChooser <
Entry<2, 10>, // Value of 2 and relative probability of 10
Entry<5, 50>,
Entry<6, 80>,
Entry<20, 01>
> chooser;
chooser.choose(); // Returns the number 2 on average 10/141 times, etc.
Efficiency
Ideone
Generally, the template based implementation is very similar to a basic one. However, there are a few differences:
With -O2 optimizations or no optimizations, the template version can be ~1-5% slower
With -O3 optimizations, the template version was actually ~1% faster when generating numbers for 1 - 10,000 times consecutively.
Notes
This uses rand() for choosing numbers. If being statistically accurate is important to you or you would like to use C++11's <random>, you can use the slightly modified version below the first source.
Source
Ideone
#define onlyAtEnd(a) typename std::enable_if<sizeof...(a) == 0 > ::type
template<int a, int b>
class Entry
{
public:
static constexpr int VAL = a;
static constexpr int PROB = b;
};
template<typename... EntryTypes>
class NumChooser
{
private:
const int SUM;
static constexpr int NUM_VALS = sizeof...(EntryTypes);
public:
static constexpr int size()
{
return NUM_VALS;
}
template<typename T, typename... args>
constexpr int calcSum()
{
return T::PROB + calcSum < args...>();
}
template <typename... Ts, typename = onlyAtEnd(Ts) >
constexpr int calcSum()
{
return 0;
}
NumChooser() : SUM(calcSum < EntryTypes... >()) { }
template<typename T, typename... args>
constexpr int find(int left, int previous = 0)
{
return left < 0 ? previous : find < args... >(left - T::PROB, T::VAL);
}
template <typename... Ts, typename = onlyAtEnd(Ts) >
constexpr int find(int left, int previous)
{
return previous;
}
constexpr int choose()
{
return find < EntryTypes... >(rand() % SUM);
}
};
C++11 <random> version
Ideone
#include <random>
#define onlyAtEnd(a) typename std::enable_if<sizeof...(a) == 0 > ::type
template<int a, int b>
class Entry
{
public:
static constexpr int VAL = a;
static constexpr int PROB = b;
};
template<typename... EntryTypes>
class NumChooser
{
private:
const int SUM;
static constexpr int NUM_VALS = sizeof...(EntryTypes);
std::mt19937 gen;
std::uniform_int_distribution<> dist;
public:
static constexpr int size()
{
return NUM_VALS;
}
template<typename T, typename... args>
constexpr int calcSum()
{
return T::PROB + calcSum < args...>();
}
template <typename... Ts, typename = onlyAtEnd(Ts) >
constexpr int calcSum()
{
return 0;
}
NumChooser() : SUM(calcSum < EntryTypes... >()), gen(std::random_device{}()), dist(1, SUM) { }
template<typename T, typename... args>
constexpr int find(int left, int previous = 0)
{
return left < 0 ? previous : find < args... >(left - T::PROB, T::VAL);
}
template <typename... Ts, typename = onlyAtEnd(Ts) >
constexpr int find(int left, int previous)
{
return previous;
}
int choose()
{
return find < EntryTypes... >(dist(gen));
}
};
// Same usage as example above
Perhaps something like (untested code!)
/* n is the size of tables, numtab[i] the number of index i,
probtab[i] its probability; the sum of all probtab should be 1.0 */
int random_inside(int n, int numtab[], double probtab[])
{
double r = drand48();
double p = 0.0;
for (int i=0; i<n; i++) {
p += probtab[i];
if (r>=p) return numtab[i];
}
}
Here you have a correct answer in my last comment:
how-to-select-a-value-from-a-list-with-non-uniform-probabilities
I've written a template function to determine the median of any vector or array of any type that can be sorted with sort. The function and a small test program are below:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace::std;
template <class T, class X>
void median(T vec, size_t size, X& ret)
{
sort(vec, vec + size);
size_t mid = size/2;
ret = size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
int main()
{
vector<double> v;
v.push_back(2); v.push_back(8);
v.push_back(7); v.push_back(4);
v.push_back(9);
double a[5] = {2, 8, 7, 4, 9};
double r;
median(v.begin(), v.size(), r);
cout << r << endl;
median(a, 5, r);
cout << r << endl;
return 0;
}
As you can see, the median function takes a pointer as an argument, T vec. Also in the argument list is a reference variable X ret, which is modified by the function to store the computed median value.
However I don't find this a very elegant solution. T vec will always be a pointer to the same type as X ret. My initial attempts to write median had a header like this:
template<class T>
T median(T *vec, size_t size)
{
sort(vec, vec + size);
size_t mid = size/2;
return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
I also tried:
template<class T, class X>
X median(T vec, size_t size)
{
sort(vec, vec + size);
size_t mid = size/2;
return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
I couldn't get either of these to work. My question is, can anyone show me a working implementation of either of my alternatives?
Thanks for looking!
The idiomatic approach is to use iterators. To enable this, you can derive the return type from the iterator:
template <class I>
typename iterator_traits<I>::value_type median(I start, I finish)
{
...
}
I'd do this:
template <class T>
void median( T* vec, size_t size, T& ret )
{
sort( vec, vec + size );
size_t mid = size/2;
ret = size % 2 == 0 ? ( vec[mid] + vec[mid-1] ) / 2 : vec[mid];
}
template <class T>
void median( vector<T>& vec, T& ret )
{
median( &*vec.begin(), vec.size(), ret );
}
But that's just me.