Возьмите этот простой пример:
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
Что я делаю не так?
Возможно, полезно знать, что 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
. Получается, что когда вы обращаетесь к a(1)
в цикле for, возвращаемое значение (в ans
переменная) имеет нулевую комплексную часть (null pi
), поэтому считается вещественной.
С другой стороны, ARRAYFUN, по-видимому, напрямую обращается к значениям матрицы (без возврата их в переменную ANS), поэтому он имеет доступ как к указателям pr
, так и к указателям pi
. которые не равны нулю, поэтому все элементы считаются ненастоящими.
Пожалуйста, имейте в виду, что это всего лишь моя интерпретация, и я могу ошибаться...