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

misc.

parent 52f1cf4e
......@@ -17,7 +17,7 @@
<properties>
<!-- .. EMA-Libraries ................................................. -->
<Embedded-MontiArc-Math.version>0.2.12-SNAPSHOT</Embedded-MontiArc-Math.version>
<Embedded-MontiArc-Math.version>0.2.13-SNAPSHOT</Embedded-MontiArc-Math.version>
<!-- .. Libraries .................................................. -->
<guava.version>25.1-jre</guava.version>
......
......@@ -92,24 +92,27 @@ public class OptimizationSolverConverter {
return defined;
}
//ToDo: This will become obsolete, as the function call is to be generated dynamically.
private static String getOutputVariableDeclarations(MathOptimizationStatementSymbol symbol, Problem problemType, EMAMBluePrintCPP bluePrint) {
String result = "";
if (!isOptimizationVariableAlreadyDefined(symbol.getOptimizationVariable(), bluePrint))
result += ExecuteMethodGenerator.generateExecuteCode(symbol.getOptimizationVariable(), new ArrayList<>());
List<MathValueSymbol> vars = symbol.getOptimizationVariables();
for(MathValueSymbol var : vars)
if (!isOptimizationVariableAlreadyDefined(var, bluePrint))
result += ExecuteMethodGenerator.generateExecuteCode(var, new ArrayList<>());
if (symbol.hasReturnValue()) {
MathValueSymbol expr = symbol.getObjectiveValue();
MathValueSymbol decl = new MathValueSymbol(expr.getName());
decl.setType(expr.getType());
result += ExecuteMethodGenerator.generateExecuteCode(decl, new ArrayList<>());
} else {
problemType.setObjectiveValueVariable("objectiveValue" + problemType.getId());
MathValueSymbol decl = new MathValueSymbol(problemType.getObjectiveValueVariable());
//problemType.setObjectiveValueVariable("objectiveValue" + problemType.getId());
//MathValueSymbol decl = new MathValueSymbol(problemType.getObjectiveValueVariable());
MathValueType type = new MathValueType();
ASTElementType astType = new ASTElementType();
astType.setName("Q");
type.setType(astType);
decl.setType(type);
result += ExecuteMethodGenerator.generateExecuteCode(decl, new ArrayList<>());
//decl.setType(type);
//result += ExecuteMethodGenerator.generateExecuteCode(decl, new ArrayList<>());
}
return result;
}
......
......@@ -2,6 +2,7 @@
package de.monticore.lang.monticar.generator.cpp.converter;
import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathValueSymbol;
import de.monticore.lang.math._symboltable.matrix.MathMatrixAccessOperatorSymbol;
import de.monticore.lang.math._symboltable.matrix.MathMatrixAccessSymbol;
import de.monticore.lang.math._symboltable.matrix.MathMatrixArithmeticValueSymbol;
......@@ -12,6 +13,7 @@ import de.monticore.lang.monticar.generator.cpp.converter.ExecuteMethodGenerator
import de.monticore.lang.monticar.generator.cpp.converter.OptimizationSolverConverter;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
/**
......@@ -24,6 +26,9 @@ public class OptimizationSymbolHandler extends BaseExecuteMethodGeneratorHandler
private String currentOptimizationVariableName = "x";
private String currentOptimizationVariableMatrixType = "ADMat";
//Todo:In Progress:
private List<MathValueSymbol> optimizationVariables = new ArrayList<>();
@Override
protected boolean canHandleSymbol(MathExpressionSymbol symbol) {
boolean canHandle = false;
......@@ -90,21 +95,30 @@ public class OptimizationSymbolHandler extends BaseExecuteMethodGeneratorHandler
for (MathMatrixAccessOperatorSymbol vec : matVal.getVectors()) {
for (MathMatrixAccessSymbol elem : vec.getMathMatrixAccessSymbols()) {
String textRep = elem.getTextualRepresentation();
if (textRep.contentEquals(getCurrentOptimizationVariableName()) || textRep.contains(getCurrentOptimizationVariableName() + "("))
return true;
for (String varName : getCurrentOptimizationVariableNames())
if (textRep.contentEquals(varName) || textRep.contains(varName + "("))
return true;
}
}
return result;
}
public String getCurrentOptimizationVariableName() {
return currentOptimizationVariableName;
public List<String> getCurrentOptimizationVariableNames() {
List<String> varNames = new ArrayList<>();
for (MathValueSymbol var : optimizationVariables){
varNames.add(var.getName());
}
return varNames;
}
public void setCurrentOptimizationVariableName(String currentOptimizationVariableName) {
this.currentOptimizationVariableName = currentOptimizationVariableName;
public void setOptimizationVariables(List<MathValueSymbol> optimizationVariables) {
this.optimizationVariables = optimizationVariables;
}
//public void setCurrentOptimizationVariableName(String currentOptimizationVariableName) {
// this.currentOptimizationVariableName = currentOptimizationVariableName;
//}
public String getCurrentOptimizationVariableMatrixType() {
return currentOptimizationVariableMatrixType;
}
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.problem;
import de.monticore.lang.math._symboltable.expression.MathConditionalExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathConditionalExpressionsSymbol;
import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathValueType;
import de.monticore.lang.math._symboltable.expression.*;
import de.monticore.lang.mathopt._symboltable.MathOptimizationStatementSymbol;
import de.se_rwth.commons.logging.Log;
......@@ -59,7 +56,7 @@ public class OptimizationProblemClassification {
private static boolean checkIfQP(MathOptimizationStatementSymbol symbol) {
boolean result = false;
String optvar = symbol.getOptimizationVariable().getName();
//String optvar = symbol.getOptimizationVariable().getName();
String text = symbol.getTextualRepresentation();
if (!containsNonLinearFunctions(text)) {
......@@ -96,9 +93,13 @@ public class OptimizationProblemClassification {
private static boolean isMixedInteger(MathOptimizationStatementSymbol symbol) {
boolean result = false;
MathValueType type = ProblemAssignmentHandler.getInstance().getVariableWithTypeInformations(symbol.getOptimizationVariable()).getType();
if (type.getType().isWholeNumber())
result = true;
for(MathValueSymbol optimizationVariable : symbol.getOptimizationVariables()){
MathValueType type = ProblemAssignmentHandler.getInstance().getVariableWithTypeInformations(optimizationVariable).getType();
if (type.getType().isWholeNumber())
result = true;
}
return result;
}
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.problem;
import de.monticore.lang.math._symboltable.MathVariableDeclarationSymbol;
import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathValueSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationType;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/**
......@@ -27,15 +33,12 @@ public class Problem {
*/
private int n;
/**
* name of the optimization variable
*/
private String optimizationVariableName;
private List<MathValueSymbol> optimizationVariables = new ArrayList<>();
private List<MathValueSymbol> independentOptVariables = new ArrayList<>();
/**
* data type of the optimization variable
*/
private String optimizationVariableType;
private List<MathOptimizationConditionSymbol> constraintFunctions = new ArrayList<>();
private MathExpressionSymbol stepSize;
/**
* dimensions of the optimization variable
......@@ -45,12 +48,12 @@ public class Problem {
/**
* variable which contains the objective value
*/
private String objectiveValueVariable;
private MathValueSymbol objectiveValueVariable;
/**
* objective function
*/
private String objectiveFunction;
private MathExpressionSymbol objectiveFunction;
// getter setter
......@@ -73,36 +76,36 @@ public class Problem {
this.n = n;
}
public String getOptimizationVariableName() {
return optimizationVariableName;
public List<MathValueSymbol> getOptimizationVariables() {
return optimizationVariables;
}
public void setOptimizationVariableName(String optimizationVariableName) {
this.optimizationVariableName = optimizationVariableName;
public void setOptimizationVariables(List<MathValueSymbol> optimizationVariables) {
this.optimizationVariables = optimizationVariables;
}
public String getObjectiveValueVariable() {
return objectiveValueVariable;
public List<MathValueSymbol> getIndependentOptVariables() {
return independentOptVariables;
}
public void setObjectiveValueVariable(String objectiveValueVariable) {
this.objectiveValueVariable = objectiveValueVariable;
public void setIndependentVariables(List<MathValueSymbol> independentOptVariables) {
this.independentOptVariables = independentOptVariables;
}
public String getObjectiveFunction() {
return objectiveFunction;
public MathValueSymbol getObjectiveValueVariable() {
return objectiveValueVariable;
}
public void setObjectiveFunction(String objectiveFunction) {
this.objectiveFunction = objectiveFunction;
public void setObjectiveValueVariable(MathValueSymbol objectiveValueVariable) {
this.objectiveValueVariable = objectiveValueVariable;
}
public String getOptimizationVariableType() {
return optimizationVariableType;
public MathExpressionSymbol getObjectiveFunction() {
return objectiveFunction;
}
public void setOptimizationVariableType(String optimizationVariableType) {
this.optimizationVariableType = optimizationVariableType;
public void setObjectiveFunction(MathExpressionSymbol objectiveFunction) {
this.objectiveFunction = objectiveFunction;
}
public Vector<Integer> getOptimizationVariableDimensions() {
......@@ -121,6 +124,14 @@ public class Problem {
this.optimizationProblemType = optimizationProblemType;
}
public MathExpressionSymbol getStepSize() {
return stepSize;
}
public void setStepSize(MathExpressionSymbol stepSize) {
this.stepSize = stepSize;
}
/**
* Default value if no lower bound is set
*/
......@@ -133,10 +144,7 @@ public class Problem {
* number of constraints in function g
*/
private int m;
/**
* function g: R^n -> R^m
*/
private Vector<String> constraintFunctions = new Vector<>();
/**
* lower bound of x
*/
......@@ -172,14 +180,15 @@ public class Problem {
this.m = m;
}
public Vector<String> getConstraintFunctions() {
public List<MathOptimizationConditionSymbol> getConstraintFunctions() {
return constraintFunctions;
}
public void setConstraintFunctions(Vector<String> constraintFunctions) {
public void setConstraintFunctions(List<MathOptimizationConditionSymbol> constraintFunctions) {
this.constraintFunctions = constraintFunctions;
}
public Vector<String> getxL() {
return xL;
}
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.generator.cpp.mathopt.optimizationSolver.problem;
import de.monticore.lang.math._symboltable.MathVariableDeclarationSymbol;
import de.monticore.lang.math._symboltable.expression.*;
import de.monticore.lang.math._symboltable.matrix.MathMatrixNameExpressionSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
......@@ -40,17 +41,21 @@ public class ProblemAssignmentHandler {
private void setOptimizationVariableFromSymbol(Problem p, MathOptimizationStatementSymbol symbol) {
Vector<Integer> dimensions = new Vector<>();
p.setN(getOptimizationVarDimension(symbol, dimensions));
p.setOptimizationVariableName(getOptimizationVarName(symbol));
p.setOptimizationVariableType(getOptimizationVarType(symbol));
p.setOptimizationVariableDimensions(dimensions);
List<MathValueSymbol> optVars = symbol.getOptimizationVariables();
List<MathValueSymbol> indVars = symbol.getIndependentVariables();
MathExpressionSymbol stepSize = symbol.getStepSizeExpression();
getOptimizationSymbolHandler().setCurrentOptimizationVariableName(getOptimizationVarName(symbol));
p.setN(getOptimizationVarDimensions(symbol, dimensions));
p.setOptimizationVariables(optVars);
p.setIndependentVariables(indVars);
p.setStepSize(stepSize);
}
private void setObjectiveFunctionFromSymbol(Problem p, MathOptimizationStatementSymbol symbol) {
p.setObjectiveValueVariable(getObjectiveValueVarName(symbol));
p.setObjectiveFunction(getObjectiveFunctionAsCode(symbol));
p.setObjectiveValueVariable(symbol.getObjectiveValue());
p.setObjectiveFunction(symbol.getObjectiveExpression());
}
private String[] getBoundsFromConstraint(Problem p, MathOptimizationConditionSymbol constraint) {
......@@ -72,7 +77,7 @@ public class ProblemAssignmentHandler {
} else {
name = "";
}
return name.contentEquals(p.getOptimizationVariableName());
return p.getOptimizationVariables().contains(name);
}
private void mergeBoundsInX(Problem p, Vector<String> xL, Vector<String> xU, MathExpressionSymbol expr, String currXL, String currXU, Vector<String> xMatrixElementConstraints) {
......@@ -114,14 +119,28 @@ public class ProblemAssignmentHandler {
}
private void setBoundsOnXFromTypeDeclaration(MathOptimizationStatementSymbol symbol, Vector<String> xL, Vector<String> xU, int n) {
//ToDo refactor the string away.
Double lower = Double.parseDouble(Problem.LOWER_BOUND_INF);
Double upper = Double.parseDouble(Problem.UPPER_BOUND_INF);
String lowerBoundX = Problem.LOWER_BOUND_INF;
String upperBoundX = Problem.UPPER_BOUND_INF;
MathValueType type = getVariableWithTypeInformations(symbol.getOptimizationVariable()).getType();
if (type.getType().getRangeOpt().isPresent()) {
lowerBoundX = Double.toString(type.getType().getRange().getStartValue().doubleValue());
upperBoundX = Double.toString(type.getType().getRange().getEndValue().doubleValue());
//ToDo: Where would be the variable bound information? e.g. Q var (0:100)
for(MathValueSymbol var : symbol.getOptimizationVariables()){
MathValueType type = getVariableWithTypeInformations(var).getType();
if (type.getType().getRangeOpt().isPresent()) {
if(type.getType().getRange().getStartValue().doubleValue() < lower)
lower = type.getType().getRange().getStartValue().doubleValue();
if(type.getType().getRange().getEndValue().doubleValue() > upper)
upper = type.getType().getRange().getEndValue().doubleValue();
}
}
lowerBoundX = Double.toString(lower);
upperBoundX = Double.toString(upper);
//ToDo: How does xL and xU get written in the correct places??
//A: Currently it is written everywhere..
for (int i = 0; i < n; i++) {
xL.add(lowerBoundX);
xU.add(upperBoundX);
......@@ -136,12 +155,14 @@ public class ProblemAssignmentHandler {
Vector<String> xU = new Vector<>();
Vector<String> xMatrixElementConstraints = new Vector<>();
// add constraints
setBoundsOnXFromTypeDeclaration(symbol, xL, xU, p.getN());
//ToDo: Implement in template through ipopt
//setBoundsOnXFromTypeDeclaration(symbol, xL, xU, p.getN());
addConstraintsOnObjectiveVariable(symbol, g, gL, gU);
addSubjectToConstraints(p, symbol, xL, xU, g, gL, gU, xMatrixElementConstraints);
// set nlp
p.setM(g.size());
p.setConstraintFunctions(g);
p.setConstraintFunctions(symbol.getConstraints());
p.setgL(gL);
p.setgU(gU);
p.setxL(xL);
......@@ -252,32 +273,38 @@ public class ProblemAssignmentHandler {
return numberExpr;
}
private int getOptimizationVarDimension(MathOptimizationStatementSymbol symbol, Vector<Integer> dimensions) {
private int getOptimizationVarDimensions(MathOptimizationStatementSymbol symbol, Vector<Integer> dimensions) {
int n = 1;
dimensions.clear();
MathValueSymbol optVarDeclaration = getVariableWithTypeInformations(symbol.getOptimizationVariable());
List<MathExpressionSymbol> dims = optVarDeclaration.getType().getDimensions();
for (MathExpressionSymbol d : dims) {
if (getNumber(d) != null) {
int currDim = getNumber(d).getValue().getRealNumber().intValue();
n *= currDim;
dimensions.add(currDim);
for (MathValueSymbol optVar : symbol.getOptimizationVariables()){
int currentN = 1;
MathValueSymbol optVarDeclaration = getVariableWithTypeInformations(optVar);
List<MathExpressionSymbol> dims = optVarDeclaration.getType().getDimensions();
for (MathExpressionSymbol d : dims) {
if (getNumber(d) != null) {
int currDim = getNumber(d).getValue().getRealNumber().intValue();
currentN *= currDim;
dimensions.add(currDim);
}
}
n += currentN;
}
return n;
}
private String getOptimizationVarName(MathOptimizationStatementSymbol symbol) {
return symbol.getOptimizationVariable().getName();
private List<MathValueSymbol> getOptimizationVarName(MathOptimizationStatementSymbol symbol) {
return symbol.getOptimizationVariables();
}
public MathValueSymbol getVariableWithTypeInformations(MathValueSymbol symbol) {
return ComponentConverter.currentBluePrint.getMathInformationRegister().getFullTypeInformation(symbol);
}
private String getOptimizationVarType(MathOptimizationStatementSymbol symbol) {
return TypeConverter.getVariableTypeNameForMathLanguageTypeName(getVariableWithTypeInformations(symbol.getOptimizationVariable()).getType());
}
//private String getOptimizationVarType(MathOptimizationStatementSymbol symbol) {
// return TypeConverter.getVariableTypeNameForMathLanguageTypeName(getVariableWithTypeInformations(symbol.getOptimizationVariable()).getType());
//}
private String getObjectiveValueVarName(MathOptimizationStatementSymbol symbol) {
String objValueVar = "";
......@@ -288,9 +315,14 @@ public class ProblemAssignmentHandler {
}
private String getObjectiveFunctionAsCode(MathOptimizationStatementSymbol symbol) {
MathExpressionSymbol substitutedObjFunc = ComponentConverter.currentBluePrint.getMathInformationRegister().resolveMathExpressionToAtomarExpression(symbol.getObjectiveExpression().getAssignedMathExpressionSymbol(), symbol.getOptimizationVariable().getName());
MathFunctionFixer.fixMathFunctions(substitutedObjFunc, ComponentConverter.currentBluePrint);
return ExecuteMethodGenerator.generateExecuteCode(substitutedObjFunc, new ArrayList<>());
//Todo: why do we need a subsitute instead of renaming c-code "x"?
MathExpressionSymbol expressionSymbol = symbol.getObjectiveExpression().getAssignedMathExpressionSymbol();
for(MathValueSymbol optimizationVariable : symbol.getOptimizationVariables())
expressionSymbol = ComponentConverter.currentBluePrint.getMathInformationRegister().
resolveMathExpressionToAtomarExpression(
expressionSymbol, optimizationVariable.getName());
MathFunctionFixer.fixMathFunctions(expressionSymbol, ComponentConverter.currentBluePrint);
return ExecuteMethodGenerator.generateExecuteCode(expressionSymbol, new ArrayList<>());
}
private OptimizationSymbolHandler getOptimizationSymbolHandler() {
......
......@@ -55,7 +55,9 @@ public class CplexSolverGeneratorImplementation implements QPSolverGeneratorImpl
@Override
public String generateSolverCode(Problem optimizationProblem, List<FileContent> auxillaryFiles, EMAMBluePrintCPP bluePrint) {
/* ToDo: Fix after Ipopt works
String result = "";
GeneratorCPP generator = (GeneratorCPP) bluePrint.getGenerator();
if ((optimizationProblem instanceof QPProblem) || (optimizationProblem instanceof MIQPProblem)) {
// create view model from problem class
......@@ -81,7 +83,8 @@ public class CplexSolverGeneratorImplementation implements QPSolverGeneratorImpl
} else {
Log.error(String.format("CPLEX can not solve problemes of type %s", optimizationProblem.getClass().toString()));
}
return result;
return result;*/
return "";
}
@Override
......
......@@ -13,9 +13,9 @@ public class CplexViewModel extends SolverViewModel {
}
// methods
@Override
//@Override
public void setOptimizationVariableType(String optimizationVariableType) {
super.setOptimizationVariableType(optimizationVariableType);
//super.setOptimizationVariableType(optimizationVariableType);
// also set active type
if (optimizationVariableType.contentEquals("mat")) {
this.setOptimizationVariableTypeActive("CplexMat");
......
......@@ -63,6 +63,7 @@ public class IpoptSolverGeneratorImplementation implements NLPSolverGeneratorImp
@Override
public String generateSolverCode(Problem optimizationProblem, List<FileContent> auxillaryFiles, EMAMBluePrintCPP bluePrint) {
String result = "";
//optimizationProblem.
// GeneratorEMAMOpt2CPP generator = (GeneratorEMAMOpt2CPP) bluePrint.getGenerator();
GeneratorCPP generator = (GeneratorCPP) bluePrint.getGenerator();
if ((optimizationProblem instanceof NLPProblem) || (optimizationProblem instanceof DNLPProblem)) {
......@@ -77,18 +78,21 @@ public class IpoptSolverGeneratorImplementation implements NLPSolverGeneratorImp
// set execute command
vm.setKnownVariablesFromBluePrint(bluePrint);
String knownVariables = ", ";
/*
for (String s : vm.getKnownVariables()) {
knownVariables += s + ", ";
}
if (knownVariables.length() >= 2) {
knownVariables = knownVariables.substring(0, knownVariables.length() - 2);
}
}*/
vm.setKnownVariablesWithNumbers();
String objVar = vm.getObjectiveVariableName();
if (objVar.isEmpty())
objVar = "objectiveValue" + optimizationProblem.getId();
result = String.format("%s::solveOptimizationProblemIpOpt(%s, %s%s);\n", vm.getCallSolverName(), vm.getOptimizationVariableName(), objVar, knownVariables);
//ToDo: modify call. Restriction: only same type? (Matrix opposed to skalar)
//Dynamic function call, better generated by vm
result = String.format("%s::solveOptimizationProblemIpOpt(%s, %s%s);\n", vm.getCallSolverName(), vm.getOptimizationVariables().get(0).getName(), objVar, knownVariables);
// generate templates by view model
vm.resolveIpoptNameConflicts();
generateIpoptTemplates(vm, auxillaryFiles);
necessaryIncludes.add(vm.getCallSolverName());
addCMakeDependenciesToGenerator(bluePrint);
......
/* (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;
import de.monticore.lang.mathopt._symboltable.MathOptimizationConditionSymbol;
import de.monticore.lang.mathopt._symboltable.MathOptimizationType;
import de.monticore.lang.monticar.generator.Variable;
import de.monticore.lang.monticar.generator.cpp.EMAMBluePrintCPP;
......@@ -11,49 +16,49 @@ import java.util.*;
public abstract class SolverViewModel extends ViewModelBase {
private String id;
/**
* Name of the generated solver execution class name
*/
private String callSolverName;