# 機能設計書 99-Random

## 概要

本ドキュメントは、Julia標準ライブラリのRandomモジュールの設計を記述する。疑似乱数生成器（RNG）とそのインターフェース、各種分布からのサンプリング、配列のシャッフル・部分配列生成など、乱数に関する包括的な機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：科学計算、モンテカルロシミュレーション、機械学習、暗号学的用途など、高品質な乱数生成はJuliaの重要な基盤機能である。Randomモジュールは、高速なXoshiro256++をデフォルトRNGとして採用し、再現可能なシード制御と効率的なSIMD並列生成をサポートする。

**機能の利用シーン**：`rand()`による一様乱数生成、`randn()`による正規分布乱数生成、`shuffle()`による配列シャッフル、`randperm()`による順列生成、`randstring()`によるランダム文字列生成、`seed!(rng, seed)`によるシード設定。

**主要な処理内容**：
1. 抽象RNGインターフェース（`AbstractRNG`）の定義
2. Sampler機構（`Sampler`, `SamplerType`, `SamplerTrivial`, `SamplerSimple`）
3. Xoshiro256++ RNG実装（デフォルト）
4. MersenneTwister RNG実装
5. RandomDevice（OS乱数源）
6. TaskLocalRNG（タスクごとの乱数状態）
7. `rand`/`rand!`による一様分布サンプリング
8. `randn`/`randn!`による正規分布サンプリング（Zigguratアルゴリズム）
9. `randexp`による指数分布サンプリング
10. ユーティリティ：`shuffle`, `randperm`, `randcycle`, `randsubseq`, `randstring`, `bitrand`

**関連システム・外部連携**：DSFMT（Double precision SIMD-oriented Fast Mersenne Twister）ライブラリ、SHA-2ハッシュ（シード処理）、OS乱数源（/dev/urandom等）。

**権限による制御**：特にない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ライブラリ機能のため関連画面なし |

## 機能種別

疑似乱数生成ライブラリ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rng | AbstractRNG | No | 乱数生成器（デフォルト: default_rng()） | NULLでないこと |
| S | Type/Collection | No | サンプリング対象（デフォルト: Float64） | 対応するSamplerが存在すること |
| dims | Dims | No | 出力配列の次元 | 非負整数のタプル |
| seed | Integer/Vector{UInt8} | No | RNGのシード値 | 型に応じた有効範囲 |

### 入力データソース

- ユーザコードからの直接指定
- OS乱数源（RandomDevice）
- タスクローカルRNG状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 乱数値 | Float64/Int/etc. | 生成された乱数値 |
| 乱数配列 | Array{T} | 指定次元の乱数配列 |
| シャッフル配列 | Vector{T} | シャッフルされた配列 |
| 順列 | Vector{Int} | ランダム順列 |

### 出力先

Julia値として返却

## 処理フロー

### 処理シーケンス

```
1. rand(rng, X) 呼出
   └─ Sampler(rng, X, Val(1)) でSamplerオブジェクト生成
2. Samplerディスパッチ
   ├─ SamplerType{T}: 型に対するサンプリング
   ├─ SamplerTrivial{T}: 値に対するサンプリング（プリコンピュート不要）
   └─ SamplerSimple{T}: 値に対するサンプリング（プリコンピュートデータ付き）
3. rand(rng, sampler) でRNGから乱数取得
   ├─ Float64: [0,1)区間のCloseOpen01
   ├─ Integer: typemin:typemax全範囲
   └─ Collection: インデックスサンプリング
4. randn: Zigguratアルゴリズムによる正規分布生成
5. 配列版: rand!(rng, A, sampler) でin-place生成
```

### フローチャート

