Mercurial > octave-nkf
comparison scripts/optimization/sqp.m @ 10549:95c3e38098bf
Untabify .m scripts
author | Rik <code@nomad.inbox5.com> |
---|---|
date | Fri, 23 Apr 2010 11:28:50 -0700 |
parents | 83de7b060e91 |
children | 35338deff753 |
comparison
equal
deleted
inserted
replaced
10548:479536c5bb10 | 10549:95c3e38098bf |
---|---|
222 | 222 |
223 obj_grd = @fd_obj_grd; | 223 obj_grd = @fd_obj_grd; |
224 have_hess = 0; | 224 have_hess = 0; |
225 if (iscell (objf)) | 225 if (iscell (objf)) |
226 if (length (objf) > 0) | 226 if (length (objf) > 0) |
227 __sqp_obj_fun__ = obj_fun = objf{1}; | 227 __sqp_obj_fun__ = obj_fun = objf{1}; |
228 if (length (objf) > 1) | 228 if (length (objf) > 1) |
229 obj_grd = objf{2}; | 229 obj_grd = objf{2}; |
230 if (length (objf) > 2) | 230 if (length (objf) > 2) |
231 obj_hess = objf{3}; | 231 obj_hess = objf{3}; |
232 have_hess = 1; | 232 have_hess = 1; |
233 endif | 233 endif |
234 endif | 234 endif |
235 else | 235 else |
236 error ("sqp: invalid objective function"); | 236 error ("sqp: invalid objective function"); |
237 endif | 237 endif |
238 else | 238 else |
239 __sqp_obj_fun__ = obj_fun = objf; | 239 __sqp_obj_fun__ = obj_fun = objf; |
240 endif | 240 endif |
241 | 241 |
242 ce_fun = @empty_cf; | 242 ce_fun = @empty_cf; |
243 ce_grd = @empty_jac; | 243 ce_grd = @empty_jac; |
244 if (nargin > 2) | 244 if (nargin > 2) |
245 ce_grd = @fd_ce_jac; | 245 ce_grd = @fd_ce_jac; |
246 if (iscell (cef)) | 246 if (iscell (cef)) |
247 if (length (cef) > 0) | 247 if (length (cef) > 0) |
248 __sqp_ce_fun__ = ce_fun = cef{1}; | 248 __sqp_ce_fun__ = ce_fun = cef{1}; |
249 if (length (cef) > 1) | 249 if (length (cef) > 1) |
250 ce_grd = cef{2}; | 250 ce_grd = cef{2}; |
251 endif | 251 endif |
252 else | 252 else |
253 error ("sqp: invalid equality constraint function"); | 253 error ("sqp: invalid equality constraint function"); |
254 endif | 254 endif |
255 elseif (! isempty (cef)) | 255 elseif (! isempty (cef)) |
256 ce_fun = cef; | 256 ce_fun = cef; |
257 endif | 257 endif |
258 endif | 258 endif |
259 __sqp_ce_fun__ = ce_fun; | 259 __sqp_ce_fun__ = ce_fun; |
260 | 260 |
261 ci_fun = @empty_cf; | 261 ci_fun = @empty_cf; |
262 ci_grd = @empty_jac; | 262 ci_grd = @empty_jac; |
263 | 263 |
264 if (nargin > 3) | 264 if (nargin > 3) |
265 ## constraint function given by user with possibly gradient | 265 ## constraint function given by user with possibly gradient |
266 __sqp_cif__ = cif; | 266 __sqp_cif__ = cif; |
267 ## constraint function given by user without gradient | 267 ## constraint function given by user without gradient |
268 __sqp_cifcn__ = @empty_cf; | 268 __sqp_cifcn__ = @empty_cf; |
269 if (iscell (__sqp_cif__)) | 269 if (iscell (__sqp_cif__)) |
270 if (length (__sqp_cif__) > 0) | 270 if (length (__sqp_cif__) > 0) |
271 __sqp_cifcn__ = __sqp_cif__{1}; | 271 __sqp_cifcn__ = __sqp_cif__{1}; |
272 endif | 272 endif |
273 elseif (! isempty (__sqp_cif__)) | 273 elseif (! isempty (__sqp_cif__)) |
274 __sqp_cifcn__ = __sqp_cif__; | 274 __sqp_cifcn__ = __sqp_cif__; |
275 endif | 275 endif |
276 | 276 |
277 if (nargin < 5) | 277 if (nargin < 5) |
278 ci_grd = @fd_ci_jac; | 278 ci_grd = @fd_ci_jac; |
279 if (iscell (cif)) | 279 if (iscell (cif)) |
280 if (length (cif) > 0) | 280 if (length (cif) > 0) |
281 __sqp_ci_fun__ = ci_fun = cif{1}; | 281 __sqp_ci_fun__ = ci_fun = cif{1}; |
282 if (length (cif) > 1) | 282 if (length (cif) > 1) |
283 ci_grd = cif{2}; | 283 ci_grd = cif{2}; |
284 endif | 284 endif |
285 else | 285 else |
286 error ("sqp: invalid equality constraint function"); | 286 error ("sqp: invalid equality constraint function"); |
287 endif | 287 endif |
288 elseif (! isempty (cif)) | 288 elseif (! isempty (cif)) |
289 ci_fun = cif; | 289 ci_fun = cif; |
290 endif | 290 endif |
291 else | 291 else |
292 global __sqp_lb__; | 292 global __sqp_lb__; |
293 if (isvector (lb)) | 293 if (isvector (lb)) |
294 __sqp_lb__ = lb; | 294 __sqp_lb__ = lb; |
295 elseif (isempty (lb)) | 295 elseif (isempty (lb)) |
296 if (isa (x, "single")) | 296 if (isa (x, "single")) |
297 __sqp_lb__ = -realmax ("single"); | 297 __sqp_lb__ = -realmax ("single"); |
298 else | 298 else |
299 __sqp_lb__ = -realmax; | 299 __sqp_lb__ = -realmax; |
300 endif | 300 endif |
301 else | 301 else |
302 error ("sqp: invalid lower bound"); | 302 error ("sqp: invalid lower bound"); |
303 endif | 303 endif |
304 | 304 |
305 global __sqp_ub__; | 305 global __sqp_ub__; |
306 if (isvector (ub)) | 306 if (isvector (ub)) |
307 __sqp_ub__ = ub; | 307 __sqp_ub__ = ub; |
308 elseif (isempty (lb)) | 308 elseif (isempty (lb)) |
309 if (isa (x, "single")) | 309 if (isa (x, "single")) |
310 __sqp_ub__ = realmax ("single"); | 310 __sqp_ub__ = realmax ("single"); |
311 else | 311 else |
312 __sqp_ub__ = realmax; | 312 __sqp_ub__ = realmax; |
313 endif | 313 endif |
314 else | 314 else |
315 error ("sqp: invalid upper bound"); | 315 error ("sqp: invalid upper bound"); |
316 endif | 316 endif |
317 | 317 |
318 if (lb > ub) | 318 if (lb > ub) |
319 error ("sqp: upper bound smaller than lower bound"); | 319 error ("sqp: upper bound smaller than lower bound"); |
320 endif | 320 endif |
321 __sqp_ci_fun__ = ci_fun = @cf_ub_lb; | 321 __sqp_ci_fun__ = ci_fun = @cf_ub_lb; |
322 ci_grd = @cigrad_ub_lb; | 322 ci_grd = @cigrad_ub_lb; |
323 endif | 323 endif |
324 __sqp_ci_fun__ = ci_fun; | 324 __sqp_ci_fun__ = ci_fun; |
325 endif | 325 endif |
326 | 326 |
327 iter_max = 100; | 327 iter_max = 100; |
328 if (nargin > 6 && ! isempty (maxiter)) | 328 if (nargin > 6 && ! isempty (maxiter)) |
329 if (isscalar (maxiter) && maxiter > 0 && round (maxiter) == maxiter) | 329 if (isscalar (maxiter) && maxiter > 0 && round (maxiter) == maxiter) |
330 iter_max = maxiter; | 330 iter_max = maxiter; |
331 else | 331 else |
332 error ("sqp: invalid number of maximum iterations"); | 332 error ("sqp: invalid number of maximum iterations"); |
333 endif | 333 endif |
334 endif | 334 endif |
335 | 335 |
336 tol = sqrt (eps); | 336 tol = sqrt (eps); |
337 if (nargin > 7 && ! isempty (tolerance)) | 337 if (nargin > 7 && ! isempty (tolerance)) |
338 if (isscalar (tolerance) && tolerance > 0) | 338 if (isscalar (tolerance) && tolerance > 0) |
339 tol = tolerance; | 339 tol = tolerance; |
340 else | 340 else |
341 error ("sqp: invalid value for tolerance"); | 341 error ("sqp: invalid value for tolerance"); |
342 endif | 342 endif |
343 endif | 343 endif |
344 | 344 |
345 iter = 0; | 345 iter = 0; |
346 | 346 |
396 t3 = all (lambda_i >= 0); | 396 t3 = all (lambda_i >= 0); |
397 t4 = norm (lambda .* con); | 397 t4 = norm (lambda .* con); |
398 | 398 |
399 if (t2 && t3 && max ([t0; t1; t4]) < tol) | 399 if (t2 && t3 && max ([t0; t1; t4]) < tol) |
400 info = 101; | 400 info = 101; |
401 break; | 401 break; |
402 endif | 402 endif |
403 | 403 |
404 ## Compute search direction p by solving QP. | 404 ## Compute search direction p by solving QP. |
405 | 405 |
406 g = -ce; | 406 g = -ce; |
411 idx = isinf (d) & d < 0; | 411 idx = isinf (d) & d < 0; |
412 d(idx) = []; | 412 d(idx) = []; |
413 C(idx,:) = []; | 413 C(idx,:) = []; |
414 | 414 |
415 [p, obj_qp, INFO, lambda] = qp (x, B, c, F, g, [], [], d, C, | 415 [p, obj_qp, INFO, lambda] = qp (x, B, c, F, g, [], [], d, C, |
416 Inf (size (d))); | 416 Inf (size (d))); |
417 | 417 |
418 info = INFO.info; | 418 info = INFO.info; |
419 | 419 |
420 ## Check QP solution and attempt to recover if it has failed. | 420 ## Check QP solution and attempt to recover if it has failed. |
421 | 421 |
422 ## Choose mu such that p is a descent direction for the chosen | 422 ## Choose mu such that p is a descent direction for the chosen |
423 ## merit function phi. | 423 ## merit function phi. |
424 | 424 |
425 [x_new, alpha, obj_new] = linesearch_L1 (x, p, obj_fun, obj_grd, | 425 [x_new, alpha, obj_new] = linesearch_L1 (x, p, obj_fun, obj_grd, |
426 ce_fun, ci_fun, lambda, obj); | 426 ce_fun, ci_fun, lambda, obj); |
427 | 427 |
428 ## Evaluate objective function, constraints, and gradients at | 428 ## Evaluate objective function, constraints, and gradients at |
429 ## x_new. | 429 ## x_new. |
430 | 430 |
431 c_new = feval (obj_grd, x_new); | 431 c_new = feval (obj_grd, x_new); |
444 ## y = grad_x L (x_new, lambda) - grad_x L (x, lambda}) | 444 ## y = grad_x L (x_new, lambda) - grad_x L (x, lambda}) |
445 | 445 |
446 y = c_new - c; | 446 y = c_new - c; |
447 | 447 |
448 if (! isempty (A)) | 448 if (! isempty (A)) |
449 t = ((A_new - A)'*lambda); | 449 t = ((A_new - A)'*lambda); |
450 y -= t; | 450 y -= t; |
451 endif | 451 endif |
452 | 452 |
453 delx = x_new - x; | 453 delx = x_new - x; |
454 | 454 |
455 if (norm (delx) < tol * norm (x)) | 455 if (norm (delx) < tol * norm (x)) |
456 info = 101; | 456 info = 101; |
457 break; | 457 break; |
458 endif | 458 endif |
459 | 459 |
460 if (have_hess) | 460 if (have_hess) |
461 | 461 |
462 B = feval (obj_hess, x); | 462 B = feval (obj_hess, x); |
463 | 463 |
464 else | 464 else |
465 | 465 |
466 ## Update B using a quasi-Newton formula. | 466 ## Update B using a quasi-Newton formula. |
467 | 467 |
468 delxt = delx'; | 468 delxt = delx'; |
469 | 469 |
470 ## Damped BFGS. Or maybe we would actually want to use the Hessian | 470 ## Damped BFGS. Or maybe we would actually want to use the Hessian |
471 ## of the Lagrangian, computed directly. | 471 ## of the Lagrangian, computed directly. |
472 | 472 |
473 d1 = delxt*B*delx; | 473 d1 = delxt*B*delx; |
474 | 474 |
475 t1 = 0.2 * d1; | 475 t1 = 0.2 * d1; |
476 t2 = delxt*y; | 476 t2 = delxt*y; |
477 | 477 |
478 if (t2 < t1) | 478 if (t2 < t1) |
479 theta = 0.8*d1/(d1 - t2); | 479 theta = 0.8*d1/(d1 - t2); |
480 else | 480 else |
481 theta = 1; | 481 theta = 1; |
482 endif | 482 endif |
483 | 483 |
484 r = theta*y + (1-theta)*B*delx; | 484 r = theta*y + (1-theta)*B*delx; |
485 | 485 |
486 d2 = delxt*r; | 486 d2 = delxt*r; |
487 | 487 |
488 if (d1 == 0 || d2 == 0) | 488 if (d1 == 0 || d2 == 0) |
489 info = 102; | 489 info = 102; |
490 break; | 490 break; |
491 endif | 491 endif |
492 | 492 |
493 B = B - B*delx*delxt*B/d1 + r*r'/d2; | 493 B = B - B*delx*delxt*B/d1 + r*r'/d2; |
494 | 494 |
495 endif | 495 endif |
496 | 496 |
497 x = x_new; | 497 x = x_new; |
498 | 498 |
552 | 552 |
553 endfunction | 553 endfunction |
554 | 554 |
555 | 555 |
556 function [x_new, alpha, obj] = linesearch_L1 (x, p, obj_fun, obj_grd, | 556 function [x_new, alpha, obj] = linesearch_L1 (x, p, obj_fun, obj_grd, |
557 ce_fun, ci_fun, lambda, obj) | 557 ce_fun, ci_fun, lambda, obj) |
558 | 558 |
559 ## Choose parameters | 559 ## Choose parameters |
560 ## | 560 ## |
561 ## eta in the range (0, 0.5) | 561 ## eta in the range (0, 0.5) |
562 ## tau in the range (0, 1) | 562 ## tau in the range (0, 1) |
725 cigradfcn = @fd_ci_jac; | 725 cigradfcn = @fd_ci_jac; |
726 | 726 |
727 if (iscell (__sqp_cif__) && length (__sqp_cif__) > 1) | 727 if (iscell (__sqp_cif__) && length (__sqp_cif__) > 1) |
728 cigradfcn = __sqp_cif__{2}; | 728 cigradfcn = __sqp_cif__{2}; |
729 endif | 729 endif |
730 | 730 |
731 if (! isempty (cigradfcn)) | 731 if (! isempty (cigradfcn)) |
732 res = [feval(cigradfcn,x); eye(numel(x)); -eye(numel(x))]; | 732 res = [feval(cigradfcn,x); eye(numel(x)); -eye(numel(x))]; |
733 endif | 733 endif |
734 | 734 |
735 endfunction | 735 endfunction |