Skip to content

Commit ee6082f

Browse files
authored
Add Ex(1) sampler (#327)
1 parent 9e744f4 commit ee6082f

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
3+
#include <cmath>
4+
#include <cstdint>
5+
#include <array>
6+
7+
template <int D> struct ExponentialDistSampler {
8+
std::array<double, (1 << D)> minuslogps;
9+
10+
constexpr ExponentialDistSampler() {
11+
for (int i = 0; i < (1 << D); ++i) minuslogps.at(i) = -log((0.5 + i) / (1 << D));
12+
}
13+
14+
double sample(uint32_t random_mask) const {
15+
return minuslogps.at(random_mask & ((1 << D) - 1));
16+
}
17+
18+
// p ~ U(0, 1) => -log(p) ~ Ex(1)
19+
// P[exp(-|dx| / T) >= p] = P[|dx| <= -log(p) * T]
20+
bool check_sa(double abs_dx, double T, uint32_t random_mask) const {
21+
return abs_dx <= minuslogps.at(random_mask & ((1 << D) - 1)) * T;
22+
}
23+
};
24+
// const ExponentialDistSampler<16> log_ps;

heuristic/exponential_dist_sampler.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: Fast sampler of exponential distribution (高速指数分布サンプラー・擬似焼きなまし法の遷移判定)
3+
documentation_of: ./exponential_dist_sampler.hpp
4+
---
5+
6+
母数 $\lambda = 1$ の指数分布を模擬するサンプラー.
7+
8+
典型的な用途として,擬似焼きなまし法 (simulated annealing, SA) の遷移判定を(指数関数や対数関数の計算を毎回行うことなく)高速に行える.
9+
10+
## 使用方法
11+
12+
```cpp
13+
constexpr int D = 18;
14+
const ExponentialDistSampler<D> eds; // 2^D 個のサンプルを前計算
15+
16+
// 下位 D bit がランダムに分布した mask を与えると x ~ Ex(1) をサンプル
17+
uint32_t mask;
18+
double x = eds.sample(mask);
19+
20+
double dx;
21+
double T;
22+
23+
// コストの変化が abs(dx), 温度 T のとき焼きなまし法の遷移を受理するか確率的に判定
24+
bool upd = eds.check_sa(abs(dx), T, mask);
25+
```

0 commit comments

Comments
 (0)