# 機能設計書 29-統計関数

## 概要

本ドキュメントは、Nushellにおける統計関数機能の設計仕様を記述する。

### 本機能の処理概要

統計関数機能は、数値リストに対する統計的計算を提供する。平均、合計、中央値、標準偏差、分散、最小値、最大値、最頻値、積などの統計量を計算し、データ分析やレポート作成を支援する。

**業務上の目的・背景**：データ分析において、基本的な統計量の計算は不可欠である。ログファイルの集計、パフォーマンスデータの分析、ファイルサイズの統計など、様々な場面で統計関数が必要となる。これらの関数をパイプライン内で直接使用できることで、データ分析ワークフローの効率化を実現する。

**機能の利用シーン**：
- 数値データの平均・合計を計算する場合
- データの分散・標準偏差を調べる場合
- 最大値・最小値を見つける場合
- テーブルの各列に対して統計処理を行う場合

**主要な処理内容**：
1. `math avg` - 平均値の計算
2. `math sum` - 合計の計算
3. `math median` - 中央値の計算
4. `math stddev` - 標準偏差の計算
5. `math variance` - 分散の計算
6. `math min` - 最小値の取得
7. `math max` - 最大値の取得
8. `math mode` - 最頻値の取得
9. `math product` - 積の計算

**関連システム・外部連携**：特になし。Nushell内部の数学処理として動作する。

**権限による制御**：特になし。すべてのユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 結果表示画面 | コマンド実行結果の表示 |

## 機能種別

計算処理 / 統計関数

## 入力仕様

### 入力パラメータ

#### math avg / sum / median / min / max / mode / product

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | パイプラインから数値リストを受け取る | - |

#### math stddev / variance

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --sample / -s | Switch | No | 標本標準偏差/分散を計算（N-1で除算） | - |

### 入力データソース

パイプライン入力（数値リスト、テーブル、Range、レコード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (avg) | Number | 平均値 |
| result (sum) | Number/Duration/Filesize | 合計値 |
| result (median) | Number | 中央値 |
| result (stddev) | Float | 標準偏差 |
| result (variance) | Float | 分散 |
| result (min/max) | Any | 最小/最大値 |
| result (mode) | List | 最頻値のリスト |
| result (product) | Number | 積 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ リスト、テーブル、Range、レコードを受け付ける
2. 入力型を判定
   ├─ Range: 有界チェック後展開
   ├─ List: リストとして処理
   ├─ Table: 列ごとに処理
   └─ Record: 各フィールドに処理
3. 統計計算を実行
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{入力型}
    B -->|List| C[値リストとして処理]
    B -->|Table| D[列ごとに処理]
    B -->|Range| E{有界範囲?}
    B -->|Record| F[フィールドごとに処理]
    E -->|Yes| G[展開して処理]
    E -->|No| H[エラー]
    C --> I[統計計算実行]
    D --> J[各列に統計計算]
    G --> I
    F --> K[各フィールドに計算]
    I --> L[結果出力]
    J --> M[レコードとして出力]
    K --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-1 | Duration/Filesizeサポート | avg/sum/median/min/maxはDuration/Filesizeもサポート | 該当コマンド使用時 |
| BR-29-2 | 標本分散 | --sampleオプションでN-1で除算する標本分散を計算 | stddev/variance使用時 |
| BR-29-3 | NaN除外 | median/modeはNaN値を除外して計算 | 該当コマンド使用時 |
| BR-29-4 | 空入力エラー | 空のリストに対してはエラーを返す | 常時 |
| BR-29-5 | テーブル処理 | テーブル入力時は各列に対して演算を適用 | 常時 |

### 計算ロジック

**分散（variance）の計算式**：
- 母分散: `SS / N` （SSは偏差平方和）
- 標本分散: `SS / (N-1)`

偏差平方和(SS): `Σ(x²) - (Σx)² / N`

**標準偏差（stddev）の計算式**：
- `sqrt(variance)`

**中央値（median）の計算式**：
- 奇数個: 中央の値
- 偶数個: 中央2つの平均

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnsupportedInput | 空入力 | 空のリスト | データを入力する |
| IncorrectValue | 無界Range | Rangeが有界でない | 有界Rangeを使用 |
| UnsupportedInput | 型エラー | 数値以外の入力 | 数値を入力する |
| PipelineEmpty | 空パイプライン | 入力がない場合 | データを入力する |

### リトライ仕様

該当なし

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

該当なし（ステートレス処理）

## パフォーマンス要件

- リスト入力時は一度のイテレーションで計算を実行
- テーブル入力時はIndexMapを使用して列ごとに値を収集
- 大量データでもメモリ効率を考慮した実装

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

特になし

## 備考

- すべてのmath統計コマンドは定数式として評価可能（is_const = true）
- reducers.rsで共通のreducer_for関数を使用してSummation/Product/Minimum/Maximumを実装
- modeは複数の最頻値がある場合リストで返す

---

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

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

### 推奨読解順序

#### Step 1: 共通インフラを理解する

統計関数で共有される基盤コードを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | utils.rs | `crates/nu-command/src/math/utils.rs` | run_with_function関数（7-18行目）、calculate関数（65-115行目） |
| 1-2 | reducers.rs | `crates/nu-command/src/math/reducers.rs` | Reduce enum（4-9行目）、reducer_for関数（14-21行目） |

**読解のコツ**: utils.rsのcalculate関数がList/Table/Range/Recordの入力型判定とディスパッチを担当。reducers.rsがsum/product/min/maxの共通ロジックを提供。

#### Step 2: 基本統計関数を理解する

