ExampleOne

From SeSAm-Wiki

Jump to: navigation, search

Contents

Example One: Programming Mathematical Functions

Suppose we want to add a new primitive atan2 with arguments x and y , that is defined like this:

syntax:

atan2(x, y)
where:
x - x coordinate of the point.
y - y coordinate of the point.
return:
number - an implementation-dependent approximation to the arc tangent of the quotient, y/x, of the arguments y and x, where the signs of the arguments are used to determine the quadrant of the result.
description:
It is intentional and traditional for the two-argument arc tangent function that the argument named y be first and the argument named x be second.

First of all we have to define a declaration of the function, this includes the input and output values, a documentation and everything that is needed to specify how functions can be syntactically put together. Afterwards we will create a definition for the actual function that describes as well the semantics of the function.

Creating the function declaration

To define this Function-Declaration we simply create a new class extending a given abstract class like this:

public final class FunctionDeclarationATan2
extends AbstractSpecificFunctionArgsDeclaration {
public FunctionDeclarationATan2() {
super(
"atan2",
DoubleType.getInstance(),
CollectionsHelper.createList(
DoubleType.getInstance(),
DoubleType.getInstance()),
false,
false);
setDocumentation(
"This calculates the value atan2(x,y)");
}
}

This still causes a compile error, but we don't mind at the moment. We have called the super constructor with some arguments that are:

  • "atan2", the name of the function,
  • DoubleType.getInstance(), the type of the return value of the function. SeSAm-Types are usually Singletons. Examples of valid types are: DoubleType, ImageType, Position2DType, StringType, ActivityType,... ,
  • CollectionsHelper(...), a list of types for the input-parameters of this function declaration,
  • false, a flag indicating if this function should return the same value if its parameters won't change (e.g. RandomInt wouldn't make sense as constant function...),
  • false, a flag indicating if this function declaration should be marked as ExpertFunction.

Additionally we add a documentation string to the primitive. This will be shown as tooltip in SeSAm. But now... let's go on. We still have compile-errors because we haven't implemented the abstract function createFunction yet:

public IFunction createFunction(ICreateFunctionArgs
createFunctionArgs, IFunctionList functions) {
if (Info6Assert.AssERTION_ON)
Info6Assert.assertEquals(2, functions.size());
return new FunctionATan2(
(IFunction) functions.get(0),
(IFunction) functions.get(1));
}

Whereas the declaration provides knowledge about correct composition of the functions, the actual functions store the composition of the functions. This actual functions extend the interfaceIFunctionand are created whencreateFunctionin the function declaration is called. Here we get a list containing the functions for the two input parameters and create the resulting function by instantiating the yet not existing function definitionFunctionATan2.

Creating the function definition

Now we want to create the already referenced but not yet implemented part behind the declaration of the function. We need two private variables to store the inner functions for the arguments. These functions are given to the constructor. Then we need the methodexecute, which is called at runtime to calculate the resulting value of the function. Functions can be dependent of their input-parameters, as well as from theexecuteFunctionsArgsthat are given with the call. These contain references to the calling agent, the world-class, and so on, but we will give examples later.

public class FunctionATan2 extends AbstractFunction {
private final IFunction argument1;
private final IFunction argument2;
public FunctionATan2(IFunction arg1, IFunction arg2) {
super();
argument1 = arg1;
argument2 = arg2;
}
public Object execute(IExecuteFunctionArgs executeFunctionArgs)
throws SimulationRuntimeException {
int x = ((Double)argument1.execute(executeFunctionArgs)).intValue();
int y = ((Double)argument2.execute(executeFunctionArgs)).intValue();
return new Double(Math.atan2(x,y));
}
}

Integration to SeSAm

To integrate this new function into SeSAm you can use the plugin-mechanism of SeSAm. Just create a new.jar-file containing the complied classes and a textfile calledplugin.ini, looking like this:

<plugin>
<functionSection>
<function className="sesam.math.FunctionDeclarationATan2"/>
</functionSection>
</plugin>

fk/16.11.2005: no, it does not look like this, but you only have to give the plugin class. It then would look like:

<root>
<plugin2004 className="de.uniwue.ki.mas.basics.feature.spatial.SpatialPlugin"/>
</root>

(sorry, after version 1.9.4 the old form of declaration does not work any more.) If you put the resulting.jar-archive into theSeSAm/plugins-directory and restart SeSAm, the new primitive will be available to the modeller. It is also allowed to put.ini-files (instead of.jar-archives) into the plugins directory. Then you just have to ensure that all referenced classes are in the classpath of your JAVA-environment. As the picture shows the function is now available:

Image:bild.jpg

Personal tools