225

私がEEで学士号を取得するために勉強していたとき、MATLABでは、ワンライナーであっても、各関数を独自のファイルで定義する必要がありました。

私は現在大学院の学位を取得するために勉強しており、MATLABでプロジェクトを作成する必要があります。これは、MATLABの新しいバージョンの要件ですか?

1つのファイルに複数の関数を入れることができる場合、これに制限はありますか?たとえば、ファイル内のすべての関数にファイルの外部からアクセスできますか、それともファイルと同じ名前の関数のみにアクセスできますか?

注:MATLABリリースR2007bを使用しています。

4

9 に答える 9

278

mファイルの最初の関数(つまり、main関数)は、そのmファイルが呼び出されたときに呼び出されます。main関数がm-fileと同じ名前である必要はありませんが、わかりやすくするために同じ名前にする必要があります。関数とファイル名が異なる場合は、ファイル名を使用してメイン関数を呼び出す必要があります。

ローカル関数(または古い用語では「サブ関数」)と呼ばれるmファイル内の後続のすべての関数は、そのmファイル内のメイン関数と他のローカル関数によってのみ呼び出すことができます。他のmファイルの関数はそれらを呼び出すことができません。R2016b以降、ローカル関数をスクリプトに追加することもできますが、スコープの動作は同じです(つまり、スクリプト内からのみ呼び出すことができます)。

さらに、他の関数内で関数を宣言することもできます。これらは入れ子関数と呼ばれ、入れ子関数内からのみ呼び出すことができます。また、ネストされている関数の変数にアクセスできるため、操作が少し難しいですが、非常に便利です。

思考のためのより多くの食べ物...

SCFrenchJonas(R2013b以降、関数によって容易になります)からの回答で述べられているように、出力引数として関数ハンドルを渡すなど、上記で概説した通常の関数スコープ動作を回避する方法がいくつかあります。ただし、関数やファイルを整理するためのより良いオプションがある可能性があるため、このようなトリックに頼る習慣をつけることはお勧めしません。localfunctions

たとえば、ローカル関数、、、およびとともに、mファイルにメイン関数があるとしAます。ここで、他に2つの関連する関数があり、それぞれm-filesと、に、、、、およびを呼び出せるようにしたいとします。ここにあなたが持っているいくつかのオプションがあります:A.mDEFBCB.mC.mDEF

  • 、、、およびそれぞれを独自の個別のmファイルに入れて、他の関数がそれらを呼び出せるようにしますD。欠点は、これらの関数の範囲が広く、、、、およびだけに制限されていないことですが、利点は、これが非常に単純であることです。EFABC

  • 、、をローカル関数として使用し、関数ハンドルを返すだけのメイン関数としてdefineMyFunctionsmファイルを作成します(Jonasの例のように)。これにより、、、を同じファイルに保持できますが、呼び出すことができるすべての関数がそれらを呼び出すことができるため、これらの関数のスコープに関しては何もしません。次に、関数ハンドルを引数として渡して、必要な場所に確実に配置できるようにする必要があります。DEFDEFdefineMyFunctions

  • DEおよびFをローカル関数としてコピーB.mします。C.mこれにより、使用範囲が、、、およびに制限されますがA、同じコードの3つのコピーが異なる場所にあるため、コードの更新と保守は悪夢になります。BC

  • プライベート関数を使用してください!、、が同じディレクトリにある場合は、と呼ばれるサブディレクトリを作成しABそこにそれぞれ個別のmファイルとして配置できます。これによりスコープが制限されるため、すぐ上のディレクトリ内の関数(つまり、、、および)からのみ呼び出すことができ、同じ場所にまとめられます(ただし、mファイルは異なります)。CprivateDEFABC

    myDirectory/
        A.m
        B.m
        C.m
        private/
            D.m
            E.m
            F.m
    

これはすべてあなたの質問の範囲外であり、おそらくあなたが必要とするよりも詳細ですが、すべてのmファイルを整理するというより一般的な懸念に触れるのは良いことだと思いました。;)

于 2010-08-25T20:28:24.767 に答える
81