```mermaid
flowchart TD
    A[rand/randn/randexp呼出] --> B{rng指定?}
    B -->|なし| C[default_rng = TaskLocalRNG]
    B -->|あり| D[指定RNG使用]
    C --> E[Sampler生成]
    D --> E
    E --> F{サンプリング対象}
    F -->|Type| G[SamplerType]
    F -->|値| H[SamplerTrivial/SamplerSimple]
    G --> I[rand rng sampler]
    H --> I
    I --> J{出力形式}
    J -->|スカラー| K[値を返却]
    J -->|配列| L[rand!でin-place生成]
    L --> M[配列を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | デフォルトRNG | default_rng()はTaskLocalRNG（Xoshiro256++ベース） | rng未指定時 |
| BR-99-02 | Samplerプロトコル | 新しい型のサンプリングはSampler(rng, X, repetition)を定義して拡張 | カスタム型 |
| BR-99-03 | Val(1) vs Val(Inf) | 1回のみの生成と複数回生成で最適なSamplerが異なりうる | Sampler選択時 |
| BR-99-04 | Float64 [0,1) | Float64のデフォルトサンプリングは[0,1)半開区間 | rand(Float64) |
| BR-99-05 | BigInt非対応 | BigIntの一様サンプリングは範囲が無限のため非サポート | rand(BigInt) |

### 計算ロジック

- Float64生成: UInt52をビットマスクして[1,2)の浮動小数点数を作り、1を引いて[0,1)にする
- 正規分布（Ziggurat）: テーブルベースの棄却サンプリング
- LessThan Sampler: 上限値以下の値が得られるまでリジェクション

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | MethodError | サポートされていない型でSampler生成 | MethodError |
| - | ArgumentError | 空のコレクションからサンプリング | ArgumentError |

### リトライ仕様

LessThan SamplerはリジェクションサンプリングのためループするがTimeoutなし（確率的に収束する）。

## トランザクション仕様

該当なし

## パフォーマンス要件

- XoshiroSimd.jlによるSIMD並列乱数生成（バルク生成時）
- UnsafeViewによるreinterpretを回避した効率的メモリアクセス
- @inboundsマクロによる境界チェック省略（rand!ループ内）

## セキュリティ考慮事項

- Xoshiro/MersenneTwisterは暗号学的にセキュアではない
- 暗号学的用途にはRandomDeviceを使用すべき
- シード値は推測可能であってはならない場面ではランダムシードを使用

## 備考

- `Random.seed!`でグローバルRNGのシード設定が可能
- MersenneTwisterはDSFMT（C実装）をラップしている
- SHA-2ハッシュによるシードの混合処理が行われる

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Random.jl | `stdlib/Random/src/Random.jl` | AbstractRNG抽象型（43行目）、UniformBits/FloatInterval型階層（56-104行目）、Sampler型階層（110-216行目） |

**読解のコツ**: Randomモジュールの設計パターンは「Samplerプロトコル」に集約される。`Sampler(rng, X, repetition)`が型Xに対するサンプリング戦略を返し、`rand(rng, sampler)`が実際の乱数を生成する。この2段階のディスパッチを理解することが鍵である。

#### Step 2: RNG実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Xoshiro.jl | `stdlib/Random/src/Xoshiro.jl` | Xoshiro256++の実装（デフォルトRNG） |
| 2-2 | RNGs.jl | `stdlib/Random/src/RNGs.jl` | RandomDevice、TaskLocalRNGの実装 |
| 2-3 | MersenneTwister.jl | `stdlib/Random/src/MersenneTwister.jl` | MT19937の実装 |

#### Step 3: 乱数生成インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Random.jl | `stdlib/Random/src/Random.jl` | rand/rand!のメソッドディスパッチ（260-301行目） |
| 3-2 | generation.jl | `stdlib/Random/src/generation.jl` | 各型に対するrand実装 |

**主要処理フロー**:
- **262行目**: `rand(rng, X)` → `rand(rng, Sampler(rng, X, Val(1)))` にディスパッチ
- **265行目**: `rand(rng, Type{X})` → `rand(rng, Sampler(rng, X, Val(1)))::X`
- **278-283行目**: `rand!(rng, A, sp)` - eachindexループでin-place生成

#### Step 4: 正規分布・ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | normal.jl | `stdlib/Random/src/normal.jl` | randn（Zigguratアルゴリズム）、randexp |
| 4-2 | misc.jl | `stdlib/Random/src/misc.jl` | shuffle, randperm, randcycle, randstring, randsubseq |

### プログラム呼び出し階層図

```
rand(X) (Random.jl:267)
    +-- rand(default_rng(), X) (Random.jl:262)
            +-- Sampler(rng, X, Val(1)) (Random.jl:143)
            |       +-- SamplerType{X}() or SamplerTrivial(x)
            +-- rand(rng, sampler) (generation.jl)
                    +-- [Xoshiro] rand(rng::Xoshiro, ::SamplerType{Float64})
                    +-- [MT] rand(rng::MersenneTwister, ...)

rand!(A, X) (Random.jl:272)
    +-- rand!(default_rng(), A, X)
            +-- Sampler(rng, X)
            +-- rand!(rng, A, sp) - eachindex loop

randn(rng) (normal.jl)
    +-- Ziggurat algorithm
    +-- rand(rng, UInt52Raw()) for uniform bits

shuffle(rng, A) (misc.jl)
    +-- Fisher-Yates algorithm
    +-- rand(rng, 1:i) for each step
```

### データフロー図

```
[入力]                     [処理]                          [出力]

Type/Collection ──────────> Sampler生成 ────────────────> SamplerType/Trivial/Simple
                                |
RNG状態 ──────────────────> rand(rng, sampler) ─────────> 乱数値/配列
  (Xoshiro/MT/Device)          |
                               +-- Float64: ビットマスク
                               +-- Int: 範囲制限
                               +-- Collection: インデックス

seed値 ────────────────────> seed!(rng, seed) ───────────> RNG状態更新
                                +-- SHA2ハッシュ混合
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Random.jl | `stdlib/Random/src/Random.jl` | ソース | モジュール定義、コアインターフェース |
| Xoshiro.jl | `stdlib/Random/src/Xoshiro.jl` | ソース | Xoshiro256++ RNG実装 |
| RNGs.jl | `stdlib/Random/src/RNGs.jl` | ソース | RandomDevice, TaskLocalRNG |
| MersenneTwister.jl | `stdlib/Random/src/MersenneTwister.jl` | ソース | MT19937 RNG実装 |
| DSFMT.jl | `stdlib/Random/src/DSFMT.jl` | ソース | DSFMTライブラリラッパー |
| generation.jl | `stdlib/Random/src/generation.jl` | ソース | 型別rand実装 |
| normal.jl | `stdlib/Random/src/normal.jl` | ソース | randn（正規分布）、randexp（指数分布） |
| misc.jl | `stdlib/Random/src/misc.jl` | ソース | shuffle, randperm, randstring等 |
| XoshiroSimd.jl | `stdlib/Random/src/XoshiroSimd.jl` | ソース | SIMD最適化バルク生成 |
