MATLAB ユーザーコミュニティー

MATLAB & Simulink ユーザーコミュニティー向け日本語ブログ

お気に入りR2019b新機能 – 入力引数の検証

Posted by Jiro Doke,

こんにちは、道家です。朝晩の気温もだいぶ下がり、秋という感じになってきましたね。

少し前になりましたが、R2019bがリリースされました。社員であるというのもありますが、 私はだいたい新バージョンがリリースされましたらすぐにインストールし、まず リリースノート に目を通します。今回も沢山新しい機能が追加されていますが、その中で私が一番気に入って いる新機能を紹介します。

Function Argument Validation

それが Function Argument Validation。実は最新機能過ぎてまだ日本語のドキュメントが追いついていませんが、 これは関数入力の検証機能です。MATLAB ユーザーならご存知かと思いますが、MATLABは 変数にうるさくありません。C のように型やサイズを事前に定義する必要はありませんし、 いつでも自由自在に変更することもできます。その自由度が良いと言える一方、いろいろ注意 しなければならないこともあります。例えば、関数を定義したときの入力引数には何も制約が ないので、期待する入力が渡されたかのチェック(Validation)を関数の中で行う必要が あります。

例を見てみましょう。次の様な関数を作成するとします。

function special_plot(Y, linespec, varargin)

仕様は以下となります。

help special_plot
  special_plot(Y) はデータベクトル Y の離散プロットを作成します。
  special_plot(Y, LINESPEC) は LINESPEC をもとにプロットをカスタマイズします。
      LINESPEC の詳細は plot 関数を参照してください。
  special_plot(___, PARAM1, VAL1, ...) はオプションのパラメーターを指定できます。
 
  パラメーター: [] は既定値
     showMean     - 平均値をグラフに表示するか - [true] | false
     showMax      - 最大値をグラフに表示するか - true | [false]
     showMin      - 最小値をグラフに表示するか - true | [false]
     titleString  - タイトルの文字列      - char の文字列 ['Special Plot']
     ylabelString - Yラベルの文字列      - char の文字列 ['値']

データベクトルの離散プロットを作成します。

data = rand(1,20);
special_plot(data)

オプションで離散プロットの属性を変えたり、最大値を表示したり、Yラベルの表示を変えたりできます。

special_plot(data,'*','showMax',true,'ylabelString','値段')

描画の部分はこの様なコードとなります。

hLines = stem(Y,linespec);
legendString = {'データ'};
hold on
if showMean  % 平均値をグラフに追加
    h = plot([1 length(Y)],[mean(Y) mean(Y)],'r--','LineWidth',2);
    hLines = [hLines h];
    legendString = [legendString {'平均'}];
end
if showMax  % 最大値をグラフに追加
    h = plot([1 length(Y)],[max(Y) max(Y)],'k:','LineWidth',2);
    hLines = [hLines h];
    legendString = [legendString {'最大値'}];
end
if showMin  % 最小値をグラフに追加
    h = plot([1 length(Y)],[min(Y) min(Y)],'k-.','LineWidth',2);
    hLines = [hLines h];
    legendString = [legendString {'最小値'}];
end
hold off
title(titleString)
ylabel(ylabelString)
legend(hLines,legendString)

入力検証

特別な配慮が必要なのは入力引数の検証です。特にオプション入力などがあると、引数を 確認し、適切な既定値なども設定する必要がでてきます。従来の入力検証ですと以下のように なります。

% 少なくとも1つ入力があるか?
narginchk(1,inf)

% Y は double の行ベクトルか?
validateattributes(Y,{'double'},{'row'},1)

% 入力引数が1つの場合は LINESPEC はデフォルト
if nargin == 1
    linespec = ' ';
end
validateattributes(linespec,{'char'},{'row'},2)

% LINESPECがパラメーターの一つである場合、オプション定義としてみなす
if ismember(lower(linespec),{'showmean','showmax','showmin','titlestring','ylabelstring'})
    opts = [{linespec}, varargin];
    linespec = ' ';
else
    opts = varargin;
end

% 既定値の設定
showMean = true;
showMax = false;
showMin = false;
titleString = 'Special Plot';
ylabelString = '値';

% オプション入力の処理
if ~isempty(opts)
    if mod(numel(opts),2) ~= 0 % ペアで入力されているか確認
        error('オプション入力は Parameter-Value ペアでなければなりません')
    end
    for id = 1:2:numel(opts)  % ペアごとに処理
        param = validatestring(opts{id},{'showMean','showMax','showMin','titleString','ylabelString'},id+2);
        value = opts{id+1};
        switch param  % パラメーター名に合わせて適切な変数を設定
            case 'showMean'
                validateattributes(value,{'logical'},{'scalar'},id+3)
                showMean = value;
            case 'showMax'
                validateattributes(value,{'logical'},{'scalar'},id+3)
                showMax = value;
            case 'showMin'
                validateattributes(value,{'logical'},{'scalar'},id+3)
                showMin = value;
            case 'titleString'
                validateattributes(value,{'char'},{'row'},id+3)
                titleString = value;
            case 'ylabelString'
                validateattributes(value,{'char'},{'row'},id+3)
                ylabelString = value;
        end
    end
end

R2019b では arguments ブロックを使用

R2019b で新しく加わった arguments ブロックを使用すると入力引数に型、サイズ、など の制約条件を指定することができます。またオプションのパラメーターには既定値を設定する ことができます。

まず関数シグネチャを以下のように変えます。

function special_plot(Y, linespec, opts)

その後、直後に arguments ブロックを追加します。

arguments
    Y (1,:) double
    linespec (1,:) char = ' '
    opts.showMean (1,1) logical = true
    opts.showMax (1,1) logical = false
    opts.showMin (1,1) logical = false
    opts.titleString (1,:) char = 'Special Plot'
    opts.ylabelString (1,:) char = '値'
end

以上です!描画のコードは以前とほぼ同じです(オプションの変数名を showMean -> opts.showMean のように変更する必要があります)。

皆さんが気に入った新機能は?

R2019b を既に試された方、お気に入りの新機能を教えてください。もしくは、最新機能でなくても いいので、MATLAB の一押し機能がありましたら教えてください。


Get the MATLAB code

Published with MATLAB® R2019b

309 views (last 30 days)  | |

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.