Optional custom x0 for IPM initialization - #74
Conversation
|
Does this initialization actually help over the default initialization? For best performance IPMs should be initialized near the central path which is what the default initialization does. |
|
I don’t expect this to beat the default initializer in general. For cold starts the default initialization is likely better, since it is designed for central path / better convergence. The intent here is just to expose a hook for callers that have an educated guess from outside information and want If you think this could be misleading as a normal user-facing API, I can mark it experimental. |
|
Yeah no problem. I was just curious if having a good guess for |
|
My main motivating case is when QOCO is used as a refinement step after another method has already produced a near-feasible primal candidate. For example, a DP/heuristic solve of a simplified problem may give a good So yes, I expect this to be very problem-dependent. I’m not claiming it improves generic cold starts; it’s mainly for workflows with an external primal guess. A synthetic example would be a «burning gas + pistons» dynamic (in time) allocation problem: use DP on a simplified level/snapshot model to get an integer redistribution plan, then use that as the primal guess for a conic solve that adds the time dynamics and coupling constraints. |
I understand, but even with a good prior for |
|
Unfortunately, I don’t have a shareable instance right now :( |
|
Have you observed any cases where a custom initialization is better than the default initialization? |
|
Yes, I have, in a few problem-specific cases. The main improvement I saw was not necessarily faster convergence to the same optimum, but better intermediate solutions when the solver did not reach a feasible/acceptable point within the iteration budget. With a good external primal guess, even the first few IPM steps could improve the result compared with the default start. |
Adds
qoco_set_x0()so callers can pass an optional primal starting point afterqoco_setup()and beforeqoco_solve()When
x0is set, QOCO copies it into the workspace and treats it as being in the original problem scaling. During init proc we use it for the starting point forx(obviously), recomputes0 = h - Gx0, and pushs0into the cone interior viabring2coneif needed. The existing initializer still picksy0and an interiorz0Also adds the C API docs and tests for copying
x0, clearing it withNULL, scaling behavior, and slack init