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® 结果不同。请参阅按绝对值对复数值排序的函数

  • 对于要求按绝对值对复数输入排序的函数,具有零值虚部的复数输入必须按绝对值排序。这些函数包括 ismemberunionintersectsetdiffsetxor

按绝对值对复数值排序的函数

按绝对值对复数值排序的函数包括 sortissortedsortrowsmedianminmax。这些函数按绝对值对复数排序,即使虚部为零也是如此。一般来说,按绝对值排序的结果不同于按实部排序的结果。因此,如果这些函数的输入在生成的代码中是具有零值虚部的复数,而在 MATLAB 中是实数,则生成的代码会产生与 MATLAB 不同的结果。在以下示例中,sort 的输入在 MATLAB 中是实数,而在生成的代码中是具有零值虚部的复数:

  •  您将实数输入传递给生成的使用复数输入的函数

  •  sort 的输入是在生成的代码中返回复数的函数的输出

生成的复数参数 MEX 函数的输入和输出

对于由 codegen 命令、fiaccel (Fixed-Point Designer) 命令或 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

含复数操作数的表达式的结果

一般来说,包含一个或多个复数操作数的表达式会在生成的代码中产生复数结果,即使结果的值为零也是如此。以如下代码行为例:

z = x + y; 

假设在运行时,x 的值为 2 + 3iy 的值为 2 - 3i。在 MATLAB 中,此代码产生实数结果 z = 4。在代码生成中,xy 的类型是已知的,但其值是未知的。由于此表达式的两个操作数中至少有一个是复数,因此将 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。即使实部或虚部为零,也会执行完整的计算。

  • 实数值乘以复数值 c(a + bi) 定义为 ca + cbi