Main Content

複素数データのコード生成

複素数変数を定義する際の制限事項

コード生成では、代入時に変数の実数/複素数を設定しなければなりません。複素数定数を変数に代入するか、関数 complex を使用します。次に例を示します。

x = 5 + 6i; % x is a complex number by assignment.
y = complex(5,6); % y is the complex number 5 + 6i.

代入後に変数の実数/複素数を変更することはできません。次の関数のコード生成は、x(k) = 3 + 4i によって x の実数/複素数が変更されるため失敗します。

function x = test1( )
x = zeros(3,3); % x is real
for k = 1:numel(x)
    x(k) = 3 + 4i;
end
end

この問題を解決するには、複素数の定数を x に代入します。

function x = test1( )
x = zeros(3,3)+ 0i; %x is complex
for k = 1:numel(x)
    x(k) = 3 + 4i;
end
end

ゼロ値の虚数部をもつ複素数データのコード生成

コード生成では、すべてのゼロ値の虚数部をもつ複素数データは複素数のままです。データは実数にはなりません。この動作は次の影響があります。

  • 場合によっては、複素数データを絶対値で並べ替える関数の結果が MATLAB® の結果と異なる可能性があります。複素数値を絶対値で並べ替える関数を参照してください。

  • 複素数の入力が絶対値で並べ替えられている必要がある関数については、ゼロ値の虚数部をもつ複素数の入力を絶対値で並べ替えなければなりません。このような関数には ismemberunionintersectsetdiff および setxor があります。

複素数値を絶対値で並べ替える関数

複素数値を絶対値で並べ替える関数には、sortissortedsortrowsmedianminmax などがあります。これらの関数は、虚数部がゼロの場合でも複素数を絶対値で並べ替えます。一般に絶対値の並べ替えは、実数部の並べ替えとは異なる結果を生じます。このため、これらの関数の入力が、生成コード内ではゼロ値の虚数部をもつ複素数であるが、MATLAB では実数の場合、生成されたコードは MATLAB とは異なる結果を生じる場合があります。次の例では sort の入力は MATLAB では実数ですが、生成されたコードではゼロ値の虚数部をもつ複素数です。

  •  複素数入力用に生成された関数に実数入力を渡す

  •  生成されたコードで sort の入力が複素数を返す関数からの出力

複素数の引数用に生成された MEX 関数の入力と出力

codegen (MATLAB Coder) コマンド、fiaccel コマンド、または MATLAB Coder™ アプリによって生成された MEX 関数は、次のようになります。

  • 複素数入力用に MEX 関数を生成すると仮定します。実数入力で MEX 関数を呼び出す場合、MEX 関数は実数の入力をゼロ値の虚数部をもつ複素数値に変換します。

  • MEX 関数がすべてゼロ値の虚数部をもつ複素数値を返す場合、MEX 関数は実数値として MATLAB ワークスペースに値を返します。たとえば、以下の関数を考えます。

    function y = foo()
        y = 1 + 0i;   % y is complex with imaginary part equal to zero
    end     

    foo の MEX 関数を生成してコード生成レポートを表示すると、y が複素数なのがわかります。

    codegen foo -report

    This image shows the properties for y in the code generation report. The report shows that y is a complex In the Class column.

    この MEX 関数を実行した場合、MATLAB ワークスペースを見ると、foo_mex の結果は実数値 1 です。

    z = foo_mex 
    ans =
    
         1

複素数オペランドをもつ式の結果

一般的に、1 つ以上の複素数オペランドを含む式は、結果の値が 0 の場合でも、生成コードで複素数の結果を生成します。次のコード行について考えます。

z = x + y; 

実行時に x が値 2 + 3i をもち、y が値 2 - 3i をもつと仮定します。MATLAB では、このコードは実数の結果 z = 4 を出力します。コード生成中は、xy の型は既知ですが、値は既知ではありません。この式のオペランドは 1 つあるいは両方が複素数のため、z は複素変数として定義され、実数部と虚数部を保持する必要があります。生成されたコードでは、z は複素数の結果 4 + 0i になり、MATLAB コードのように 4 にはなりません。

この動作には以下の例外があります。

  • 複素数の結果の虚数部がゼロの場合、MEX 関数は実数値として結果を MATLAB ワークスペースに返します。複素数の引数用に生成された MEX 関数の入力と出力を参照してください。

  • 引数の虚数部がゼロの場合、外部関数の複素数引数は実数です。

    function y = foo()
        coder.extrinsic('sqrt')
        x = 1 + 0i;   % x is complex
        y = sqrt(x);  % x is real, y is real
    end     
  • 複素数の引数を受け取り実数の結果を生成する関数は、実数値を返します。

    y = real(x); % y is the real part of the complex number x.
    y = imag(x); % y is the real-valued imaginary part of x.
    y = isreal(x); % y is false (0) for a complex number x.
    
  • 実数の引数を受け取り複素数の結果を生成する関数は複素数値を返します。

    z = complex(x,y); % z is a complex number for a real x and y.
    

非有限値を使用する複素数の乗算の結果

複素数の乗算のオペランドに非有限値が含まれている場合、生成されるコードでは MATLAB で生成される結果とは異なる結果が生じる可能性があります。この違いは、コード生成における複素数の乗算の定義方法により発生します。コード生成の場合、次のようになります。

  • 複素数値と複素数値の乗算 (a + bi) (c + di)(ac - bd) + (ad + bc)i と定義されます。実数または虚数部が 0 である場合でも、完全な計算が実行されます。

  • 実数値と複素数値の乗算 c(a + bi)ca + cbi と定義されます。