使用 isreal 结果不一致

发布于 2024-09-17 11:09:34 字数 297 浏览 4 评论 0原文

举这个简单的例子:

a = [1 2i];

x = zeros(1,length(a));
for n=1:length(a)
    x(n) = isreal(a(n));
end

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

y = arrayfun(@isreal,a);

但结果并不相同:

x =
     1     0
y =
     0     0

我做错了什么?

Take this simple example:

a = [1 2i];

x = zeros(1,length(a));
for n=1:length(a)
    x(n) = isreal(a(n));
end

In an attempt to vectorize the code, I tried:

y = arrayfun(@isreal,a);

But the results are not the same:

x =
     1     0
y =
     0     0

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾听心声的旋律 2024-09-24 11:09:34

这当然看起来是一个错误,但这里有一个解决方法:

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

ans =

     1     0

为什么这有效?我不太确定,但似乎当您在调用 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

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

This certainly appears to be a bug, but here's a workaround:

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

ans =

     1     0

Why does this work? I'm not totally sure, but it appears that when you perform an indexing operation on the variable before calling ISREAL it removes the "complex" attribute from the array element if the imaginary component is zero. Try this in the Command Window:

>> 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

Apparently, ARRAYFUN must internally maintain the "complex" attribute of the array elements it passes to ISREAL, thus treating them all as being complex numbers even if the imaginary component is zero.

执着的年纪 2024-09-24 11:09:34

了解 MATLAB 分别存储矩阵的实数/复数部分可能会有所帮助。请尝试以下操作:

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

Structure address = 17bbc5b0 
m = 1
n = 2
pr = 1c6f18a0 
pi = 1c6f0420
   1.0000                  0 + 2.0000i

其中 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

>> 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

因此,当您在 for 循环中访问 a(1) 时,返回的值(在 ans 变量中)的复数似乎为零-part (null pi),因此被认为是真实的。

另一方面,ARRAYFUN 似乎直接访问矩阵的值(而不在 ANS 变量中返回它们),因此它可以访问 pr 和 pi 指针,这两个指针不为空,因此所有元素都被认为是非真实的。

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

It might help to know that MATLAB stores the real/complex parts of a matrix separately. Try the following:

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

Structure address = 17bbc5b0 
m = 1
n = 2
pr = 1c6f18a0 
pi = 1c6f0420
   1.0000                  0 + 2.0000i

where pr is a pointer to the memory block containing the real part of all values, and pi pointer to the complex part of all values in the matrix. Since all elements are stored together, then in this case they all have a complex part.

Now compare these two approaches:

>> 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

versus

>> 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

So it seems that when you access a(1) in the for loop, the value returned (in the ans variable) has a zero complex-part (null pi), thus is considered real.

One the other hand, ARRAYFUN seems to be directly accessing the values of the matrix (without returning them in ANS variable), thus it has access to both pr and pi pointers which are not null, thus are all elements are considered non-real.

Please keep in mind this just my interpretation, and I could be mistaken...

三人与歌 2024-09-24 11:09:34

回答这个问题真的很晚了……MATLAB 函数 ISREAL 在许多用途上以一种非常违反直觉的方式运行。它告诉您给定的数组作为一个整体是否根本没有复杂的部分 - 它告诉您有关存储的信息,它并没有真正告诉您有关<的任何信息em>数组中的值。在这方面,它有点像 ISSPARSE 函数。例如,

isreal(complex(1)) % returns FALSE

您会在 MATLAB 中发现某些运算会自动修剪所有全零的虚部。简而言之

x = complex(1);
isreal(x); % FALSE, we just forced there to be an imaginary part
isreal(x(1)); % TRUE - indexing realised it could drop the zero imaginary part
isreal(x(:)); % FALSE - "(:)" indexing is just a reshape, not real indexing

,MATLAB 确实需要一个函数,以数组上的元素方式回答“这个值的虚部是否为零”的问题。

Answering really late on this one... The MATLAB function ISREAL operates in a really rather counter-intuitive way for many purposes. It tells you if a given array taken as a whole has no complex part at all - it tells you about the storage, it doesn't really tell you anything about the values in the array. It's a bit like the ISSPARSE function in that regard. So, for example

isreal(complex(1)) % returns FALSE

What you'll find in MATLAB is that certain operations automatically trim any all-zero imaginary parts. So, for example

x = complex(1);
isreal(x); % FALSE, we just forced there to be an imaginary part
isreal(x(1)); % TRUE - indexing realised it could drop the zero imaginary part
isreal(x(:)); % FALSE - "(:)" indexing is just a reshape, not real indexing

In short, MATLAB really needs a function which answers the question "does this value have zero imaginary part", in an elementwise way on an array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文