# 機能設計書 19-ブロードキャスト

## 概要

本ドキュメントは、Julia言語におけるブロードキャスト機能の設計を記述する。broadcast / @. による要素単位の演算自動拡張を提供する。

### 本機能の処理概要

Broadcastモジュールは、異なるサイズの配列間で要素単位の演算を自動的に拡張する「ブロードキャスティング」機構を提供する。NumPyのbroadcastingと同様の概念だが、Juliaの多重ディスパッチと型システムを活用し、カスタム型への拡張が容易な設計となっている。

**業務上の目的・背景**：数値計算では、スカラーとベクトル、ベクトルと行列など、異なる次元のオブジェクト間で要素単位の演算を行うことが頻繁にある。明示的なループを記述せずに、簡潔な構文で要素単位演算を表現できることは生産性と可読性の両面で重要である。さらに、中間配列の生成を回避するfusion最適化により、メモリ効率と性能を大幅に向上させる。

**機能の利用シーン**：（1）要素単位の演算（sin.(x), x .+ y等）、（2）@.マクロによるドット演算の一括適用、（3）ブロードキャスト代入（A .= B .+ C）によるin-place演算、（4）カスタム型のブロードキャスト動作定義、（5）Bool結果のBitArray格納。

**主要な処理内容**：
1. BroadcastStyleトレイトシステム（AbstractArrayStyle, DefaultArrayStyle, Style{Tuple}等）
2. Broadcasted{Style}遅延評価オブジェクトの構築
3. broadcast_axes（形状計算）とbroadcast_shape（サイズ互換性検証）
4. copy/copyto!による結果配列の確保と計算実行
5. @__dot__（@.）マクロによるドット演算の一括変換
6. BroadcastFunction型による関数オブジェクト化
7. dotview関数によるブロードキャスト代入先のビュー生成

**関連システム・外部連携**：BitArray（Bool結果のデフォルト格納先）。LinearAlgebra等のstdlibとの統合。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 参照画面 | REPL上でブロードキャスト演算を実行 |

## 機能種別

計算処理（要素単位演算の自動拡張）/ メタプログラミング（@.マクロ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| f | Function | Yes | 適用する関数 | callable |
| args... | Any | Yes | ブロードキャストする引数群 | サイズ互換性（各次元が1またはn） |

### 入力データソース

Julia式からの直接入力。ドット構文（f.(args...)）。@.マクロ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | AbstractArray/Tuple/スカラー | ブロードキャスト演算結果 |

### 出力先

メモリ上の結果オブジェクトとして返却。broadcast!はin-placeで既存配列に書き込み。

## 処理フロー

### 処理シーケンス

```
1. ドット構文の降下
   └─ f.(args...) がBroadcasted(f, args...)に変換される（lowering）
2. BroadcastStyle決定
   └─ 各引数のBroadcastStyleを取得し、result_styleで統合
3. 形状計算
   └─ broadcast_shapesで各引数のaxesを統合、互換性検証
4. 結果配列確保
   └─ similar(Broadcasted{Style}, ElType, axes)で結果配列を確保
5. 計算実行
   └─ copyto!(dest, Broadcasted)で要素単位計算を実行
```

### フローチャート

