ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

多次元配列

概要

2 次元よりも大きい配列は、MATLAB® では多次元配列と呼ばれます。MATLAB の多次元配列は、通常の 2 次元行列を拡張したものです。行列には 2 つの次元があります。行の次元と列の次元です。

2 つの添字を使って、2 次元行列の要素にアクセスすることができます。1 つは行のインデックスで、もう 1 つは列のインデックスです。

多次元配列は追加の添字をインデックスに使用します。たとえば、3 次元配列は 3つの添字を使います。

  • 次元 1 の最初の参照、行

  • 次元 2 の 2 番目の参照、列

  • 3 番目の添字は配列の次元 3 のページを参照します。次の図は 3 次元以上を表すためにページ の概念を使用します。

たとえば、ページ 2 の 2 行 3 列の要素にアクセスするためには、添字 (2,3,2) を使います。

配列の次元を増すには、添字を加えます。たとえば、4 元配列には 4 つの添字があります。最初の 2 つは行と列の組み合わせで、後の 2 つはデータの 3 次元目と 4 次元目にアクセスします。

行列 (すなわち 2 次元配列) に対して実行することのできる演算の多くは、多次元配列に対しても実行できます。

    メモ   一般の多次元配列関数は、datatypes ディレクトリにあります。

多次元配列の作成

多次元配列の作成に、2 次元行列に使った方法を使うことができます。さらに、MATLAB では多次元配列の作成に有効な特殊な連結関数を提供しています。

この節では、次の内容を説明します。

インデックス付き代入を使用した多次元配列の作成および拡張

2 次元配列を作成し、それを拡張することで多次元配列を作成できます。2 次元配列 A を作成し、インデックス付き代入を使用して A を 3 次元配列に拡張します。

A = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7]
A(:,:,1) =
     5     7     8
     0     1     9
     4     3     6

A(:,:,2) =
     1     0     4
     3     5     6
     9     8     7

新しい要素に単一値を代入することで、配列を拡張できます。MATLAB は処理される要素の次元数に合わせてスカラー値を拡張します。この拡張はスカラー拡張と呼ばれます。

スカラー拡張を使用して、3 番目のページによる A の拡張を行います。

A(:,:,3) = 5
A(:,:,1) =
     5     7     8
     0     1     9
     4     3     6
A(:,:,2) =
     1     0     4
     3     5     6
     9     8     7
A(:,:,3) =
     5     5     5
     5     5     5
     5     5     5

配列の行、列またはページを拡張するには、同様の代入ステートメントを使用します。代入式の右辺と左辺の配列の次元は同じでなければなりません。

A を 3 x 3 x 3 x 2 の 4 次元配列に拡張します。MATLAB は 1 番目の代入において、拡張された次元の代入されていない要素をゼロで埋めることで A のパディングを行います。2 番目と 3 番目の代入では、そのゼロを指定値に置換します。

A(:,:,1,2) = [1 2 3; 4 5 6; 7 8 9];
A(:,:,2,2) = [9 8 7; 6 5 4; 3 2 1];
A(:,:,3,2) = [1 0 1; 1 1 0; 0 1 1];

MATLAB 関数を使用した配列の生成

MATLAB 関数 randnoneszeros などを使用して、2 次元配列を作成するのと同じように多次元配列を作成できます。ユーザーが与える引数は、結果の配列に対応する次元のサイズを表します。たとえば、一様分布の乱数の 4 x 3 x 2 の配列を作成するためには、次のように指定します。

B = randn(4,3,2)

単一の定数値で満たされた配列を作成するには、関数 repmat を使用します。関数 repmat は、配列次元のベクトルから配列 (この場合、1 行 1 列の配列) を複製します。

B = repmat(5, [3 4 2])

B(:,:,1) =
     5     5     5     5
     5     5     5     5
     5     5     5     5

B(:,:,2) =
     5     5     5     5
     5     5     5     5
     5     5     5     5

    メモ   配列の任意の次元のサイズがゼロで、空配列の形式になることがあります。たとえば、10 x 0 x 20 は多次元配列の有効サイズです。

関数 cat を使用した多次元配列の作成

関数 cat は多次元配列を簡単に作成することができます。この関数は、指定した次元方向に配列のリストを連結します。

