ドキュメンテーション センター

  • 評価版
  • 製品アップデート

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

行列のサイズと形状の変更

行列サイズの拡大

結果の行列が、不規則な型にならない限り、任意の既存の行列のサイズを拡大することができます 「矩形行列の維持」を参照)。たとえば、4 行 3 列 と 7 行 3 列は、結果の行列がすべて 3 列なので、垂直に連結することができます。

既存の行列のサイズを拡大するために、次の 2 とおりの方法があります。

  • 新しい要素を行列に連結する

  • 行列の範囲外の位置に保存する

    メモ   行列がより多くのスペースを必要とし、時間と共に行列のサイズを繰り返し拡大しようとする (通常、プログラミング ループで行われている) 場合、最初に行列を作成し、この行列に対してメモリ スペースを事前に割り当てることが望ましいです。「メモリの事前割り当て」を参照してください。

行列への連結

オリジナルの行列とサイズが矛盾しない新しい要素、またはブロックを追加することにより、行列を拡大しようとする場合、連結が最も有効です。これは、特定の次元について連結されるすべての行列のサイズが、その次元と等しくなければならないことを意味します。「行列の連結」を参照してください。

この例は、ユーザー定義の関数 compareResults を行列 stats04 および行列 stats03 のデータを使って実行します。ループを通るたびに、この関数の結果は comp04 に保存されるデータの終わりに連結されます。

col = 10;
comp04 = [];

for k = 1:50
   t = compareResults(stats04(k,1:col), stats03(k,1:col));
   comp04 = [comp04; t];
end

構造体またはセル配列への連結-  通常の行列と同じように、構造体の配列やセルの配列に付加できます。次の例では、構造体 S で構成される 3 行 8 列の行列を作成します。それぞれが 3 つのフィールド、xyz をもち、2 番目の構造体行列 S2 をオリジナルに連結します。

3 行 8 列の構造体配列 S を作成します。

for k = 1:24
   S(k) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);
end
S = reshape(S, 3, 8);

3 行 2 列の第 2 の配列を作成し、S と同じフィールド名を使用します。

for k = 25:30
   S2(k-24) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);
end
S2= reshape(S2, 3, 2);

水平の次元について、S2S に連結します。

S = [S S2]
S = 
3x10 struct array with fields:
    x
    y
    z

より小さいブロックを行列に追加

サイズが矛盾する行列に、1 つ、または複数の要素を追加することは、多くの場合、オリジナルの行列の範囲外の新しい要素を保存することにより可能です。MATLAB® は、行列を四角形型に保つために、自動的にゼロを埋めます。

3 行 5 列を作成し、連結を使用して新しい要素を追加します。5 列の行列に 1 行 1 列の行列を連結しようと試みているため、この操作は失敗します。

A = [ 10  20  30  40  50; ... 60  70  80  90 100; ... 110 120 130 140 150]; 60  70  80  90 100; ... 110 120 130 140 150];

A = [A; 160] vertcat の使用中にエラーが発生しました。CAT 引数の次元が一致していません。

これを再び行いますが、今度は、MATLAB が、行列のサイズに調整を行えるような方法で行います。この行列にまだ存在しない、4 行 1列目は、新しい要素を保存します。MATLAB は、2 列目から 5 列目をゼロで埋めることにより、完全な行にすることで、行列 A を拡大します。

A(4,1) = 160
A =
    10    20    30    40    50
    60    70    80    90   100
   110   120   130   140   150
   160     0     0     0     0

    メモ   行列の存在しない位置から読み取りすると、エラーが生じます。これらの位置には書き込みのみ可能です。

前述のように、1 つの要素を指定して追加するのではなく、行列を追加することにより、元の行列を拡大することもできます。

A(4:6,1:3) = magic(3)+100
A =
    10    20    30    40    50
    60    70    80    90   100
   110   120   130   140   150
   108   101   106     0     0
   103   105   107     0     0
   104   109   102     0     0

新しい要素を順次に追加する必要はありません。新しい要素を代入する場合はいつでも、MATLAB は、結果の行列が四角形型になるように、ゼロを埋めます。

A(4,8) = 300
A =
    10    20    30    40    50     0     0     0
    60    70    80    90   100     0     0     0
   110   120   130   140   150     0     0     0
     0     0     0     0     0     0     0   300

構造体またはセル配列の拡大-  行列と同じように、構造体の配列やセルの配列を拡大できます。次の例では、オリジナルの配列の範囲を超えてセルを保存することによって、セル配列に追加のセルを加えます。MATLAB はデータ構造を四角形型に保つために、空のセル ([]) で埋めます。

オリジナルの配列は、2 行 3 列です。

C = {'Madison', 'G', [5 28 1967]; ...
     46, '325 Maple Dr', 3015.28}

C{3,1} にセルを追加し、MATLAB は、すべての行を付け加えます。

C{3, 1} = ...
struct('Fund_A', .45, 'Fund_E', .35, 'Fund_G', 20);
C = 
    'Madison'       'G'                [1x3 double]
    [        46]    '325 Maple Dr'    [3.0153e+003]
    [1x1 struct]                []               []

文字配列の拡大-  他の MATLAB 配列と同じ方法で文字配列を拡大できますが、一般的には推奨されません。MATLAB は、初期値が設定されていない要素をゼロで埋めることで、配列を拡大します。MATLAB や他のいくつかのプログラミング言語では、ゼロが文字列の終了として解釈されるので、拡大された文字列をフルの長さより短いものとして扱う関数もあります。

1 行 5 列の文字配列を 12 文字に拡大します。結果は、一見すると標準的な文字列であるように見えます。

