# 機能設計書 8-数学関数

## 概要

本ドキュメントは、Julia言語における三角関数・指数関数・対数関数・双曲線関数・特殊関数等の数学関数に関する機能設計書である。

### 本機能の処理概要

Base.Mathモジュールとして提供される数学関数群を定義する。三角関数（sin, cos, tan等）、逆三角関数（asin, acos, atan等）、指数関数（exp, exp2, exp10）、対数関数（log, log2, log10, log1p）、双曲線関数（sinh, cosh, tanh等）、べき根（sqrt, cbrt, fourthroot）、およびこれらの度数法・pi倍版を網羅的に提供する。

**業務上の目的・背景**：科学計算・工学計算・統計処理・信号処理等のあらゆる数値計算分野で数学関数は不可欠である。Julia言語では高精度かつ高速な数学関数実装を提供し、LLVMの最適化とカスタム実装を組み合わせることで、libm相当以上の精度と性能を実現している。

**機能の利用シーン**：物理シミュレーション（三角関数・指数関数）、統計分析（対数関数）、信号処理（FFTの基礎となる三角関数）、機械学習（exp, log, sigmoid等）、幾何計算（atan2, hypot等）で使用される。

**主要な処理内容**：
1. 三角関数群（sin, cos, sincos, tan, sec, csc, cot）とその逆関数
2. 度数法版三角関数（sind, cosd, tand等）とpi倍版（sinpi, cospi, tanpi等）
3. 指数・対数関数（exp, log, exp2, log2, exp10, log10, expm1, log1p）
4. 双曲線関数（sinh, cosh, tanh等）とその逆関数
5. べき根関数（sqrt, cbrt, fourthroot）とhypot
6. 多項式評価（evalpoly, @evalpoly）

**関連システム・外部連携**：Core.Intrinsics（sqrt_llvm等）、LLVM数学ライブラリと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 数学関数は画面に直接関連しないが、REPL上での計算結果表示に使用される |

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | Number | Yes | 関数の引数 | 関数の定義域内であること |
| p | Tuple/AbstractVector | Yes（evalpoly） | 多項式の係数 | 空でないこと |

### 入力データソース

関数呼び出し引数として直接渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 関数値 | Number | 数学関数の計算結果 |
| sincos結果 | Tuple{Number, Number} | (sin(x), cos(x))のタプル |

### 出力先

関数の戻り値として返される。

## 処理フロー

### 処理シーケンス

```
1. 引数の定義域チェック
   └─ 定義域外の場合はDomainErrorを投げる
2. 引数の範囲縮小（range reduction）
   └─ 三角関数等では引数を基本周期に縮小
3. 多項式近似またはIntrinsics呼び出し
   └─ Horner法による多項式評価、またはLLVM命令
4. 結果の精度補正
   └─ two_mul等による高精度補正
```

### フローチャート

