最終更新日時: 2025年10月23日 01時15分43秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<random>

# std::normal_distribution(C++11)

    namespace std {
      template <class RealType = double>
      class normal_distribution;
    }

## 概要

`normal_distribution`は、平均μ、標準偏差σの正規分布にしたがう乱数を生成するクラスである。

$$ p(x \mid \mu, \sigma ) = \frac{1}{\sigma \sqrt{2 \pi}} \exp \left( - \frac{(x - \mu)^2}{2 \sigma ^2} \right) $$

正規分布は釣り鐘型の分布で、平均値を中心に左右に値が分散する。 標準偏差は値が分布する広がり方(ばらつき)の尺度である。 平均値が最も出現確率が高く、平均値 ± 標準偏差の範囲に全体の約68 %が含まれる。

正規分布は、以下のような用途に使用できる：

- 平均身長170cm、標準偏差5cmというパラメータから、平均付近の身長データを作成する

テンプレートパラメータは、以下を意味する：

- `RealType` : 生成する実数の型。

## メンバ関数

### 構築・リセット

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++11
`~normal_distribution() = default;` | デストラクタ | C++11
`reset` | 状態をリセットする | C++11

### 生成

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator()` | 乱数を生成する | C++11

### プロパティ

名前 | 説明 | 対応バージョン
--- | --- | ---
`mean` | 分布の平均値を取得する | C++11
`stddev` | 分布の標準偏差を取得する | C++11
`param` | 分布のパラメータを取得／設定する | C++11
`min` | 生成し得る値の下限を取得する | C++11
`max` | 生成し得る値の上限を取得する | C++11

## メンバ型

型 | 説明 | 対応バージョン
--- | --- | ---
`result_type` | 乱数生成結果の実数型 `RealType`。 | C++11
`param_type` | 分布パラメータの型。未規定。 | C++11

## 非メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator==` | 等値比較 | C++11
`operator!=` | 非等値比較 | C++11
`operator<<` | ストリームへの出力 | C++11
`operator>>` | ストリームからの入力 | C++11

## 例

    #include <random>
    #include <fstream>
    #include <cstdint>

    int main()
    {
      std::random_device seed_gen;
      std::uint32_t seed = seed_gen();
      std::default_random_engine engine(seed);

      // 平均0.0、標準偏差1.0で分布させる
      std::normal_distribution<> dist(0.0, 1.0);

      std::ofstream file("normal_distribution.tsv");
      for (std::size_t n = 0; n < 1000 * 1000; ++n) {
        // 正規分布で乱数を生成する
        double result = dist(engine);
        file << result << "\t\n";
      }
    }

### 出力

このプログラムによってある時に得られた結果（normal_distribution.tsv）を図示する。

## バージョン

### 言語

- C++11

### 処理系

- Clang:
- GCC: 4.6.1 ✅
- ICC:
- Visual C++:

### 参考

- 正規分布 - Wikipedia
- Marsaglia polar method - Wikipedia
  - GCC 4.9時点においてlibstdc++で使用されているアルゴリズム
  - ボックス＝ミュラー法の変形版。棄却採択処理を含んでいる。
- ボックス＝ミュラー法 - Wikipedia
  - Boost 1.55.0まで、Boost.Randomの`normal_distribution`の実装に使われていたアルゴリズム。
- Ziggurat sampling - Wikipedia
  - Boost 1.56.0以降で、Boost.Randomの`normal_distribution`の実装に使われているアルゴリズム。
  - ボックス＝ミュラー法やPolar法など他の方式よりも、効率を大幅に改善しており、生成される乱数の精度も良い。