Commit 92374348 authored by Jan Philipp Haller's avatar Jan Philipp Haller
Browse files

Bugfix mpc generation

parent f50b4bb5
Pipeline #422156 failed with stage
in 1 minute and 24 seconds
......@@ -3,6 +3,7 @@ package de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.solv
import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.Generator;
import de.monticore.lang.monticar.generator.Variable;
import de.monticore.lang.monticar.generator.cmake.CMakeConfig;
import de.monticore.lang.monticar.generator.cmake.CMakeFindModule;
import de.monticore.lang.monticar.generator.cpp.EMAMBluePrintCPP;
......@@ -74,24 +75,23 @@ public class IpoptSolverGeneratorImplementation implements NLPSolverGeneratorImp
options.put("Retape", "true");
vm.setOptions(options);
// set execute command
vm.setKnownVariablesFromBluePrint(bluePrint);
vm.setExternalVariablesFromBluePrint(bluePrint);
String knownVariables = ", ";
/*
for (String s : vm.getKnownVariables()) {
knownVariables += s + ", ";
for (Variable v : vm.getExternalVariables()) {
knownVariables += v.getName() + ", ";
}
if (knownVariables.length() >= 2) {
knownVariables = knownVariables.substring(0, knownVariables.length() - 2);
}*/
vm.setKnownVariablesWithNumbers();
}
String objVar = vm.getObjectiveVariableName();
if (objVar.isEmpty())
objVar = "objectiveValue" + optimizationProblem.getId();
//ToDo: modify call. Restriction: only same type? (Matrix opposed to skalar)
//Dynamic function call, better generated by vm
if(!vm.getOptimizationVariables().isEmpty()) {
result = String.format("%s::solveOptimizationProblemIpOpt(%s, %s%s);\n", vm.getCallSolverName(), vm.getOptimizationVariables().get(0).getName(), objVar, knownVariables);
result = String.format("%s::solveOptimizationProblemIpOpt(%s, %s%s);\n", vm.getCallSolverName(), /*vm.getOptimizationVariables().get(0).getName()*/ "" , objVar, knownVariables);
}
result = String.format("%s::solveOptimizationProblemIpOpt(%s);\n", vm.getCallSolverName(),vm.getIpoptSolverFunctionCallParameters());
// generate templates by view model
generateIpoptTemplates(vm, auxillaryFiles);
necessaryIncludes.add(vm.getCallSolverName());
......@@ -144,12 +144,12 @@ public class IpoptSolverGeneratorImplementation implements NLPSolverGeneratorImp
public List<CMakeFindModule> getCMakeDependencies() {
CMakeFindModule findCPPAD = new CMakeFindModule("CPPAD", "cppad/ipopt/solve.hpp", "", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), true, false, true);
CMakeFindModule findIPOpt = new CMakeFindModule("Ipopt", "coin/IpNLP.hpp", "ipopt", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), true, true, true);
CMakeFindModule findCoinMumps = new CMakeFindModule("CoinMumps", "", "coinmumps", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
CMakeFindModule findCoinLapack = new CMakeFindModule("CoinLapack", "", "coinlapack", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
CMakeFindModule findCoinBlas = new CMakeFindModule("CoinBlas", "", "coinblas", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
CMakeFindModule findCoinMetis = new CMakeFindModule("CoinMetis", "", "coinmetis", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
CMakeFindModule findGfortran = new CMakeFindModule("GFortran", "", "gfortran", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
return Arrays.asList(findCPPAD, findIPOpt, findCoinMumps, findCoinLapack, findCoinBlas, findCoinMetis, findGfortran);
//CMakeFindModule findCoinMumps = new CMakeFindModule("CoinMumps", "", "coinmumps", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
//CMakeFindModule findCoinLapack = new CMakeFindModule("CoinLapack", "", "coinlapack", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
//CMakeFindModule findCoinBlas = new CMakeFindModule("CoinBlas", "", "coinblas", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
//CMakeFindModule findCoinMetis = new CMakeFindModule("CoinMetis", "", "coinmetis", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
//CMakeFindModule findGfortran = new CMakeFindModule("GFortran", "", "gfortran", new ArrayList<String>(), new ArrayList<String>(), new ArrayList(), new ArrayList(), new ArrayList(), false, true, true);
return Arrays.asList(findCPPAD, findIPOpt);
}
}
......@@ -12,6 +12,8 @@ import de.monticore.lang.math._symboltable.matrix.MathMatrixVectorExpressionSymb
import de.monticore.lang.math._symboltable.visitor.MathExpressionSymbolVisitor;
import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
import de.monticore.lang.mathopt._symboltable.visitor.MathOptExpressionSymbolVisitor;
import de.monticore.lang.monticar.generator.Variable;
import de.monticore.lang.monticar.generator.cpp.EMAMBluePrintCPP;
import de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.problem.Problem;
import de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.solver.template.SolverViewModel;
......@@ -49,6 +51,9 @@ public class IpoptViewModel extends SolverViewModel {
*/
private static final String[] IPOPT_RESERVATED_VARS = {IPOPT_OPTIMIZATION_VAR, IPOPT_OBJECTIVE_VAR, IPOPT_CONSTRAINT_FUNCTION_VAR};
//external variables from EMAM workspace, somehow derived with Blueprint
List<Variable> externalVariables = new ArrayList<>();
// constructor
/**
......@@ -65,7 +70,7 @@ public class IpoptViewModel extends SolverViewModel {
public Boolean isMPCModel(){
Boolean containsAssignment = false;
//ToDo: Better check if recursive definition exists. aka. same active var left and right.
//Better check if recursive definition exists. aka. same active var left and right.
for( MathOptimizationConditionSymbol optConSym : getConstraintFunctions()){
if(optConSym.getOperator()=="==")
containsAssignment = true;
......@@ -73,6 +78,85 @@ public class IpoptViewModel extends SolverViewModel {
return hasStepSize() && containsAssignment;
}
public boolean isExternalVariable(String varName){
for(Variable v: getExternalVariables()){
if(v.getName().equals(varName))
return true;
}
return false;
}
public void setExternalVariablesFromBluePrint(EMAMBluePrintCPP bluePrint) {
this.externalVariables.clear();
List<Variable> variables = bluePrint.getMathInformationRegister().getVariables();
variables.addAll(bluePrint.getVariables());
for (Variable v : variables) {
if (!isOptScopedVariable(v.getName()) && (v.isConstantVariable() || v.isInputVariable())) {
if(!isExternalVariable(v.getName()))
this.externalVariables.add(v);
}
}
}
public String getExternalVariableType(Variable extVar){
if(extVar.getVariableType() != null){
return extVar.getVariableType().getTypeNameTargetLanguage();
}
return "double";
}
public List<Variable> getExternalVariables(){
return externalVariables;
}
public String getIpoptSolverFunctionCallParameters(){
//original result = String.format("%s::solveOptimizationProblemIpOpt(%s, %s%s);\n", vm.getCallSolverName(), /*vm.getOptimizationVariables().get(0).getName()*/ "" , objVar, knownVariables);
String result = "";
//Pointer to optimization variables (return values)
for (MathValueSymbol opt : getOptimizationVariables()){
String varName = opt.getName();
result += varName+", ";
}
//Objective variable (return value)
result += getObjectiveVariableName()+", ";
//External Variables, treated as constants regarding optimization
for(Variable var : getExternalVariables()){
String varName = var.getName();
result += varName+", ";
}
if (result.length() >= 2) {
result = result.substring(0, result.length() - 2);
}
return result;
}
public String getIpoptSolverFunctionParameters(){
String result = "";
//Pointer to optimization variables (return values)
for (MathValueSymbol opt : getOptimizationVariables()){
String varType = getVariableType(opt);
String varName = opt.getName();
result += varType+ " &"+varName+", ";
}
//Objective variable (return value)
result += getVariableType(getObjectiveVariable()) + " &"+getObjectiveVariableName()+", ";
//External Variables, treated as constants regarding optimization
for(Variable var : getExternalVariables()){
String varType = var.getVariableType().getTypeNameTargetLanguage();
String varName = var.getName();
result += varType+ " "+varName+", ";
}
if (result.length() >= 2) {
result = result.substring(0, result.length() - 2);
}
return result;
}
public String getVariableType(MathValueSymbol symbol){
//String debug = "type"+symbol.getType().getName() +
// "\n typeType: "+symbol.getType().getType().getName() + "\n isRational: "+symbol.getType().getType().isRational();
......@@ -222,8 +306,13 @@ public class IpoptViewModel extends SolverViewModel {
}
public String getConstraintLowerBound(MathOptimizationConditionSymbol constraint){
if(constraint.getLeft() != null)
return constraint.getLeft().getTextualRepresentation();
if(constraint.getLeft() != null) {
if(containsOptScopedVariable(constraint.getLeft())){
return "-1E19"; // This constraint is already covered by the variable constraints of the independent Variable
} else {
return constraint.getLeft().getTextualRepresentation();
}
}
else if(constraint.getLowerBound().isPresent())
return constraint.getLowerBound().get().getTextualRepresentation();
else
......@@ -231,35 +320,8 @@ public class IpoptViewModel extends SolverViewModel {
}
public String getObjectiveFunctionWithIpoptVectorEntries() {
MathExpressionSymbol symbol = getObjectiveFunction();
MathValueVisitor valueVisitor = new MathValueVisitor();
MathAccessVisitor accessVisitor = new MathAccessVisitor();
valueVisitor.handle(symbol);
accessVisitor.handle(symbol);
//getObjectiveFunction().
//replaceVariablesWithIpoptVectorEntry()
//ähnlich zu getConstraintForFG_Eval!
for (MathValueSymbol value : valueVisitor.getMathValueSymbols()){
if(isOptScopedVariable(value.getName())) {
value.getValue();
}
}
for (MathNameExpressionSymbol value : accessVisitor.getMathNameExpressionSymbols()){
if(isOptScopedVariable(value.getNameToAccess()))
return "";
}
for (MathMatrixNameExpressionSymbol value : accessVisitor.getMathMatrixNameExpressionSymbols()){
if(isOptScopedVariable(value.getNameToAccess()))
return "";
}
return "";
return getIpoptTextualRepresentation(symbol, "vars", 0);
}
public String listClassesInScope(){
......@@ -427,8 +489,46 @@ public class IpoptViewModel extends SolverViewModel {
return modifiedConstraints;
}
private boolean replacementListContainsKey(List<String[]> list, String key){
for (String[] element : list){
if(element[0].equals(key))
return true;
}
return false;
}
public String getIpoptTextualRepresentation(MathExpressionSymbol symbol, String vectorname, int offset){
if(symbol==null)
return "";
MathAccessVisitor mav = new MathAccessVisitor();
String textRep = symbol.getTextualRepresentation();
mav.handle(symbol);
List<String[]> replacementList = new ArrayList<>();
for (MathMatrixNameExpressionSymbol matAccess : mav.getMathMatrixNameExpressionSymbols()){
if(isOptScopedVariable(matAccess.getNameToAccess())) {
String replacement = transformEMAMMatrixAccessToVectorNotation(matAccess, vectorname, offset);
String search = matAccess.getTextualRepresentation();
String replacementPair[] = {search, replacement};
if(!replacementListContainsKey(replacementList, search))
replacementList.add(replacementPair);
}
}
for (MathNameExpressionSymbol matAccess : mav.getMathNameExpressionSymbols()){
if(isOptScopedVariable(matAccess.getNameToAccess())) {
String replacement = transformEMAMValueToVectorNotation(matAccess, vectorname, offset);
String search = matAccess.getTextualRepresentation();
String replacementPair[] = {search, replacement};
if(!replacementListContainsKey(replacementList, search))
replacementList.add(replacementPair);
}
}
for(String replacementPair[] : replacementList) {
textRep = textRep.replace(replacementPair[0],replacementPair[1]);
}
return textRep;
}
public String getConstraintForFG_Eval(MathExpressionSymbol constraint, int nr){
......@@ -444,54 +544,16 @@ public class IpoptViewModel extends SolverViewModel {
//MPC
MathMatrixNameExpressionSymbol left = (MathMatrixNameExpressionSymbol) optCondition.getLeft();
String leftSide = transformEMAMMatrixAccessToVectorNotation(left,"fg",1);
String rightSide = getIpoptTextualRepresentation(optCondition.getRight(),"vars",0);
MathAccessVisitor mav = new MathAccessVisitor();
mav.handle(optCondition.getRight());
List<String[]> replacementList = new ArrayList<>();
for (MathMatrixNameExpressionSymbol matAccess : mav.getMathMatrixNameExpressionSymbols()){
if(isOptScopedVariable(matAccess.getNameToAccess())) {
String replacement = transformEMAMMatrixAccessToVectorNotation(matAccess, "vars", 1);
String search = matAccess.getTextualRepresentation();
String replacementPair[] = {search, replacement};
replacementList.add(replacementPair);
}
}
String rightSide = optCondition.getRight().getTextualRepresentation();
for(String replacementPair[] : replacementList) {
rightSide = rightSide.replace(replacementPair[0],replacementPair[1]);
}
result = leftSide+" = "+rightSide;
}else{
}
} else {
String leftside = "fg[ 1 +"+getNumberVariables() + " + " + getIpoptConstraintRef(nr) + " ] ";
String rightside = ((MathOptimizationConditionSymbol) constraint).getRight().getTextualRepresentation();
MathAccessVisitor mav = new MathAccessVisitor();
mav.handle(optCondition.getRight());
List<String[]> replacementList = new ArrayList<>();
for (MathMatrixNameExpressionSymbol matAccess : mav.getMathMatrixNameExpressionSymbols()){
if(isOptScopedVariable(matAccess.getNameToAccess())) {
String replacement = transformEMAMMatrixAccessToVectorNotation(matAccess, "vars", 0);
String search = matAccess.getTextualRepresentation();
String replacementPair[] = {search, replacement};
replacementList.add(replacementPair);
}
}
for (MathNameExpressionSymbol matAccess : mav.getMathNameExpressionSymbols()){
if(isOptScopedVariable(matAccess.getNameToAccess())) {
String replacement = transformEMAMValueToVectorNotation(matAccess, "vars", 0);
String search = matAccess.getTextualRepresentation();
String replacementPair[] = {search, replacement};
replacementList.add(replacementPair);
}
}
for(String replacementPair[] : replacementList) {
rightside = rightside.replace(replacementPair[0],replacementPair[1]);
}
String rightside = getIpoptTextualRepresentation(((MathOptimizationConditionSymbol) constraint).getRight(), "vars", 0);
result = leftside + " = " + rightside;
}
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.solver.template;
import de.monticore.lang.math._symboltable.MathVariableDeclarationSymbol;
import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathValueExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathValueSymbol;
......@@ -16,8 +16,6 @@ import java.util.*;
public abstract class SolverViewModel extends ViewModelBase {
private String id;
/* Variables which must be set in constructor */
......@@ -49,10 +47,6 @@ public abstract class SolverViewModel extends ViewModelBase {
//private int numberConstraints;
private List<MathValueSymbol> emamVariables = new ArrayList<>();
private List<NumberedVariable> knownVariablesWithNumbers = new ArrayList<>(); //Rename & write getter
//all variables from EMAM workspace, somehow derived with Blueprint
private HashSet<MathValueSymbol> allEMAMVariables = new LinkedHashSet<>();
/* ?? */
/**
......@@ -202,40 +196,6 @@ public abstract class SolverViewModel extends ViewModelBase {
}*/
}
protected boolean containsVariable(String variable) {
//TBI
Boolean result = false;
/*
if (exprContainsVar(objectiveFunction.getTextualRepresentation(), variable)) {
result = true;
}
for (String s : constraintFunctions) {
if (exprContainsVar(s, variable)) {
result = true;
}
}*/
return result;
}
private boolean exprContainsVar(String expr, String variable) {
String sepVar1 = "" + variable + "";
String sepVar2 = "" + variable + "[";
Boolean matches1 = expr.contains(sepVar1);
Boolean matches2 = expr.contains(sepVar2);
return matches1 || matches2;
}
protected String findRelpacementVariable(String variable) {
String replacementVar = variable;
while (containsVariable(replacementVar)) {
replacementVar += "Tmp";
}
return replacementVar;
}
public String getOptimizationVariableTypeActive() {
return optimizationVariableTypeActive;
......@@ -249,32 +209,6 @@ public abstract class SolverViewModel extends ViewModelBase {
}*/
}
public List<NumberedVariable> getKnownVariablesWithNumbers(){
return knownVariablesWithNumbers;
}
//obsolete
public void setKnownVariablesFromBluePrint(EMAMBluePrintCPP bluePrint) {
//TBI
/*
List<Variable> variables = bluePrint.getMathInformationRegister().getVariables();
variables.addAll(bluePrint.getVariables());
for (Variable v : variables) {
String name = v.getNameTargetLanguageFormat();
String type = v.getVariableType().getTypeNameTargetLanguage();
if ((!name.contentEquals(optimizationVariableName)) && (!name.contentEquals(objectiveVariableName)) && (!v.isForLoopVariable()) && (!knownVariables.contains(name))) {
knownVariables.add(name);
knownVariablesWithType.add(String.format("%s %s", type, name));
}
}*/
}
public Vector<Integer> getOptimizationVariableDimensions() {
//return optimizationVariableDimensions;
return new Vector<Integer>();
}
public MathOptimizationType getOptimizationProblemType() {
return optimizationProblemType;
}
......
......@@ -101,7 +101,7 @@ class ${viewModel.callSolverName}
public:
//ToDo: Function header generation, add initialization parameters
static bool solveOptimizationProblemIpOpt()
static bool solveOptimizationProblemIpOpt(${viewModel.getIpoptSolverFunctionParameters()})
{
bool ok = true;
......@@ -158,7 +158,6 @@ class ${viewModel.callSolverName}
</#list>
// Initialize constraint bounds
<#list viewModel.getSimplifiedConstraintFunctions() as constr>
// Constraint: ${constr.getName()}
......@@ -173,7 +172,10 @@ class ${viewModel.callSolverName}
</#if>
</#list>
//Push constants to namespace
<#list viewModel.getExternalVariables() as ext>
${viewModel.getExternalVariableType(ext)} AnonymNS${viewModel.id}::${ext.getName()} = ${ext.getName()};
</#list>
// object that computes objective and constraints
AnonymNS${viewModel.id}::FG_eval_${viewModel.callSolverName} fg_eval;
......@@ -193,17 +195,22 @@ class ${viewModel.callSolverName}
// Check some of the solution values
ok&=solution.status==CppAD::ipopt::solve_result<Dvector>::success;
// assign solution values
<#if viewModel.optimizationVariableDimensions?size == 0>
x${viewModel.id} = solution.x[0];
<#else>
//ToDO: ADMat variables
<#list viewModel.getOptimizationVariables() as opt>
&${opt.getName()} = solution.x[${opt?index?c}];
</#list>
for (int i${viewModel.id} = 0; i${viewModel.id} < solution.x.size(); i${viewModel.id}++)
{
x${viewModel.id}(i${viewModel.id}) = solution.x[i${viewModel.id}];
}
</#if>
// objective value
<#if viewModel.optimizationProblemType.name() == "MINIMIZATION">
y${viewModel.id} = solution.obj_value;
<#else>
y${viewModel.id} = -1 * solution.obj_value;
......@@ -217,9 +224,4 @@ class ${viewModel.callSolverName}
}
};
#endif
/*
Debug:
${viewModel.listClassesInScope()}
*/
\ No newline at end of file
#endif
\ No newline at end of file
Markdown is supported
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