/*
* Copyright 2011-2013 JOptimizer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.joptimizer.optimizers;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import cern.colt.matrix.DoubleFactory1D;
import cern.colt.matrix.DoubleFactory2D;
import cern.colt.matrix.DoubleMatrix1D;
import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import com.joptimizer.functions.BarrierFunction;
import com.joptimizer.functions.LinearMultivariateRealFunction;
/**
* Basic Phase I Method (implemented as a Barried Method).
*
* @see "S.Boyd and L.Vandenberghe, Convex Optimization, p. 579"
* @author alberto trivellato (alberto.trivellato@gmail.com)
*/
public class BasicPhaseIBM {
private BarrierMethod originalProblem;
private int originalDim =-1;
private int dim =-1;
private Algebra ALG = Algebra.DEFAULT;
private DoubleFactory1D F1 = DoubleFactory1D.dense;
private DoubleFactory2D F2 = DoubleFactory2D.dense;
private Log log = LogFactory.getLog(this.getClass().getName());
public BasicPhaseIBM(BarrierMethod originalProblem) {
this.originalProblem = originalProblem;
originalDim = originalProblem.getDim();
this.dim = originalProblem.getDim()+1;//variable Y=(X, s)
}
public double[] findFeasibleInitialPoint() throws Exception{
log.debug("findFeasibleInitialPoint");
OptimizationRequest or = new OptimizationRequest();
//objective function: s
DoubleMatrix1D C = F1.make(dim);
C.set(dim-1, 1.);
LinearMultivariateRealFunction objectiveFunction = new LinearMultivariateRealFunction(C.toArray(), 0);
or.setF0(objectiveFunction);
or.setToleranceFeas(originalProblem.getToleranceFeas());
or.setTolerance(originalProblem.getTolerance());
or.setCheckKKTSolutionAccuracy(originalProblem.isCheckKKTSolutionAccuracy());
// // Inquality constraints: fi(X)-s
// ConvexMultivariateRealFunction[] inequalities = new ConvexMultivariateRealFunction[originalProblem.getFi().length];
// for(int i=0; i originalProblem.getToleranceFeas()){
throw new Exception("The initial point for Basic Phase I Method must be equalities-feasible");
}
}
//DoubleMatrix1D originalFiX0 = originalProblem.getFi(X0);
double s = originalProblem.getBarrierFunction().calculatePhase1InitialFeasiblePoint(X0.toArray(), originalProblem.getToleranceFeas());
//lucky strike?
// int maxIneqIndex = Utils.getMaxIndex(originalFiX0);
// if(originalFiX0.get(maxIneqIndex) + originalProblem.getTolerance()<0){
// //the given notFeasible starting point is in fact already feasible
// return X0;
// }
if(s < 0){
//the given notFeasible starting point is in fact already feasible
return X0.toArray();
}
// DoubleMatrix1D initialPoint = F1.make(1, -Double.MAX_VALUE);
// initialPoint = F1.append(X0, initialPoint);
// for(int i=0; i0){
// if(ineq.get(maxIneqIndex)>=0){
// throw new Exception("Infeasible problem");
// }
double[] originalSolution = Arrays.copyOf(response.getSolution(), originalDim);
if(Double.isNaN(originalProblem.getBarrierFunction().value(originalSolution))){
throw new Exception("Infeasible problem");
}
return originalSolution;
}
private class PhaseIBarrierMethod extends BarrierMethod{
public PhaseIBarrierMethod(BarrierFunction barrierFunction) {
super(barrierFunction);
}
@Override
protected boolean checkCustomExitConditions(DoubleMatrix1D Y){
DoubleMatrix1D X = Y.viewPart(0, dim-1);
//equalities
DoubleMatrix1D originalRPriX = F1.make(0);
if(getA()!=null){
originalRPriX = originalProblem.getA().zMult(X, originalProblem.getB().copy(), 1., -1., false);
}
boolean b2 = Math.sqrt(ALG.norm2(originalRPriX)) < originalProblem.getToleranceFeas();
//inequalities
boolean b1 = !Double.isNaN(originalProblem.getBarrierFunction().value(X.toArray())) || Y.get(Y.size()-1)<0;
log.debug("checkCustomExitConditions: " + (b1 && b2));
return b1 && b2;
}
}
/**
* Just looking for one out of all the possible solutions.
* @see "Convex Optimization, C.5 p. 681".
*/
private DoubleMatrix1D findOneRoot(double[][] A, double[] b) throws Exception{
return F1.make(originalProblem.findEqFeasiblePoint(A, b));
}
}
Ads help maintain this website.