LoginSignup
94
64

More than 3 years have passed since last update.

[MATLAB]初心者が初見で必ずthinking顔になるもの特集

Last updated at Posted at 2020-04-15

JavaScript初心者向けの良記事「[JavaScript]初心者が初見で必ずthinking顔になるもの特集」を見た瞬間に、「あっ…これMATLABでもめっちゃあるあるな奴やんけ…」と思ったのでMATLAB芸人として我慢できず、反射的に書きました。

タイトルが思いっきりパクリなのですが、先行記事をリスペクトしすぎる上での判断なので勘弁頂きたい。だって本当に素晴らしいタイトルなんですもの😇

MATLAB、開発チームの心遣いからか大変便利な演算子やコマンドが多く素晴らしいと思う一方で、あまりにも情報圧縮しすぎてググりにくいという弊害があると思っています。(本文に上げている[~, x]とかどう調べろっつーねん)
なので初心者が:thinking:となる→ググっても見つからず時間が溶ける😇 という事案がそこそこ発生します。私もいっぱい溶かしてきたので、皆さんがそうならないことを願ってこの記事を書きます。

なお本記事の副読本としてMathworks公式ドキュメントMATLAB の演算子と特殊文字を一通り読むことを強く勧めます。
(そもそも最初からこれちゃんと読んでおけば:thinking:となるのを回避できるのですが…私は必要に応じてしか読んでないから😇となっている)

\

is 何

逆行列。MATLAB Tシャツでもおなじみ、MATLABで最もセクシーな演算子。
MATLABの言語設定を日本語にしていると¥になってしまう点が少し残念。

% 行列を作成
A = [1 2;
    1 3];

%単位行列
B = [1 0;
    0 1];

%Aの逆行列を計算
C = A \ B

image.png
ちなみに逆行列は、inv(A)とかA^-1でも求められます。\を使うと通ぶれるので積極的に使いましょう。

なお\inv(A)と比べ計算時間が早い&残差誤差も少ないという優れた特徴があります、詳細は下記。教えてくれた@sasayaさんありがとう!
https://jp.mathworks.com/help/matlab/ref/inv.html

これはもう\を使うしかないですね。

.*

is 何

各要素ごとの掛け算。大変便利なので覚えましょう。
ドット.と演算子を組み合わせることで「各要素ごとの**」になります。
個人的によく使うのは.* ./ .^ あたり。

A = [1 2 3];
B = [10 20 30];

C = A .* B

image.png

(:, n)

is 何

n列目の要素全て。逆に(n, :)だとn行目の要素全てになる。

A = [1 2;
    3 4];

n = 2;

B = A(:, n)
C = A(n, :)

image.png

さらなる発展形として、(:, :, n)というのもある。
画像データのRGBのいずれか1つを抽出する際に有効。

img = imread('peppers.png');

img_Red = img(:, :, 1);
img_Green = img(:, :, 2);
img_Blue = img(:, :, 3);

subplot(2,2,1);
imshow(img);

subplot(2,2,2);
imshow(img_Red);

subplot(2,2,3);
imshow(img_Green);

subplot(2,2,4);
imshow(img_Blue);

image.png

subplot(211)

is 何

subplot(2,1,1)の省略形。
つまり、上記のコードは下記でも同じように動くのである。著しく可読性を下げるので人に見せるコードでは使わないようにしましょう、してくれ頼む。

img = imread('peppers.png');

img_Red = img(:, :, 1);
img_Green = img(:, :, 2);
img_Blue = img(:, :, 3);

subplot(221);
imshow(img);

subplot(222);
imshow(img_Red);

subplot(223);
imshow(img_Green);

subplot(224);
imshow(img_Blue);

image.png

...

is 何

長ったらしいコードの改行。

options=optimoptions('ga','InitialPopulationMatrix', ...
                        initpop,'Display','iter','OutputFcn',@myfun);

ちなみに、複数行の行列を宣言する場合においてセミコロン;の後にこの改行を書かなくてもOKです。
(追記)改行さえしてあれば;すらも不要です。可読性的にどうなの、というのはさておき。

% これでももちろんOKだけど
A = [1 2 3; ...
    4 5 6];

% これでもOK
A = [1 2 3; 
    4 5 6];

% これでもOK
A = [1 2 3 
    4 5 6];

'

is 何

複素共役転置
ただの転置は.'だが、転置する対象が実数の場合は'.'のどちらを使っても結果は同じなので'を使う人も多い(と勝手に思っている)。しかしながら将来におけるバグの原因となるので、使い分けたほうがベターではある。