B = cat(dim, A1, A2...)

ここで A1A2 などは連結する配列で、dim は配列を連結する次元です。

たとえば、関数 cat を使って新しい配列を作るには、次のようにします。

B = cat(3, [2 8; 0 5], [1 3; 7 9])

B(:,:,1) =
     2     8
     0     5

B(:,:,2) =
     1     3
     7     9

関数 cat では、既存のデータと新しいデータを任意に組み合わせることができます。さらに、関数 cat を入れ子の形式にすることができます。たとえば、次の行は 4 次元配列を作成します。

A = cat(3, [9 2; 6 5], [7 1; 8 4])
B = cat(3, [3 5; 0 1], [5 6; 2 1])
D = cat(4, A, B, cat(3, [1 2; 3 4], [4 3;2 1]))

関数 cat は、必要に応じて次元の間に "1" の添字を自動的に加えます。たとえば、2 x 2 x 1 x 2 の配列を作成するためには、次のように入力します。

C = cat(4, [1 2; 4 5], [7 8; 3 2])

上記の場合では、関数 cat は最後の次元の大きさが 1 でない 4 次元配列を作成するために必要とされるだけの、大きさが 1 の次元を挿入します。dim 引数が 5 ならば、上記のステートメントは 2 x 2 x 1 x 1 x 2 の配列を作成します。この結果、配列を表すインデックス式に 1 を加えます。4 次元の場合の値 8 にアクセスするためには、次の表現を使ってください。

多次元配列に関する情報の取得

作成した多次元配列に関する情報を得るために、以下の MATLAB 関数を使うことができます。

  • size — 各配列の次元サイズを返します。

    size(C)
    ans =
        2      2      1      2
      rows  columns  dim3   dim4
    

  • ndims — 配列の次元数を返します。

    ndims(C)
    ans =
        4
    

  • whos — 配列の形式とストレージの情報を出力します。

    whos
    Name     Size       Bytes   Class
    
    A        2x2x2         64   double array
    B        2x2x2         64   double array
    C        4-D           64   double array
    D        4-D          192   double array
    
    Grand total is 48 elements using 384 bytes
    

多次元配列のインデックス

2 次元行列に適用する多くの概念は、多次元配列にも拡張されます。

多次元配列の 1 つの要素にアクセスするには、整数の添字を使います。最初のインデックスは行次元、2 番目のインデックスは列次元、3 番目のインデックスは最初のページというように、各添字は次元をインデックス付けします。

ランダムな整数の 10 x 5 x 3 の配列 nddata の場合を考えてみましょう。

nddata = fix(8 * randn(10,5,3));

たとえば、nddata のページ 2 の要素 (3,2) にアクセスするには、nddata(3,2,2) を使用します。

配列の添字としてベクトルを使うことができます。この場合、各ベクトルの要素は配列の次元により定義される領域内で有効な添字でなければなりません。nddata の 3 ページの要素 (2,1)(2,3)(2,4) にアクセスするには、次のようにしてください。

nddata(2,[1 3 4],3);

コロンと多次元配列のインデックス

MATLAB のコロンを使ったインデックス付けは、多次元配列にも拡張されます。たとえば、nddata の 2 ページの 3 番目の列にアクセスするには、nddata(:,3,2) を使用します。

コロン演算子は、データのサブセットにアクセスするのにも有効です。たとえば、nddata(2:3,2:3,1) は、nddata のページ 1 のデータのサブセットである 2 行 2 列の配列になります。この行列は、配列の最初のページの 2 行目、3 行目と 2 列目、3 列目のデータから構成されています。

コロン演算子は、代入ステートメントの両辺で配列の添字として表すことができます。たとえば、ゼロから構成される 4 行 4 列の配列を作成する場合は、次のようにします。

C = zeros(4, 4)

配列 nddata の 2 行 2 列のサブセットを C の中央の 4 要素に代入します。

C(2:3,2:3) = nddata(2:3,1:2,2)

多次元配列の線形インデックス

MATLAB の線形インデックスは、多次元配列にも拡張されます。この場合、MATLAB はストレージ列を作成するページをベースに機能し、列方向に要素を付け加えていきます。このトピックに関しては、線形インデックス操作を参照してください。

