Main Content

配列のタイプ

多次元配列

MATLAB® の多次元配列は、3 つ以上の添字をもった配列です。これは、2 つを超える引数と共に zerosonesrandrandn を呼び出すことによって作成されます。たとえば、次の例を考えてみましょう。

R = randn(3,4,5);

は、3*4*5 = 60 個の正規分布する乱数要素をもつ 3 x 4 x 5 の配列を作成します。

3 次元配列は、3 次元の物理的データを表わします。たとえば、四角形グリッド上でサンプリングした室温を表します。また、行列の数列 A(k) や時間依存行列のサンプル A(t) を表します。後者の場合、tk 番目の行列、または k 番目の行列の (i, j) 番目の要素は、A(i,j,k) によって表されます。

4 次の魔方陣の MATLAB バージョンとデューラー バージョンは、2 つの列が入れ替わっています。列を入れ替えることにより、異なる魔方陣を作ることができます。ステートメント

p = perms(1:4);

は、1:4 の順列 4! = 24 の組み合わせを生成します。k 番目の順列は、行ベクトル p(k,:) です。したがって、

A = magic(4);
M = zeros(4,4,24);

for k = 1:24
   M(:,:,k) = A(:,p(k,:));
end

は、3 次元配列 M に 24 種の魔方陣を格納します。M のサイズは、

size(M)

ans =
     4     4    24

メモ

この例に示されている行列の順はユーザーの結果と異なる可能性があります。関数 perms は常に入力ベクトルの置き換えを返しますが、その順序は MATLAB バージョンによって違うことがあります。

ステートメント

sum(M,d)

は、d 番目の添字を変更して和を計算します。 

sum(M,1)

は、24 個の行ベクトル

34    34    34    34

および

sum(M,2)

は、24 個の列ベクトル

34    
34    
34    
34

最終的に、

S = sum(M,3)

は、24 個の行列を足したものなります。結果は 4 x 4 x 1 になり、4 行 4 列の配列に見えます。

S =
   204   204   204   204
   204   204   204   204
   204   204   204   204
   204   204   204   204

cell 配列

MATLAB の cell 配列は、多次元配列で、その要素は他の配列のコピーです。空行列の cell 配列は、関数 cell で作成できます。しかし、非常に頻繁に cell 配列は、中かっこ {} を使って様々なものを囲むことによって作成されます。中かっこは、種々のセルの内容にアクセスするための添字と共に使われることもあります。たとえば、次の例を考えてみましょう。

C = {A sum(A) prod(prod(A))}

は、1 行 3 列の cell 配列を作成します。3 つのセルは、魔方陣、列方向の和を表わす行ベクトル、すべての要素の積から構成されています。C を表示すると、次のようになります。

C = 
    [4x4 double]    [1x4 double]    [20922789888000]

これは、最初の 2 つのセルは、スペースの関係で出力するには大きすぎるためです。しかし、3 番目のセルは 1 つの数値 16! なので、出力されています。

覚えておく必要のある 2 つの重要なことがあります。まず、セルの中の個々の内容を取り出すには、添字を中かっこで囲んで使います。たとえば、C{1} は魔方陣で、C{3} は 16! です。2 番目に、cell 配列は、他の配列の "コピー" を含み、他の配列への "ポインター" ではありません。その後 A を変更しても C は何も変更されません。

3 次元配列は、"同じ" サイズの一連の行列を格納するときに使うことができます。cell 配列は、"異なる" サイズの一連の行列を格納するためにも使うことができます。たとえば、次の例を考えてみましょう。

M = cell(8,1);
for n = 1:8
   M{n} = magic(n);
end
M

は、異なる次数の一連の魔方陣を作成します。

M = 
    [           1]
    [ 2x2  double]
    [ 3x3  double]
    [ 4x4  double]
    [ 5x5  double]
    [ 6x6  double]
    [ 7x7  double]
    [ 8x8  double]

今まで使ってきた馴染みのある魔方陣も取り出すことができます。

M{4}

文字とテキスト

MATLAB へテキストを入力するには、一重引用符を利用します。たとえば、次の例を考えてみましょう。

s = 'Hello'

結果は、今まで取り扱ってきた数値行列や配列と異なる種類のものです。これは、1 行 5 列の文字配列です。

内部的に、文字は数字として格納されますが、浮動小数点形式ではありません。ステートメント

a = double(s)

は、文字配列を ASCII コードの浮動小数点表現を含む数値行列に変換します。結果は、次のようになります。

a =
    72    101    108    108    111

ステートメント

s = char(a)

は、逆の変換を行います。

数字を文字に変換することにより、ユーザーのコンピューターで使用可能なフォントの種類を調べることができます。基本的な ASCII 文字セットの中のプリント可能な文字は、整数 32:127 で表されます (32 よりも小さい整数は、プリントできない制御文字を表します)。これらの整数は、次のように適切な 6 行 16 列の配列に並べられます。

F = reshape(32:127,16,6)';

拡張 ASCII 文字セットの中のプリント可能な文字は、F+128 によって表されます。これらの整数が文字として解釈されるとき、結果は現在使われているフォントに依存します。次のステートメントをタイプします。

char(F)
char(F+128)

するとコマンド ウィンドウで使われているフォントが変化します。フォントを変更するには、[ホーム] タブの [環境] セクションで、[基本設定][フォント] をクリックします。コードの行にタブを使っている場合は、他の行とタブ位置を合わせるために Monospaced などの固定幅フォントをお使いください。

大かっこの中で連結すると、テキスト変数が結合されます。ステートメント

h = [s, ' world']

は、文字を水平方向に結合し、次を生成します。

h =
   Hello world

ステートメント

v = [s; 'world']

