2
votes

Can I control the order of output for MATLAB symbolic expressions?

For example:

syms x y  
f=y*x   

MATLAB will normally return:

f=  
x*y  

but I'd like to get:

f=  
y*x 

I'm using MATLAB R2012b. How can I do this?

NEW EDIT 2016/11/9
I found these yesterday and it seems so weird to me:
Under R2008a

%%feedback.m
function H=feedback(G1,G2,key)  
if nargin==2
    key=-1;
end
H=G1/(sym(1)-key*G1*G2);
H=simple(H);

%%matlab command window
syms G1 G2 G3 G4 G5 G6 H1 H2 H3 H4
c1=feedback(G4*G5,H3);
c2=feedback(G2*G3,H2);
c3=feedback(c1*c2,H4/G2/G5);
G=feedback(c3*G1*G6,H1);
pretty(G)

MATLAB returns

G=
G3 G2 G4 G5 G1 G6/(1 + G2 G3 H2 + G4 G5 H3 + G4 G5 H3 G2 G3 H2 + G4 G3 H4 + G3 G2 G4 G5 G1 G6 H1)

Unfortunately, my R2008a doesn't have the symbolic math toolbox (I've been trying reinstallment many times, doesn't work). Hence I can't verify if it's true. I think if 2008a can make it, why can't 2012b.
I hope this may be helpful to my problem asked above.

2
Not that it's the issue, but why are you using a 4,5 year old MATLAB version? That'll give rise to lots of deprecated functions and compatibility issues with newer versions.Adriaan
@Adriaan: sadly, that is true: it's a reality of the tool that's driving me away from it to be honest -- MATLAB isn't made with long-term support in mind. Like, at all: every new version seems to come with things that break at least some old code. Sometimes, pretty badly. Most other languages at least provide some sort guarantee of backwards compatibility across versions. That is part of the reason why I still work with MATLAB R2010a much of my time, because my company did start projects requiring long-term support, and those projects will not be done with R2010a for at least 2 more years.Rody Oldenhuis
If you just want to reverse the sortorder, see the answer that I found. If you want to do things that are more complicated, I doubt that there will be an easy way. (As any solution should obviously generalize to work in all possible situations).Dennis Jaheruddin
@Adriaan I totally agree with Rody Oldenhuis. Every half year MATLAB has another new version. And most annoying, there're always big changes in the new version. Sometimes it even change the funtions that I used to use. It just drives me crazy....Sam.X.
@Sam.X. How is the order of the variables 'controlled' in the example? It appears pretty random to me, first there is G2 G3 and at another spot there is G3 G2Dennis Jaheruddin

2 Answers

0
votes

Not sure if this applies to R2012b, but on my R2010a, the class sym has a disp method, which is run when displaying your little function (and of course, all sym objects). Here is the relevant code:

allstrs = mupadmex(X.s,0);
allstrs = strrep(allstrs,'MLVar','');
disp(allstrs);

where X is the sym object, and s is a private property thereof.

The function mupadmex() is, as the name implies, a MEX binary. The corresponding M-code contains this:

%   MUPADMEX(STMT) executes STMT in MuPAD. STMT must be a string or cell
%   array of strings. A cell array is converted into a MuPAD matrix or array.
%   Y = MUPADMEX(STMT) executes STMT in MuPAD and returns the result as
%   sym object Y. STMT must be a string or cell array of strings. If STMT
%   is a cell Y is a string reference instead of a sym.
%   Y = MUPADMEX(FCN,ARG1,ARG2, ...) evaluates FCN(ARG1,ARG2,...). The inputs
%   must be strings.
%   Y = MUPADMEX(... ,0) returns Y as a string instead of a sym.
%   Y = MUPADMEX(REF ,1) adds REF to the garbage list.
%   Y = MUPADMEX(STMT,2) frees any garbage.
%   Y = MUPADMEX(VAL ,3) formats VAL as 'symr'.
%   Y = MUPADMEX(VAL ,4) formats VAL as 'symfl'.
%   Y = MUPADMEX(VAL ,5) toggles the trace feature. VAL must be 'on' or 'off'.
%   Y = MUPADMEX(STMT,6) resets MuPAD.
%   Y = MUPADMEX(VAL ,7) toggles the pretty-print feature.
%   Y = MUPADMEX(VAL ,8) sets the complex unit. VAL is 'I' or 'sqrtmone'.
%   Y = MUPADMEX(... ,9) returns Y as a logical instead of a sym.
%   Y = MUPADMEX(VAL ,10) toggles the synchronous evaluation mode (out-of-process kernel only).
%   Y = MUPADMEX(... ,11) returns Y as a string reference.
%   Y = MUPADMEX(VAL ,12) print out memory usage
%   Y = MUPADMEX(VAL ,13) toggles lazy evaluation mode
%   Y = MUPADMEX(VAL ,14) evaluates all the lazy statements
%   [Y,STATUS] = ... sets STATUS to 0 if the command completes without error
%   and otherwise sets STATUS to 1 and Y to the error string.

As you can see, it says nothing about formatting the string.

So, in short, you can do the following:

  1. You'd have to alter the toolbox code
  2. Write a display wrapper like this:

    function disp_sym(X)
    
        str = evalc('X');
        str = regexp(str, '=', 'split');
        fml = strtrim(str{2});
        eq  = str{1};
    
        fml = regexp(fml, '*', 'split');
        fml = fml(end:-1:1);
    
        disp( [eq '=' sprintf('%s*', fml{1:end-1}) fml{end}]);
    
    end
    

    But, that gets fugly, overly specific and non-portable really quickly.

0
votes

I actually found an answer by @horchler which appears to answer this question fully. Even though it was given as an answer to a different question.

Note that I quote the answer, but that I will not put it in a quote block to enhance readability:


I believe that it's alphabetical based on the ASCII values of the variable names in your equations. As per the documentation for solve, sym/symvar is used to parse the equations in the case where you don't supply the names of output variables. The help for sym/symvar indicates that it returns variables in lexicographical order, i.e. alphabetical (symvar does the same, even though it doesn't say so, by making calls to setdiff). If you look at the actual code for solve.m (type edit solve in your command window) and examine the sub-function called assignOutputs (line 190 in R2012b) you'll see that it makes a call to sort and that there's a comment about lexicographical order.

In R2012b (and likely earlier) the documentation differs from that of R2013a in a way that seems relevant to your issue. In R2013a, this sentence is added:

If you explicitly specify independent variables vars, then the solver uses the same order to return the solutions.

I'm still running R2012b, so I can't confirm this different behavior.