0

Octave でプログラムを書いているときに問題が発生しました。Gauss-Legandre Quadrature を実装し、Gauss-Legandre 関数にいくつかの引数を渡し、関数をセル キューブに統合するように渡しました。時間。私はこのコードを持っています:

    for weight=1:length(w)
        temp=1; 
        for fun=1:length(c)
            %liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
            f=c{fun};
            nargin(func2str(c{fun}))
            if (nargin (func2str(c{fun})) == 1)
                disp('a');
                temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
            else
                    (b-a)/2 * x(weight) + (a+b)/2;  
                temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
            end
        end
        %mnozenie wyniku przez odpowiedni wspolczynnik - wage
        temp*=w(weight);
        result+=temp;
    end

セル配列には、統合したい関数への関数ハンドラがあります。関数が取る引数の数に応じて、関数に対して2つの異なる呼び出しを使用したいと考えています。セル配列に、Octave 作業ディレクトリと同じディレクトリにある .m ファイルに書き込まれた関数へのハンドラがある場合、すべて正常に動作しますが、Octave 実行時に関数を定義すると、たとえば次のようになります。

    function result=a(x)
    result=x*x
    end

タイプ

    c{1}=@a

このセル配列を関数 Kwadratury に渡します nargin のエラーがあります

    error: nargin: invalid function
    error: called from:

それはなぜですか、どうすれば解決できるので、.mファイルだけでなくOctaveでも関数を定義できます。

4

1 に答える 1

0

解決策があると思いますが、これはOctave固有であり、MATLABにほとんど慣れているため、マイレージは異なる場合があります。

nargin文字列引数を指定して関数を呼び出します。これは、narginその関数を解決し、引数の数を確認する必要があることを意味します。関数をインラインで宣言すると、その関数はそのスコープ(つまり、基本スコープ)内で定義されるため、関数名の解決はどの関数内からも機能しません(または、組み込み関数に解決される可能性があります。より悪い行動)。

最善の解決策は、nargin(c{fun})の代わりにを使用することですnargin(func2str(c{fun}))。そうすれば、実際の関数ハンドルを渡すことができ、関数名を実際の関数に解決する必要がないため、あいまいさが生じる可能性がありません。

一般に、文字列を使用して関数を渡すことはお勧めしません。MATLABに関数ハンドルが含まれているので、コード(または静的コード分析ツール)を読んでいる人なら誰でも、関数を操作していることを理解できます。文字列を使用すると、すべてがあいまいになります。文字列'a'は関数を参照しますaか、それともアルファベットの最初の文字を参照しますか?

インライン関数の使用に関しては、Octaveがこれをサポートしているかどうかはわかりませんが、関数が非常に単純な場合は、例のような無名関数をで定義する方が簡単a = @(x)(x*x);です。これはMATLABでサポートされている構造であるため、コードを他の環境に移植しやすくなります(MATLABと互換性を持たせるには、に置き換える必要があります)X *= AX = X * A;

編集: 別の可能性は、複数のパラメーターを持つフォームが機能するかどうかを試して、必要に応じて1つのパラメーターフォームにフォールバックすることです。

try
   (b-a)/2 * x(weight) + (a+b)/2;  
   temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
catch ME
   try
       disp('a');
       temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
   catch ME
   end
end

ME返されたエラーが、他のエラーを通過させるために間違った数の引数が使用されていることを実際に示しているかどうかを確認することをお勧めします。これは醜い回避策であることは認めますが、Octaveは明らかにの関数ハンドルをサポートしていないためnargin、インライン関数に必要なものを取得する唯一の方法である可能性があります。

于 2011-11-20T21:53:07.883 に答える