合計・平均・積を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sum.rs | `crates/nu-command/src/math/sum.rs` | summation関数（84-87行目） |
| 2-2 | avg.rs | `crates/nu-command/src/math/avg.rs` | average関数（88-97行目） |
| 2-3 | product.rs | `crates/nu-command/src/math/product.rs` | product関数（78-81行目） |

**主要処理フロー**:
1. **sum.rs 84-86行目**: reducer_for(Reduce::Summation)でreducerを取得し適用
2. **avg.rs 89-90行目**: 合計を計算後、要素数で除算
3. **avg.rs 93-95行目**: Filesize/Durationは専用の除算処理

#### Step 3: 分布統計関数を理解する

中央値・最頻値を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | median.rs | `crates/nu-command/src/math/median.rs` | median関数（87-144行目）、Pick enum（82-85行目） |
| 3-2 | mode.rs | `crates/nu-command/src/math/mode.rs` | mode関数（113-166行目）、HashableType構造体（16-29行目） |

**主要処理フロー**:
- **median.rs 88-93行目**: NaNを除外してソート
- **median.rs 95-99行目**: 偶数/奇数で処理分岐
- **mode.rs 117-140行目**: HashMapで頻度カウント
- **mode.rs 150-162行目**: 最大頻度の値を収集

#### Step 4: 分散・標準偏差を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | variance.rs | `crates/nu-command/src/math/variance.rs` | compute_variance関数（142-156行目）、sum_of_squares関数（110-140行目） |
| 4-2 | stddev.rs | `crates/nu-command/src/math/stddev.rs` | compute_stddev関数（118-129行目） |

**主要処理フロー**:
- **variance.rs 110-140行目**: 偏差平方和の計算
- **variance.rs 146-150行目**: sample flagによるN-1またはNの選択
- **stddev.rs 121-125行目**: varianceの平方根を計算

#### Step 5: 最小・最大値を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | min.rs | `crates/nu-command/src/math/min.rs` | minimum関数（85-88行目） |
| 5-2 | max.rs | `crates/nu-command/src/math/max.rs` | maximum関数（87-90行目） |
| 5-3 | reducers.rs | `crates/nu-command/src/math/reducers.rs` | min関数（42-59行目）、max関数（23-40行目） |

**主要処理フロー**:
- **reducers.rs 34-38行目**: partial_cmpで比較してbiggestを更新
- **reducers.rs 53-57行目**: partial_cmpで比較してsmallestを更新

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

```
MathAvg::run / MathSum::run / MathMedian::run / etc.
    │
    └─ run_with_function(call, input, mf)
           │
           └─ calculate(values, name, mf)
                  │
                  ├─ PipelineData::ListStream → helper_for_tables()
                  │                                    │
                  │                                    └─ 列ごとにmf適用
                  │
                  ├─ PipelineData::Value(List) → mf(vals) または helper_for_tables()
                  │
                  ├─ PipelineData::Value(Range) → ensure_bounded() → mf()
                  │
                  ├─ PipelineData::Value(Record) → フィールドごとにmf適用
                  │
                  └─ PipelineData::Value(single) → mf([val])

mf（数学関数）の例:
├─ average() → reducer_for(Summation) → sum / len
├─ summation() → reducer_for(Summation)
├─ median() → sort → Pick::Median or Pick::MedianAverage
├─ mode() → HashMap頻度カウント
├─ compute_variance() → sum_of_squares() / N
├─ compute_stddev() → sqrt(variance)
├─ minimum() → reducer_for(Minimum)
└─ maximum() → reducer_for(Maximum)
```

### データフロー図

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

List<Number> ───▶ math avg ───▶ sum / len ───▶ Number
      │
      ├─▶ math sum ───▶ reducer_for(Summation) ───▶ Number
      │
      ├─▶ math median ───▶ sort → 中央値 ───▶ Number
      │
      ├─▶ math stddev ───▶ sqrt(variance) ───▶ Float
      │         │
      │         └─ --sample: N-1で除算
      │
      ├─▶ math variance ───▶ SS / N ───▶ Float
      │
      ├─▶ math min ───▶ reducer_for(Minimum) ───▶ Any
      │
      ├─▶ math max ───▶ reducer_for(Maximum) ───▶ Any
      │
      ├─▶ math mode ───▶ 頻度カウント ───▶ List
      │
      └─▶ math product ───▶ reducer_for(Product) ───▶ Number

Table ───▶ math * ───▶ helper_for_tables() ───▶ Record
   │                          │
   │                          └─ 列ごとに統計計算
   │
   └─ [{a: 1, b: 2}, {a: 3, b: 4}] → {a: stat(a), b: stat(b)}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| avg.rs | `crates/nu-command/src/math/avg.rs` | ソース | math avg コマンド実装 |
| sum.rs | `crates/nu-command/src/math/sum.rs` | ソース | math sum コマンド実装 |
| median.rs | `crates/nu-command/src/math/median.rs` | ソース | math median コマンド実装 |
| stddev.rs | `crates/nu-command/src/math/stddev.rs` | ソース | math stddev コマンド実装 |
| variance.rs | `crates/nu-command/src/math/variance.rs` | ソース | math variance コマンド実装 |
| min.rs | `crates/nu-command/src/math/min.rs` | ソース | math min コマンド実装 |
| max.rs | `crates/nu-command/src/math/max.rs` | ソース | math max コマンド実装 |
| mode.rs | `crates/nu-command/src/math/mode.rs` | ソース | math mode コマンド実装 |
| product.rs | `crates/nu-command/src/math/product.rs` | ソース | math product コマンド実装 |
| utils.rs | `crates/nu-command/src/math/utils.rs` | ソース | 共通ユーティリティ |
| reducers.rs | `crates/nu-command/src/math/reducers.rs` | ソース | 集約関数 |
| mod.rs | `crates/nu-command/src/math/mod.rs` | ソース | mathモジュール定義 |