たとえば、5 x 4 x 3 x 2 の配列 C を考えてみましょう。

再び、単一の添字は、この列の中にインデックスを直接設定します。たとえば、C(4) は、次のような結果になります。

ans =
     0

2 つの添字 (i,j) を使って、行と列のインデックスを設定すると、MATLAB は前述のようにオフセット値を計算します。2 つの添字は、オリジナルの配列次元の範囲で設定されている場合、多次元配列の最初のページへ常にアクセスします。

複数の添字が存在する場合、すべての添字がオリジナルの配列の次元内になければなりません。たとえば、C は 5 行しかないので、C(6,2) は、誤った指定になります。

2 つより多い添字を指定すると、MATLAB はそのインデックスの設定法に従って、配列を拡張します。たとえば、4 次元配列の中でサイズが [d1 d2 d3 d4] の、4 つの添字 (i,j,k,l) を考えます。MATLAB は、次のようにストレージ列の中でオフセットを計算します。

(l-1)(d3)(d2)(d1)+(k-1)(d2)(d1)+(j-1)(d1)+i

たとえば、添字 (3, 4, 2, 1) で配列 C を指し示す場合、MATLAB は値 5 を返します (ストレージ列の中の 38 番目)。

通常、次元 [d1 d2 d3 ... dn] の配列に対して、任意の添字 (s1 s2 s3 ... sn) を使用してオフセットを計算する場合の式は次のようになります。

(sn-1)(dn-1)(dn-2)...(d1)+(sn-1-1)(dn-2)...(d1)+...+(s2-1)(d1)+s1

この方法により、添字の番号を使って配列にインデックスを付けることができます。添字には、任意の数の 1 が付加できますが、この部分は 0 になります。たとえば、

C(3,2,1,1,1,1,1,1)

は、以下と等価です。

C(3,2)

多次元配列のインデックス付けのあいまいさの回避

次のような代入ステートメント

A(:,:,2) = 1:10

は、データを受け取る側の次元の形についての情報を指定しないため、あいまいな表現です。上記の例で、ステートメントは 1 次元ベクトルを 2 次元のものに代入しようとします。そのような場合、MATLAB はエラーを出力します。あいまいさを解決するためには、代入するデータに対する対象物 (左側の型) すなわち、データの型と対象物に関する十分な情報が必要です。たとえば、

A(1,:,2) = 1:10;

多次元配列の変形

型、またはサイズを変更しない限り、MATLAB 配列は、作成時に指定した次元を保持しています。要素を加えたり、削除することで配列のサイズを変更します。配列の形状は、同じ要素を保持しながら配列の行、列またはページ次元を再指定して変更します。関数 reshape は配列の形を変更します。多次元配列では、次のような形式になります。

B = reshape(A,[s1 s2 s3 ...])

s1, s2 などは、変更される行列の各次元の希望するサイズを表します。変更後の配列には、オリジナルの配列と同じ要素数がなければなりません (次元のサイズの積は一定になります)。

M

reshape(M, [6 5])

関数 reshape は、列単位で操作します。オリジナルのデータ構造の各列から連続する要素を操作することで行列を変更します。

C

reshape(C, [6 2])

nddata の変形によっていくつかの新しい配列が生成されます。

B = reshape(nddata, [6 25])
C = reshape(nddata, [5 3 10])
D = reshape(nddata, [5 3 2 5])

大きさが 1 の次元の削除

MATLAB は後続の大きさが 1 の次元をすべての多次元配列から削除します。たとえば、コマンド rand(3,2,1,1) でサイズが 3 x 2 x 1 x 1 の配列の作成を試行すると、MATLAB は配列の最後から大きさが 1 の次元を取り除いて、3 行 2 列の行列を作成します。これは、すべての配列は技術上、"無限" 数の大きさが 1 の次元が後続しているためです。3 行 2 列の配列はサイズ 3 x 2 x 1 x 1 x 1 x ...の配列と同等です。

たとえば、次の 2 行 2 列の行列 A について考えてみましょう。

A = eye(2)

A =

     1     0
     0     1 

A は 2 行 2 列の単位行列です。

A の 4 番目の次元のサイズを求めます。

size(A,4)

ans =

     1