は、文字を垂直方向に結合し、次を生成します。

v =
   Hello
   world

h'w' の前に空白が挿入されていなければならないことと、v で 2 つの単語は同じ長さでなければならないことに注意してください。結果の配列は、共に文字配列で、h は 1 行 11 列で、v は 2 行 5 列です。

異なる長さの行を含むテキストの内容を操作するには、長さを揃えた文字配列にするか、文字ベクトルの cell 配列にするかの 2 つの方法があります。文字配列を作る際には配列のすべての行を同じ長さにしなければなりません。(短い行の末尾を空白文字で埋めてください。)関数 char はこの埋め合わせを自動的に行います。たとえば、次の例を考えてみましょう。

S = char('A','rolling','stone','gathers','momentum.')

は、5 行 9 列の文字配列です。

S =
A        
rolling  
stone    
gathers  
momentum.

または、1 つの cell 配列にテキストを格納することができます。たとえば、次の例を考えてみましょう。

C = {'A';'rolling';'stone';'gathers';'momentum.'}

は、配列の各行が異なる長さであることができるので埋め合わせの必要のない、5 行 1 列の cell 配列を作ります。

C = 
    'A'
    'rolling'
    'stone'
    'gathers'
    'momentum.'

パディングされた文字配列は、次のように文字ベクトルの cell 配列に変換できます。

C = cellstr(S)

そして、逆も可能です。

S = char(C)

構造体

構造体は、テキストの "フィールド識別子" によりアクセスできる要素をもつ多次元 MATLAB 配列です。たとえば、次の例を考えてみましょう。

S.name = 'Ed Plum';
S.score = 83;
S.grade = 'B+'

は、3 つのフィールドをもったスカラー構造体を作成します。

S = 
     name: 'Ed Plum'
    score: 83
    grade: 'B+'

MATLAB の中のすべてのものと同じように、構造体は配列で、そのため付加的な要素も挿入することができます。この場合、配列の各々の要素は、いくつかのフィールドをもつ構造体です。フィールドは、一度に一つのものを加えることができます。

S(2).name = 'Toni Miller';
S(2).score = 91;
S(2).grade = 'A-';

または、すべての要素が単一ステートメントで加えられます。

S(3) = struct('name','Jerry Garcia',... 
               'score',70,'grade','C')

構造体は、内容の概略だけをプリントしても十分に大きいものです。

S = 
1x3 struct array with fields:
    name
    score
    grade

種々のフィールドを他の MATLAB 配列に集め直すのにいくつかの方法があります。これらは、"コンマでリストを分離する" 記法をもとにしています。以下のように入力すると、

S.score

次の事柄と等価です。

S(1).score, S(2).score, S(3).score

これは、各要素をコンマによる分離で表現するものです。

大かっこ内のリストなどを作成する式を囲むと、MATLAB はリストからの各項目を配列に保存します。この例では、MATLAB は、構造体配列 S の各要素の score フィールドを含む、数値の行ベクトルを作成します。

scores = [S.score]
scores =
    83    91    70

avg_score = sum(scores)/length(scores)
avg_score =
   81.3333

テキスト フィールドの 1 つ (たとえば、name) から文字配列を作成するには、S.name で生成されるコンマ区切りリストに関数 char を呼び出します。

names = char(S.name)
names =
   Ed Plum    
   Toni Miller
   Jerry Garcia

同様に、中かっこ内のリストを作成する式を囲むと name フィールドから cell 配列を作成できます。

names = {S.name}
names = 
    'Ed Plum'    'Toni Miller'    'Jerry Garcia'

構造体配列の各要素のフィールドを、構造体の外側の別々の変数に割り当てるには、出力全体を大かっこで囲み等号の左に指定します。

[N1 N2 N3] = S.name
N1 =
   Ed Plum
N2 =
   Toni Miller
N3 =
   Jerry Garcia

ダイナミックなフィールド名

構造体のデータにアクセスする最も一般的な方法は、参照するフィールド名を指定することです。構造体データにアクセスする他の方法は、ダイナミックなフィールド名を使うことです。こうした名前は、MATLAB により実行時に評価される可変表現としてフィールドを表します。以下のドットとかっこの構文は、ダイナミックなフィールド名を表現します。

structName.(expression)

MATLAB の標準のインデックス構文を使ってこのフィールドにインデックスを付けることができます。たとえば、フィールド名の式を評価し、7 行目の 1 列から 25 列のフィールドの値を得るには、以下を実行します。

structName.(expression)(7,1:25)

ダイナミックなフィールド名の例.  下記の関数 avgscore は、テストの平均点を計算し、ダイナミックなフィールド名を使って testscores 構造体から情報を取得します。

function avg = avgscore(testscores, student, first, last)
for k = first:last
   scores(k) = testscores.(student).week(k);
end
avg = sum(scores)/(last - first + 1);

ダイナミックなフィールドである student に異なる値を与えて次の関数を実行することができます。最初に、25 週間の得点を含む構造体を初期化します。

testscores.Ann_Lane.week(1:25) = ...
  [95 89 76 82 79 92 94 92 89 81 75 93 ...
   85 84 83 86 85 90 82 82 84 79 96 88 98];

testscores.William_King.week(1:25) = ...
  [87 80 91 84 99 87 93 87 97 87 82 89 ...
   86 82 90 98 75 79 92 84 90 93 84 78 81];

ここで、ダイナミックなフィールド名を使用して、実行時に testscores 構造体に学生の名前のフィールドを指定し、avgscore を実行します。

avgscore(testscores, 'Ann_Lane', 7, 22)
ans = 
   85.2500

avgscore(testscores, 'William_King', 7, 22)
ans = 
   87.7500