一般に、あなたの質問に対する答えはノーです。ファイルごとに複数の外部から見える関数を定義することはできません。ただし、関数ハンドルをローカル関数に戻すことができます。そのための便利な方法は、それらを構造体のフィールドにすることです。次に例を示します。

function funs = makefuns
  funs.fun1=@fun1;
  funs.fun2=@fun2;
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

そして、これがどのように使用できるかです:

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1
于 2010-08-26T01:15:12.287 に答える
38

1つのファイルに複数の個別にアクセス可能な関数を含める唯一の方法は、オブジェクト指向プログラミングを使用して静的メソッドを定義することです。などの機能にアクセスします。myClass.static1()myClass.static2()

OOP機能はR2008a以降正式にサポートされているだけなので、文書化されていない古いOOP構文を使用したい場合を除いて、@gnoviceで説明されているように答えはノーです。

編集

外部からアクセス可能なファイル内の複数の関数を定義するもう1つの方法は、複数の関数ハンドルを返す関数を作成することです。つまり、定義関数をとして呼び出し、その後でなど[fun1,fun2,fun3]=defineMyFunctionsを使用できます。out1=fun1(inputs)

于 2010-08-25T20:37:33.227 に答える
24

私はSCFrenchの答えが本当に好きです-assignin関数を使用して関数をワークスペースに直接インポートするように簡単に変更できることを指摘したいと思います。(このようにすることで、Pythonの「yからxをインポートする」方法の多くを思い出します)

function message = makefuns
  assignin('base','fun1',@fun1);
  assignin('base','fun2',@fun2);
  message='Done importing functions to workspace';
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

そして、このように使用されます:

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1
于 2013-06-01T06:59:54.213 に答える
12

SCFrenchの回答と同じ線に沿っていますが、よりC#スタイルのスピンがあります。

私は複数の静的メソッドを含むクラスを作成します(そしてしばしばそうします)。例えば:

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end

メソッドは静的であるため、クラスをインスタンス化する必要はありません。次のように関数を呼び出します。

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     
于 2014-07-31T09:35:53.840 に答える
4

Octaveを使用して1つの.mファイルに複数の関数を定義し、そのファイルの関数を使用する必要がある.mファイル内からコマンドを使用します。

source("mycode.m");

これがMatlabで利用できるかどうかはわかりません。

octave:8> help source
'source' is a built-in function

 -- Built-in Function:  source (FILE)
     Parse and execute the contents of FILE.  This is equivalent to
     executing commands from a script file, but without requiring the
     file to be named `FILE.m'.
于 2013-07-13T01:14:45.347 に答える
3

次のようなメイン関数と一緒に、関数を1つのメインファイルにグループ化することもできます。

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

% paste your subfunctions below ....
function str=subfun1
str='hello'

次に、subfun1を呼び出すと、次のようになります。str = main('subfun1')

于 2013-06-03T18:46:20.833 に答える
0

R2017bの時点では、これは公式には不可能です。関連するドキュメントには次のように記載されています。

プログラムファイルには、複数の機能を含めることができます。ファイルに関数定義のみが含まれている場合、最初の関数がメイン関数であり、MATLABがファイル名に関連付ける関数です。メイン関数またはスクリプトコードに続く関数は、ローカル関数と呼ばれます。ローカル関数はファイル内でのみ使用できます。

ただし、他の回答で提案されている回避策は、同様のことを実現できます。

于 2017-10-23T10:19:48.727 に答える
-2

私はSCFRenchとオクターブのRuHashaを試してまし

そして最後にそれは動作します: しかし私はいくつかの変更を行いました

function message = makefuns
    assignin('base','fun1', @fun1);   % Ru Hasha
    assignin('base', 'fun2', @fun2);  % Ru Hasha
    message.fun1=@fun1;               % SCFrench
    message.fun2=@fun2;               % SCFrench
end

function y=fun1(x)
    y=x;
end

function z=fun2
    z=1;
end

他の「m」ファイルで呼び出すことができます:

printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());

アップデート:

+72も+20もオクターブで機能しなかったので答えを追加しました。私が書いたものは完璧に機能します(そして先週の金曜日に後で投稿を書いたときにテストしました)。

于 2018-11-23T15:09:39.617 に答える