19.2 Broadcasting

Last-modified: 2025-03-03 (月) 21:43:33

19.2 ブロードキャスト

ブロードキャストとは、行列や配列のオペランドや引数のサイズが異なる場合に、Octaveの二項演算子や関数がどのように動作するかを指します。バージョン3.6.0以降、Octaveは要素ごとの二項演算子や関数を使用するときに、ベクトル、行列、配列を自動的にブロードキャストするようになりました。大まかに言えば、小さな配列は、互換性のある形状になるまで、大きな配列に「ブロードキャスト」されます。ルールは、対応する配列の次元が次のいずれかである必要があるということです。

1.イコールある、または
2.そのうちの 1 つは 1 である必要があります。

すべての次元が等しい場合、ブロードキャストは行われず、通常の要素ごとの演算が行われます。高次元の配列では、次元の数が同じでない場合、欠落している末尾の次元は 1 として扱われます。次元の 1 つが 1 の場合、その単一次元の配列は、他の配列の次元と一致するまでその次元に沿ってコピーされます。たとえば、次の例を考えてみましょう。

x = [1 2 3;
    4 5 6;
    7 8 9];
y = [10 20 30];
x + y

ブロードキャストを行わないと、x + y寸法が一致しないためエラーになります。ただし、ブロードキャストを行うと、次の操作が実行されたのと同じになります。

x = [1 2 3
    4 5 6
    7 8 9];
y = [10 20 30
    10 20 30
    10 20 30];
x + y
⇒    11   22   33
      14   25   36
      17   28   39

つまり、サイズの小さい方の配列が、[1 3]シングルトン次元 (行数) に沿って、最大になるまでコピーされます[3 3]。ただし、実際のコピーは行われません。内部実装では、メモリにコピーせずに目的の効果を達成するために、必要な次元に沿って要素を再利用します。

両方の配列は相互にブロードキャストできます。たとえば、ベクトルの要素とそれ自体の要素のすべてのペアの差などです。

y - y'
⇒    0   10   20
    -10    0   10
   -20  -10    0

ここで、サイズのベクトル[1 3]と両方は、通常の行列減算が行われる前に、 [3 1]サイズの行列にブロードキャストされます。[3 3]

ブロードキャストの特殊なケースとして、ブロードキャストされる配列のすべての次元が 1 の場合、つまり配列がスカラーである場合が挙げられます。したがって、たとえば、x - 42や など の操作はmax (x, 2)ブロードキャストの基本的な例です。

高次元の例として、imgサイズがRGB画像で[m n 3]、各色に異なるスカラーを掛けたいとします。次のコードはこれをブロードキャストで実現します。

img .*= permute ([0.8, 0.9, 1.2], [1, 3, 2]);

ベクトルの次元 [0.8, 0.9, 1.2]を と一致させるために permute を使用していることに注意してくださいimg。

ブロードキャスト セマンティクスを使用して記述されていない関数の場合、 bsxfun強制的にブロードキャストするように設定するのに役立ちます。

: C = bsxfun (f, A, B)

2 つの配列引数AとBにバイナリ関数fを要素ごとに 適用し、必要に応じていずれかの入力引数のシングルトン次元を拡張します。

fは、関数ハンドル、インライン関数、または評価する関数の名前を含む文字列です。関数fは、同じ長さの 2 つの列ベクトル引数、または 1 つの列ベクトル引数と 1 つのスカラーを受け入れることができる必要があります 。

AとBの次元は等しいか、シングルトンである必要があります。配列のシングルトン次元は、他の配列と同じ次元に拡張されます。

See also: arrayfun, cellfun.

ブロードキャストは、2 つのブロードキャスト条件のいずれかが満たされている場合にのみ適用されます。ただし、通常どおり、2 つの次元が異なり、どちらも 1 でない場合は、ブロードキャストは適用されません。

x = [1 2 3
     4 5 6];
y = [10 20
     30 40];
x + y

れにより、非準拠の引数に関するエラーが発生します。

一般的な算術演算の他に、2つの引数を取るいくつかの関数もブロードキャストします。ブロードキャストする関数と演算子の完全なリストは

     plus      +
     minus     -
     times     .*
     rdivide   ./
     ldivide   .\
     power     .^
     lt        <
     le        <=
     eq        ==
     gt        >
     ge        >=
     ne        !=  ~=
     and       &
     or        |
     atan2
     hypot
     max
     min
     mod
     rem
     xor
     +=  -=  .*=  ./=  .\=  .^=  &=  |=

ブロードキャストの威力を示す実際の例を示します。Floyd-Warshall アルゴリズムは、グラフ内のすべての頂点のペア間の最短経路の長さを計算するために使用されます。次数nのグラフ隣接行列の単純な実装は次のようになります。

for k = 1:n
 for i = 1:n
   for j = 1:n
     dist(i,j) = min (dist(i,j), dist(i,k) + dist(k,j));
   endfor
 endfor
endfor

最も内側のループをベクトル化すると、次のようになります。

for k = 1:n
 for i = 1:n
   dist(i,:) = min (dist(i,:), dist(i,k) + dist(k,:));
 endfor
endfor

双方向のブロードキャストを使用すると、次のようになります。

for k = 1:n
 dist = min (dist, dist(:,k) + dist(k,:));
endfor

100 個の頂点を持つグラフの場合、3 つの手法の相対的な時間パフォーマンスは、単純なコードでは 7.3 秒、単一ベクトル化コードでは 87 ミリ秒、完全にブロードキャストされたコードでは 1.3 ミリ秒です。1000 個の頂点を持つグラフの場合、ベクトル化には 11.7 秒かかりますが、ブロードキャストには 1.15 秒しかかかりません。したがって、一般的には、パフォーマンスのためにブロードキャスト セマンティクスを使用してコードを書く価値があります。

ただし、より単純な操作で十分な場合は、ブロードキャストに頼らないように注意してください。行列aとbについては、次の点を考慮してください。

c = sum (permute (a, [1, 3, 2]) .* permute (b, [3, 2, 1]), 3);

この操作は、要素ごとの乗算中に、次元が入れ替わった 2 つの行列を相互にブロードキャストして、より大きな 3 次元配列を取得し、この配列を 3 番目の次元に沿って合計します。少し考えれば、この操作は、はるかに高速な通常の行列乗算にすぎないことがわかります。 c = a*b;

用語に関する注意: 「ブロードキャスト」は、Python プログラミング言語の Numpy 数値環境で普及した用語です。他のプログラミング言語や環境では、ブロードキャストはバイナリ シングルトン拡張(BSX、MATLABでは関数名の由来bsxfun)、リサイクル(R プログラミング言語)、単一命令複数データ(SIMD)、またはレプリケーションと呼ばれることもあります。