4

I came across a weird problem today while practicing using classes in MATLAB. It seems like MATLAB can't parse parentheses around an object.

I created a user-defined class named vector that has various attributes: magnitude, angle, length in the x and y directions. I overloaded the unary minus operator so that I can have

a = vector(5,50) % creates a vector with magnitude 5 and angle 50 (in degrees)
a.ang % prints the angle
b = -a
b.ang % 230 degrees

This is all fine and good, but say that I want to find the angle of the -a in one line. You'd expect something like

(-a).ang

to work but instead I get

 (-a).ang
     |
 Error: Unexpected MATLAB operator.

I can't use

 -a.ang

either because the dot operator has higher precedence than the minus. Any explanation of why matlab can't parse parentheses around an object?

EDIT: Here's the vector class that I created.

classdef vector
    properties
        mag
        ang % in degrees
        x
        y
    end

    methods
        function v = vector(mag,ang)
            if nargin == 2
                v.mag = mag;
                v.ang = ang;
                v.x = mag*cosd(ang);
                v.y = mag*sind(ang);
            end
        end
        function res = plus(u,v)
            x = u.x + v.x;
            y = u.y + v.y;
            res = vector(norm([x,y]), atan2d(y,x));
        end
        function res = minus(u,v)
            x = u.x - v.x;
            y = u.y - v.y;
            res = vector(norm([x,y]), atan2d(y,x));
        end
        function res = uminus(v)
            res = vector;
            res.x = -v.x;
            res.y = -v.y;
            res.mag = v.mag;
            res.ang = mod(v.ang+180,360);
        end

    end
end
wyverniv
  • 279
  • 1
  • 2
  • 11
  • 3
    I wouldn't be surprised, if there wasn't any solution to your problem. I came across similar issues, all unsolvable, except for adding more lines of code. You can always just use `b.ang` (in your case). And besides, there is nothing wrong with adding a - say - temporary object. Alternatively, you could add a new method e.g. `minusang` which gives the angle in negative direction. Or even `ang(x)` and x a value in degrees that rotates the vector. – rst Feb 04 '16 at 07:14
  • 1
    Matlab is **terrrible** at chaining operators. It drives me crazy that I can't just write, say `x=1:10; sin(x)(3)` . – Carl Witthoft Feb 04 '16 at 15:53
  • 1
    Does your class return a `struct`, or something unique to your class? Please post your class definition so we can analyse. Further: are you expecting to be able to flip the sign of the `ang` value but not flip the sign of other parts of `a` ? Is `b.mag` also sign-flipped in your example? and so on. – Carl Witthoft Feb 04 '16 at 15:55
  • @CarlWitthoft: As you can see from my class definition, using a unary minus doesn't change the magnitude of the vector, so ideally, (-b).mag == b.mag – wyverniv Feb 05 '16 at 06:36

2 Answers2

2

I think I've found the answer. In general, Matlab does not support two sets of parentheses chained together because it could either be an indexing or a function call.

MATLAB's parser is limited, partly for historical reasons. It has never been possible to do something like f(4)(1) because of the ambiguity. Does it mean that f(4) is a function handle and then we want to pass 1 into that function or does it mean that f is a function, we pass 4 into that function, it returns a vector and then we index into the first element of that? Well, the parser doesn't know either. It could be defined, but it hasn't up till now.

Source: https://www.mathworks.com/matlabcentral/newsreader/view_thread/280225

Also, once I had realized that the two side-by-side parentheses were the problem, it seems that the main workarounds are either:

  1. Use the SUBSREF function to explicitly evaluate the parentheses
  2. Define your own anonymous function to perform the indexing and array handling for you.

Those workarounds are explained in the first two answers in the below link.

How can I index a MATLAB array returned by a function without first assigning it to a local variable?

Thanks for looking over my question guys!

Community
  • 1
  • 1
wyverniv
  • 279
  • 1
  • 2
  • 11
1

I cannot replicate vector function but for a simple structure like this

a.ang=[2,4,6,8]

what you need is

-a.ang

instead of

(-a).ang

which will reproduce the error you mentioned

PagMax
  • 8,088
  • 8
  • 25
  • 40