A は 2 行 2 列の行列ですが、A の 4 番目の次元は 1 です。実際、2 番目より後の次元のサイズはすべて 1 です。

配列の最初の 2 つの次元は常に関連性があるので削除されることはありません。

size(3)

ans =

     1     1

MATLAB では、スカラーも 1 行 1 列の行列です。

MATLAB は、配列の作成や形状変更時に明示的に指定したり、結果が 1 次元の配列になる計算を行う場合に、大きさが 1 の次元を作成します。

B = repmat(5, [2 3 1 4]);

size(B)
ans =
     2     3     1     4

関数 squeeze は、配列から大きさが 1 の次元を削除します。

C = squeeze(B);

size(C)
ans =
     2     3     4

関数 squeeze は、2 次元配列には影響を与えません。行ベクトルは、行のまま残ります。

配列の次元の並べ替え

関数 permute は配列の次元を並べ替えます。

B = permute(A, dims);

dims は、A の次元に対して新しい順番を指定するベクトルです。ここで、1 は最初の次元 (行)、2 は 2 番目の次元 (列)、3 はページに対応します。

関数 permute のより詳細な観察として、サイズ 5 x 4 x 3 x 2 の配列 A を考えます。列の次元を最初に、次に 2 ページ目の次元、1 ページ目の次元、最後に行の次元になるように次元を再構成します。結果は、4 x 2 x 3 x 5 の配列になります。

permute の処理は、行列の行と列次元を入れ替える関数 transpose を拡張したものと考えることができます。関数 permute では、入力次元のリストの順序によって添字の並べ替え順序が決定されます。上記の例では、A の要素 (4,2,1,2) は、B の要素 (2,2,1,4) になり、A の要素 (5,4,3,2) は、B の要素 (4,2,3,5) などのようになります。

逆転置

関数 ipermute permute の逆操作をします。入力配列 A と次元のベクトル v を指定すると、関数 ipermutepermute(B,v)A を返すような配列 B を返します。

たとえば、次のステートメントは、入力配列 C と等しい配列 E を作成します。

D = ipermute(C, [1 4 2 3]);
E = permute(D, [1 4 2 3]) 

同じ次元ベクトルを使って、関数 ipermute を呼び出して変換した後で、オリジナルの配列を得ることができます。

多次元配列の計算

多くの MATLAB の計算関数や数学関数は、多次元配列を引数としています。これらの関数は、多次元配列の特定の次元を操作します。すなわち、個々の要素、ベクトル、行列を操作します。

ベクトルを操作する関数

一般的にベクトルを処理する関数 (summean など) は、既定により多次元配列の次元のうち大きさが 1 でない最初の次元に対して処理を行います。これらの関数のほとんどは、操作する次元をオプションで指定することができます。しかし、これには例外があります。たとえば、関数 cross は2 ベクトルの外積を求め、長さ 3 をもち、大きさが 1 でない最初の次元を処理します。

    メモ   多くの場合、関数の入力引数には他の制限があります。たとえば、サイズが同じ複数の配列を受け入れる関数もあります。関数の引数の詳細は、オンライン ヘルプを参照してください。

要素ごとの演算

MATLAB の関数で 2 次元配列に要素ごとの処理をする関数 (たとえば elfun ディレクトリの 三角関数と指数関数) は、多次元配列に対しても等価な処理を行います。たとえば関数 sin は、関数の入力引数と同じサイズの配列を返します。出力配列の各要素は、入力配列の対応する要素の正弦値です。

同様に、代数演算、論理演算、比較演算は各次元で同じサイズである多次元配列の対応する要素を操作します。オペランドがスカラーと配列であれば、演算子は配列の各要素にスカラーを適用します。

面と行列に操作する関数

matfun ディレクトリにある線形代数や行列関数のように、面や行列に対する演算を行う関数は、引数として多次元配列を受け入れません。つまり、matfun ディレクトリにある関数や配列演算子 *^\/ に対して多次元引数を使うことはできません。多次元引数やオペランドを指定するとエラーになります。

多次元配列内で行列関数や行列に対する演算子を適用するためにインデックスを使うことができます。たとえば、3 次元配列 A を作成します。

