Commit d78ad76a authored by Christoph Richter's avatar Christoph Richter
Browse files

Ipopt: Include constraints in opt var matrix elements directly on opt var

parent b1728418
......@@ -157,6 +157,11 @@ public class Problem {
*/
private Vector<String> gU = new Vector<>();
/**
* Additional constraints on optimization variable
*/
private Vector<String> xMatrixElementConstraints = new Vector<>();
// getter setter
public int getM() {
......@@ -206,4 +211,12 @@ public class Problem {
public void setgU(Vector<String> gU) {
this.gU = gU;
}
public void setXMatrixElementConstraints(Vector<String> xMatrixElementConstraints) {
this.xMatrixElementConstraints = xMatrixElementConstraints;
}
public Vector<String> getXMatrixElementConstraints() {
return xMatrixElementConstraints;
}
}
package de.monticore.lang.monticar.generator.cpp.optimizationSolver.problem;
import de.monticore.lang.math._symboltable.expression.*;
import de.monticore.lang.math._symboltable.matrix.MathMatrixNameExpressionSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationStatementSymbol;
import de.monticore.lang.monticar.generator.Generator;
......@@ -64,13 +65,34 @@ public class ProblemAssignmentHandler {
}
private boolean isConstraintOnOptVar(Problem p, MathExpressionSymbol expr) {
return expr.getTextualRepresentation().contentEquals(p.getOptimizationVariableName());
String name = "";
if (expr instanceof MathNameExpressionSymbol) {
name = ((MathNameExpressionSymbol) expr).getNameToResolveValue();
} else if (expr instanceof MathMatrixNameExpressionSymbol) {
name = ((MathMatrixNameExpressionSymbol) expr).getNameToAccess();
} else {
name = "";
}
return name.contentEquals(p.getOptimizationVariableName());
}
private void mergeBoundsInX(Problem p, Vector<String> xL, Vector<String> xU, MathExpressionSymbol expr, String currXL, String currXU) {
for (int i = 0; i < p.getN(); i++) {
xL.set(i, String.format("std::fmax(%s, %s)", xL.get(i), currXL));
xU.set(i, String.format("std::fmin(%s, %s)", xU.get(i), currXU));
private void mergeBoundsInX(Problem p, Vector<String> xL, Vector<String> xU, MathExpressionSymbol expr, String currXL, String currXU, Vector<String> xMatrixElementConstraints) {
if (expr instanceof MathMatrixNameExpressionSymbol) {
MathMatrixNameExpressionSymbol matNameExpr = (MathMatrixNameExpressionSymbol) expr;
String indexExpr = ExecuteMethodGeneratorMatrixExpressionHandler.generateExecuteCode(matNameExpr.getMathMatrixAccessOperatorSymbol(), new ArrayList<>());
indexExpr = indexExpr.replaceAll(",", "+");
if (MathConverter.curBackend.usesZeroBasedIndexing()) {
indexExpr += " - " + matNameExpr.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().size();
}
String funcSigniture = String.format("%s, %s, %s", currXL, indexExpr, currXU);
xMatrixElementConstraints.add(funcSigniture);
} else if (expr instanceof MathNameExpressionSymbol) {
for (int i = 0; i < p.getN(); i++) {
xL.set(i, String.format("std::fmax(%s, %s)", xL.get(i), currXL));
xU.set(i, String.format("std::fmin(%s, %s)", xU.get(i), currXU));
}
} else {
Log.error("Function mergeBoundsInX: Constraint expression must be an optimization variable here.");
}
}
......@@ -95,10 +117,11 @@ public class ProblemAssignmentHandler {
Vector<String> gU = new Vector<>();
Vector<String> xL = new Vector<>();
Vector<String> xU = new Vector<>();
Vector<String> xMatrixElementConstraints = new Vector<>();
// add constraints
setBoundsOnXFromTypeDeclaration(symbol, xL, xU, p.getN());
addConstraintsOnObjectiveVariable(symbol, g, gL, gU);
addSubjectToConstraints(p, symbol, xL, xU, g, gL, gU);
addSubjectToConstraints(p, symbol, xL, xU, g, gL, gU, xMatrixElementConstraints);
// set nlp
p.setM(g.size());
p.setConstraintFunctions(g);
......@@ -106,17 +129,18 @@ public class ProblemAssignmentHandler {
p.setgU(gU);
p.setxL(xL);
p.setxU(xU);
p.setXMatrixElementConstraints(xMatrixElementConstraints);
}
private void addSubjectToConstraints(Problem p, MathOptimizationStatementSymbol symbol, Vector<String> xL, Vector<String> xU, Vector<String> g, Vector<String> gL, Vector<String> gU) {
private void addSubjectToConstraints(Problem p, MathOptimizationStatementSymbol symbol, Vector<String> xL, Vector<String> xU, Vector<String> g, Vector<String> gL, Vector<String> gU, Vector<String> xMatrixElementConstraints) {
for (MathExpressionSymbol constraint : symbol.getSubjectToExpressions()) {
// find function
if (constraint instanceof MathOptimizationConditionSymbol) {
MathOptimizationConditionSymbol singleConstraint = (MathOptimizationConditionSymbol) constraint;
addSingleConstraint(p, g, gL, gU, xL, xU, singleConstraint);
addSingleConstraint(p, g, gL, gU, xL, xU, singleConstraint, xMatrixElementConstraints);
} else if (constraint instanceof MathForLoopExpressionSymbol) {
MathForLoopExpressionSymbol loopConstraint = (MathForLoopExpressionSymbol) constraint;
addLoopConstraints(p, g, gL, gU, xL, xU, loopConstraint);
addLoopConstraints(p, g, gL, gU, xL, xU, loopConstraint, xMatrixElementConstraints);
}
}
}
......@@ -137,7 +161,7 @@ public class ProblemAssignmentHandler {
}
}
private void addLoopConstraints(Problem p, Vector<String> g, Vector<String> gL, Vector<String> gU, Vector<String> xL, Vector<String> xU, MathForLoopExpressionSymbol loopConstraint) {
private void addLoopConstraints(Problem p, Vector<String> g, Vector<String> gL, Vector<String> gU, Vector<String> xL, Vector<String> xU, MathForLoopExpressionSymbol loopConstraint, Vector<String> xMatrixElementConstraints) {
Optional<MathExpressionSymbol> startExpr = ForLoopHeadConverter.getForLoopStart(loopConstraint.getForLoopHead());
Optional<MathExpressionSymbol> endExpr = ForLoopHeadConverter.getForLoopEnd(loopConstraint.getForLoopHead());
Optional<MathExpressionSymbol> stepExpr = ForLoopHeadConverter.getForLoopStep(loopConstraint.getForLoopHead());
......@@ -158,12 +182,13 @@ public class ProblemAssignmentHandler {
for (double i = loopStart; i <= loopEnd; i += loopStep) {
for (MathExpressionSymbol constraint : loopConstraint.getForLoopBody()) {
if (constraint instanceof MathOptimizationConditionSymbol) {
addSingleConstraint(p, g, gL, gU, xL, xU, (MathOptimizationConditionSymbol) constraint);
if (!isConstraintOnOptVar(p, constraint)) {
int size = g.size();
addSingleConstraint(p, g, gL, gU, xL, xU, (MathOptimizationConditionSymbol) constraint, xMatrixElementConstraints);
if (!isConstraintOnOptVar(p, constraint) && (g.size() == size + 1)) {
g.set(g.size() - 1, replaceLoopVariable(g.lastElement(), loopConstraint.getForLoopHead().getNameLoopVariable(), Double.toString(i)));
}
} else if (constraint instanceof MathForLoopExpressionSymbol) {
addLoopConstraints(p, g, gL, gU, xL, xU, (MathForLoopExpressionSymbol) constraint);
addLoopConstraints(p, g, gL, gU, xL, xU, (MathForLoopExpressionSymbol) constraint, xMatrixElementConstraints);
}
}
}
......@@ -184,11 +209,11 @@ public class ProblemAssignmentHandler {
Log.error(String.format("Cannot resolve value of \"%s\"", loopExpressionSymbol.getForLoopHead().getTextualRepresentation()), loopExpressionSymbol.getForLoopHead().getSourcePosition());
}
private void addSingleConstraint(Problem p, Vector<String> g, Vector<String> gL, Vector<String> gU, Vector<String> xL, Vector<String> xU, MathOptimizationConditionSymbol singleConstraint) {
private void addSingleConstraint(Problem p, Vector<String> g, Vector<String> gL, Vector<String> gU, Vector<String> xL, Vector<String> xU, MathOptimizationConditionSymbol singleConstraint, Vector<String> xMatrixElementConstraints) {
MathExpressionSymbol expr = singleConstraint.getBoundedExpression();
String[] bounds = getBoundsFromConstraint(p, singleConstraint);
if (isConstraintOnOptVar(p, expr)) {
mergeBoundsInX(p, xL, xU, expr, bounds[0], bounds[1]);
mergeBoundsInX(p, xL, xU, expr, bounds[0], bounds[1], xMatrixElementConstraints);
} else {
MathFunctionFixer.fixMathFunctions(expr, ComponentConverter.currentBluePrint);
String gAsString = ExecuteMethodGenerator.generateExecuteCode(expr, new ArrayList<>());
......
......@@ -74,6 +74,11 @@ public abstract class SolverViewModel extends ViewModelBase {
*/
private Vector<String> gU;
/**
* additional constraints on single optimization variable matrix elements which can not be evaluated static
*/
private Vector<String> xMatrixElementConstraints;
/**
* starting point of the iteration for x
*/
......@@ -117,6 +122,7 @@ public abstract class SolverViewModel extends ViewModelBase {
this.gU = problem.getgU();
this.xL = problem.getxL();
this.xU = problem.getxU();
this.xMatrixElementConstraints = problem.getXMatrixElementConstraints();
this.objectiveFunction = problem.getObjectiveFunction();
this.optimizationVariableName = problem.getOptimizationVariableName();
setOptimizationVariableType(problem.getOptimizationVariableType());
......@@ -360,4 +366,12 @@ public abstract class SolverViewModel extends ViewModelBase {
public void setOptimizationVariableTypeActive(String optimizationVariableTypeActive) {
this.optimizationVariableTypeActive = optimizationVariableTypeActive;
}
public Vector<String> getxMatrixElementConstraints() {
return xMatrixElementConstraints;
}
public void setxMatrixElementConstraints(Vector<String> xMatrixElementConstraints) {
this.xMatrixElementConstraints = xMatrixElementConstraints;
}
}
......@@ -165,6 +165,11 @@ class ${viewModel.callSolverName}
}
}
};
static void addConstraintOnX(Dvector &xl, Dvector &xu, const double &lower, int index, const double &upper) {
xl[index] = std::fmax(xl[index], lower);
xu[index] = std::fmin(xu[index], upper);
};
public:
static bool solveOptimizationProblemIpOpt(
......@@ -215,6 +220,11 @@ class ${viewModel.callSolverName}
i${viewModel.id}++;
</#list>
// limits for special matrix elements of x
<#list viewModel.xMatrixElementConstraints as element>
addConstraintOnX(xl, xu, ${element});
</#list>
// lower and upper limits for g
Dvector gl(ng),gu(ng);
<#list viewModel.constraintFunctions as g>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment