[37] | 1 | function solver = findapplicablesolvers(options,ProblemClass,solvers,socp_are_really_qc); |
---|
| 2 | %findapplicablesolvers Internal function to select solver based on problem category |
---|
| 3 | |
---|
| 4 | % Author Johan Löfberg |
---|
| 5 | % $Id: findapplicablesolvers.m,v 1.2 2005/09/16 09:00:45 joloef Exp $ |
---|
| 6 | |
---|
| 7 | %problem = 0; |
---|
| 8 | |
---|
| 9 | % % UNDOCUMENTED |
---|
| 10 | % force_solver = yalmip('solver'); |
---|
| 11 | % if length(force_solver)>0 |
---|
| 12 | % options.solver = force_solver; |
---|
| 13 | % end |
---|
| 14 | % |
---|
| 15 | % % *************************************************** |
---|
| 16 | % % Maybe the user is stubborn and wants to pick solver |
---|
| 17 | % % *************************************************** |
---|
| 18 | % if length(options.solver)>0 |
---|
| 19 | % |
---|
| 20 | % % Create tags with version also |
---|
| 21 | % temp = solvers; |
---|
| 22 | % for i = 1:length(temp) |
---|
| 23 | % if length(temp(i).version)>0 |
---|
| 24 | % temp(i).tag = lower([temp(i).tag '-' temp(i).version]); |
---|
| 25 | % end |
---|
| 26 | % end |
---|
| 27 | % |
---|
| 28 | % index = find(strcmp(lower({solvers.tag}),lower(options.solver))); |
---|
| 29 | % index2 = find(strcmp(lower({temp.tag}),lower(options.solver))); |
---|
| 30 | % if isempty(index) & isempty(index2) |
---|
| 31 | % solver = []; |
---|
| 32 | % problem = -3; |
---|
| 33 | % return; |
---|
| 34 | % else |
---|
| 35 | % solvers = solvers(union(index,index2)); |
---|
| 36 | % end |
---|
| 37 | % |
---|
| 38 | % end |
---|
| 39 | |
---|
| 40 | % ************************************************ |
---|
| 41 | % Prune based on objective |
---|
| 42 | % ************************************************ |
---|
| 43 | if ProblemClass.objective.sigmonial |
---|
| 44 | keep = ones(length(solvers),1); |
---|
| 45 | for i = 1:length(solvers) |
---|
| 46 | keep(i) = solvers(i).objective.sigmonial; |
---|
| 47 | end |
---|
| 48 | solvers = solvers(find(keep)); |
---|
| 49 | end |
---|
| 50 | if ProblemClass.objective.polynomial |
---|
| 51 | keep = ones(length(solvers),1); |
---|
| 52 | for i = 1:length(solvers) |
---|
| 53 | keep(i) = solvers(i).constraint.equalities.quadratic | solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex | solvers(i).objective.polynomial | solvers(i).objective.sigmonial; |
---|
| 54 | end |
---|
| 55 | solvers = solvers(find(keep)); |
---|
| 56 | end |
---|
| 57 | if ProblemClass.objective.quadratic.nonconvex |
---|
| 58 | keep = ones(length(solvers),1); |
---|
| 59 | for i = 1:length(solvers) |
---|
| 60 | keep(i) = solvers(i).objective.polynomial | solvers(i).objective.sigmonial | solvers(i).objective.quadratic.nonconvex; |
---|
| 61 | end |
---|
| 62 | solvers = solvers(find(keep)); |
---|
| 63 | end |
---|
| 64 | if ProblemClass.objective.quadratic.convex |
---|
| 65 | keep = ones(length(solvers),1); |
---|
| 66 | for i = 1:length(solvers) |
---|
| 67 | direct = solvers(i).objective.polynomial | solvers(i).objective.sigmonial | solvers(i).objective.quadratic.nonconvex | solvers(i).objective.quadratic.convex; |
---|
| 68 | indirect = solvers(i).constraint.inequalities.semidefinite.linear | solvers(i).constraint.inequalities.secondordercone; |
---|
| 69 | if direct | indirect |
---|
| 70 | keep(i)=1; |
---|
| 71 | else |
---|
| 72 | keep(i)=0; |
---|
| 73 | end |
---|
| 74 | end |
---|
| 75 | solvers = solvers(find(keep)); |
---|
| 76 | end |
---|
| 77 | if ProblemClass.objective.linear |
---|
| 78 | keep = ones(length(solvers),1); |
---|
| 79 | for i = 1:length(solvers) |
---|
| 80 | keep(i) = solvers(i).objective.polynomial | solvers(i).objective.sigmonial | solvers(i).objective.quadratic.nonconvex | solvers(i).objective.quadratic.convex | solvers(i).objective.linear; |
---|
| 81 | end |
---|
| 82 | solvers = solvers(find(keep)); |
---|
| 83 | end |
---|
| 84 | |
---|
| 85 | |
---|
| 86 | % ****************************************************** |
---|
| 87 | % Prune based on rank constraints |
---|
| 88 | % ****************************************************** |
---|
| 89 | if ProblemClass.constraint.inequalities.rank |
---|
| 90 | keep = ones(length(solvers),1); |
---|
| 91 | for i = 1:length(solvers) |
---|
| 92 | keep(i) = solvers(i).constraint.inequalities.rank; |
---|
| 93 | end |
---|
| 94 | solvers = solvers(find(keep)); |
---|
| 95 | end |
---|
| 96 | |
---|
| 97 | % ****************************************************** |
---|
| 98 | % Prune based on semidefinite constraints |
---|
| 99 | % ****************************************************** |
---|
| 100 | if ProblemClass.constraint.inequalities.semidefinite.sigmonial |
---|
| 101 | keep = ones(length(solvers),1); |
---|
| 102 | for i = 1:length(solvers) |
---|
| 103 | keep(i) = solvers(i).constraint.inequalities.semidefinite.sigmonial; |
---|
| 104 | end |
---|
| 105 | solvers = solvers(find(keep)); |
---|
| 106 | end |
---|
| 107 | if ProblemClass.constraint.inequalities.semidefinite.polynomial |
---|
| 108 | keep = ones(length(solvers),1); |
---|
| 109 | for i = 1:length(solvers) |
---|
| 110 | keep(i) = solvers(i).constraint.inequalities.semidefinite.sigmonial | solvers(i).constraint.inequalities.semidefinite.polynomial; |
---|
| 111 | end |
---|
| 112 | solvers = solvers(find(keep)); |
---|
| 113 | end |
---|
| 114 | if ProblemClass.constraint.inequalities.semidefinite.quadratic |
---|
| 115 | keep = ones(length(solvers),1); |
---|
| 116 | for i = 1:length(solvers) |
---|
| 117 | keep(i) = solvers(i).constraint.inequalities.semidefinite.sigmonial | solvers(i).constraint.inequalities.semidefinite.polynomial | solvers(i).constraint.inequalities.semidefinite.quadratic; |
---|
| 118 | end |
---|
| 119 | solvers = solvers(find(keep)); |
---|
| 120 | end |
---|
| 121 | if ProblemClass.constraint.inequalities.semidefinite.linear |
---|
| 122 | keep = ones(length(solvers),1); |
---|
| 123 | for i = 1:length(solvers) |
---|
| 124 | keep(i) = solvers(i).constraint.inequalities.semidefinite.sigmonial | solvers(i).constraint.inequalities.semidefinite.polynomial | solvers(i).constraint.inequalities.semidefinite.quadratic | solvers(i).constraint.inequalities.semidefinite.linear; |
---|
| 125 | end |
---|
| 126 | solvers = solvers(find(keep)); |
---|
| 127 | end |
---|
| 128 | |
---|
| 129 | % ****************************************************** |
---|
| 130 | % Prune based on second order cone constraints |
---|
| 131 | % ****************************************************** |
---|
| 132 | if ProblemClass.constraint.inequalities.secondordercone & ~socp_are_really_qc |
---|
| 133 | keep = ones(length(solvers),1); |
---|
| 134 | for i = 1:length(solvers) |
---|
| 135 | keep(i) = solvers(i).constraint.inequalities.secondordercone | solvers(i).constraint.inequalities.semidefinite.linear; |
---|
| 136 | end |
---|
| 137 | solvers = solvers(find(keep)); |
---|
| 138 | end |
---|
| 139 | if ProblemClass.constraint.inequalities.rotatedsecondordercone |
---|
| 140 | keep = ones(length(solvers),1); |
---|
| 141 | for i = 1:length(solvers) |
---|
| 142 | keep(i) = solvers(i).constraint.inequalities.rotatedsecondordercone | solvers(i).constraint.inequalities.secondordercone | solvers(i).constraint.inequalities.semidefinite.linear; |
---|
| 143 | end |
---|
| 144 | solvers = solvers(find(keep)); |
---|
| 145 | end |
---|
| 146 | |
---|
| 147 | % ****************************************************** |
---|
| 148 | % Prune based on element-wise inequality constraints |
---|
| 149 | % ****************************************************** |
---|
| 150 | if ProblemClass.constraint.inequalities.elementwise.sigmonial |
---|
| 151 | keep = ones(length(solvers),1); |
---|
| 152 | for i = 1:length(solvers) |
---|
| 153 | keep(i) = solvers(i).constraint.inequalities.elementwise.sigmonial; |
---|
| 154 | end |
---|
| 155 | solvers = solvers(find(keep)); |
---|
| 156 | end |
---|
| 157 | if ProblemClass.constraint.inequalities.elementwise.polynomial |
---|
| 158 | keep = ones(length(solvers),1); |
---|
| 159 | for i = 1:length(solvers) |
---|
| 160 | keep(i) = solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex | solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial; |
---|
| 161 | end |
---|
| 162 | solvers = solvers(find(keep)); |
---|
| 163 | end |
---|
| 164 | if ProblemClass.constraint.inequalities.elementwise.quadratic.nonconvex |
---|
| 165 | keep = ones(length(solvers),1); |
---|
| 166 | for i = 1:length(solvers) |
---|
| 167 | keep(i) = solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial | solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex; |
---|
| 168 | end |
---|
| 169 | solvers = solvers(find(keep)); |
---|
| 170 | end |
---|
| 171 | if ProblemClass.constraint.inequalities.elementwise.quadratic.convex | (ProblemClass.constraint.inequalities.secondordercone & socp_are_really_qc) |
---|
| 172 | keep = ones(length(solvers),1); |
---|
| 173 | for i = 1:length(solvers) |
---|
| 174 | keep(i) = solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial | solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex | solvers(i).constraint.inequalities.elementwise.quadratic.convex | solvers(i).constraint.inequalities.secondordercone | solvers(i).constraint.inequalities.semidefinite.linear; |
---|
| 175 | end |
---|
| 176 | solvers = solvers(find(keep)); |
---|
| 177 | end |
---|
| 178 | if ProblemClass.constraint.inequalities.elementwise.linear |
---|
| 179 | keep = ones(length(solvers),1); |
---|
| 180 | for i = 1:length(solvers) |
---|
| 181 | keep(i) = solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial | solvers(i).constraint.inequalities.semidefinite.quadratic | solvers(i).constraint.inequalities.elementwise.linear; |
---|
| 182 | end |
---|
| 183 | solvers = solvers(find(keep)); |
---|
| 184 | end |
---|
| 185 | |
---|
| 186 | % ****************************************************** |
---|
| 187 | % Prune based on element-wise constraints |
---|
| 188 | % ****************************************************** |
---|
| 189 | if ProblemClass.constraint.equalities.sigmonial |
---|
| 190 | keep = ones(length(solvers),1); |
---|
| 191 | for i = 1:length(solvers) |
---|
| 192 | keep(i) = solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.equalities.sigmonial; |
---|
| 193 | end |
---|
| 194 | solvers = solvers(find(keep)); |
---|
| 195 | end |
---|
| 196 | if ProblemClass.constraint.equalities.polynomial |
---|
| 197 | keep = ones(length(solvers),1); |
---|
| 198 | for i = 1:length(solvers) |
---|
| 199 | indirect = solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex | solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial; |
---|
| 200 | indirect = indirect | solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial; |
---|
| 201 | direct = solvers(i).constraint.equalities.sigmonial | solvers(i).constraint.equalities.polynomial; |
---|
| 202 | keep(i) = direct | indirect; |
---|
| 203 | end |
---|
| 204 | solvers = solvers(find(keep)); |
---|
| 205 | end |
---|
| 206 | if ProblemClass.constraint.equalities.quadratic |
---|
| 207 | keep = ones(length(solvers),1); |
---|
| 208 | for i = 1:length(solvers) |
---|
| 209 | indirect = solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial | solvers(i).constraint.inequalities.elementwise.quadratic.nonconvex; |
---|
| 210 | direct = solvers(i).constraint.equalities.sigmonial | solvers(i).constraint.equalities.polynomial | solvers(i).constraint.equalities.quadratic; |
---|
| 211 | keep(i) = direct | indirect; |
---|
| 212 | end |
---|
| 213 | solvers = solvers(find(keep)); |
---|
| 214 | end |
---|
| 215 | if ProblemClass.constraint.equalities.linear |
---|
| 216 | keep = ones(length(solvers),1); |
---|
| 217 | for i = 1:length(solvers) |
---|
| 218 | indirect = solvers(i).constraint.inequalities.elementwise.linear | solvers(i).constraint.inequalities.elementwise.sigmonial | solvers(i).constraint.inequalities.elementwise.polynomial; |
---|
| 219 | direct = solvers(i).constraint.equalities.linear | solvers(i).constraint.equalities.sigmonial | solvers(i).constraint.equalities.polynomial; |
---|
| 220 | keep(i) = direct | indirect; |
---|
| 221 | end |
---|
| 222 | solvers = solvers(find(keep)); |
---|
| 223 | end |
---|
| 224 | |
---|
| 225 | |
---|
| 226 | % ****************************************************** |
---|
| 227 | % Discrete data |
---|
| 228 | % ****************************************************** |
---|
| 229 | if ProblemClass.constraint.integer |
---|
| 230 | keep = ones(length(solvers),1); |
---|
| 231 | for i = 1:length(solvers) |
---|
| 232 | keep(i) = solvers(i).constraint.integer; |
---|
| 233 | end |
---|
| 234 | solvers = solvers(find(keep)); |
---|
| 235 | end |
---|
| 236 | if ProblemClass.constraint.binary |
---|
| 237 | keep = ones(length(solvers),1); |
---|
| 238 | for i = 1:length(solvers) |
---|
| 239 | keep(i) = solvers(i).constraint.integer | solvers(i).constraint.binary; |
---|
| 240 | end |
---|
| 241 | solvers = solvers(find(keep)); |
---|
| 242 | end |
---|
| 243 | |
---|
| 244 | if isempty(solvers) |
---|
| 245 | solver = []; |
---|
| 246 | else |
---|
| 247 | solver=solvers; |
---|
| 248 | % solver = solvers(1); |
---|
| 249 | end |
---|
| 250 | |
---|
| 251 | % if isempty(solver) |
---|
| 252 | % if length(options.solver)>0 % User selected available solver, but it is not applicable |
---|
| 253 | % problem = -4; |
---|
| 254 | % else |
---|
| 255 | % problem = -2; |
---|
| 256 | % end |
---|
| 257 | % end |
---|
| 258 | |
---|
| 259 | |
---|
| 260 | % FIX : Hack when chosing the wrong fmincon thingy |
---|
| 261 | if ~isempty(solver) |
---|
| 262 | if (length(options.solver)==0 | isequal(options.solver,'fmincon')) & isequal(solver.tag,'fmincon') & isequal(solver.version,'geometric') |
---|
| 263 | if ~(ProblemClass.objective.sigmonial | ProblemClass.constraint.inequalities.elementwise.sigmonial) |
---|
| 264 | solver.version = 'standard'; |
---|
| 265 | solver.call = 'callfmincon'; |
---|
| 266 | solver.objective.linear = 1; |
---|
| 267 | solver.objective.quadratic.convex = 1; |
---|
| 268 | solver.objective.quadratic.nonconvex = 1; |
---|
| 269 | solver.objective.polynomial = 1; |
---|
| 270 | solver.objective.sigmonial = 1; |
---|
| 271 | solver.constraint.equalities.elementwise.linear = 1; |
---|
| 272 | solver.constraint.equalities.elementwise.quadratic.convex = 1; |
---|
| 273 | solver.constraint.equalities.elementwise.quadratic.nonconvex = 1; |
---|
| 274 | solver.constraint.equalities.elementwise.polynomial = 1; |
---|
| 275 | solver.constraint.equalities.elementwise.sigmonial = 1; |
---|
| 276 | solver.constraint.inequalities.elementwise.linear = 1; |
---|
| 277 | solver.constraint.inequalities.elementwise.quadratic.convex = 1; |
---|
| 278 | solver.constraint.inequalities.elementwise.quadratic.nonconvex = 1; |
---|
| 279 | solver.constraint.inequalities.elementwise.polynomial = 1; |
---|
| 280 | solver.constraint.inequalities.elementwise.sigmonial = 1; |
---|
| 281 | solver.constraint.inequalities.semidefinite.linear = 1; |
---|
| 282 | solver.constraint.inequalities.semidefinite.quadratic = 1; |
---|
| 283 | solver.constraint.inequalities.semidefinite.polynomial = 1; |
---|
| 284 | solver.dual = 1; |
---|
| 285 | end |
---|
| 286 | end |
---|
| 287 | end |
---|
| 288 | |
---|
| 289 | |
---|