greeting = 'Hello';    greeting(1,8:12) = 'World'
greeting =
   Hello  World

しかし、さらに詳しく調べると、拡大点で文字列の終了が現れます。

uint8(greeting)
ans =
   72  101  108  108  111    0    0   87  111  114  108  100

これは、strcmp のようないくつかの関数では、予期しない結果が返される原因となります。

strcmp(greeting, 'Hello  World')
ans =
     0

行列サイズの縮小

空の配列 [] を行と列に代入することで、行列の行と列を 削除することができます。次のように指定します。

A = magic(4)
A =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

続いて、次を使用して A の 2 列目を削除します。

A(:, 2) = []

これによって行列 A が次のように変更されます。

A = 
   16    3   13
    5   10    8
    9    6   12
    4   15    1

行列から単一要素を削除する場合、結果はもはや行列になりません。たとえば、

A(1,2) = []

は、エラーになります。線形インデックスを使うと、単一要素を削除することも、一連の要素を削除することもできます。これによって残りの要素が行ベクトルに変形します。

A(2:2:10) = []

結果は次のようになります。

A = 
    16     9     3     6    13    12     1

行列の変形

次の関数を使用して行列の形状を変更します。

関数

説明

reshape

行列の形状を変更します。

rot90

行列を 90 度回転します。

fliplr

縦軸に対して行列を反転します。

flipud

横軸に対して行列を反転します。

flipdim

特定の方向に行列を反転します。

transpose

主対角線に対して行列を反転させ、行ベクトルを列ベクトルに、あるいはその逆に変換します。

ctranspose

行列転置を行って、各要素を複素共役要素に置き換えます。

行列の変形方法例を以下に示します。

行列の変形-  3 行 4 列の行列 A を、2 行 6 列の行列に変形するには、次のように指定します。

A = [1 4 7 10; 2 5 8 11; 3 6 9 12]
A =
    1    4    7    10
    2    5    8    11
    3    6    9    12

B = reshape(A, 2, 6)
B =
    1    3    5    7    9   11
    2    4    6    8   10   12

行列の転置-  A を転置して、行要素が列になるようにします。関数 transpose、または転置用の演算子(.') を使用します。

B = A.'
B =
     1     2     3
     4     5     6
     7     8     9
    10    11    12

行列の複素共役転置を行う ctranspose という関数も別にあります。行列 A に対して関数 ctranpose を実行するのと同じ結果が、演算子 A' でも得られます。

A = [1+9i 2-8i 3+7i; 4-6i 5+5i 6-4i]
A =
   1.0000 + 9.0000i   2.0000 -8.0000i   3.0000 + 7.0000i
   4.0000 -6.0000i   5.0000 + 5.0000i   6.0000 -4.0000i

B = A'
B =
   1.0000 -9.0000i   4.0000 + 6.0000i
   2.0000 + 8.0000i   5.0000 -5.0000i
   3.0000 -7.0000i   6.0000 + 4.0000i

行列の回転-  行列を 90 度回転します。

B = rot90(A)
B =
    10    11    12
     7     8     9
     4     5     6
     1     2     3

行列の反転-  A を左から右方向に反転します。

B = fliplr(A)
B =
    10     7     4     1
    11     8     5     2
    12     9     6     3

メモリの事前割り当て

時間が経つにつれて配列のサイズを繰り返し拡大する (たとえば、プログラミング ループを通るたびに、配列に要素を追加する) と、ユーザー プログラムのパフォーマンスに悪影響を及ぼす可能性があります。これは、以下の理由によります。

  • MATLAB は、ユーザーが配列のサイズを増加させるたびに、より多くのメモリ割り当てに、時間を費やす必要があります。

  • この新たに割り当てられたメモリは、連続ではない可能性があり、MATLAB が配列に行う操作を低速化することになります。

時間が経つと拡大することが予想される配列について、適切なサイズ設定の方法は、可能性のある最大のサイズの配列を推定し、その配列が作成される時点で、配列にそのサイズのメモリを事前に割り当てます。こうして、ユーザー プログラムは、連続した 1 ブロックを確保するメモリ割り当てを行います。

次のコマンドは、25,000 行 10,000 列に十分なメモリを事前に割り当て、各要素を 0 に初期化します。

A = zeros(25000, 10000);

事前割り当てされる配列の構築

配列の推定された最大のサイズに対して、いったん事前にメモリが割り当てられると、必要に応じて、既存のデータに加えるたびに、配列にデータを保存することができます。この例は、大規模な配列を事前割り当てし、その後、ファイルの最後に至るまでファイルからデータのブロックを配列に読み込みます。

blocksize = 5000;
maxrows = 2500000; cols = 20;
rp = 1;     % row pointer

% Preallocate A to its maximum possible size
A = zeros(maxrows, cols);

% Open the data file, saving the file pointer.
fid = fopen('statfile.dat', 'r');
 
while true
   % Read from file into a cell array.  Stop at EOF.
   block = textscan(fid, '%n', blocksize*cols);
   if isempty(block{1})   break,   end;
 
   % Convert cell array to matrix, reshape, place into A.
   A(rp:rp+blocksize-1, 1:cols) = ...
      reshape(cell2mat(block), blocksize, cols);
 
   % Process the data in A.
   evaluate_stats(A);               % User-defined function
 
   % Update row pointer
   rp = rp + blocksize;
end

    メモ   最終的に、事前に割り当てたメモリよりも多くのメモリが行列で必要になる場合、同様の方法で追加のストレージを事前に割り当て、オリジナルの配列に、この追加のストレージを連結することができます。

この情報は役に立ちましたか?