MATLABで、スクリプトと関数定義を同じファイルに含めることはできますか?


82

関数がf()ありmy_file.m、それをスクリプトであるで使用したいとします。

  1. 関数をで定義することは可能my_file.mですか?
  2. そうでない場合は、で定義されていると仮定しf.mます。どうすればそれを呼び出すことができmy_file.mますか?

オンラインドキュメントを読みましたが、これを行うための最良の方法が明確ではありませんでした。


4
Octaveのスクリプトに関数を入れることができることに注意してください。
ジェレマイアウィルコック

2
コードを整理する方法については、この回答を検討してくださいstackoverflow.com/a/3569946/18775
Anton Daneyko 2013


4
本当の質問は、このばかげたバグを修正するためにMathworksの誰に文句を言うのかということです。
ドライダム2015年

3
MATLAB 2016b以降、関数はスクリプトで定義できます。なぜ彼らがこのかなり基本的な機能を追加するのに32年待ったのかわかりません。
onewhaleid 2017年

回答:


49

リリースR2016b以降、次のようにスクリプトローカル関数を含めることができます。

data = 1:10;            % A vector of data
squaredData = f(data);  % Invoke the local function

function y = f(x)
  y = x.^2;
end

リリースR2016bより前は、MATLABスクリプト内で定義できる関数のタイプは無名関数のみでした。例えば:

data = 1:10;            % A vector of data
f = @(x) x.^2;          % An anonymous function
squaredData = f(data);  % Invoke the anonymous function

匿名関数は単一の式で定義する必要があるため、単純な操作に適していることに注意してください。より複雑な関数の場合は、独自のファイルで定義し、MATLABパスのどこかに配置してスクリプトにアクセスできるようにしてから、他の関数と同じようにスクリプトから呼び出す必要があります。


37

この制限を回避する方法は、スクリプトを引数をとらない関数に変換することです(グローバル名前空間の変数が必要な場合は、関数に明示的に渡すか、「evalin」を使用して取得します)。

次に、「スクリプト」で必要なすべての追加機能を定義できます。これはハックですが、重要な機能がいくつか必要な場合には、非常に強力であることがわかりました。

編集:これは単純な例です。これはすべて、単一のファイルに含めることができます。

function [] = myScriptAsAFunction()
   img = randn(200);
   img = smooth(img);
   figure(1);
   imagesc(img);
   axis image;
   colorbar;
end

function simg = smooth(img)
    simg = img / 5;
end

6
+1、すべてがはっきりと見えると、本当にイライラします。すべて閉じる; matlabスクリプトの上部にあります。非常に多くの変数とプロットが浮かんでいる場合、それらを追跡することができず、十分な関数を使用していません。
Bi Rico

1
この「ハック」のサンプル実装を含めていただけますか?これがどのように機能するのか理解できないようです。
ジェームステイラー

1
このアプローチの1つの問題は、関数が終了したときに変数がワークスペースに入らないことです。スクリプトの終了時にこれらの変数を再生/検索/使用する場合、これは問題になる可能性があります。
chessofnerd 2015

1
@chessofnerd問題が発生した場合は、関数出力で変数を返すか、assigninを使用します。
ジョン

1
@ジョン、私は個人的に、すべての変数を自分で作業スペースに表示するのではなく、個別に返す必要があるのは少し面倒だと感じています。そうは言っても、私は聞いたことがありませんでしたassignin。それは私がもっと使っているかもしれないすてきな機能です!
chessofnerd 2015

19

あなたはこのようなことをすることができます(あなたのファイルが名前を付けられていると仮定してmy_file.m):

function my_file
   %script here
end

function out = f(in)
   %function here
end

実行ボタンをクリックすると、関数my_fileがデフォルトで実行されます。


2
これはジョンの答えとは違うのですか?
sancho.s ReinstateMonicaCellio 2016

7

1)スクリプト内に関数をネストすることはできません。

2)fmがパス上または現在のディレクトリにあることを確認し、他の関数と同じように呼び出すことができます。


@Oneirosによって提案された内容に従うと、スクリプト内に関数をネストできます。fスクリプト内(彼の例)から関数(彼の例)を呼び出すこともできますmy_file
marcelocra 2014年

7

R2016b以降、スクリプト内でローカル関数を定義できます。

x = 1;
y = add1(x);

function z = add1(x)
    z = x + 1;
end

3

私はジョンによるソリューションを実装しまし、そしてそれが役に立つと思いました。ただし、いくつかの注意点があります(Octaveでは、Matlabも同様に動作する可能性があります)。

  1. clear all補助関数を使用する前にメイン関数内のコードに含まれている場合、それは機能しません。ファイル内でtest3.m、コメント/コメント解除clear allすると、コードが機能する/機能しなくなります。

    function [] = test3()
      %clear all
      a = myfunc( 1 );
      a
    endfunction;
    
    %---------------------------------
    % Auxiliary functions
    
    function retval = myfunc( a )
      retval = 2 * a;
    endfunction;
    

    スクリプトを実行すると、関数外のコードが実行され(この場合、そのようなコードはありません)、定義された関数(この場合、test3およびmyfunc)がワークスペースに追加される最初のパスがあるようです。2番目のパスはmain関数を実行しますがmyfuncclear allがアクティブであるかどうかは検出されません。

  2. chessofnerdが指摘しているように、すぐに使用できるmain関数の変数はワークスペースに移動しません。


2

サンプルファイルには多くの関数を含めることができます。ただし、ファイルを実行すると、最初の1つだけがメイン関数として機能できます。その他は、このファイルでのみ使用できます。状況によっては、大きな関数を定義したい場合があります。それをより小さな関数に分割し、その下に定義することができます。

しかし、答えを見つける最も簡単な方法は試してみることです〜

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.