Last active
May 21, 2024 10:23
-
-
Save smoge/a5a213f7d7461c3a607ef6fedbc5bf76 to your computer and use it in GitHub Desktop.
sum6.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <chrono> | |
#include <execution> | |
#include <iostream> | |
#include <numeric> | |
#include <random> | |
#include <vector> | |
class RandomNumberGenerator { | |
public: | |
RandomNumberGenerator() : gen_(std::random_device{}()), dis_(0.0, 100.0) {} | |
void generate(std::vector<double> &values) { | |
std::generate(values.begin(), values.end(), | |
[this]() { return dis_(gen_); }); | |
} | |
private: | |
std::mt19937 gen_; | |
std::uniform_real_distribution<> dis_; | |
}; | |
void adjust_to_positive(std::vector<double> &arr) { | |
auto min_value = | |
*std::min_element(std::execution::par, arr.begin(), arr.end()); | |
double adjustment_value = 1.0 - min_value; | |
std::for_each(std::execution::par, arr.begin(), arr.end(), | |
[adjustment_value](double &val) { val += adjustment_value; }); | |
} | |
void normalize_array(std::vector<double> &arr) { | |
const double sum = | |
std::reduce(std::execution::par, arr.begin(), arr.end(), 0.0); | |
const double epsilon = 1e-8; | |
if (std::abs(sum) <= epsilon) { | |
throw std::runtime_error( | |
"Cannot normalize array with sum too close to 0.0"); | |
} | |
double inv_sum = 1.0 / sum; | |
std::for_each(std::execution::par, arr.begin(), arr.end(), | |
[inv_sum](double &val) { val *= inv_sum; }); | |
} | |
int main() { | |
const size_t list_sizes[] = {1000, 10000, 100000, 1000000}; | |
RandomNumberGenerator rng; | |
for (size_t n : list_sizes) { | |
std::vector<double> values(n); | |
auto start = std::chrono::high_resolution_clock::now(); | |
rng.generate(values); | |
auto gen_end = std::chrono::high_resolution_clock::now(); | |
auto adjust_start = std::chrono::high_resolution_clock::now(); | |
adjust_to_positive(values); | |
auto adjust_end = std::chrono::high_resolution_clock::now(); | |
normalize_array(values); | |
auto end = std::chrono::high_resolution_clock::now(); | |
std::chrono::duration<double> gen_duration = gen_end - start; | |
std::chrono::duration<double> adjust_duration = adjust_end - adjust_start; | |
std::chrono::duration<double> norm_duration = end - adjust_end; | |
std::cout << "Size: " << n << "\nGeneration time: " << gen_duration.count() | |
<< "s" << "\nAdjustment time: " << adjust_duration.count() << "s" | |
<< "\nNormalization time: " << norm_duration.count() << "s\n\n"; | |
} | |
return 0; | |
} | |
Size: 1000 | |
Generation time: 7.0092e-05s | |
Adjustment time: 1.217e-06s | |
Normalization time: 4.77e-07s | |
Size: 10000 | |
Generation time: 0.000810673s | |
Adjustment time: 1.1917e-05s | |
Normalization time: 4.245e-06s | |
Size: 100000 | |
Generation time: 0.00764328s | |
Adjustment time: 0.000131727s | |
Normalization time: 9.2728e-05s | |
Size: 1000000 | |
Generation time: 0.0753062s | |
Adjustment time: 0.00181232s | |
Normalization time: 0.00111687s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment