How can I write a CVX problem inside of a `for-loop` and save the result of an iteration to be used in the next one?

Hello, folks

I’m trying to use CVX to solve an linear optimization problem. My problem has intertemporal constraints, i.e, a decision taken at time step (or iteration) i affects the problem at time step i+1.

For that, my idea was to solve an optimization as many times as I need using a for loop. This means I coded something like

for i = 1:20
   cvx_begin
   variables x
       # Here's some code
       if i > 1
          x - xpast <= 10;
          xpast - x <= 10;
       end
   cvx_end
   xpast = x;
end

Right after cvx_end, I’d save the variables I needed for the next iteration as xpast and then, when i > 1, I’d use xpast to ensure I explicitly have the intertemporal constriants.

This seems logical to me: At iteration i = 1, CVX solves the problem, i.e., defines x, and save its value to xpast. At i = 2, the if condition will be checked and xpast will be used. At this point, because xpast is saved after cvx_end, I know it’s just “any other” Matlab variable.

I am not sure this is correct, though. I have tried to create a reproducible example (at the end of this post) that display the issue I’m facing, but I failed. In the simpler reproducible example, the status of each optimization problem is Solved. When I run my actual problem, I run into problems and get the following error message:

Error using  + 
Disciplined convex programming error:
   Illegal operation: {real affine} - {invalid}

Error in  -  (line 21)
z = plus( x, y, true, cheat );

Error in problem1_multi_interval_final_project (line 131)
       # Here's the line where I have x - xpast <= [number]

At this point, I feel like asking: Is there any problem in embedding the entire body of a CVX problem inside of a for loop? Before I made the last round of alterations in my code, I didn’t have the Illegal operation issue, but the statuses of my problems showed that in iterations 2 and 3, the status was Inaccurate/Solved, and in iteration 4 the status was Infeasible.

If you see any obvious error (I’m not experienced in Matlab or CVX) and/or any thing that just seems weird to you, please let me know. Thank you for your help.


Here’s the reproducible example that (sadly) does not reproduce the problem I’m dealing with, but shows the way I structured my problem.

problem_status = strings(3,1);
stored_x = zeros(3,1);
stored_x_past = zeros(2,1);

for i = 1:3
   cvx_begin quiet
   % Primal and dual variables -----------------------------------------------
   variables x
   	
   % -------------------------------------------------------------------------
   % Objective function 
   % -------------------------------------------------------------------------
   minimize x
   
   % -------------------------------------------------------------------------
   % Constraints
   % -------------------------------------------------------------------------
   subject to
   
   x >= 5;
      if i > 1
          x - x_past <= 2;
          x_past - x <= 2;
      end	
   cvx_end
   
   x_past = x;
   problem_status(i) = cvx_status;
   stored_x(i) = x;
   
   if i > 2
	stored_x(i) = x_past;
   end
end

Note that

>> problem_status

problem_status = 

  3×1 string array

    "Solved"
    "Solved"
    "Solved"

and

>> stored_x

stored_x =

    5.0000
    5.0000
    5.0000

and

>> stored_x_past

stored_x_past =

         0
    5.0000
    5.0000

You can have

for i=1:n....
  cvx_begin
  variables x y  .
   ..
  cvx_end
  x_array(i) = x;
  y_array(i) = y;
end

which solves a separate optimization problem for each time through the for loop. At the end of which x_array and y_array have the optimal values of x and y for all the optimization problems.

If an optimization problem is not solved to optimality, due to solver numerical difficulty, or determination that the problem is infeasible or unbounded, the optimal variable values may be populated with NaN. If those are used or transformed into inputs for the next iteration of the for loop, CVX will consider NaN input data to be invalid, and issue an error message.

Perhaps you want to solve a single intertemporal problem, in which one or more for loops might be used to construct the constraints. That would have the form

cvx_begin
...
for i=1:n.
  % construct ith constraint
end
...
cvx_end

All the constraints are in a single optimization problem. You might be able to construct the intertemportal constraints without a for loop, using vectorized operations, which can save a lot oif CVX “model building” time.