Philosophical question: How to get a vector from the output of solve? Why isn't it a vector already?

6 views (last 30 days)
I am solving an equation of several variables, and the result is a struct.
SNvec = solve(nvecEqabcd,[a1,b1,c1,d1]);
I want to write it to my latex file. So I sprintf a string that will eventually get printed to my latex file (after some processing to make it pretty):
string.steadyn=sprintf('The steady state of the nvec equation is: $rupup = %f, rdowndown = %f, rupdown = rdownup = %f, r00 = %f, rbb = %f.$',struct2array(SNvec),1-sum(struct2array(SNvec)))
But today, for some reason, struct2array doesn't work. I look that up and apparently it works for some versions of matlab but it isn't really meant to be used. So I could change my sprintf to use the struct variables, SNvec.a1, etc or I could set the output of 'solve' to four different variables, then assign them to a vector:
[Eqa1, Eqb1, Eqc1, Eqd1] = solve(nvecEqabcd,[a1,b1,c1,d1]);
Equilnvec = [Eqa1, Eqb1, Eqc1, Eqd1] ;
But in my mind, the solution to my equation is a single object, a vector, with whatever dimension it happens to have, it might be twenty dimensions next time. The fact that matlab, which was invented to deal with matrices and vectors, doesn't naturally treat this thing like a vector, suggests to me that I'm thinking about something the wrong way. Why do I have to manually turn it into a vector? Is there a smart way to turn the struct into a vector? Should I be doing something else?
Obviously, low priority here, I can get my code to run and am just curious if anybody has insight about how to think about this.

Accepted Answer

Steven Lord
Steven Lord on 20 Mar 2023
syms x y
sol = solve(x == 5, y^2 == 4)
sol = struct with fields:
x: [2×1 sym] y: [2×1 sym]
ans = 
ans = 
How exactly would you want those two solutions to the system of equations to be represented as one vector? I could potentially see storing the solutions as one matrix but I'd be worried about ambiguity with a vector representation.
As an example, if the solution vector was [5 5 -2 2] and just looking at that vector, does it represent the four solutions to a univariate problem, the two solutions to a system of two equations in two unknowns, or the unique solution to a system of four equations in four unknowns?
Steven Lord
Steven Lord on 20 Mar 2023
That is one possible way the solutions could be stored in the struct, yes. But we'd need to create names for each of those fields and there could be many potential solutions. With this approach, the names of the fields are obvious: they're the names of the variables for which you're solving.
There's also the point Walter Roberson made in a comment on John D'Errico's answer. In what order should the values for the variables be stored in those vectors? Do you know how to determine the order in which MATLAB returns the list of variables for a given equation or set of equations? It's not as simple as you might think. See the documentation page for the symvar function and this documentation page.
And yes, there have been posts here on MATLAB Answers and on the old MATLAB newsgroup where users have complained that solve had a bug because they didn't realize this order dependency when they called solve with multiple outputs (with names in the "wrong" order.)
syms x y
[yy, xx] = solve([x-5==0, y^2==4])
yy = 
xx = 
You might think that yy corresponds to y and xx to x, but it's the reverse. You don't have this problem with the one-output form:
sol = solve([x-5 == 0, y^2 == 4])
sol = struct with fields:
x: [2×1 sym] y: [2×1 sym]
ans = 
ans = 

Sign in to comment.

More Answers (1)

John D'Errico
John D'Errico on 20 Mar 2023
Edited: John D'Errico on 20 Mar 2023
I tried it with a vector, wondering if that might make solve work more easily. And it does work.
A = magic(3);
X = sym('X',[3,1]);
B = [1;2;3];
Xsol = solve(A*X == B)
Xsol = struct with fields:
X1: 1/20 X2: 3/10 X3: 1/20
But struct2array has no problem.
ans = 
syms a b c
abc = solve(A*[a;b;c] == B)
abc = struct with fields:
a: 1/20 b: 3/10 c: 1/20
ans = 
Which also seems to work. So as long as a unique solution is returned, it works nicely. The vector was not necessary. The problem for you was surely that solve is returning multiple solutions.
In the case where there are multiple solutions, maybe you need to use struct2cell.
syms x y
xy = solve(x^2 + y^2==2,x+y==1)
xy = struct with fields:
x: [2×1 sym] y: [2×1 sym]
xycell = struct2cell(xy)
xycell = 2×1 cell array
{2×1 sym} {2×1 sym}
And now with some more manipulations, convert those results into an array as you might desire. Perhaps like this:
ans = 
Hope this helps.
Emily on 20 Mar 2023
Thanks, Walter Roberson. Good point that it is safer not to assume that the order of the variables in the struct will be the order that I sent them in. I will use subs, that is a nice clean way of getting a vector.

Sign in to comment.




Community Treasure Hunt

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

Start Hunting!