% これと
A = [1:3]';

% これは結果が同じ
A = [1:3].';

image.png

複素数の場合は言わずもがら、結果が変わってくるのでご注意。

A = [1+i 1-i];

B = A.'
C = A'

image.png

1i

is 何

複素数の作成。【MATLAB】行列を与えると随伴行列を返す関数を作って...@eigsさんのコメントから拝借。

複素数は下記3つのいずれのパターンでも書ける、試しに足してみよう。

A = 1i;
B = i;
C = sqrt(-1);

D = A + B + C

image.png

iが複素数として使えるのは使用以前に内容を定義していない場合のみで、定義していた場合は下記のようになる。

i = 1;

A = 1i;
B = i;
C = sqrt(-1);

D = A + B + C

image.png

1i2iのように使うのが一番よさそうですね。試してみたら0.1iもいけました。
sqrt(2)iは流石にNG、sqrt(2)*1iならOK。

e3

is 何

10の累乗。e3なら10の3乗ということ。何気に便利。e+3e+03といった表現も可能です。
実際にはeの前に何かしらの数字が必要になります。

A = 2.5e3
B = 2.5e-3

image.png

複素数1iとの組み合わせもいけるのかしら?と思ったが1ie31i*e3はNG。下記ならOK。

A = 1i * 1e3
B = 1e3 * 1i

image.png

@(x)

is 何

無名関数の関数ハンドル。
そもそも無名関数って何じゃい、って方は丸田先生のSlideShare「関数型プログラミング入門 for Matlab ユーザー」を読みましょう、神。

f = @(x) sin(x) + sin(3*x);
fplot(f);

image.png

ちなみにfplotは関数から直接グラフをplotするための関数で、これも上記SlideShare内で紹介されています。
念のためfplotを使わない場合は下記。plot結果がスムーズでなくなる点もSlideShareにて言及されてます、神。

f = @(x) sin(x) + sin(3*x);
X = [-5 : 0.1 : 5];
Y = f(X);
plot(X,Y);

image.png

[~, x]

is 何

関数の戻り値のうち不要なものを~で捨てる。高速化のためのテクニック。

A = [20 30 10 0];

% A行列のうちで小→大に並び替える際の順番だけを知りたい
[~, idx] = sort(A)

% idxを使ってA行列の2番目に大きい数字を取り出す
A( idx(2) )

image.png

(:)

is 何

行列の書き下し。

A = [1 2;
    3 4];

B = A(:)

image.png

これどこで使うんだろう?と思ってたが、表記ゆれ対策を力業で実装にて行列の全要素加算に使っていてなるほど!と唸りました。

A = [1 2;
    3 4];

B = sum( A(:) )

image.png

これって組み込み関数にないのか?:thinking: と思ったら2018bからsum(A,'all')で可能になったとのこと。
https://jp.mathworks.com/help/matlab/ref/sum.html#mw_e734edf5-eab5-4791-be5c-355b3db91052

うーん、可読性はsum(A,'all')に軍配が、クールさはsum(A(:))に軍配があるかな。

[]

is 何

空の配列を定義。
何に使うかというと、forループ内でデータを横に横に(もしく縦に縦に)つなげる際の初期化に使うと便利。

A = [];
for i = 1:3
    A = [A i];
end

image.png

ただしこのやり方は処理速度を劣化させる。処理速度を速めるには配列サイズをあらかじめ確定させる必要がある…が、面倒なので急いでいる時は[]を使ってしまう悪い癖。

A = zeros(1, 3);
for i = 1:3
    A(i) = i;
end

[]を使った場合は実行時間0.07秒、配列サイズ確定の場合は実行時間0.02秒でした。

gcf

Get Current Figureの略。現在アクティブになっているfigureのハンドルを取得する。
同様にgcaはGet Current Axesの略なのでセットで覚えましょう。

clc

Clear Command Windowの略。コマンドウィンドウを一旦消す。
clc (コマンドウィンドウ消す)
clear all (ワークスペース消す)
close all (Figure閉じる)
をワンセットで使っている人も多いと思う。

小ネタとして、最近のMATLABだとお気に入りコマンドを作成登録できる。
上記3つのセットを登録しておくと楽ができます。
image.png

image.png

image.png

まとめ

今後:thinking:→😇となるようなことがあれば追記していきます。
また他にも:thinking:→😇となった経験をお持ちの方はコメントや編集リクエストにてお寄せ下さい。

94
64
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
64