# 機能設計書 30-三角関数

## 概要

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

### 本機能の処理概要

三角関数機能は、三角関数および双曲線関数の計算を提供する。sin、cos、tan、およびその逆関数（arcsin、arccos、arctan）、双曲線関数（sinh、cosh、tanh）とその逆関数を含む。科学計算やデータ変換に使用される。

**業務上の目的・背景**：科学計算、グラフィックス処理、信号処理などの分野では三角関数が不可欠である。角度変換、波形生成、座標変換など、様々な計算で三角関数が必要となる。

**機能の利用シーン**：
- 角度を使った計算を行う場合
- 座標変換（極座標⇔直交座標）を行う場合
- 波形データの生成・分析を行う場合
- 機械学習の活性化関数（tanh）を使用する場合

**主要な処理内容**：
1. `math sin` - 正弦（サイン）の計算
2. `math cos` - 余弦（コサイン）の計算
3. `math tan` - 正接（タンジェント）の計算
4. `math arcsin` - 逆正弦の計算
5. `math arccos` - 逆余弦の計算
6. `math arctan` - 逆正接の計算
7. `math sinh` - 双曲線正弦の計算
8. `math cosh` - 双曲線余弦の計算
9. `math tanh` - 双曲線正接の計算

**関連システム・外部連携**：nu-cmd-extraクレートで提供される追加数学関数。

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

## 関連画面

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

## 機能種別

計算処理 / 三角関数

## 入力仕様

### 入力パラメータ

#### math sin / cos / tan

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --degrees / -d | Switch | No | 度数法で入力（ラジアンではなく） | - |

#### math arcsin / arccos / arctan

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --degrees / -d | Switch | No | 度数法で出力（ラジアンではなく） | - |

#### math sinh / cosh / tanh

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

### 入力データソース

パイプライン入力（数値、数値リスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (sin/cos/tan) | Float | 三角関数の値 |
| result (arcsin/arccos/arctan) | Float | 逆三角関数の値（ラジアンまたは度） |
| result (sinh/cosh/tanh) | Float | 双曲線関数の値 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 数値（Int/Float）またはリストを受け付ける
2. オプションを確認
   └─ --degrees: 度数法⇔ラジアン変換
3. 各要素に対して演算を実行
   └─ input.map()で各要素にoperate関数を適用
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{空入力?}
    B -->|Yes| C[PipelineEmptyエラー]
    B -->|No| D[input.map で処理]
    D --> E{入力型}
    E -->|Int/Float| F[数値として処理]
    E -->|Other| G[OnlySupportsThisInputTypeエラー]
    F --> H{--degrees?}
    H -->|Yes, sin/cos/tan| I[to_radians変換]
    H -->|No| J[そのまま使用]
    I --> K[三角関数計算]
    J --> K
    K --> L{arcsin/arccos?}
    L -->|Yes| M{値が[-1,1]範囲内?}
    M -->|No| N[UnsupportedInputエラー]
    M -->|Yes| O[逆関数計算]
    L -->|No| O
    O --> P{--degrees? arcsin/arccos/arctan}
    P -->|Yes| Q[to_degrees変換]
    P -->|No| R[結果出力]
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-1 | ラジアン入力 | デフォルトはラジアン入力 | sin/cos/tan使用時 |
| BR-30-2 | 度数法オプション | --degreesで度数法入出力に切替 | sin/cos/tan/arc*使用時 |
| BR-30-3 | 定義域チェック | arcsin/arccosは[-1,1]範囲のみ有効 | arcsin/arccos使用時 |
| BR-30-4 | リスト処理 | リスト入力時は各要素に演算を適用 | 常時 |
| BR-30-5 | 双曲線関数のラジアン固定 | sinh/cosh/tanhは--degreesオプションなし | sinh/cosh/tanh使用時 |

### 計算ロジック

**度数法⇔ラジアン変換**：
- 入力変換（sin/cos/tan）: `val.to_radians()` （度→ラジアン）
- 出力変換（arc*）: `val.to_degrees()` （ラジアン→度）

