How do I compare the 2-dimensional "faces" of a 3-dimensional matrix?
1 view (last 30 days)
Show older comments
Robert Rouse
on 7 Apr 2015
Commented: Johan Löfberg
on 9 Apr 2015
I'm solving a problem which has several solutions, but each iteration of my algorithm will output a single solution as a 2-dimensional (2 by 3) matrix. I wrote a for-loop into the algorithm so that it outputs a set of solutions as a matrix which I've called "sols", so "sols(2, 3, 100)", say, will be the output when I cycle through 100 iterations and so will display the 100 solutions as various 'faces' of the matrix.
The problem is, there are only several solutions to the problem, not all the faces of the matrix "sols" are distinct. My algorithm will output this three dimensional matrix containing the 100 solutions, but not all of 100 solutions will be different. What I'd like to do is write something into the code to then take the matrix sols(2,3,100) and create another output which only displays the distinct 2-dimension matrices (faces) of the 3-dimensional matrix.
I need the algorithm to either output the distinct 2-dimensional matrices or just the first rows of each 2-dimensional matrix, if that's any easier. A command like "unique(sols) came to mind, but of course that just outputs the distinct elements in each matrix, which is meaningless to me as I'd require either the distinct top or bottom rows of each matrix or the distinct 2-dimensional (2 by 3) matrices.
How could I do this?
.
Here's my code below, though you'd require YALMIP to run it:
sdpvar z1 z2 x(2,2,'full') t(2,2,'full') g(2,2,2,2,'full') sols(2,2,100,'full');
vc1 = [0 <= x]; vc2 = [0 <= t]; vc3 = sum(x) == 1; vc4 = sum(t) == 1;
F = [vc1, vc2, vc3, vc4];
g(:,:,1,1) = [3/4,3/4; 1,0]; g(:,:,2,1) = [3/4,1; 3/4,0];
g(:,:,1,2) = [3/8,3/8; 1,0]; g(:,:,2,2) = [3/8,1; 3/8,0];
eq1 = z1 - x(:,1).'*g(:,:,1,1)*x(:,2) <= 0;
eq2 = z1 - x(:,1).'*g(:,:,1,2)*x(:,2) <= 0;
eq3 = z2 - x(:,1).'*g(:,:,2,1)*x(:,2) <= 0;
eq4 = z2 - x(:,1).'*g(:,:,2,2)*x(:,2) <= 0;
eq5 = [[1,0]*g(:,:,1,1)*x(:,2), [1,0]*g(:,:,1,2)*x(:,2)]*t(:,1) - z1 <= 0;
eq6 = [[0,1]*g(:,:,1,1)*x(:,2), [0,1]*g(:,:,1,2)*x(:,2)]*t(:,1) - z1 <= 0;
eq7 = [x(:,1).'*g(:,:,2,1)*[1;0], x(:,1).'*g(:,:,2,2)*[1;0]]*t(:,2) - z2 <= 0;
eq8 = [x(:,1).'*g(:,:,2,1)*[0;1], x(:,1).'*g(:,:,2,2)*[0;1]]*t(:,2) - z2 <= 0;
G = [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8];
objective = 0;
sol = optimize(F+G, objective);
r = recover(depends([F+G]));
for i=1:100
randomobjective = randn(length(r),1)'*r;
sol = optimize([F+G, objective >= value(objective)], randomobjective);
sols(:,:,i)=double(x);
end
sols
1 Comment
Johan Löfberg
on 9 Apr 2015
Your claim that the set is polyhedral is not obvious after performing some eliminations. Use the simplex-structure of x and t to remove redundant parametrization
Reduced = replace(replace(F+G,x(2,:),1-x(1,:)),t(2,:),1-t(1,:))
This set still contains bilinear stuff (although less than in the original model).
>> sdisplay(sdpvar(Reduced(3:6)))
ans =
'-z1+0.7500*x(1,1)+x(1,2)-x(1,1)*x(1,2)'
'-z1+0.3750*x(1,1)+x(1,2)-x(1,1)*x(1,2)'
'-z2+x(1,1)+0.7500*x(1,2)-x(1,1)*x(1,2)'
'-z2+x(1,1)+0.3750*x(1,2)-x(1,1)*x(1,2)'
Accepted Answer
Robert Rouse
on 9 Apr 2015
Edited: Robert Rouse
on 9 Apr 2015
2 Comments
Johan Löfberg
on 9 Apr 2015
But in no sense are you theoretically guaranteed to have computed points on the boundary of the feasible set, as it is nonconvex and fmincon just as well can get stuck at basically any point
If it was convex, and you wanted to do ray-shooting to generate points on the feasible set, you should remove the objective >= value(objective), which was something I added when I though you actually had an objective, and wanted to generate new points with the same objecvtive
More Answers (2)
Johan Löfberg
on 9 Apr 2015
Since your initial solve is simply a feasibility problem with the objective 0, what you are doing in the for-loop is that you are generating some weird vertices of the feasible set, where every new vertex has a larger inner product with the random direction, than the previous combination. This looks really weird. (in your mail to me, I didn't note that objective was 0)
If your goal really is to generate all optimal solutions (for some undefined objective here), you are pretty much doomed using this approach, as the feasible set is nonconvex and a ray-shooting procedure will not be applicable (unless you for some reason now that the set actually is convex, and that the nonlinear solver you use actually will be able to solve the seemingly nonconvex problem to global optimality)
If you are trying to generate vertices of the feasible set, you are also doomed using this approach (for the same reason)
Perhaps you could look at the vertices of the convex hull instead, but most likely you will have to analyze it analytically
4 Comments
Johan Löfberg
on 9 Apr 2015
BTW, the definition of g and sol as sdpvars is completely redundant (you don't use them as such)
Robert Rouse
on 9 Apr 2015
2 Comments
Johan Löfberg
on 9 Apr 2015
It looks like you are trying to look at the convex hull of two polytopes or something. Is that what you are doing?
Johan Löfberg
on 9 Apr 2015
Oh, it's cubic now. Even worse now then, and a nonlinear programming approach seems even further away from being a sensible way to enumerate the feasible set.
See Also
Categories
Find more on Rubik's Cube in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!