Commit bd393569 authored by Christian Moll's avatar Christian Moll

Merge branch 'dev-nico' into 'master'

Dev nico into master

See merge request !1
parents 37904fc2 b8ed3735
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>lu.list.itis.dkd.tui</groupId> <groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip-cps</artifactId> <artifactId>tulip-cps</artifactId>
<version>1.3.1</version> <version>1.4.0</version>
<name>TULIP Complex Problem Solving</name> <name>TULIP Complex Problem Solving</name>
<licenses> <licenses>
...@@ -47,12 +47,49 @@ ...@@ -47,12 +47,49 @@
<dependency> <dependency>
<groupId>lu.list.itis.dkd.tui</groupId> <groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId> <artifactId>tulip</artifactId>
<version>2.3.1</version> <version>2.4.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>dk.ange</groupId> <groupId>maven2.dk.ange</groupId>
<artifactId>javaoctave</artifactId> <artifactId>javaoctave</artifactId>
<version>0.6.4</version> <version>0.6.4</version>
</dependency> </dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.1b3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.23</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8</version>
<scope>runtime</scope>
</dependency>
</dependencies> </dependencies>
<repositories>
<repository>
<id>Kenai</id>
<name>Kenai</name>
<url>https://svn.kenai.com/svn/javaoctave~maven-repository</url>
</repository>
</repositories>
</project> </project>
\ No newline at end of file
...@@ -22,15 +22,17 @@ package lu.list.itis.dkd.tui.cps.system; ...@@ -22,15 +22,17 @@ package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault; import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable; import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.system.executor.Executor;
import lu.list.itis.dkd.tui.cps.variable.Variable; import lu.list.itis.dkd.tui.cps.variable.Variable;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import java.util.logging.Level; import org.slf4j.Logger;
import java.util.logging.Logger; import org.slf4j.LoggerFactory;
import java.util.LinkedHashSet;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptException;
/** /**
* Class modelling a mathematical equation that is evaluated by an engine. * Class modelling a mathematical equation that is evaluated by an engine.
...@@ -44,9 +46,12 @@ public class Equation { ...@@ -44,9 +46,12 @@ public class Equation {
private Mapping mapping; private Mapping mapping;
private Mapping lockedMapping; private Mapping lockedMapping;
@Nullable @Nullable
private ScriptEngine scriptEngine; // private ScriptEngine scriptEngine;
private Executor scriptExecutor;
private String script; private String script;
private static Logger LOGGER = LoggerFactory.getLogger(Equation.class.getSimpleName());
/** /**
* Constructor * Constructor
* *
...@@ -77,11 +82,49 @@ public class Equation { ...@@ -77,11 +82,49 @@ public class Equation {
* mapping. * mapping.
*/ */
public void evaluate() { public void evaluate() {
Preconditions.checkState(scriptEngine != null); // Preconditions.checkState(scriptEngine != null);
// try {
// mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables()));
// } catch (ScriptException e) {
// Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "Exception while
// executing script!", e); //$NON-NLS-1$
// }
LinkedHashSet<Variable> dependentVariables;
String evaluationErrors;
Preconditions.checkState(scriptExecutor != null);
try { try {
mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables())); scriptExecutor.resetExecutionErrors();
} catch (ScriptException e) {
Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "Exception while executing script!", e); //$NON-NLS-1$ for (Variable variable : lockedMapping.getIndependentVariables()) {
scriptExecutor.set(variable);
}
scriptExecutor.eval(this.script);
} catch (Exception exception) {
LOGGER.error("Error while evaluating script {}", this.script, exception); //$NON-NLS-1$
}
dependentVariables = mapping.getDependentVariables();
for (Variable variable : dependentVariables) {
try {
variable = scriptExecutor.get(variable);
} catch (Exception exception) {
LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$
}
}
evaluationErrors = scriptExecutor.getExecutionErrors();
if (evaluationErrors.length() > 0) {
LOGGER.warn("Error while evaluating equation : {}", evaluationErrors); //$NON-NLS-1$
LOGGER.warn("Script = {}", this.script); //$NON-NLS-1$
LinkedHashSet<Variable> independentVariables = mapping.getIndependentVariables();
for (Variable variable : independentVariables) {
LOGGER.trace("{} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
} }
} }
...@@ -90,17 +133,20 @@ public class Equation { ...@@ -90,17 +133,20 @@ public class Equation {
* *
* @return The formula with variables replaced by their values, ready for evaluation. * @return The formula with variables replaced by their values, ready for evaluation.
*/ */
private String replaceVariables() { // private String replaceVariables() {
String result = new String(script); // String result = new String(script);
//
for (Variable variable : lockedMapping.getIndependentVariables()) { // for (Variable variable : lockedMapping.getIndependentVariables()) {
result = result.replaceAll(variable.getName(), variable.getValue().toString()); // result = result.replaceAll(variable.getName(), variable.getValue().toString());
} // }
result = result.replaceAll(lockedMapping.getDependentVariable().getName(), lockedMapping.getDependentVariable().getValue().toString()); //
// for (Variable variable : lockedMapping.getDependentVariables()) {
assert result != null; // result = result.replaceAll(variable.getName(), variable.getValue().toString());
return result; // }
} //
// assert result != null;
// return result;
// }
/** /**
* Method for setting the script engine to use. * Method for setting the script engine to use.
...@@ -108,8 +154,17 @@ public class Equation { ...@@ -108,8 +154,17 @@ public class Equation {
* @param engine * @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas. * The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/ */
public void setScriptEngine(ScriptEngine engine) { // public void setScriptEngine(ScriptEngine engine) {
scriptEngine = engine; // scriptEngine = engine;
// }
/**
* Method for setting the script engine to use.
*
* @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/
public void setExecutor(Executor executor) {
this.scriptExecutor = executor;
} }
/** /**
......
package lu.list.itis.dkd.tui.cps.system;
public class Import
{
private String function;
private String from;
public Import (String function, String from)
{
this.function = function;
this.from = from;
}
public String getFunction()
{
return function;
}
public void setFunction(String function)
{
this.function = function;
}
public String getFrom()
{
return from;
}
public void setFrom(String from)
{
this.from = from;
}
}
...@@ -28,9 +28,6 @@ import com.google.common.base.Preconditions; ...@@ -28,9 +28,6 @@ import com.google.common.base.Preconditions;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
/** /**
* Class implementing a system of linear equations. The class holds a number of equations and * Class implementing a system of linear equations. The class holds a number of equations and
* defines the engine that evaluates the equations. The class may be driven by a clock react to * defines the engine that evaluates the equations. The class may be driven by a clock react to
...@@ -43,7 +40,7 @@ import javax.script.ScriptEngineManager; ...@@ -43,7 +40,7 @@ import javax.script.ScriptEngineManager;
@NonNullByDefault @NonNullByDefault
public class LinearEquationSystem extends System { public class LinearEquationSystem extends System {
private ConcurrentHashMap<Mapping, Equation> equations; private ConcurrentHashMap<Mapping, Equation> equations;
private ScriptEngine scriptEngine; // private ScriptEngine scriptEngine;
/** /**
* Constructor issuing a super call and initialising the map of equations. * Constructor issuing a super call and initialising the map of equations.
...@@ -57,9 +54,9 @@ public class LinearEquationSystem extends System { ...@@ -57,9 +54,9 @@ public class LinearEquationSystem extends System {
public LinearEquationSystem(boolean lockToNesting) { public LinearEquationSystem(boolean lockToNesting) {
super(); super();
equations = new ConcurrentHashMap<>(); equations = new ConcurrentHashMap<>();
scriptEngine = new ScriptEngineManager().getEngineByName("js"); //$NON-NLS-1$ // scriptEngine = new ScriptEngineManager().getEngineByName("js"); //$NON-NLS-1$
this.lockSystemForNesting = lockToNesting; this.lockSystemForNesting = lockToNesting;
assert scriptEngine != null : "Script engine cannot be null;"; //$NON-NLS-1$ // assert scriptEngine != null : "Script engine cannot be null;"; //$NON-NLS-1$
} }
/** /**
...@@ -70,7 +67,7 @@ public class LinearEquationSystem extends System { ...@@ -70,7 +67,7 @@ public class LinearEquationSystem extends System {
* @return An instance of the equation map for chain-calling. * @return An instance of the equation map for chain-calling.
*/ */
public ConcurrentHashMap<Mapping, Equation> addEquation(Equation equation) { public ConcurrentHashMap<Mapping, Equation> addEquation(Equation equation) {
equation.setScriptEngine(scriptEngine); // equation.setScriptEngine(scriptEngine);
equations.put(equation.getMapping(), equation); equations.put(equation.getMapping(), equation);
return equations; return equations;
} }
......
...@@ -24,7 +24,6 @@ import lu.list.itis.dkd.dbc.annotation.NonNullByDefault; ...@@ -24,7 +24,6 @@ import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable; import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.variable.Variable; import lu.list.itis.dkd.tui.cps.variable.Variable;
import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
/** /**
...@@ -37,8 +36,8 @@ import java.util.LinkedHashSet; ...@@ -37,8 +36,8 @@ import java.util.LinkedHashSet;
*/ */
@NonNullByDefault @NonNullByDefault
public class Mapping { public class Mapping {
private Collection<Variable> independentVariables; private LinkedHashSet<Variable> independentVariables;
private Variable dependentVariable; private LinkedHashSet<Variable> dependentVariables;
/** /**
* Constructor initialising the mapping. * Constructor initialising the mapping.
...@@ -48,11 +47,11 @@ public class Mapping { ...@@ -48,11 +47,11 @@ public class Mapping {
* @param dependentVariable * @param dependentVariable
* The dependent variable of the mapping. * The dependent variable of the mapping.
*/ */
public Mapping(Collection<Variable> independentVariables, Variable dependentVariable) { public Mapping(LinkedHashSet<Variable> independentVariables, LinkedHashSet<Variable> dependentVariables) {
// Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables // Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables
// cannot be empty."); //$NON-NLS-1$ // cannot be empty."); //$NON-NLS-1$
this.independentVariables = independentVariables; this.independentVariables = independentVariables;
this.dependentVariable = dependentVariable; this.dependentVariables = dependentVariables;
} }
/** /**
...@@ -60,17 +59,17 @@ public class Mapping { ...@@ -60,17 +59,17 @@ public class Mapping {
* *
* @return The value of independentVariables. * @return The value of independentVariables.
*/ */
public Collection<Variable> getIndependentVariables() { public LinkedHashSet<Variable> getIndependentVariables() {
return independentVariables; return independentVariables;
} }
/** /**
* Simple getter method for dependentVariable. * Simple getter method for dependentVariables.
* *
* @return The value of dependentVariable. * @return The value of dependentVariables.
*/ */
public Variable getDependentVariable() { public LinkedHashSet<Variable> getDependentVariables() {
return dependentVariable; return dependentVariables;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
...@@ -84,7 +83,14 @@ public class Mapping { ...@@ -84,7 +83,14 @@ public class Mapping {
separator = ", "; //$NON-NLS-1$ separator = ", "; //$NON-NLS-1$
} }
renderer.append(" => ").append(dependentVariable.getName()); //$NON-NLS-1$ renderer.append(" => "); //$NON-NLS-1$
separator = ""; //$NON-NLS-1$
for (Variable variable : dependentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
return renderer.toString(); return renderer.toString();
} }
...@@ -143,12 +149,16 @@ public class Mapping { ...@@ -143,12 +149,16 @@ public class Mapping {
* @return A deep copy of the {@link Mapping}. * @return A deep copy of the {@link Mapping}.
*/ */
public Mapping lock() { public Mapping lock() {
LinkedHashSet<Variable> clones = new LinkedHashSet<>(); LinkedHashSet<Variable> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable variable : independentVariables) { for (Variable variable : independentVariables) {
clones.add(variable.clone()); clonedIndependentVariables.add(variable.clone());
}
LinkedHashSet<Variable> clonedDependentVariables = new LinkedHashSet<>();
for (Variable variable : dependentVariables) {
clonedDependentVariables.add(variable.clone());
} }
return new Mapping(clones, dependentVariable.clone()); return new Mapping(clonedIndependentVariables, clonedDependentVariables);
} }
// /** // /**
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2016.
*
* This file is part of TULIP.
*
* TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3,
* as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST
* proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license.
*
* For all non-commercial purposes, TULIP is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, version 3 of the License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import com.google.common.base.Preconditions;
import java.io.CharArrayWriter;
import java.util.LinkedHashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import dk.ange.octave.OctaveEngine;
import dk.ange.octave.type.Octave;
import dk.ange.octave.type.OctaveDouble;
/**
* @author Nico Mack [nico.mack@list.lu]
* @since 1.1
* @version 1.3.0
*/
@NonNullByDefault
public class OctaveEquation extends Equation {
private OctaveMapping mapping, lockedMapping;
@Nullable
private String script;
private OctaveEngine scriptEngine;
private CharArrayWriter engineErrors;
private static final Logger logger = Logger.getLogger(OctaveEquation.class.getSimpleName());
/**
* Constructor
*
* @param mapping
* The mapping of variables to take into account for the equation.
* @param script
* The mathematical representation of the equation in string form. Note that the names of
* the variables in the script must coincide with the names of the variables in the
* mapping.
*/
public OctaveEquation(OctaveMapping mapping, String script) {
super(mapping, script);
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
this.engineErrors = new CharArrayWriter();
}
/**
* Method called to evaluate the script of the equation with the variables provided by the
* mapping.
*/
@Override
public synchronized void evaluate() {
LinkedHashSet<Variable> dependentVariables;
String evaluationErrors;
Preconditions.checkState(scriptEngine != null);
try {
engineErrors.reset();
scriptEngine.setErrorWriter(engineErrors);
initParameters();
scriptEngine.eval(this.script);
} catch (Exception exception) {
logger.log(Level.SEVERE, "Error while evaluating script " + this.script, exception); //$NON-NLS-1$
}
dependentVariables = mapping.getDependentVariables();
for (Variable variable : dependentVariables) {
try {
OctaveDouble result = scriptEngine.get(OctaveDouble.class, variable.getName());
variable.setValue(result.get(1));
} catch (Exception exception) {
logger.log(Level.SEVERE, "Error while retrieving variable " + variable.getName(), //$NON-NLS-1$
exception);
}
}
evaluationErrors = engineErrors.toString();
if (evaluationErrors.length() > 0) {
logger.log(Level.WARNING, "Error while evaluating equation :" + evaluationErrors); //$NON-NLS-1$
}
}
/**
* Method used to replace variables with their actual values in the formula.
*/
private void initParameters() {
for (Variable variable : lockedMapping.getIndependentVariables()) {
Double numericValue = Double.valueOf(variable.getValue().toString());
if (isNegative(numericValue)) {
numericValue *= -1d;
}
scriptEngine.put(variable.getName(), Octave.scalar(numericValue));
}
}
private static boolean isNegative(double _double) {
return Double.doubleToRawLongBits(_double) < 0;
}
/**
* Method for setting the script engine to use.
*
* @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/
public void setScriptEngine(OctaveEngine engine) {
scriptEngine = engine;
}
}
\ No newline at end of file
/**
* Copyright Luxembourg Institute of Science and Technology, 2016.
*
* This file is part of TULIP.
*
* TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3,
* as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST
* proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license.
*
* For all non-commercial purposes, TULIP is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, version 3 of the License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import com.google.common.base.Preconditions;
import java.util.Collection;
import java.util.LinkedHashSet;
/**
*
* @author Nico Mack [nico.mack@list.lu]
* @since 1.1
* @version 1.3.1
*/
public class OctaveMapping extends Mapping {
private LinkedHashSet<Variable> dependentVariables;
/**
*
* @param independentVariables
* @param dependentVariables
*/
public OctaveMapping(LinkedHashSet<Variable> independentVariables, LinkedHashSet<Variable> dependentVariables) {
super(independentVariables, null);
Preconditions.checkArgument(!dependentVariables.isEmpty(), "The set of output variables cannot be empty."); //$NON-NLS-1$
this.dependentVariables = dependentVariables;
}
/**
* Simple getter method for dependentVariable.
*
* @return The value of dependentVariable.
*/
public LinkedHashSet<Variable> getDependentVariables() {
return dependentVariables;
}
@Override
public String toString() {
String separator = ""; //$NON-NLS-1$
StringBuilder renderer = new StringBuilder();
Collection<Variable> independentVariables = super.getIndependentVariables();
for (Variable variable : independentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
renderer.append(" => "); //$NON-NLS-1$
separator = ""; //$NON-NLS-1$
for (Variable variable : dependentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
return renderer.toString();
}
/**
* Method for locking the mapping; cloning all variables such that they may not be influenced by
* the evaluation of the equation.
*
* @return A deep copy of the {@link Mapping}.
*/
@Override
public synchronized Mapping lock() {
Collection<Variable> independentVariables = super.getIndependentVariables();
LinkedHashSet<Variable> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable variable : independentVariables) {
clonedIndependentVariables.add(variable.clone());
}
LinkedHashSet<Variable> clonedDependentVariables = new LinkedHashSet<>();
for (Variable variable : dependentVariables) {
clonedDependentVariables.add(variable.clone());
}
return new OctaveMapping(clonedIndependentVariables, clonedDependentVariables);
}
}
\ No newline at end of file
package lu.list.itis.dkd.tui.cps.system.executor;