A = cat(3, [1 2 3; 9 8 7; 4 6 5], [0 3 2; 8 8 4; 5 3 5], ...
    [6 4 7; 6 8 5; 5 4 3]);

この多次元配列全体に関数 eig を入力すると、エラーになります。

eig(A)
???未定義の関数またはメソッド 'eig'
('double' 型、属性 'full 3d real' の入力引数)。

しかし、配列内の面に関数 eig を適用することはできます。たとえば、配列の 1ページだけ (この場合、2 ページ目) をインデックス付けするためにコロン表記を使います。

eig(A(:,:,2))
ans =
   12.9129
   -2.6260
    2.7131

    メモ   最初の例では添字がコロンではありません。エラーを防ぐには squeeze を使用しなければなりません。たとえば、 eig(A(2,:,:)) は入力されたサイズが [1 3 3] のため、エラーを返します。しかし、式 eig(squeeze(A(2,:,:))) は、eig に有効な 2 次元行列を渡します。

データの多次元配列化

多次元配列を使ってデータを表現する方法は 2 つあります。

  • 2 次元データの面またはページとして表現します。そうすることによって、これらのページを行列として扱うことができます。

  • 多変数データ、または多次元データを扱います。たとえば、各要素が室内の等間隔点で観測された温度、または気圧に対応する 4 次元配列のようなものです。

たとえば、RGB イメージを考えます。1 つのイメージに対して、多次元配列はデータを保存しアクセスするためのおそらく最も簡単な方法です。

イメージの面全体にアクセスする場合は、次の式を使います。

redPlane = RGB(:,:,1);

サブイメージにアクセスする場合は、次の式を使います。

subimage = RGB(20:40,50:85,:);

RGB イメージは、表示やフィルター処理のような操作に対して面内でアクセスされる必要があるデータの良い例です。しかし、他の場合ではデータ自身が多次元であるかもしれません。たとえば、室内の等間隔点で観測された温度について考えます。各値の位置もデータセットの一部であり、各要素の物理的な配置位置が情報の一部になります。このようなデータは、多次元配列として表現できます。

ここですべての測定値の平均を算出する場合には、次の式を使用します。

mean(mean(mean(TEMP)));

各ページの室内の"中央" 値 (要素 (2,2)) ベクトルを得るには以下を実行します。

B = TEMP(2,2,:);

多次元セル配列

数値配列のように、MATLAB の多次元セル配列の操作は、2 次元セル配列操作の拡張です。数値配列に対して使う場合と同様に多次元セル配列を作成するために、関数 cat を使うことができます。

たとえば、簡単な 3 次元セル配列 C を作成します。

A{1,1} = [1 2;4 5];
A{1,2} = 'Name';
A{2,1} = 2-4i;
A{2,2} = 7;
B{1,1} = 'Name2';
B{1,2} = 3;
B{2,1} = 0:1:3;
B{2,2} = [4 5]';
C = cat(3, A, B);

C のセルに対する添字は、次のようになります。

多次元構造体配列

多次元構造体配列は、2 次元構造体配列の拡張です。他の多次元配列タイプのように、直接代入、または関数 cat を使って作成できます。

patient(1,1,1).name = 'John Doe';
patient(1,1,1).billing = 127.00;
patient(1,1,1).test = [79 75 73; 180 178 177.5; 220 210 205];
patient(1,2,1).name = 'Ann Lane';
patient(1,2,1).billing = 28.50;
patient(1,2,1).test = [68 70 68; 118 118 119; 172 170 169];
patient(1,1,2).name = 'Al Smith';
patient(1,1,2).billing = 504.70;
patient(1,1,2).test = [80 80 80; 153 153 154; 181 190 182];
patient(1,2,2).name = 'Dora Jones';
patient(1,2,2).billing = 1173.90;
patient(1,2,2).test = [73 73 75; 103 103 102; 201 198 200];

多次元構造体配列への関数の適用

多次元構造体配列に関数を適用するために、インデックスを使ってフィールドとフィールドの要素に対して操作を行います。たとえば、patient(1,1,2)test 配列の列の和を求めます。

sum((patient(1,1,2).test));

同様に、patient 配列のすべての billing フィールドを加えます。

total = sum([patient.billing]);
この情報は役に立ちましたか?