Dear users, Please note that, from Monday, August 16, 2019, RSA keys shorter than 2048bit will no longer be accepted for security reasons. Please update your keys as needed before this date. If you need assistance with regard to this process, please contact sia@list.lu

Thank you for your understanding.

Commit e896f500 authored by Eric Tobias's avatar Eric Tobias

Changed CPS to no longer use Octave by default

parent 64f96cf6
......@@ -40,5 +40,10 @@
<artifactId>javaoctave</artifactId>
<version>0.6.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
* Copyright CRP Henri Tudor, 2014. All rights reserved. If you wish to use this code for any
* purpose, please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps.system;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import com.google.common.base.Preconditions;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import com.google.common.base.Preconditions;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
/**
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 24 Feb 2014
* @version 1
*/
@NonNullByDefault
public class Equation
{
private Mapping mapping, lockedMapping;
@Nullable
private ScriptEngine scriptEngine;
private String script;
public class Equation {
private Mapping mapping, lockedMapping;
@Nullable
private ScriptEngine scriptEngine;
private String script;
/**
* 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 Equation(Mapping mapping, String script) {
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
}
/**
* 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 Equation(Mapping mapping, String script)
{
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
}
/**
* Simple getter method for mapping.
*
* @return The value of mapping.
*/
public Mapping getMapping() {
return mapping;
}
/**
* Simple getter method for mapping.
* @return The value of mapping.
*/
public Mapping getMapping()
{
return mapping;
}
/**
* Method called to evaluate the script of the equation with the variables provided by the
* mapping.
*/
public void evaluate() {
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$
}
}
/**
* Method called to evaluate the script of the equation with
* the variables provided by the mapping.
*/
@SuppressWarnings("null")
public void evaluate()
{
Preconditions.checkState(scriptEngine != null);
try{
mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables()));
} catch (ScriptException e) {
Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "", e);
}
}
/**
* Method used to replace variables with their actual values in the formula.
*
* @return The formula with variables replaced by their values, ready for evaluation.
*/
private String replaceVariables() {
String result = new String(script);
/**
* Method used to replace variables with their actual values in the formula.
* @return
* The formula with variables replaced by their values, ready for evaluation.
*/
private String replaceVariables()
{
String result = new String(script);
for (Variable variable : lockedMapping.getIndependentVariables()) {
result = result.replaceAll(variable.getName(), variable.getValue().toString());
}
result = result.replaceAll(lockedMapping.getDependentVariable().getName(), lockedMapping.getDependentVariable().getValue().toString());
for(Variable variable : lockedMapping.getIndependentVariables())
{
result = result.replaceAll(variable.getName(), variable.getValue().toString());
}
result = result.replaceAll(lockedMapping.getDependentVariable().getName(), lockedMapping.getDependentVariable().getValue().toString());
assert result != null;
return result;
}
assert result != null;
return result;
}
/**
* Method for setting the script engine to use.
*
* @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/
public void setScriptEngine(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 setScriptEngine(ScriptEngine engine)
{
scriptEngine = engine;
}
/**
* Method querying whether the {@link Equation} instance is
* affected by a change of the {@link Variable} instance and
* would need to recompute.
* @param variable
* The variable to look up.
* @return
* <code>True</code> if the {@link Variable} instance is
* an independent variable that is part of this
* {@link Equation} isntance's computation.
*/
public boolean catersTo(Variable variable)
{
return mapping.catersTo(variable);
}
/**
* Method querying whether the {@link Equation} instance is affected by a change of the
* {@link Variable} instance and would need to recompute.
*
* @param variable
* The variable to look up.
* @return <code>True</code> if the {@link Variable} instance is an independent variable that is
* part of this {@link Equation} isntance's computation.
*/
public boolean catersTo(Variable variable) {
return mapping.catersTo(variable);
}
/**
* Method used to make a local copy of all variables to lock
* down the state for asynchronous, clock-driven computation.
*/
public void saveState()
{
lockedMapping = mapping.lock();
}
/**
* Method used to make a local copy of all variables to lock down the state for asynchronous,
* clock-driven computation.
*/
public void saveState() {
lockedMapping = mapping.lock();
}
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
* Copyright CRP Henri Tudor, 2014. All rights reserved. If you wish to use this code for any
* purpose, please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps.system;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.base.Preconditions;
import lu.list.itis.dkd.cps.InputEvent;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import com.google.common.base.Preconditions;
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 defines the engine that
* evaluates the equations. The class may be driven by a clock
* react to input changes synchronously.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
* 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
* input changes synchronously.
*
* @author Eric Tobias [eric.tobias@tudor.lu]
* @since 1.0
* @version 1.2.0
*/
@NonNullByDefault
public class LinearEquationSystem extends System
{
private ConcurrentHashMap<Mapping, Equation> equations;
// private ScriptEngine scriptEngine;
// private static OctaveEngine scriptEngine;
// static {
// OctaveEngineFactory l_Factory = new OctaveEngineFactory();
// l_Factory.setOctaveProgram(new File ("/opt/local/bin/octave"));
// l_Factory.setWorkingDir(new File("./octave"));
// scriptEngine = l_Factory.getScriptEngine();
// }
@NonNullByDefault
public class LinearEquationSystem extends System {
private ConcurrentHashMap<Mapping, Equation> equations;
private ScriptEngine scriptEngine;
/**
* Constructor issuing a super call and initialising the map of equations.
*
* @param lockToNesting
* Boolean indicating whether nested systems will have their inputs locked during
* computation. Doing so will result in a synchronous behaviour of the system while
* choosing <code>false</code> will have the nested systems evaluate their equations
* first, possibly propagating results to systems higher up in the nesting tree.
*/
public LinearEquationSystem(boolean lockToNesting) {
super();
equations = new ConcurrentHashMap<>();
scriptEngine = new ScriptEngineManager().getEngineByName("js"); //$NON-NLS-1$
this.lockSystemForNesting = lockToNesting;
assert scriptEngine != null : "Script engine cannot be null;"; //$NON-NLS-1$
}
/**
* Method used for adding an {@link Equation} instance to the system.
*
* @param equation
* The {@link Equation} instance to add.
* @return An instance of the equation map for chain-calling.
*/
public ConcurrentHashMap<Mapping, Equation> addEquation(Equation equation) {
equation.setScriptEngine(scriptEngine);
equations.put(equation.getMapping(), equation);
return equations;
}
/** {@inheritDoc} */
@Override
public synchronized void clockTicked(long tick) {
super.clockTicked(tick);
for (Equation equation : equations.values()) {
equation.evaluate();
}
}
/**
* Constructor issuing a super call and initialising the map of
* equations.
* @param lockToNesting
* Boolean indicating whether nested systems will have their
* inputs locked during computation. Doing so will result
* in a synchronous behaviour of the system while choosing
* <code>false</code> will have the nested systems evaluate
* their equations first, possibly propagating results to
* systems higher up in the nesting tree.
*/
@SuppressWarnings("null")
public LinearEquationSystem(boolean lockToNesting)
{
super();
equations = new ConcurrentHashMap<>();
// scriptEngine = new ScriptEngineManager().getEngineByName("js");
this.lockSystemForNesting = lockToNesting;
// assert scriptEngine != null : "Script engine cannot be null;";
}
/**
* Method used for adding an {@link Equation} instance to the system.
* @param equation
* The {@link Equation} instance to add.
* @return
* An instance of the equation map for chain-calling.
*/
public ConcurrentHashMap<Mapping, Equation> addEquation(Equation equation)
{
// ((OctaveEquation)equation).setScriptEngine(scriptEngine);
// equation.setScriptEngine(scriptEngine);
equations.put(equation.getMapping(), equation);
return equations;
}
/** {@inheritDoc} */
@Override
public synchronized void inputChanged(InputEvent input) {
Preconditions.checkArgument(input != null && input.getSource() != null,
"Neither the input nor the input source may be null."); //$NON-NLS-1$
/** {@inheritDoc} */
@Override
public synchronized void clockTicked(long tick)
{
super.clockTicked(tick);
for(Equation equation : equations.values())
{
equation.evaluate();
}
}
/** Invoke super method dealing with nested systems. */
super.inputChanged(input);
/** {@inheritDoc} */
@SuppressWarnings("null")
@Override
public synchronized void inputChanged(InputEvent input)
{
Preconditions.checkArgument(input != null && input.getSource() != null,
"Neither the input nor the input source may be null.");
/** Invoke super method dealing with nested systems. */
super.inputChanged(input);
for(Equation equation : equations.values())
{
if(equation.catersTo((Variable) input.getSource()))
{
equation.evaluate();
}
}
}
for (Equation equation : equations.values()) {
if (equation.catersTo((Variable) input.getSource())) {
equation.evaluate();
}
}
}
/** {@inheritDoc} */
@Override
public void saveState()
{
for(Equation equation : equations.values())
{
equation.saveState();
}
}
/** {@inheritDoc} */
@Override
public void saveState() {
for (Equation equation : equations.values()) {
equation.saveState();
}
}
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
* Copyright CRP Henri Tudor, 2014. All rights reserved. If you wish to use this code for any
* purpose, please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps.system;
import java.util.LinkedHashSet;
import com.google.common.base.Preconditions;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import com.google.common.base.Preconditions;
import java.util.LinkedHashSet;
/**
* Class describing the mapping between a set of input
* variables and an output variable. The order of input
* variables is preserved and essential when defining the
* equation.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 24 Feb 2014
* @version 1
* Class describing the mapping between a set of input variables and an output variable. The order
* of input variables is preserved and essential when defining the equation.
*
* @author Eric Tobias [eric.tobias@tudor.lu]
* @since 1.0
* @version 1.2.0
*/
@NonNullByDefault
public class Mapping
{
private LinkedHashSet<Variable> independentVariables;
private Variable dependentVariable;
/**
* Constructor initialising the mapping.
* @param independentVariables
* The independent variables of the mapping.
* @param dependentVariable
* The dependent variable of the mapping.
*/
public Mapping(LinkedHashSet<Variable> independentVariables, Variable dependentVariable)
{
Preconditions.checkArgument(! independentVariables.isEmpty(), "The set of input variables cannot be empty.");
this.independentVariables = independentVariables;
this.dependentVariable = dependentVariable;
}
/**
* Simple getter method for independentVariables.
* @return The value of independentVariables.
*/
public LinkedHashSet<Variable> getIndependentVariables()
{
return independentVariables;
}
/**
* Simple getter method for dependentVariable.
* @return The value of dependentVariable.
*/
public Variable getDependentVariable()
{
return dependentVariable;
}
/** {@inheritDoc} */
@SuppressWarnings("null")
@Override
public String toString()
{
String separator = "";
StringBuilder renderer = new StringBuilder ();
for(Variable variable : independentVariables)
{
renderer.append(separator).append(variable.getName());
separator = ", ";
}
renderer.append(" => ").append(dependentVariable.getName());
return renderer.toString();
// String result = "";
// for(Variable variable : independentVariables)
// {
// result = result.concat(variable.getName() + ", ");
// }
//
// return result.trim().substring(0, result.length() - 2).concat(" => " + dependentVariable.getName());
}
/**
* {@inheritDoc}<br><br>
*
* The method invocation will compute the hash code based
* on the {@link #toString()} output.
*/
@Override
public int hashCode()
{
return toString().hashCode();
}
/** {@inheritDoc} */
@Override
public boolean equals(@Nullable Object object)
{
if(object == null) return false;
if(object == this) return true;
if(object instanceof Mapping)
{
Mapping mapping = (Mapping) object;
if(mapping.toString().equals(toString()))
{
return true;
}
}
return false;
}
/**
* Method querying whether the {@link Mapping} instance holds
* the {@link Variable} instance given as a parameter as an
* independent {@link Variable} instance.
* @param variable
* The variable to look up.
* @return
* <code>True</code> if the {@link Variable} instance is
* an independent variable managed by this {@link Mapping}
* instance.
*/
public boolean catersTo(Variable variable)
{
for(Variable _variable : independentVariables)
{
if(_variable.equals(variable))
{
return true;
}
}
//return (independentVariables.contains(variable));
return false;
}
/**
* 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}.
*/
public Mapping lock()
{
LinkedHashSet<Variable> clones = new LinkedHashSet<>();
for(Variable variable : independentVariables)
{
clones.add(variable.clone());
}
return new Mapping(clones, dependentVariable.clone());
}
public class Mapping {
private LinkedHashSet<Variable> independentVariables;
private Variable dependentVariable;
/**
* Constructor initialising the mapping.
*
* @param independentVariables
* The independent variables of the mapping.
* @param dependentVariable
* The dependent variable of the mapping.
*/
public Mapping(LinkedHashSet<Variable> independentVariables, Variable dependentVariable) {
Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables cannot be empty."); //$NON-NLS-1$
this.independentVariables = independentVariables;
this.dependentVariable = dependentVariable;
}
/**
* Simple getter method for independentVariables.
*
* @return The value of independentVariables.
*/
public LinkedHashSet<Variable> getIndependentVariables() {
return independentVariables;
}
/**
* Simple getter method for dependentVariable.
*
* @return The value of dependentVariable.
*/
public Variable getDependentVariable() {
return dependentVariable;
}
/** {@inheritDoc} */
@Override
public String toString() {
String separator = ""; //$NON-NLS-1$
StringBuilder renderer = new StringBuilder();
for (Variable variable : independentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
renderer.append(" => ").append(dependentVariable.getName()); //$NON-NLS-1$
return renderer.toString();
}
/**
* {@inheritDoc}<br>
* <br>
*
* The method invocation will compute the hash code based on the {@link #toString()} output.
*/
@Override
public int hashCode() {
return toString().hashCode();
}
/** {@inheritDoc} */
@Override
public boolean equals(@Nullable Object object) {
if (object == null)
return false;
if (object == this)
return true;
if (object instanceof Mapping) {
Mapping mapping = (Mapping) object;
if (mapping.toString().equals(toString())) {
return true;
}
}
return false;
}
/**
* Method querying whether the {@link Mapping} instance holds the {@link Variable} instance
* given as a parameter as an independent {@link Variable} instance.
*
* @param variable
* The variable to look up.
* @return <code>True</code> if the {@link Variable} instance is an independent variable managed
* by this {@link Mapping} instance.
*/
public boolean catersTo(Variable variable) {
for (Variable _variable : independentVariables) {
if (_variable.equals(variable)) {
return true;
}
}
return (independentVariables.contains(variable));
}
/**
* 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}.
*/
public Mapping lock() {
LinkedHashSet<Variable> clones = new LinkedHashSet<>();
for (Variable variable : independentVariables) {
clones.add(variable.clone());
}
return new Mapping(clones, dependentVariable.clone());
}
}
\ No newline at end of file
......@@ -59,7 +59,7 @@ public class OctaveEquation extends Equation {
* Method called to evaluate the script of the equation with the variables provided by the
* mapping.