Commit 46af2a81 authored by Sascha Niklas Schneiders's avatar Sascha Niklas Schneiders
Browse files

fixed #42

parent de58d937
......@@ -30,7 +30,7 @@ import java.util.List;
* @author Sascha Schneiders
*/
public class GeneratorCPP implements Generator {
public static GeneratorCPP currentInstance;
private Path modelsDirPath;
private boolean isGenerateTests = false;
private boolean isGenerateAutopilotAdapter = false;
......@@ -50,6 +50,7 @@ public class GeneratorCPP implements Generator {
this.mathCommandRegister = new MathCommandRegisterCPP();
useOctaveBackend();
TypeConverter.clearTypeSymbols();
currentInstance = this;
}
......
package de.monticore.lang.monticar.generator.cpp;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math.math._symboltable.matrix.MathMatrixExpressionSymbol;
import de.monticore.lang.math.math._symboltable.matrix.MathMatrixNameExpressionSymbol;
import de.monticore.lang.monticar.generator.Generator;
import de.monticore.lang.monticar.generator.MathCommandRegister;
import de.monticore.lang.monticar.generator.cpp.commands.*;
import de.monticore.lang.monticar.generator.cpp.symbols.MathStringExpression;
import de.se_rwth.commons.logging.Log;
/**
* @author Sascha Schneiders
......@@ -49,5 +55,62 @@ public class MathCommandRegisterCPP extends MathCommandRegister {
registerMathCommand(new MathKMeansCommand());
registerMathCommand(new MathSqrtmCommand());
registerMathCommand(new MathSqrtmDiagCommand());
//for fixing some errors
registerMathCommand(new MathRowCommand());
registerMathCommand(new MathColumnCommand());
}
/**
* Set input to converted string of mathExpressionSymbol.getTextualRepresentation()
*
* @param mathExpressionSymbol
* @param input
* @return
*/
public static boolean containsCommandExpression(MathExpressionSymbol mathExpressionSymbol, String input) {
mathExpressionSymbol = mathExpressionSymbol.getRealMathExpressionSymbol();
Log.info("trying containsCommand " + input + "class: " + mathExpressionSymbol.getClass().getName(), "Info");
try {
//if ((mathExpressionSymbol.isMatrixExpression() && ((MathMatrixExpressionSymbol) mathExpressionSymbol).isMatrixNameExpression()))
{
//MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol = (MathMatrixNameExpressionSymbol) mathExpressionSymbol;
//String fullName = mathMatrixNameExpressionSymbol.getTextualRepresentation();
String fullName = input;
while (fullName.length() > 0) {
fullName = removeTrailingStrings(fullName, "(");
String name = calculateName(fullName);
Log.info("" + input + " name: " + name, "containsCommandExpression");
if (GeneratorCPP.currentInstance.getMathCommandRegister().getMathCommand(name) != null) {
return true;
}
fullName = fullName.substring(name.length() + 1);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
public static String removeTrailingStrings(String fullString, String firstStringParts) {
while (fullString.startsWith(firstStringParts)) {
fullString = fullString.substring(1);
}
return fullString;
}
public static String calculateName(String fullName) {
int index = fullName.indexOf("(");
String name = "";
if (index != -1) {
name = fullName.substring(0, index);
}
if (name.contains(".")) {
Log.info(name, "Splitting");
name = name.split("\\.")[1];
}
return name;
}
}
package de.monticore.lang.monticar.generator.cpp;
import de.monticore.lang.monticar.generator.cpp.converter.ComponentConverterMethodGeneration;
import de.se_rwth.commons.logging.Log;
/**
* @author Sascha Schneiders
*/
......@@ -30,4 +33,30 @@ public class StringValueListExtractorUtil {
public static String getElement(String valueListString, int element) {
return getElement(valueListString, element, ",");
}
public static boolean containsPortName(String input) {
Log.info("trying containsPortName" + input, "Info");
try {
//if ((mathExpressionSymbol.isMatrixExpression() && ((MathMatrixExpressionSymbol) mathExpressionSymbol).isMatrixNameExpression()))
{
//MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol = (MathMatrixNameExpressionSymbol) mathExpressionSymbol;
//String fullName = mathMatrixNameExpressionSymbol.getTextualRepresentation();
String fullName = input;
while (fullName.length() > 0) {
fullName = MathCommandRegisterCPP.removeTrailingStrings(fullName, "(");
String name = MathCommandRegisterCPP.calculateName(fullName);
Log.info("" + input + " name: " + name, "containsCommandExpression");
if (ComponentConverterMethodGeneration.currentComponentSymbol.getPort(name).isPresent()) {
return true;
}
fullName = fullName.substring(name.length() + 1);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
}
package de.monticore.lang.monticar.generator.cpp.commands;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.monticar.generator.BluePrint;
import de.monticore.lang.monticar.generator.MathCommand;
/**
* @author Sascha Schneiders
*/
public class MathColumnCommand extends MathCommand {
public MathColumnCommand() {
setMathCommandName("col");
}
@Override
public void convert(MathExpressionSymbol mathExpressionSymbol, BluePrint bluePrint) {
//Do nothing
}
}
......@@ -11,7 +11,9 @@ import de.monticore.lang.monticar.generator.cpp.converter.ComponentConverter;
import de.monticore.lang.monticar.generator.cpp.converter.ExecuteMethodGenerator;
import de.monticore.lang.monticar.generator.cpp.MathFunctionFixer;
import de.monticore.lang.monticar.generator.cpp.converter.MathConverter;
import de.monticore.lang.monticar.generator.cpp.converter.StringIndexHelper;
import de.monticore.lang.monticar.generator.cpp.symbols.MathStringExpression;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
......@@ -65,7 +67,10 @@ public class MathExpCommand extends MathCommand {
valueListString += ExecuteMethodGenerator.generateExecuteCode(mathExpressionSymbol, new ArrayList<String>());
//OctaveHelper.getCallOctaveFunction(mathExpressionSymbol, "sum","Double", valueListString));
List<MathMatrixAccessSymbol> newMatrixAccessSymbols = new ArrayList<>();
MathStringExpression stringExpression = new MathStringExpression("exp"+valueListString);
Log.info("Previous valueList: "+valueListString,"EXPCOMMAND");
valueListString = StringIndexHelper.modifyContentBetweenBracketsByRemoving(valueListString, "-1)", ")");
Log.info("New valueList: "+valueListString,"EXPCOMMAND");
MathStringExpression stringExpression = new MathStringExpression("exp" +valueListString);
newMatrixAccessSymbols.add(new MathMatrixAccessSymbol(stringExpression));
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setMathMatrixAccessSymbols(newMatrixAccessSymbols);
......
package de.monticore.lang.monticar.generator.cpp.commands;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.monticar.generator.BluePrint;
import de.monticore.lang.monticar.generator.MathCommand;
/**
* @author Sascha Schneiders
*/
public class MathRowCommand extends MathCommand {
public MathRowCommand() {
setMathCommandName("row");
}
@Override
public void convert(MathExpressionSymbol mathExpressionSymbol, BluePrint bluePrint) {
//do nothing
}
}
package de.monticore.lang.monticar.generator.cpp.converter;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.math.math._symboltable.MathForLoopHeadSymbol;
import de.monticore.lang.math.math._symboltable.expression.*;
import de.monticore.lang.math.math._symboltable.matrix.*;
import de.monticore.lang.monticar.generator.Variable;
import de.monticore.lang.monticar.generator.cpp.GeneratorCPP;
import de.monticore.lang.monticar.generator.cpp.MathFunctionFixer;
import de.monticore.lang.monticar.generator.cpp.OctaveHelper;
import de.monticore.lang.monticar.generator.cpp.*;
import de.monticore.lang.monticar.generator.cpp.symbols.MathChainedExpression;
import de.monticore.lang.monticar.generator.cpp.symbols.MathStringExpression;
import de.se_rwth.commons.logging.Log;
......@@ -123,25 +119,62 @@ public class ExecuteMethodGeneratorHandler {
public static String generateExecuteCode(MathValueType mathValueType, List<String> includeStrings) {
String result = "";
if (mathValueType.isRationalType()) {
if (mathValueType.getDimensions().size() == 0)
return "double";
else if (mathValueType.getDimensions().size() == 2) {
Log.info("Dim1:" + mathValueType.getDimensions().get(0).getTextualRepresentation() + "Dim2: " + mathValueType.getDimensions().get(1).getTextualRepresentation(), "DIMS:");
if (mathValueType.getDimensions().get(0).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getRowVectorTypeName();
} else if (mathValueType.getDimensions().get(1).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getColumnVectorTypeName();
}
return MathConverter.curBackend.getMatrixTypeName();//TODO improve in future
} else {
Log.error("0xGEEXCOMAVAT Type conversion Case not handled!");
}
result = handleRationalType(mathValueType);
} else if (mathValueType.getType().isIsWholeNumberNumber()) {
result = handleWholeNumberType(mathValueType);
} else if (mathValueType.getType().isIsBoolean()) {
result = handleBooleanType(mathValueType);
} else {
Log.error("Case not handled!");
Log.info(mathValueType.getTextualRepresentation(), "Representation:");
Log.error("MathValueType: Case not handled!");
}
return result;
}
private static String handleRationalType(MathValueType mathValueType) {
if (mathValueType.getDimensions().size() == 0)
return "double";
else if (mathValueType.getDimensions().size() == 2) {
Log.info("Dim1:" + mathValueType.getDimensions().get(0).getTextualRepresentation() + "Dim2: " + mathValueType.getDimensions().get(1).getTextualRepresentation(), "DIMS:");
if (mathValueType.getDimensions().get(0).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getRowVectorTypeName();
} else if (mathValueType.getDimensions().get(1).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getColumnVectorTypeName();
}
return MathConverter.curBackend.getMatrixTypeName();//TODO improve in future
} else {
Log.error("0xGEEXCOMAVAT Type conversion Case not handled!");
}
return null;
}
private static String handleWholeNumberType(MathValueType mathValueType) {
if (mathValueType.getDimensions().size() == 0)
return "int";
else if (mathValueType.getDimensions().size() == 2) {
//TODO handle just like RationalMatrix right now
Log.info("Dim1:" + mathValueType.getDimensions().get(0).getTextualRepresentation() + "Dim2: " + mathValueType.getDimensions().get(1).getTextualRepresentation(), "DIMS:");
if (mathValueType.getDimensions().get(0).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getRowVectorTypeName();
} else if (mathValueType.getDimensions().get(1).getTextualRepresentation().equals("1")) {
return MathConverter.curBackend.getColumnVectorTypeName();
}
return MathConverter.curBackend.getMatrixTypeName();//TODO improve in future
} else {
Log.error("0xGEEXCOMAVAT Type conversion Case not handled!");
}
return null;
}
private static String handleBooleanType(MathValueType mathValueType) {
if (mathValueType.getDimensions().size() == 0)
return "bool";
else {
Log.error("0xGEEXCOMAVAT Type conversion Case not handled!");
}
return null;
}
public static String generateExecuteCode(MathNameExpressionSymbol mathNameExpressionSymbol, List<String> includeStrings) {
Log.info(mathNameExpressionSymbol.getNameToResolveValue(), "NameToResolveValue:");
return mathNameExpressionSymbol.getNameToResolveValue();
......@@ -161,8 +194,16 @@ public class ExecuteMethodGeneratorHandler {
String result = mathAssignmentExpressionSymbol.getNameOfMathValue();
result += ExecuteMethodGenerator.getCorrectAccessString(mathAssignmentExpressionSymbol.getNameOfMathValue(), mathAssignmentExpressionSymbol.getMathMatrixAccessOperatorSymbol(), includeStrings);
result += mathAssignmentExpressionSymbol.getAssignmentOperator().getOperator() + " ";
result += ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n";
String input = ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n";
if (MathCommandRegisterCPP.containsCommandExpression(mathAssignmentExpressionSymbol.getExpressionSymbol(), input)) {
result += input;
} else {
if(!StringValueListExtractorUtil.containsPortName(input))
result += StringIndexHelper.modifyContentBetweenBracketsByAdding(input, "-1");
else
result += input;
}
Log.info("result1: " + result, "MathAssignmentExpressionSymbol");
return result;
}
......@@ -174,12 +215,14 @@ public class ExecuteMethodGeneratorHandler {
String result = mathAssignmentExpressionSymbol.getNameOfMathValue();
result += ExecuteMethodGenerator.getCorrectAccessString(mathAssignmentExpressionSymbol.getNameOfMathValue(), mathAssignmentExpressionSymbol.getMathMatrixAccessOperatorSymbol(), includeStrings);
result += mathAssignmentExpressionSymbol.getAssignmentOperator().getOperator() + " ";
result += ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n";
result += StringIndexHelper.modifyContentBetweenBracketsByAdding(ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n", "-1");
Log.info("result2: " + result, "MathAssignmentExpressionSymbol");
return result;
}
return mathAssignmentExpressionSymbol.getNameOfMathValue() + " " + mathAssignmentExpressionSymbol.getAssignmentOperator().getOperator() + " " + ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n";
String result = mathAssignmentExpressionSymbol.getNameOfMathValue() + " " + mathAssignmentExpressionSymbol.getAssignmentOperator().getOperator() + " " + ExecuteMethodGenerator.generateExecuteCode(mathAssignmentExpressionSymbol.getExpressionSymbol(), includeStrings) + ";\n";
Log.info("result3: " + result, "MathAssignmentExpressionSymbol");
return result;
}
......
......@@ -154,9 +154,30 @@ public class ExecuteMethodGeneratorMatrixExpressionHandler {
result += updateMatrixAccessString(mathMatrixAccessOperatorSymbol, counter, matrixExtractionPart, false, includeStrings);
}
result += mathMatrixAccessOperatorSymbol.getAccessEndSymbol();
Log.info("MatrixExtractionPart: " + matrixExtractionPart, "MathMatrixAccessOperatorSymbol");
Log.info("mathMatrixAccessOperatorSymbol: " + mathMatrixAccessOperatorSymbol.getTextualRepresentation(), "MathMatrixAccessOperatorSymbol");
Log.info("Oldresult: " + result, "MathMatrixAccessOperatorSymbol");
result = tryFix(result, mathMatrixAccessOperatorSymbol);
return result;
}
private static String tryFix(String result, MathMatrixAccessOperatorSymbol mathMatrixAccessOperatorSymbol) {
result=fixDoubleOffset(result,mathMatrixAccessOperatorSymbol,"]");
result=fixDoubleOffset(result,mathMatrixAccessOperatorSymbol,")");
return result;
}
private static String fixDoubleOffset(String result,MathMatrixAccessOperatorSymbol mathMatrixAccessOperatorSymbol,String endPart){
String fixingTestString = (result.substring(0, result.length() - 3) + endPart);
Log.info("Checking Possible Fixing Test String: " + fixingTestString, "MathMatrixAccessOperatorSymbol");
if (fixingTestString.equals(mathMatrixAccessOperatorSymbol.getTextualRepresentation())) {
Log.info("Fixing:" + result + " to " + mathMatrixAccessOperatorSymbol.getTextualRepresentation(), "MathMatrixAccessOperatorSymbol");
result = mathMatrixAccessOperatorSymbol.getTextualRepresentation();
}
return result;
}
public static String updateMatrixAccessStringFixForLoop(MathMatrixAccessOperatorSymbol mathMatrixAccessOperatorSymbol, int counter, String matrixExtractionPart, List<String> includeStrings) {
int ignoreCounterAt = getIgnoreCounterAt(matrixExtractionPart);
String result = "";
......
package de.monticore.lang.monticar.generator.cpp.converter;
/**
* @author Sascha Schneiders
*/
public class StringIndexHelper {
public static String modifyContentBetweenBracketsByAdding(String input, String modifier) {
String result = "";
boolean done = false;
int indexFirst = input.indexOf("(", 0);
if (indexFirst == -1)
return input;
result += input.substring(0, indexFirst);
int indexSecond = input.indexOf(",", indexFirst + 1);
if (indexSecond == -1) {
indexSecond = input.indexOf(")", indexFirst + 1);
done = true;
}
while (!done) {
result += input.substring(indexFirst, indexSecond) + modifier;
indexFirst = indexSecond;
indexSecond = input.indexOf(",", indexSecond + 1);
if (indexSecond == -1) {
indexSecond = input.indexOf(")", indexFirst + 1);
done = true;
}
}
result += input.substring(indexFirst, indexSecond) + modifier;
result += input.substring(indexSecond);
return result;
}
public static String modifyContentBetweenBracketsByRemoving(String input, String endPart, String newEndPart) {
String result = input;
if (input.endsWith(endPart)) {
int indexFirst = input.lastIndexOf(endPart);
result = input.substring(0, indexFirst);
result+=newEndPart;
}
return result;
}
}
......@@ -66,7 +66,7 @@ public class AbstractSymtab {
for (String m : modelPath) {
mp.addEntry(Paths.get(m));
}
LogConfig.init();//TODO comment for debug output
//LogConfig.init();//TODO comment for debug output
GlobalScope scope = new GlobalScope(mp, fam);
de.monticore.lang.monticar.Utils.addBuiltInTypes(scope);
return scope;
......
......@@ -69,4 +69,31 @@ public class BasicMathGenerationTest extends AbstractSymtabTest {
String restPath = "testMath/l0/";
testFilesAreEqual(files, restPath);
}
@Test
public void testMatrixAssignmentTest() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources");
ExpandedComponentInstanceSymbol componentSymbol = symtab.<ExpandedComponentInstanceSymbol>resolve("test.math.matrixAssignmentTest", ExpandedComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useArmadilloBackend();
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/testMath/l0");
List<File> files = generatorCPP.generateFiles(componentSymbol, symtab);
String restPath = "testMath/l0/";
testFilesAreEqual(files, restPath);
}
@Test
public void testMatrixArrayPortAccessTest() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources");
ExpandedComponentInstanceSymbol componentSymbol = symtab.<ExpandedComponentInstanceSymbol>resolve("test.math.matrixArrayPortAccessTest", ExpandedComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useArmadilloBackend();
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/testMath/l0");
List<File> files = generatorCPP.generateFiles(componentSymbol, symtab);
String restPath = "testMath/l0/";
testFilesAreEqual(files, restPath);
}
}
#ifndef TEST_MATH_MATRIXASSIGNMENTTEST
#define TEST_MATH_MATRIXASSIGNMENTTEST
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "armadillo.h"
using namespace arma;
class test_math_matrixAssignmentTest{
public:
void init()
{
}
void execute()
{
mat matA = (ones<mat>(2, 2));
mat matB = (ones<mat>(2, 2));
matA(1-1, 1-1) = matB(1-1, 1-1);
}
};
#endif
#ifndef HELPERA_H
#ifndef HELPERA_H
#define HELPERA_H
#define _GLIBCXX_USE_CXX11_ABI 0
#include <iostream>
......@@ -24,7 +24,7 @@ return eigenValues;
static mat getKMeansClusters(mat A, int k){
mat clusters;
kmeans(clusters,A.t(),k,random_subset,20,true);
printf("cluster centroid calculation done\n");
/*printf("cluster centroid calculation done\n");
std::ofstream myfile;
myfile.open("data after cluster.txt");
myfile << A;
......@@ -33,14 +33,14 @@ std::ofstream myfile;
std::ofstream myfile2;
myfile2.open("cluster centroids.txt");
myfile2 << clusters;
myfile2.close();
myfile2.close();*/
mat indexedData=getKMeansClustersIndexData(A.t(), clusters);
std::ofstream myfile3;
/*std::ofstream myfile3;
myfile3.open("data after index.txt");
myfile3 << indexedData;
myfile3.close();
*/
return indexedData;
}
......
#ifndef TEST_MATH_MATRIXARRAYPORTACCESSTEST
#define TEST_MATH_MATRIXARRAYPORTACCESSTEST
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "armadillo.h"
using namespace arma;
class test_math_matrixArrayPortAccessTest{
public:
mat arrayIn[5];
void init()
{
arrayIn[0]=mat(3,3);
arrayIn[1]=mat(3,3);
arrayIn[2]=mat(3,3);
arrayIn[3]=mat(3,3);
arrayIn[4]=mat(3,3);
}
void execute()
{
int variableIII = 3;
mat tmpA = arrayIn[variableIII-1];
}
};
#endif
#ifndef TEST_MATH_MATRIXASSIGNMENTTEST
#define TEST_MATH_MATRIXASSIGNMENTTEST
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "armadillo.h"
using namespace arma;
class test_math_matrixAssignmentTest{
public:
void init()
{
}
void execute()
{
mat matA = (ones<mat>(2, 2));
mat matB = (ones<mat>(2, 2));
matA(1-1, 1-1) = matB(1-1, 1-1);
}
};
#endif
package test.math;
component MatrixArrayPortAccessTest{
ports in Q^{3,3} arrayIn[5];