pythonだとデフォルト引数を簡単に設定できます(参考)が,MATLABには言語的に用意されていないため,自分で書く必要があります。
narginを使う方法
nargin
で入力された引数の個数を判定して,デフォルト値を与えます。
mySum.m
function ret = mySum(x1, x2, x3)
switch nargin
case 0
x1 = 0;
x2 = 0;
x3 = 0;
case 1
x2 = 0;
x3 = 0;
case 2
x3 = 0;
end
ret = x1 + x2 + x3;
end
existを使う方法
exist
で引数が定義されているかチェックして,個別にデフォルト値を与えます。
mySum2.m
function ret = mySum2(x1, x2, x3)
if ~exist('x1', 'var') x1 = 0; end
if ~exist('x2', 'var') x2 = 0; end
if ~exist('x3', 'var') x3 = 0; end
ret = x1 + x2 + x3;
end
テスト
test.m
global x3
x1 = 1;
x2 = 2;
x3 = 3;
ans(1) = mySum(); % 0
ans(2) = mySum(x1); % 1
ans(3) = mySum(x1,x2); % 3
ans(4) = mySum(x1,x2,x3); % 6
ans(5) = mySum2(); % 0
ans(6) = mySum2(x1); % 1
ans(7) = mySum2(x1,x2); % 3
ans(8) = mySum2(x1,x2,x3); % 6
disp(ans)
Matlab R2018a で確認。
実行結果
>> test
0 1 3 6 0 1 3 6
コメント
- 昔から
nargin
を使う方法で書いていましたが,matlabはswitch構文で自動的にbreakされるため,上記の例のように多重定義する羽目になり嫌でした。特に引数が増えると,縦に間延びしてバグが出やすくなります。また,if文でnarginの大小比較を行ってデフォルト値を与えることもできますが,可読性が悪くなるのでお勧めしません。 -
exist
を使った場合,global変数関係でバグが出そうだと思ってましたが,上記テストでは問題ありませんでした。これはなぜかというと,matlabは関数内でグローバル変数を使う場合は,関数内でもグローバル宣言が必要な仕様になっているからです(参考)。これからはexist
でデフォルト引数を管理しようと思っています。 - しばらく悩んだが,いい説明用の関数が思いつかなかった…。念のため言っておきますが,上記の
mySum.m
はあくまで説明用です。通常は,vararginをつかって,任意個数の引数に対応するよう書いてくださいネ。