Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

automatic class promotion in MATLAB

7 views
Skip to first unread message

Carlos Lopez

unread,
Dec 4, 2004, 5:38:23 PM12/4/04
to
Hi everyone:
%I am developing a higher precision library for matlab (higher than
"double") but
%I am facing a problem with the class promotion. To illustrate the
fact, I will use
%an example using single/double

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?

Penny Anderson

unread,
Dec 7, 2004, 4:37:27 PM12/7/04
to
"Carlos Lopez" <clv...@adinet.com.uy> wrote in message
news:eef50...@webx.raydaftYaTP...

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.


Carlos Lopez

unread,
Dec 8, 2004, 7:19:48 AM12/8/04
to
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".
I have included in my @dd directory my own implementation of
subsasgn; hopefully, if any of the parameters is of class dd, the
builtin subsasgn should be superseded by the one available at @dd,
but it wasn't.
I tried to include a statement "superiorto('double')" in the @dd\dd.m
file, but it did not work either.
Without such fantastic mechanism, a new class like this is difficult
to use, because every already written function should be modified to
allow for promotion. And, IMHO, I am following the documentation
rules.
Regards
Carlos

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.

Peter Boettcher

unread,
Dec 8, 2004, 8:53:01 AM12/8/04
to
"Carlos Lopez" <clv...@adinet.com.uy> writes:

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

unread,
Dec 8, 2004, 9:26:23 AM12/8/04
to
Peter Boettcher wrote:
> 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.
Well, you might be right. I am posing a problem/situation where it
makes sense the automatic promotion to a new class.
For instance:
A=zeros(2,2)
A(1,2)=sqrt(-1)
automatically changes the original "type real" of A to "complex", for
all and every element of A. Why could not make sense (or in a less
rude way: could be a problem) to specify through rules in the @dd
directory (i.e., do not affect the overall operation of matlab except
for those operations involving at least an operand of class dd) a
specific behavior?
Regards
Carlos

Carlos Lopez

unread,
Dec 8, 2004, 9:55:01 AM12/8/04
to
BTW: yes Penny, I have implemented all (or almost all) the methods
requested in your list. Apparently the last remaining problem is this
of automatic promotion.
PD: I hope my answer before have shown the right spirit; I apologize
for any inconvenience.

Penny Anderson

unread,
Dec 8, 2004, 12:55:24 PM12/8/04
to
"Carlos Lopez" <clv...@removeThisadinet.com.uy> wrote in message
news:eef5...@webx.raydaftYaTP...

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

Carlos Lopez

unread,
Dec 8, 2004, 1:49:40 PM12/8/04
to
Penny Anderson wrote:
> 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 ...
You hit the point: the problem is subsasgn is NOT overloaded, so my
implementation is not called at all.
Any cue?
Regards
Carlos

Carlos Lopez

unread,
Dec 8, 2004, 1:53:51 PM12/8/04
to
Penny Anderson wrote:
> 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.
OK. But then it is unclear for me the usefulness of statements like
"superiorto"/"inferiorto". Could you provide a hint there? BTW: I
tried with both :-)

>
> 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".
All of us are learning from those who are experts, or (like me) who
has the ability to crash against this type of walls once every month
:-)

Thank you a lot for your answers.
Regards
Carlos

Penny Anderson

unread,
Dec 8, 2004, 2:58:49 PM12/8/04
to
"Carlos Lopez" <clv...@removeThisadinet.com.uy> wrote in message
news:eef5...@webx.raydaftYaTP...

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

Carlos Lopez

unread,
Dec 8, 2004, 3:45:43 PM12/8/04
to
Penny Anderson wrote:
> 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.
I created a directory @double, and wrote a specific subsasgn.m to
catch also this possibility. But it failed (i.e. my routine in
@double\subsasgn.m was ignored by the parser)

>
> 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 ;-)
It worked. And in addition, in this case it invoked the overloaded
routine (the one in my @dd directory).
>> ddpi=dd(pi)

ddpi (hi) =

3.1416

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

Penny Anderson

unread,
Dec 10, 2004, 2:46:19 PM12/10/04
to
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...

Carlos Lopez

unread,
Dec 14, 2004, 1:01:04 PM12/14/04
to
Penny Anderson wrote:
>
>
> 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).
I want to clarify a little bit this point: the reason I said that "it
contradicts the built-in behavior" is because subsasgn is a built-in,
but it is not overloaded when one of the parameters is NOT of class
double.
The documentation, and most of the other functions invoke the
overloaded version.
It is really a pity, because it makes difficult to use every
extension who deals with higher precision/different representation.
For example: the same problem will arise with an interval
representation of a number (i.e. a number is represented by a closed
interval where the true value is bounded to belong to. So instead of
one double, you will have two).
If I could suggest something else for future versions, I would like
to add also that there should be a "defaultDataType" property in the
root object, which will be read just by a few functions like
eye,rand,zeros,ones and "[]". Right now there is no way to overload
such functions, because its parameters are usually integers
represented as doubles.
Regards
Carlos
0 new messages