2
This file is part of TON Blockchain source code.
4
TON Blockchain is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
9
TON Blockchain is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
17
In addition, as a special exception, the copyright holders give permission
18
to link the code of portions of this program with the OpenSSL library.
19
You must obey the GNU General Public License in all respects for all
20
of the code used other than OpenSSL. If you modify file(s) with this
21
exception, you may extend this exception to your version of the file(s),
22
but you are not obligated to do so. If you do not wish to do so, delete this
23
exception statement from your version. If you delete this exception statement
24
from all source files in the program, then also delete it here.
26
Copyright 2020 Telegram Systems LLP
29
#include "td/utils/Random.h"
30
#include "td/utils/misc.h"
31
#include "block/block.h"
34
const int MAX_N = 1000, MAX_K = 100, DEFAULT_K = 7;
38
long long iterations = 1000000;
40
td::uint64 TWL, WL[MAX_N];
41
double W[MAX_N], CW[MAX_N + 1], RW[MAX_N], R0;
42
int A[MAX_N], C[MAX_N];
46
static std::pair<double, double> H[MAX_N];
49
for (int i = 0; i < K; i++) {
51
double inv_wt = 1. / total_wt;
52
R0 += inv_wt; // advanced mtcarlo stats
53
for (int j = 0; j < i; j++) {
54
RW[A[j]] -= inv_wt; // advanced mtcarlo stats
56
// double p = drand48() * total_wt;
57
double p = (double)td::Random::fast_uint64() * total_wt / (1. * (1LL << 32) * (1LL << 32));
58
for (int h = 0; h < hc; h++) {
73
CHECK(a >= 0 && a < N);
74
CHECK(total_wt >= W[a]);
78
while (c > 0 && H[c - 1].first > x) {
85
C[a]++; // simple mtcarlo stats
86
// std::cout << a << ' ';
88
// std::cout << std::endl;
89
++TC; // simple mtcarlo stats
93
for (int i = 0; i < N; i++) {
99
std::cout << "running " << iterations << " steps of Monte Carlo simulation\n";
100
for (long long it = 0; it < iterations; ++it) {
103
for (int i = 0; i < N; i++) {
104
RW[i] = W[i] * (RW[i] + R0) / (double)iterations;
110
void compute_bad_approx() {
111
static double S[MAX_K + 1];
113
for (int i = 1; i <= K; i++) {
116
for (int i = 0; i < N; i++) {
118
for (int j = K; j > 0; j--) {
119
S[j] += p * S[j - 1];
123
for (int i = 0; i < N; i++) {
124
double t = 1., p = W[i];
125
for (int j = 1; j <= K; j++) {
134
<< "usage: test-weight-distr [-k<shard-val-num>][-m<iterations>][-s<rand-seed>]\nReads the set of validator "
135
"weights from stdin and emulates validator shard distribution load\n\t-k <shard-val-num>\tSets the number of "
136
"validators generating each shard\n\t-m <iterations>\tMonte Carlo simulation steps\n";
140
int main(int argc, char* const argv[]) {
142
int new_verbosity_level = VERBOSITY_NAME(INFO);
144
while ((i = getopt(argc, argv, "hs:k:m:v:")) != -1) {
147
K = td::to_integer<int>(td::Slice(optarg));
148
CHECK(K > 0 && K <= 100);
151
iterations = td::to_integer<long long>(td::Slice(optarg));
152
CHECK(iterations > 0);
155
// seed = td::to_integer<long>(td::Slice(optarg));
159
new_verbosity_level = VERBOSITY_NAME(FATAL) + (verbosity = td::to_integer<int>(td::Slice(optarg)));
169
SET_VERBOSITY_LEVEL(new_verbosity_level);
170
for (N = 0; N < MAX_N && (std::cin >> WL[N]); N++) {
174
CHECK(std::cin.eof());
175
CHECK(N > 0 && TWL > 0 && N <= MAX_N);
177
CHECK(K > 0 && K <= MAX_K);
179
for (i = 0; i < N; i++) {
181
acc += W[i] = (double)WL[i] / (double)TWL;
182
std::cout << "#" << i << ":\t" << W[i] << std::endl;
184
compute_bad_approx();
186
std::cout << "result of Monte Carlo simulation (" << iterations << " iterations):" << std::endl;
187
std::cout << "idx\tweight\tmtcarlo1\tmtcarlo2\tapprox\n";
188
for (i = 0; i < N; i++) {
189
std::cout << "#" << i << ":\t" << W[i] << '\t' << (double)C[i] / (double)iterations << '\t' << RW[i] << '\t' << B[i]
192
// same computation, but using a MtCarloComputeShare object
193
block::MtCarloComputeShare MT(K, N, W, iterations);
194
std::cout << "-----------------------\n";
195
for (i = 0; i < N; i++) {
196
std::cout << '#' << i << ":\t" << MT.weight(i) << '\t' << MT.share(i) << std::endl;