使用isreal的结果不一致

Dav*_*ave 6 arrays matlab vectorization complex-numbers elementwise-operations

举个简单的例子:

a = [1 2i];

x = zeros(1,length(a));
for n=1:length(a)
    x(n) = isreal(a(n));
end
Run Code Online (Sandbox Code Playgroud)

为了对代码进行矢量化,我尝试了:

y = arrayfun(@isreal,a);
Run Code Online (Sandbox Code Playgroud)

但结果不一样:

x =
     1     0
y =
     0     0
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

gno*_*ice 8

这肯定是一个错误,但这是一个解决方法:

>> y = arrayfun(@(x) isreal(x(1)),a)

ans =

     1     0
Run Code Online (Sandbox Code Playgroud)

为什么这样做?我不完全确定,但看起来当你调用ISREAL 之前对变量执行索引操作时,如果虚数组件为零,它将从数组元素中删除"complex"属性.在命令窗口中尝试此操作:

>> a = [1 2i];         %# A complex array
>> b = a(1);           %# Indexing element 1 removes the complex attribute...
>> c = complex(a(1));  %# ...but we can put that attribute back
>> whos
  Name       Size            Bytes  Class      Attributes

  a          1x2                32  double     complex   
  b          1x1                 8  double                  %# Not complex
  c          1x1                16  double     complex      %# Still complex
Run Code Online (Sandbox Code Playgroud)

显然,ARRAYFUN必须在内部维护它传递给ISREAL的数组元素的"复杂"属性,因此即使虚数组件为零,也将它们视为复数.

  • 顺便说一下,这个bug没有出现在GNU Octave中. (4认同)

Amr*_*mro 8

知道MATLAB分别存储矩阵的实部/复杂部分可能会有所帮助.请尝试以下方法:

>> format debug
>> a = [1 2i];
>> disp(a)

Structure address = 17bbc5b0 
m = 1
n = 2
pr = 1c6f18a0 
pi = 1c6f0420
   1.0000                  0 + 2.0000i
Run Code Online (Sandbox Code Playgroud)

where pr指向包含所有值的实部的内存块的pi指针,以及指向矩阵中所有值的复杂部分的指针.由于所有元素都存储在一起,因此在这种情况下它们都具有复杂的部分.

现在比较这两种方法:

>> arrayfun(@(x)disp(x),a)

Structure address = 17bbcff8 
m = 1
n = 1
pr = 1bb8a8d0 
pi = 1bb874d0
     1

Structure address = 17c19aa8 
m = 1
n = 1
pr = 1c17b5d0 
pi = 1c176470
        0 + 2.0000i
Run Code Online (Sandbox Code Playgroud)

>> for n=1:2, disp(a(n)), end

Structure address = 17bbc930 
m = 1
n = 1
pr = 1bb874d0 
pi = 0
     1

Structure address = 17bbd180 
m = 1
n = 1
pr = 1bb874d0 
pi = 1bb88310
        0 + 2.0000i
Run Code Online (Sandbox Code Playgroud)

所以当你a(1)在for循环中访问时,似乎返回的值(在ans变量中)具有零复数部分(null pi),因此被认为是真实的.

另一方面,ARRAYFUN似乎直接访问矩阵的值(不在ANS变量中返回它们),因此它可以访问非空的指针prpi指针,因此所有元素都被认为是非实数的.

请记住这只是我的解释,我可能会弄错...

  • 哇,我不知道这个调试选项 (2认同)