**三角関数計算**：
- Rustの標準ライブラリf64メソッドを使用
- `val.sin()`, `val.cos()`, `val.tan()`
- `val.asin()`, `val.acos()`, `val.atan()`
- `val.sinh()`, `val.cosh()`, `val.tanh()`

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | 数値以外の入力 | 数値を入力する |
| UnsupportedInput | 定義域エラー | arcsin/arccosで[-1,1]外の値 | 有効な範囲の値を入力 |
| PipelineEmpty | 空入力 | 入力がない場合 | データを入力する |

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

- Rustの標準f64数学関数を使用した高速な処理
- input.map()によるストリーム処理でメモリ効率を確保

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

特になし

## 備考

- 三角関数はnu-cmd-extraクレートで提供（追加機能）
- 双曲線関数はis_constがfalse（run_constメソッドなし）
- ln（自然対数）とexp（指数関数）も同モジュールで提供

---

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

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

### 推奨読解順序

#### Step 1: モジュール構成を理解する

三角関数モジュールの構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-cmd-extra/src/extra/math/mod.rs` | モジュール構成（1-33行目）、エクスポート |

**読解のコツ**: nu-cmd-extraクレートのmathモジュールで三角関数・双曲線関数・指数関数・対数関数が提供される。

#### Step 2: 基本三角関数を理解する

sin, cos, tanの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sin.rs | `crates/nu-cmd-extra/src/extra/math/sin.rs` | MathSin実装（6-101行目） |
| 2-2 | cos.rs | `crates/nu-cmd-extra/src/extra/math/cos.rs` | MathCos実装（6-101行目） |
| 2-3 | tan.rs | `crates/nu-cmd-extra/src/extra/math/tan.rs` | MathTan実装（6-99行目） |

**主要処理フロー**:
1. **sin.rs 40行目**: `call.has_flag("degrees")`で度数法フラグ取得
2. **sin.rs 45-48行目**: `input.map()`で各要素にoperate関数を適用
3. **sin.rs 86行目**: `val.to_radians()`で度→ラジアン変換
4. **sin.rs 88行目**: `val.sin()`で正弦計算

#### Step 3: 逆三角関数を理解する

arcsin, arccos, arctanの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | arcsin.rs | `crates/nu-cmd-extra/src/extra/math/arcsin.rs` | MathArcSin実装（6-108行目） |
| 3-2 | arccos.rs | `crates/nu-cmd-extra/src/extra/math/arccos.rs` | MathArcCos実装（6-107行目） |
| 3-3 | arctan.rs | `crates/nu-cmd-extra/src/extra/math/arctan.rs` | MathArcTan実装（6-95行目） |

**主要処理フロー**:
- **arcsin.rs 79行目**: `(-1.0..=1.0).contains(&val)`で定義域チェック
- **arcsin.rs 80行目**: `val.asin()`で逆正弦計算
- **arcsin.rs 81行目**: `val.to_degrees()`でラジアン→度変換
- **arcsin.rs 85-94行目**: 定義域外の場合UnsupportedInputエラー

#### Step 4: 双曲線関数を理解する

sinh, cosh, tanhの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sinh.rs | `crates/nu-cmd-extra/src/extra/math/sinh.rs` | MathSinH実装（6-80行目） |
| 4-2 | cosh.rs | `crates/nu-cmd-extra/src/extra/math/cosh.rs` | MathCosH実装（6-81行目） |
| 4-3 | tanh.rs | `crates/nu-cmd-extra/src/extra/math/tanh.rs` | MathTanH実装（6-79行目） |

**主要処理フロー**:
- **sinh.rs 67行目**: `val.sinh()`で双曲線正弦計算
- **cosh.rs 68行目**: `val.cosh()`で双曲線余弦計算
- **tanh.rs 66行目**: `val.tanh()`で双曲線正接計算

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

```
MathSin::run / MathCos::run / MathTan::run
    │
    ├─ call.has_flag("degrees") - 度数法フラグ取得
    │
    ├─ PipelineData::Empty → PipelineEmptyエラー
    │
    └─ input.map(operate)
           │
           └─ operate(value, head, use_degrees)
                  │
                  ├─ Value::Int/Float → 数値として処理
                  │      │
                  │      ├─ use_degrees → val.to_radians()
                  │      │
                  │      └─ val.sin() / val.cos() / val.tan()
                  │
                  └─ Other → OnlySupportsThisInputTypeエラー