```mermaid
flowchart TD
    A[数学関数呼び出し] --> B{定義域チェック}
    B -->|定義域内| C[引数の範囲縮小]
    B -->|定義域外| D[DomainError]
    C --> E{実装方式}
    E -->|Intrinsics| F[LLVM命令実行]
    E -->|多項式近似| G[evalpoly/Horner法]
    F --> H[結果返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 定義域エラー | sqrt(-1.0)等の実数範囲外引数はDomainErrorを投げる | 実引数の場合 |
| BR-02 | 複素数誘導 | 定義域外の場合、Complex引数を使えば複素数結果を取得可能 | DomainError発生時 |
| BR-03 | 度数法変換 | sind(x)はsin(deg2rad(x))と同等だが精度が高い | sind/cosd等使用時 |
| BR-04 | pi倍精度 | sinpi(x)はsin(pi*x)と同等だが精度が高い | sinpi/cospi等使用時 |
| BR-05 | log1p精度 | log1p(x)はlog(1+x)と同等だが、x≈0付近で精度が高い | 小さな値の対数計算時 |

### 計算ロジック

- evalpoly: Horner法による多項式評価 `p[1] + x*(p[2] + x*(p[3] + ...))` （math.jl 96-107行目）
- two_mul: FMA命令を使用した高精度積計算 `(xy, fma(x, y, -xy))` （math.jl 49-70行目）

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

### 操作別データベース影響一覧

該当なし（データベースを使用しない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| DomainError | DomainError | 実数範囲外の引数（sqrt(-1), log(-1)等） | Complex引数を使用する |
| DomainError | DomainError | asin/acosに\|x\|>1の引数 | 引数を[-1,1]範囲に制限する |

### リトライ仕様

数学関数は純粋関数であり、リトライは適用されない。

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

該当なし。

## パフォーマンス要件

- sqrtはLLVM Intrinsics（sqrt_llvm）により1〜数クロックサイクルで実行される
- 三角関数はカスタム実装の多項式近似により高精度かつ高速に実行される
- evalpolyは@generatedマクロによりコンパイル時にHorner法が展開される

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

特になし。

## 備考

- Math モジュールは `base/math.jl` でmodule Mathとして定義されている
- Base.Mathからexportされた関数はBaseスコープで直接使用可能
- two_mul関数はFMA命令の有無に応じて実装が切り替わる（math.jl 54-70行目）

---

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

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

### 推奨読解順序

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

Mathモジュールの構造とexportされる関数群を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | math.jl | `base/math.jl` | **3行目**: `module Math` - 独立したモジュールとして定義 |
| 1-2 | math.jl | `base/math.jl` | **5-16行目**: export文。sin, cos, exp, log等の全関数がリストされている |
| 1-3 | math.jl | `base/math.jl` | **18-30行目**: Base/Core.Intrinsicsからのimport |

**読解のコツ**: Math モジュールは Base の内部モジュールである。export された関数は Base を通じてグローバルスコープで使用可能になる。`using .Base` のドット付きインポートはサブモジュールからの相対インポートを示す。

#### Step 2: エントリーポイントを理解する

基本的な数学関数の実装パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | math.jl | `base/math.jl` | **49-70行目**: two_mul関数 - FMA命令を使用した高精度積計算 |
| 2-2 | math.jl | `base/math.jl` | **96-107行目**: evalpoly関数 - @generatedマクロによるHorner法展開 |
| 2-3 | math.jl | `base/math.jl` | **109-119行目**: _evalpoly関数 - ランタイム版Horner法 |

**主要処理フロー**:
1. **49-52行目**: `two_mul(x::T, y::T)` - 汎用版（fma使用）
2. **54-60行目**: `two_mul(x::Float64, y::Float64)` - Float64特殊化（FMAハードウェアチェック）
3. **96-107行目**: `evalpoly(x, p::Tuple)` - @generatedでコンパイル時Horner展開
4. **121-145行目**: `evalpoly(z::Complex, p::Tuple)` - 複素数版（Goertzel-likeアルゴリズム）

#### Step 3: 定義域エラー処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | math.jl | `base/math.jl` | **32-45行目**: throw_complex_domainerror等のエラーヘルパー関数 |

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

```
Base.Math モジュール (base/math.jl)
    │
    ├─ 三角関数 (sin, cos, tan, ...)
    │      ├─ 引数の範囲縮小
    │      ├─ 多項式近似 (evalpoly)
    │      └─ 結果の精度補正 (two_mul)
    │
    ├─ 指数・対数関数 (exp, log, ...)
    │      ├─ 引数の正規化
    │      └─ 多項式近似 (evalpoly)
    │
    ├─ べき根関数
    │      └─ sqrt: Core.Intrinsics.sqrt_llvm (LLVM命令)
    │
    └─ 多項式評価
           ├─ evalpoly(x, p::Tuple) - @generated Horner法
           └─ _evalpoly(x, p) - ランタイム版
```

### データフロー図

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

数値 x               ───▶ 定義域チェック              ───▶ DomainError (範囲外)
                           │
                           ▼
正規化された x        ───▶ 範囲縮小 (range reduction)  ───▶ 縮小された引数
                           │
                           ▼
縮小された引数        ───▶ 多項式近似 (evalpoly)       ───▶ 近似結果
                           │
                           ▼
近似結果              ───▶ 精度補正 (two_mul等)        ───▶ 最終結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| math.jl | `base/math.jl` | ソース | Mathモジュール本体、evalpoly、two_mul、エラーヘルパー |
| special/ | `base/special/` | ソース | 特殊関数（gamma, beta等）の実装 |
| float.jl | `base/float.jl` | ソース | 浮動小数点型の基本定義・ビットマスク |
| floatfuncs.jl | `base/floatfuncs.jl` | ソース | 浮動小数点関連ユーティリティ |
