77 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Matlab
		
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Matlab
		
	
	
| import gtsam.*
 | |
| g = [-1; -1]  % min -x1-x2
 | |
| C = [-1 0
 | |
|     0 -1
 | |
|     1 2
 | |
|     4 2
 | |
|     -1 1]';
 | |
| b =[0;0;4;12;1]
 | |
| 
 | |
| %% step 0
 | |
| m = length(C);
 | |
| active = zeros(1, m);
 | |
| x0 = [0;0];
 | |
| 
 | |
| for iter = 1:2
 | |
|     % project -g onto the nullspace of active constraints in C to obtain the moving direction
 | |
|     % It boils down to solving the following constrained linear least squares
 | |
|     % system:  min_d//  || d// - d ||^2
 | |
|     %           s.t. C*d// = 0
 | |
|     % where d = -g, the opposite direction of the objective's gradient vector
 | |
|     dgraph = GaussianFactorGraph
 | |
|     dgraph.push_back(JacobianFactor(1, eye(2), -g, noiseModel.Unit.Create(2)));
 | |
|     for i=1:m
 | |
|         if (active(i)==1)
 | |
|             ci = C(:,i);
 | |
|             dgraph.push_back(JacobianFactor(1, ci', 0, noiseModel.Constrained.All(1)));
 | |
|         end
 | |
|     end
 | |
|     d = dgraph.optimize.at(1)
 | |
|     
 | |
|     % Find the bad active constraints and remove them
 | |
|     % TODO: FIXME Is this implementation correct?
 | |
|     for i=1:m
 | |
|         if (active(i) == 1)
 | |
|             ci = C(:,i);
 | |
|             if ci'*d < 0
 | |
|                 active(i) = 0;
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|     active
 | |
|     
 | |
|     % We are going to jump:
 | |
|     %       x1 = x0 + k*d;, k>=0
 | |
|     % So check all inactive constraints that block the jump to find the smallest k
 | |
|     % ci*x1 - bi <=0
 | |
|     % ci*(x0 + k*d) - bi <= 0
 | |
|     % ci*x0-bi + ci*k*d <= 0
 | |
|     % - if ci*d < 0: great, no prob (-ci and d have the same direction)
 | |
|     % - if ci*d > 0: (-ci and d have opposite directions)
 | |
|     %     k <= -(ci*x0 - bi)/(ci*d)
 | |
|     k = 100000;
 | |
|     newActive = -1;
 | |
|     for i=1:m
 | |
|         if active(i) == 1
 | |
|             continue
 | |
|         end
 | |
|         ci = C(:,i);
 | |
|         if ci'*d > 0
 | |
|             foundNewActive = true;
 | |
|             if k > -(ci'*x0 - b(i))/(ci'*d)
 | |
|                 k = -(ci'*x0 - b(i))/(ci'*d);
 | |
|                 newActive = i;
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|     
 | |
|     % If there is no blocking constraint, the problem is unbounded
 | |
|     if newActive == -1
 | |
|         disp('Unbounded')
 | |
|     else
 | |
|         % Otherwise, make the jump, and we have a new active constraint
 | |
|         x0 = x0 + k*d
 | |
|         active(newActive) = 1
 | |
|     end
 | |
|     
 | |
| end |