MathArcSin::run / MathArcCos::run / MathArcTan::run
    │
    └─ input.map(operate)
           │
           └─ operate(value, head, use_degrees)
                  │
                  ├─ 定義域チェック（arcsin/arccos: [-1, 1]）
                  │      │
                  │      └─ 範囲外 → UnsupportedInputエラー
                  │
                  ├─ val.asin() / val.acos() / val.atan()
                  │
                  └─ use_degrees → val.to_degrees()

MathSinH::run / MathCosH::run / MathTanH::run
    │
    └─ input.map(operate)
           │
           └─ operate(value, head)  ※ degreesフラグなし
                  │
                  └─ val.sinh() / val.cosh() / val.tanh()
```

### データフロー図

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

Number ───▶ math sin ───▶ .sin() ───▶ Float
   │              │
   │              ├─ --degrees: to_radians() 変換
   │              │
   │              └─ [0 90 180] -d → [0, 1, 0]
   │
Number ───▶ math cos ───▶ .cos() ───▶ Float
   │
Number ───▶ math tan ───▶ .tan() ───▶ Float
   │
Number ───▶ math arcsin ───▶ .asin() ───▶ Float
   │              │
   │              ├─ 定義域: [-1, 1]
   │              │
   │              └─ --degrees: to_degrees() 変換
   │
Number ───▶ math arccos ───▶ .acos() ───▶ Float
   │
Number ───▶ math arctan ───▶ .atan() ───▶ Float
   │
Number ───▶ math sinh ───▶ .sinh() ───▶ Float
   │
Number ───▶ math cosh ───▶ .cosh() ───▶ Float
   │
Number ───▶ math tanh ───▶ .tanh() ───▶ Float
   │
List<Number> ───▶ math * ───▶ input.map() ───▶ List<Float>
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sin.rs | `crates/nu-cmd-extra/src/extra/math/sin.rs` | ソース | math sin コマンド実装 |
| cos.rs | `crates/nu-cmd-extra/src/extra/math/cos.rs` | ソース | math cos コマンド実装 |
| tan.rs | `crates/nu-cmd-extra/src/extra/math/tan.rs` | ソース | math tan コマンド実装 |
| arcsin.rs | `crates/nu-cmd-extra/src/extra/math/arcsin.rs` | ソース | math arcsin コマンド実装 |
| arccos.rs | `crates/nu-cmd-extra/src/extra/math/arccos.rs` | ソース | math arccos コマンド実装 |
| arctan.rs | `crates/nu-cmd-extra/src/extra/math/arctan.rs` | ソース | math arctan コマンド実装 |
| sinh.rs | `crates/nu-cmd-extra/src/extra/math/sinh.rs` | ソース | math sinh コマンド実装 |
| cosh.rs | `crates/nu-cmd-extra/src/extra/math/cosh.rs` | ソース | math cosh コマンド実装 |
| tanh.rs | `crates/nu-cmd-extra/src/extra/math/tanh.rs` | ソース | math tanh コマンド実装 |
| arcsinh.rs | `crates/nu-cmd-extra/src/extra/math/arcsinh.rs` | ソース | math arcsinh コマンド実装 |
| arccosh.rs | `crates/nu-cmd-extra/src/extra/math/arccosh.rs` | ソース | math arccosh コマンド実装 |
| arctanh.rs | `crates/nu-cmd-extra/src/extra/math/arctanh.rs` | ソース | math arctanh コマンド実装 |
| exp.rs | `crates/nu-cmd-extra/src/extra/math/exp.rs` | ソース | math exp コマンド実装 |
| ln.rs | `crates/nu-cmd-extra/src/extra/math/ln.rs` | ソース | math ln コマンド実装 |
| mod.rs | `crates/nu-cmd-extra/src/extra/math/mod.rs` | ソース | mathモジュール定義 |