```mermaid
flowchart TD
    A["f.(args...)"] --> B["Broadcasted(f, args...)構築"]
    B --> C[BroadcastStyle決定]
    C --> D[broadcast_shapes: 形状互換性検証]
    D --> E{互換?}
    E -->|No| F[DimensionMismatch]
    E -->|Yes| G["similar(Broadcasted, ElType, axes)"]
    G --> H["copyto!(dest, Broadcasted)"]
    H --> I[要素単位計算実行]
    I --> J[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | サイズ互換性 | 各次元のサイズが1またはnで一致 | broadcast呼び出し時 |
| BR-02 | Fusion最適化 | ネストしたbroadcastは中間配列なしで実行 | f.(g.(x)) |
| BR-03 | Style優先順位 | DefaultArrayStyleは他のArrayStyleに劣後 | Style統合時 |
| BR-04 | Bool→BitArray | Bool結果のブロードキャストはBitArrayを返す | Bool結果時 |
| BR-05 | スカラー扱い | broadcastable(x) = Ref(x) で非配列はスカラー扱い | 非配列引数 |
| BR-06 | Tuple対応 | Tupleは1次元コレクションとしてブロードキャスト | Style{Tuple} |

### 計算ロジック

- BroadcastStyle階層: Unknown < Style{T} < AbstractArrayStyle{N} < DefaultArrayStyle{N}
- result_style: 2つのStyleからより「強い」Styleを選択
- broadcast_shape: 各次元のmax(size_a, size_b)、ただし一方が1の場合のみ拡張可能
- Broadcasted{Style, Axes, F, Args}: 遅延評価オブジェクト（f, args, axes）

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DimensionMismatch | ブロードキャスト不可能なサイズの組み合わせ | サイズを互換にする |
| - | MethodError | BroadcastStyleの統合失敗 | カスタムStyle定義を追加 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- Fusion最適化: ネストしたbroadcast演算は1パスで実行（中間配列なし）
- SIMD最適化: @simd ivdep による要素単位計算のベクトル化
- in-place broadcast!: 結果配列への直接書き込みでメモリ割り当て回避
- 遅延評価: Broadcasted オブジェクトは実際の計算を遅延させ、最適化の機会を提供

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

- 特になし

## 備考

- @.（@__dot__）マクロは式中の全関数呼び出しと演算子にドットを付加
- BroadcastFunction(f)はbroadcast(f, ...)を関数オブジェクトとして表現
- dotview(A, args...)はブロードキャスト代入左辺のビュー生成

---

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

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

### 推奨読解順序

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

BroadcastStyleとBroadcastedの型階層。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | broadcast.jl | `base/broadcast.jl` | BroadcastStyle抽象型とサブタイプ（21-100行目） |
| 1-2 | broadcast.jl | `base/broadcast.jl` | Unknown, Style{T}, AbstractArrayStyle{N}, DefaultArrayStyle{N} |

**読解のコツ**: BroadcastStyleはトレイトパターンで実装されている。BroadcastStyle(::Type{<:MyType})をオーバーロードしてカスタム型のブロードキャスト動作を定義する。DefaultArrayStyle{N}はデフォルトで、他のArrayStyleに「負ける」。

#### Step 2: Broadcastedオブジェクトと形状計算を理解する

遅延評価オブジェクトの構築と形状互換性検証。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | broadcast.jl | `base/broadcast.jl` | Broadcasted型定義（broadcast.jl内） |
| 2-2 | broadcast.jl | `base/broadcast.jl` | broadcast_shape/combine_axes（形状計算） |

#### Step 3: 計算実行を理解する

copy/copyto!による結果配列確保と計算。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | broadcast.jl | `base/broadcast.jl` | copy(Broadcasted)（結果配列確保+計算） |
| 3-2 | broadcast.jl | `base/broadcast.jl` | copyto!(dest, Broadcasted)（in-place計算） |

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

```
f.(args...) [ドット構文]
    |
    +-- materialize(broadcasted(f, args...))
    |       +-- broadcasted(f, args...)
    |       |       +-- BroadcastStyle(typeof(arg)) [各引数のStyle取得]
    |       |       +-- result_style(styles...)     [Style統合]
    |       |       +-- Broadcasted{Style}(f, args, axes) [遅延評価オブジェクト]
    |       |
    |       +-- copy(Broadcasted)
    |               +-- similar(Broadcasted, ElType, axes) [結果配列確保]
    |               +-- copyto!(dest, Broadcasted)         [計算実行]
    |                       +-- @simd for i in eachindex(dest)
    |                               dest[i] = bc[i]

@. expr
    |
    +-- __dot__(expr)    [全演算子/関数にドットを付加]
    +-- esc(result)
```

### データフロー図

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

f, args...       ──────> Broadcasted構築 → Style決定  ──────> Broadcasted{Style}
Broadcasted      ──────> shape検証 → similar → copyto! ─────> Array/BitArray
dest, Broadcasted──────> copyto!(in-place計算)         ──────> dest（変更済み）
@. expr          ──────> __dot__(AST変換)              ──────> f.(g.(x))形式
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| broadcast.jl | `base/broadcast.jl` | ソース | Broadcastモジュール全体（Style, Broadcasted, copy, copyto!等） |
| bitarray.jl | `base/bitarray.jl` | ソース | Bool結果のBitArray格納 |
| abstractarray.jl | `base/abstractarray.jl` | ソース | axes, similar等の基本インタフェース |
| simdloop.jl | `base/simdloop.jl` | ソース | @simd ivdepによるベクトル化 |
