A=single(rand(2));%create a single-type matrix
A(1,1)=pi;%assign a double to a single
A(2,1)=pi>3;%assign a logical to a single
class(A) %check that A is still a single==> No class promotion
class(A+pi) %check that A is still a single==> No class promotion
%Possible remedy: create an @double directory, and store specific
functions subsasgn.m and subsref.m
%Hopefully this could overload the builtin operator subsasgn/subsref
to change this behavior.
%The same should be possible if you do the same with an @single
directory.
%But unfortunately it does not work.
%Is there any other way to change the default behavior for the
assignment operation in Matlab, in order
%to allow class promotion?
Carlos,
Just to be clear, if S is a single precision array, you want
>> S(index) = doubleRightHandSide
to force S to be double?
And you also want
>> T = S + doubleValue
to return a double result T?
The latter can be achieved by creating an
@single/plus.m
function where plus, on mixed single/double inputs, promotes the single
operand to double and calls the builtin('plus',...) on the two double
operands. Something like:
%%%%%%%%%%%%%
function C = plus(A,B)
if isa(A,'single') && isa(B,'double')
A = double(A);
elseif isa(A,'double') % B must be single
B = double(B);
end
C = builtin('plus',A,B);
%%%%%%%%%%%%%
But you have to do this for every two operand operation for which you want
mixed single/double interaction to promote the single to double. To find out
what these operations are, start with the list below and pick the
appropriate functions:
>> methods single
Methods for class single:
abs ctranspose gt lu prod
strcmp
acos cumprod hess max qr
strcmpi
acosh cumsum ifft min qrupdate
strncmp
all det ifftn minus qz
strncmpi
and diag imag mldivide rcond
sum
any diff inv mod rdivide
superiorfloat
asin display isfinite mpower real
svd
asinh eig isinf mrdivide reallog
tan
atan eps isletter mtimes realpow
tanh
atan2 eq isnan ne realsqrt
times
atanh exp issorted norm rem
transpose
balance expm isspace not reshape
tril
ceil fft ldivide or round
triu
chol fftn le ordeig schur
uminus
cholupdate filter linsolve ordqz sign
uplus
colon find log ordschur sin
upper
conj fix log2 permute sinh
xor
conv2 floor logical plus sort
cos full lower pow2 sparsfun
cosh ge lt power sqrt
May I ask why you want single OP double to promote to double?
Penny Anderson
The MathWorks, Inc.
Penny Anderson wrote:
> May I ask why you want single OP double to promote to double?
I agree that there might be cases when this is not needed/advisable.
I want to have control to that, because I need so in this (general!)
application.
> Hello, Penny:
> Thank you for your answer. I have used the "single" case as an
> example, because everyone can check the piece of code submitted.
> I have created a class named "dd" (acronym for double-double), which
> stores each number as an "unevaluated sum of two doubles". For
> example, it allows to represent numbers like 1+eps/2, roughly as the
> pair (1.0, eps/2). All operations have been implemented starting from
> a library available for C++.
> Thus, I want to control the promotion strategy, forcing to any
> operation involving at least one dd-type produces a dd-type answer.
> Exceptions of course are ==, ~=, etc.
> According to the documentation, every statement like
> A(3,4)=dd1 (being dd1 any number of type dd) should invoke the
> routine
> A=SUBSASGN(A,S,dd1), holding in S the information about the "3" and
> the "4".
The problem here is that if A is already a double array, you do not
want A(3,4) to suddenly convert the entire array A to a different
class. If currently A is uint8, A(2,2) = double(5), the double(5)
will be typecast to uint8 before storing into A. It's real trouble to
ask that A become double before this operation.
--
Peter Boettcher <boet...@ll.mit.edu>
MIT Lincoln Laboratory
MATLAB FAQ: http://www.mit.edu/~pwb/cssm/
Carlos,
In MATLAB there is a distinction between class (double, single, logical,
int8, sym, "dd") and attributes like sparse and complex.
Automatic promotion for the attribute complexity happens automatically.
The general rule in MATLAB is that once the *class* of the variable is
determined, that indexed assignment into that variable does not change the
class of the Left Hand Side (LHS), even if the Right Hand Side (RHS) is of a
different class.
I am not enough of a OOPS/subsasgn expert to tell you if it is possible to
over-ride this behavior in your MATLAB object "dd".
Does your
>> A = zeros(n,n); % A is double
>> A(index) = RHS_of_class_dd;
not dispatch to your @dd/subsasgn.m method?
If it does dispatch there, I imagine that within that method you could
override the class of A from double to dd, but I am not sure ...
Thank you a lot for your answers.
Regards
Carlos
Carlos,
I think that's just the way the MATLAB dispatcher works on subsasgn. A has
to be the object, then it uses the class of A to dispatch in A(index) = B.
The one exception you might try is that if A is undefined and the RHS B is
an object, then
clear A;
A(index) = B;
will dispatch to the @object/subsasgn method for the object B.
Wonder what happens is A is undefined and index is an object ;-)
ddpi (lo) =
0
>> clear A
>> A(2,2)=ddpi
A (hi) =
0 0
0 3.1416
A (lo) =
0 0
0 0
I believe that this capability (i.e. overloading of subsasgn) is
extremely relevant for this purpose. So, I wonder if there are some
fact which precludes to call @dd\subsasgn.m when some of its
parameters are of class dd. Could it happend that the parser
INDEPENDENTLY cast the right hand side to fit the left hand side? If
it does so, it does not follow the rules for overeloading
Regards
Carlos
This will be doc'd more clearly in a future release of MATLAB.
But for now, the rule is that if A is a built-in class of MATLAB (double,
single, int8, etc.) then
>> A(index) = object1
does not dispatch to @object/subsasgn.m, but instead tries to convert
object1 to the (built-in) class of A and then assigns it to A(index).
For now, you are not missing anything and there is unfortunately no way I
know of to get the behavior you are looking for.
For one thing, it would contradict the built-in behavior, for example if A
is single and RHS is int8 then
>> A(index) = RHS
casts the int8 RHS to single before assigning it to A(index).
Penny Anderson
The MathWorks, Inc.
"Carlos Lopez" <clv...@removeThisadinet.com.uy> wrote in message
news:eef5...@webx.raydaftYaTP...