3

I'm currently working on following Matlab function.

function d = sym_fun(E,A,C)
[n,m] = size(A);
if n==m
    X = sym('X%d%d', [n,n]);
    Xres = solve(A'*X*E+E'*X*A+E'*(C'*C)*E==0,X);
    xres = sym('x%d%d', size(Xres));
    for i=1:size(Xres)
        xres(i)=Xres(i);
    end %for
    LD = reshape(xres, [n,n]);
    d = diag(LD);
end %if

I'm trying to handle symbolic matrices of variable size. I need to iterate through the solution vector Xres somehow to get all the solutions to the problem. The problem lies in the line xres(i)=Xres(i), Xres(i) returns a struct and I actually need to call xres(i)=Xres.X%d%d with %d=i for this to work. I don't know how to code this though.

An even better solution would be if I could skip all that and somehow save the solution into a matrix directly. Something like the following:

X = sym('X%d%d', [n,n]);
xres = sym('x%d%d', size(Xres));
xres = solve(A'*X*E+E'*X*A+E'*(C'*C)*E==0,X);
LD = reshape(xres, [n,n]);
d = diag(LD);

My working, ugly solution to this problem.

function d = fun(E,A,C)

[n,m] = size(A);
if n==m
    X = sym('X%d%d', [n,n]);
    Xres = solve(A'*X*E+E'*X*A+E'*(C'*C)*E==0,X);
    P = sym('x%d%d', [n,n]);
    for i=1:n
        for j=1:n
            P(i,j)= eval(sprintf('Xres.X%d%d',i,j))
        end %for
    end %for
    d = diag(P);
end %if

Please show me a better one; eval(sprintf()) is an ugly workaround.

1 Answers1

0

There's always dynamic field naming (perhaps not much more elegant)

P(i,j) = Xres.(sprintf('X%d%d',i,j));

If you expect the result of your solve to be convertible to numeric, how about:

xres = structfun(@double,xres);
LD = reshape(xres, [n,n]);
d = diag(LD);

(not 100% sure on the preservation of order here, might want to double-check that on your real solution).

Another option for wrangling struct outputs is struct2cell.

nkjt
  • 7,825
  • 9
  • 22
  • 28