Any quick fix for this matrix-scalar simplification?

Hey all — I'm trying to simplify the matrix-scalar expression in the code below (treating the matrix as a whole, not expanding it). MATLAB won't simplify it for some reason. Anyone know a quick fix? Should be pretty simple — thanks!
Please note — I only want to simplify this mixed matrix-scalar expression according to standard matrix algebra rules. Each matrix should be treated as an abstract whole; no need to expand its entries.
clear;clc
syms EYY QINV tDHY DH2Y tDEX DE2X RYjia RXjian EYX tDEY DE2Y RXjia RYjian ...
EXY EXX tDHX DH2X [3 3] matrix
syms kx ky a
Y=exp(1j*ky*a);
X=exp(1j*kx*a);
MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV*(tDHY-DH2Y*Y)-...
(tDEX+DE2X*(X^-1))*RYjia*RXjian*EYX*QINV*(tDHY-DH2Y*Y)-...
(tDEY+DE2Y*(Y^-1))*RXjia*RYjian*EXY*QINV*(tDHX-DH2X*X)-...
(tDEX+DE2X*(X^-1))*EXX*QINV*(tDHX-DH2X*X);
expand(MAT)
Incorrect number or types of inputs or outputs for function expand.

8 Comments

I don't believe that the Symbolic Math Toolbox offers much for manipulating symmatrix expressions, such as expand or simplify or children.
In some (very limited number?) cases, symmatrix expressions are simplified when they are defined or otherwise developed.
For example
syms A B C [3,3] matrix
Z = A*B + A*B
Z = 
But, in a slightly more general case
syms c
Z = A*B + c*A*B
Z = 
I don't think there is anywhere to go from here to get to Z = (1+c)*A*B. Whereas in the sym case
syms a b
z = a*b + c*a*b
z = 
simplify(z)
ans = 
Will be very interested if someone demonstrates a workable approach for manipulating symmatrix expressions.
Note also that we cannot assume a symmatrix is real
assume(A,'real')
Incorrect number or types of inputs or outputs for function assume.
What do you hope the "simplified" version to be? Please be specific about how you expect / want the expression for MAT to be different from what MATLAB shows it below.
syms EYY QINV tDHY DH2Y tDEX DE2X RYjia RXjian EYX tDEY DE2Y RXjia RYjian ...
EXY EXX tDHX DH2X [3 3] matrix
syms kx ky a
Y=exp(1j*ky*a);
X=exp(1j*kx*a);
MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV*(tDHY-DH2Y*Y)-...
(tDEX+DE2X*(X^-1))*RYjia*RXjian*EYX*QINV*(tDHY-DH2Y*Y)-...
(tDEY+DE2Y*(Y^-1))*RXjia*RYjian*EXY*QINV*(tDHX-DH2X*X)-...
(tDEX+DE2X*(X^-1))*EXX*QINV*(tDHX-DH2X*X)
MAT = 
Can't speak for the OP, but I'd like the symmatrix expression below to be simplified analagously to the sym expression (following matrix algebra rules, of course).
syms A B [3,3] matrix
syms a b c d e f
Z = a*A*B + b*A*B + c*A*B + d*A*B + e*A*B + f*A*B
Z = 
syms A B
Z = a*A*B + b*A*B + c*A*B + d*A*B + e*A*B + f*A*B
Z = 
simplify(Z)
ans = 
So in this specific example you'd expect the first two terms to become (something)*(QINV*) and the other two terms left alone? Or would you expect/hope for more simplification?
I'm not the OP and therefore have no expectations about how to simplify the expression in the question.
My only point is that many useful functions for Formula Manipulation and Simplification aren't applicable to symmatrix expressions, so we're limited in this regard, even for manual manipulation.
syms A B C [3,3] matrix
syms a b c d e f
Z = a*A*B + b*A*B + c*A*B + d*A*B + e*A*B + f*A*B
Z = 
simplify doesn't work
try
simplify(Z)
catch ME
ME.message
end
ans = 'Undefined function 'simplify' for input arguments of type 'symmatrix'.'
At least in this case I can see the pattern, so maybe I can get each term individually and then extract the scalar coefficients using children
try
c = children(Z)
catch ME
ME.message
end
ans = 'Undefined function 'children' for input arguments of type 'symmatrix'.'
Can't do that either.
I'm pretty sure that other potentially useful functions don't work with symmatrix, like expand
Z = (A+B)*(A+B)
Z = 
try
expand(Z)
catch ME
ME.message
end
ans = 'Undefined function 'expand' for input arguments of type 'symmatrix'.'
Thank you all very much for your thoughtful answers and comments! I've been a bit busy lately, but I have managed to read through most of them. Specifically, what I want is to fully expand the scalar-matrix mixed expression in my earlier code and then factor out the common scalar terms. For simple expressions this can be done by hand, but for more complicated ones, it seems a bit inconvenient even with MATLAB.
It feels incredibly contradictory when software literally named MATrix LABoratory chokes on symbolic matrix variables. However, this defensive programming is necessary to prevent dangerous math errors.
The most probable explanation is that MATLAB treats symmatrix objects as non-commutative by default, while simplify(), children(), and expand() are fundamentally built on the assumption of scalar commutativity.
In fact, I noticed a long time ago that these symbolic tools seem to have an internal alphabetical sorting mechanism. If these functions are allowed hastily on matrices, they may shuffle terms alphabetically and illegally swap the matrix products.
For now, we can force the evaluation down to the element-wise level to get the intuitive factoring behavior, though we have to verify the result visually.
syms A B [3,3] matrix
syms a b c d e f
Z = c*A*B + e*A*B + d*A*B + f*A*B + b*A*B + a*A*B
Z = 
Z_simp = simplify(symmatrix2sym(Z))
Z_simp = 
For sure, simplify and others would have to be methods unique to the symmatrix class. In the meantime, we rely on the toolbox to apply some basic, known rules to simplify expressions as they are developed.
For example
syms A B C [2,2] matrix
Z = B.'*A.' + B.'*B
Z = 
(A*B).'
ans = 
Z = Z - (A*B).'
Z = 
Though interestingly the simpler result is not obtained with conjugate transpose
Z = B'*A' + B'*B
Z = 
Z = Z - (A*B)'
Z = 
Not much happening with det
Z = det(A*B) - det(B*A)
Z = 
simplify(sym(Z))
ans = 
0
Hopefully Mathworks is working on continual improvements to symmmatrix functionality, much like the introduction of diff a few years ago.

