Disable automatic conversion to reals
7 次查看(过去 30 天)
显示 更早的评论
Is there a way to disable the automatic conversion of a complex variable with zero imaginary component into a purely real variable?
>> x = complex(zeros(2,2)) % complex
x =
0.0000 + 0.0000i 0.0000 + 0.0000i
0.0000 + 0.0000i 0.0000 + 0.0000i
>> x(2,1) = -1 % magically becomes real
x =
0 0
-1 0
This is bothering me because:
- It differs from the behavior of gpuArrays, for which subsref and subsasgn preserve complexity.
- It triggers an unnecessary memory copy (and then again when I eventually store a complex value into the matrix).
- This is not playing well with MEX routines that expect the arguments to have the same datatype.
To that last point, consider the following:
>> x = complex(randn(4,100), randn(4,100)); % complex
>> y = x .* max(0,abs(x)-1); % also complex
>> for ii = 1:100
try
z = mymexfunc(x(:,ii), y(:,ii)) % sometimes not complex
catch
fprintf('Error on iter %d\n',ii);
end
end
Error on iter 44
Error on iter 62
I thought it was safe to assume that a subscripted reference from a complex array would yield a complex array, but it turns out I was wrong.
Our C/C++ developer is pretty busy these days, so before I go bother her about adding mixed-complexity support to the MEX routines, I am wondering:
- Is there an undocumented feature flag I can disable? Something like feature('auto_convert_reals',0) would be great.
- Are there alternatives to parenthetical indexing that do preserve complexity?
2 个评论
采纳的回答
Edric Ellis
2018-8-2
编辑:Edric Ellis
2018-8-2
MATLAB's behaviour has always been to drop the imaginary part on indexing operations (where it is all zero!). gpuArray is somewhat incompatible with standard MATLAB behaviour in this regard - this was a deliberate choice to improve performance of gpuArray indexing (since the very beginning, gpuArray has used interleaved-complex format).
Anyway, probably your best bet is to preprocess your MEX arguments using a simple MATLAB wrapper, something like this:
function varargout = matchComplexity(varargin)
% Require precisely as many outputs as inputs.
nargoutchk(nargin, nargin);
varargout = varargin;
% Check which are stored as real
isReal = cellfun(@isreal, varargout);
% If not all arrays stored as real, complexify those that are real
if ~all(isReal)
varargout(isReal) = cellfun(@complex, varargout(isReal), ...
'UniformOutput', false);
end
end
Clearly, you'll want to apply this only to your data arguments that are expected to match in complexity.
更多回答(2 个)
James Mentz
2019-1-28
Sorry, this is a bug, not a feature. You can have an entire array of complex number and writing a single indexed value with a number where the imaginary part = 0 will destroy all of the complex information in the entire array.
If Matlab is going to do this we need a new immutable array data type where once it's declared complex it stays complex.
I had to work around this by checking EVER value going into the array and if the imaginary part is zero I add (realmin('single') * 1i) to each entry, this doing every bit as much checking as Matlab does to make these values fragil, with the added downsize of dithering my data by realmin.
1 个评论
Rik
2019-1-28
The point is not that this behavior occurs when imag(z_input)==0, but when all imaginary parts of the resulting array are zero. I would still consider it a bug, but it is less dramatic than your post seems to suggest.
No information is lost, only the data type changes.
Jim Svensson
2022-9-1
编辑:Jim Svensson
2022-9-1
I agree that Matlab's way of automatically dropping imaginary part when zero is stupid, very annyoing and it causes extra problems in many cases. I wish it could be disabled.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!