Sign in to comment.

Answers (1)

Matt J
Matt J on 31 Aug 2026 at 4:08
Edited: Matt J less than a minute ago
Here's one approach. Limitation: all matrices in the expression must be explicit variables with names that can't end with numbers, e.g. A1, B2, etc...
syms A B C [3,3] matrix
syms c d e
Z =(c*B)*A + d*A*B + B*A*e
Z = 
[str,mlist]=symmat2str( Z );
Z = eval( collectMatrixProducts(str,mlist) )
Z = 

9 Comments

The code works, though at first glance, the result seems to produce a much longer expression than the original one. Need the OP to verify that the result commutes with actual matrices.
syms EYY QINV tDHY DH2Y tDEX DE2X RYjia RXjian EYX tDEY DE2Y RXjia RYjian EXY EXX tDHX DH2X [3 3] matrix
syms kx ky a
Y = exp(1j*ky*a);
X = exp(1j*kx*a);
Z = -(tDEY+DE2Y*(Y^-1))*EYY*QINV*(tDHY-DH2Y*Y)-(tDEX+DE2X*(X^-1))*RYjia*RXjian*EYX*QINV*(tDHY-DH2Y*Y)-(tDEY+DE2Y*(Y^-1))*RXjia*RYjian*EXY*QINV*(tDHX-DH2X*X)-(tDEX+DE2X*(X^-1))*EXX*QINV*(tDHX-DH2X*X)
Z = 
[str, mlist] = symmat2str( Z );
ZZ = eval( collectProducts(str, mlist) )
ZZ = 
function str = collectProducts(str,mlist)
P = extract(str, asManyOfList(mlist,1)+asManyOfList([mlist,'*'])).';
P = P(~cellfun('isempty', P));
for i = 1:numel(P)
if P{i}(1)=='*',
P{i}(1)='';
end
if P{i}(end)=='*',
P{i}(end)='';
end
end
[S,H] = strsplit(str,P);
Q = replace(H, '*', '_');
arg = [S(1:end-1); Q];
arg = [arg(:).', S{end}];
str = erase(strjoin(arg, ''), 'symmatrix');
[Q,I] = unique(Q);
P = P(I);
expr = str2sym(str);
expr = collect(expr, Q);
str = replace(func2str(matlabFunction(expr)), Q, P);
str = extractAfter( str ,')');
end
function [str,mlist,Mlist]=symmat2str( S )
fcn = @(expr) strtrim(char(formattedDisplayText(expr)));
str = fcn(S);
mlist = cellstr(matrixList(S));
syms(mlist{:}, '[3,3]', 'matrix') %dimensions don't matter
Mlist = mlist;
for i = 1:numel(mlist)
Mlist{i} = evalin('caller', mlist{i});
end
for i = 1:numel(mlist)
str = replace(str, fcn(Mlist{i}), mlist{i} );
end
end
function pat = asManyOfList(C, varargin)
pat = pattern(C{1});
for i = 2:numel(C)
pat = pat|C{i};
end
pat = asManyOfPattern(pat, varargin{:});
end
function mlist = matrixList(expr)
vstr = string(symvar(symmatrix2sym(expr)));
pat = digitsPattern+"_"+digitsPattern;
vstr = vstr(contains(vstr, pat));
mlist = unique(erase(vstr, pat));
end
Doesn't appear to work for a portion of the first term in the expression from the OP
syms EYY QINV tDHY DH2Y tDEX DE2X RYjia RXjian EYX tDEY DE2Y RXjia RYjian ...
EXY EXX tDHX DH2X [3 3] matrix
syms kx ky a
Y=exp(1j*ky*a);
X=exp(1j*kx*a);
%MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV*(tDHY-DH2Y*Y)
%MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV
MAT=-(tDEY+DE2Y*(Y^-1))*EYY
MAT = 
Z = MAT;
[str,mlist]=symmat2str( Z );
Z = eval( collectProducts(str,mlist) )
Z = 
Hadamard (elementwise) products shouldn't come in to play here and the operands in the second term on the RHS would be in the wrong order, in general, even if Hadamard products are corrected to a matrix products.
function str = collectProducts(str,mlist)
P=extract(str, asManyOfList(mlist,1)+asManyOfList([mlist,'*'])).';
P=P(~cellfun('isempty',P));
for i=1:numel(P)
if P{i}(1)=='*', P{i}(1)=''; end
if P{i}(end)=='*', P{i}(end)=''; end
end
[S,H]=strsplit(str,P);
Q=replace(H,'*','_');
arg=[S(1:end-1);Q];
arg=[arg(:).', S{end}];
str= erase(strjoin(arg,'') ,'symmatrix');
[Q,I]=unique(Q);
P=P(I);
expr=str2sym(str);
expr=collect(expr,Q);
str = replace(func2str(matlabFunction(expr)), Q,P);
str = extractAfter( str ,')');
end
function [str,mlist,Mlist]=symmat2str( S )
fcn=@(expr) strtrim(char(formattedDisplayText(expr)));
str=fcn(S);
mlist = cellstr(matrixList(S));
syms(mlist{:},'[3,3]','matrix') %dimensions don't matter
Mlist=mlist;
for i=1:numel(mlist)
Mlist{i}=evalin('caller',mlist{i});
end
for i=1:numel(mlist)
str=replace(str, fcn(Mlist{i}), mlist{i} );
end
end
function pat = asManyOfList(C,varargin)
pat=pattern(C{1});
for i=2:numel(C)
pat=pat|C{i};
end
pat=asManyOfPattern(pat,varargin{:});
end
function mlist = matrixList(expr)
vstr = string(symvar(symmatrix2sym(expr)));
pat = digitsPattern+"_"+digitsPattern;
vstr=vstr(contains(vstr,pat));
mlist = unique(erase(vstr,pat));
end
I fixed it. But regardless, it's not meant to be seen as finished code. It's a sketch.
syms EYY QINV tDHY DH2Y tDEX DE2X RYjia RXjian EYX tDEY DE2Y RXjia RYjian ...
EXY EXX tDHX DH2X [3 3] matrix
syms kx ky a
Y=exp(1j*ky*a);
X=exp(1j*kx*a);
%MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV*(tDHY-DH2Y*Y)
%MAT=-(tDEY+DE2Y*(Y^-1))*EYY*QINV
MAT=-(tDEY+DE2Y*(Y^-1))*EYY
MAT = 
Z = MAT;
[str,mlist]=symmat2str( Z );
Z = eval( collectMatrixProducts(str,mlist) )
Z = 
the result seems to produce a much longer expression than the original one
Yes, as I told the OP, I don't see why any simplification is expected
"I fixed it. But regardless, it's not meant to be seen as finished code. It's a sketch."
Understood, but still not fixed for anyone who wants to move the ball forward. Check the second term on RHS where the operands are reversed.
Check the second term on RHS where the operands are reversed.
Seems okay now, but of course, the solution code is no longer simple...
Thank you all very much for your thoughtful answers and comments ! I've been a bit busy lately, but I have managed to read through most of them. Specifically, what I want is to fully expand the scalar-matrix mixed expression in my earlier code and then factor out the common scalar terms. For simple expressions this can be done by hand, but for more complicated ones, it seems a bit inconvenient even with MATLAB.
Specifically, what I want is to fully expand the scalar-matrix mixed expression in my earlier code and then factor out the common scalar terms.
Yes, that is what the posted solution does. In your posted example, though, there are no common scalar terms.
I tested the associative and distributive properties using @Matt J's solution. For now, this comes closest to what we hope for when simplifying some matrix expressions involving symmatrix objects without violating the properties of matrix multiplication. 👍

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Products

Release

R2023b

Asked:

on 30 Aug 2026 at 12:24

Edited:

about 11 hours ago

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!