Primitive Operators and Properties

From Numerus
Jump to navigation Jump to search

Numerus supports a large set of primitives divided into properties and primitive operators, or primops.

A property is an identifier assigned a value at the beginning of a simulation run which is not expected to change. For example, the rows and cols properties of a CellMatrix are fixed at the start of a run and don’t change. A special type of property, called a scope, is used to look up the current values of components.

Primops are functions of zero or more arguments. Some primitives may be used without restriction; others make sense only in specific contexts; for example rows and cols are only useful in spatial contexts such as CellMatrices, AgentVectors and SimWorlds.

Here are the properties and primops supported by the current Numerus implementation, organized by type and area of applicability. All properties (except for mathematical properties) begin with a lower case letter, and all primops are composed entirely of capital letters. Primops are always functions, and therefore require an argument list (even if empty) in order to be invoked.

Notation: x, y represent values (numbers or string constants or expressions); fn represents a Javascript function; exp represents a string expression; [x, y] represents one or more optional arguments, coords represents a coords object of the form {row: r, col: c} or (in the case of 3 dimensions) {row: r, col: c, plane: p}.

Universal Properties and Primops

These can be used in any expression in any component.

Properties

self
scope
The scope of a simulator (Capsule, CellMatrix, etc.) Used to look up component values (see the section on scopes, coming soon).
Self
_cap_
Reference from the scope of a simulator to that simulator.

Control Primops

ALERT(h, [b], [t])
Displays string h in a dialog box as the header of message.
If optional string b is provided, it is the body of the message.
If optional string t is provided, it is the title of the message.
COUNT(fn, l)
fn is a boolean function of one argument and a l is list.
Returns: COUNT(f, l) applies f to each element of l and returns the number of times the result is true.
DELAY(comp, x, [y])
Returns: the value of component comp delayed by x time units. Comp is a string naming a stateful component (i.e., stock, variable or sequence).
Optional y is returned if the current time is less than x. If y is omitted then 0 is returned.
PULSE(amount, start, interval)
Returns: amount when current time is start, start + interval, start + 2*interval, etc.; 0 otherwise
DELAYN(comp scale shape init)
Returns: the n-th order exponentially smooth delay for component comp. comp should be a string naming a Stock, Sequence or Term.
STEP(x, y)
Returns: the value of x if the current time is y or greater; 0 otherwise.
TERMINATE()
Terminates the running simulation.
TOTAL(fn, l)
fn is a numerical function of one argument and a l is list.
Returns: TOTAL(fn, l) applies fn to each element of l and returns the sum of the results.
RESETTING()
Returns: true when the system is currently resetting.

Convenience Primops

These primops perform useful functions that could otherwise be programmed.

FLIP(p)
Simulates a Bernoulli trial.
Returns: true with probability p and false with probability 1-p.
BOUNCER(angle, x, y, cols, rows)
Returns: the expected angle in one step of a projectile moving on a surface bounded by [x, cols] and [y, rows], deflecting off of the edge according to the standard laws of physics.
NORMALIZE(theta)
NORMALIZE02PI(theta)
Returns: angle theta normalized on the interval [, π ] and [0, ], respectively.

Input/Output Primops

BASEDIR()
Returns: the current model directory.

In each of the following path designates a textfile. if path begins with “/” it is treated as an absolute pathname; otherwise it is treated as relative to the current model directory.

OPENREAD(path)
Opens path for reading and returns a Java BufferedReader object. The latter contains methods read and readLine to perform input. See http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html for complete details.
OPENWRITE(path)
Opens path for writing and returns a Java PrintWriter object. The latter contains methods print and println to perform output. See http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html for complete details.
READDATA(path)
Returns: the content of the file path as a string.
PRINT(x0, x1, ...)
Returns: nothing; outputs the values of its arguments to the console, separated by spaces.

Mathematical Properties

PI
PI2
PIO2
Constants π, and π/2, respectively
MPI
MPI2
MPIO2
Constants , -2π and -π/2, respectively
LN10
LN2
LOG10E
LOG2E
Constants ln(10), ln(2), log10(e) and log2(e)
SQRT1_2
SQRT2
Constants 1/√2 and 2, respectively.

Mathematical Primops

Math.XXX
The JavaScript Math functions and constants; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math.
DERIVN(fn, n)
Returns: the value of the nth derivative of fn at the current time, with precision based on the value of dt. fn should be a string naming a State (Stock or Sequence) or Term.
DISTANCE(x0, y0, x1, y1)
Returns: Euclidean distance between points (x0, y0) and (x1, y1).
RANDOM()
Returns: a uniformly distributed random number between 0 and 1.
SEED(x)
Returns: nothing; sets the seed of the random number generator. Should be part of simulation initialization.
RANDOM_HEADING()
Returns: a uniformly distributed random number between and π.
BINOMIAL(n, p)
n is an integer; 0 ≤ p ≤ 1
Returns: a random number from the binomial distribution with n trials and success probability p.
MULTIBINOMIAL(n, p, k)
Returns: Sum of k independent executions of BINOMIAL(n, p).
MULTINOMIAL(n, [p0, p1, ... pm])
Returns: an m-element vector of outcomes from performing n independent generalized Bernoulli trials.
SELECT([s0,...,sm], [p0, .... pm])
A single generalized Bernoulli trial over the states s0, ... sm with respective probabilities p0, ... pm.
Returns: One of the values si with probability pi. Note: if the probabilities do not sum to 1, pm is increased accordingly
NORMAL(x, y)
Returns: a random number from the normal distribution with mean x and standard deviation y.
POISSON(lambda)
Returns: a random number from the Poisson distribution with density lambda.
UNIFORM(x, y)
Returns: a uniformly distributed random variable between x and y.
SIN(x)
Returns: the trigonometric sin of x.
SINWAVE(x, y)
Returns: x*sin(2πt/y), where t is the current time.
COS(x)
Returns: the trigonometric cosine of x.
COSWAVE(x)
Returns: x*cos(2πt/y), where t is the current time.
TAN(x)
Returns: the trigonometric tangent of x.
ACOS(x)
Returns the trigonometric arccosine of x.
ASIN(x)
Returns the trigonometric arcsine of x.
ATAN(x)
Returns: the trigonometric arctangent of x.
ATAN2(y, x)
Returns: the trigonometric tangent of y/x.
MIN(x, y, z ...)
MAX(x, y, z, ...)
Returns:, respectively, the lowest or highest value in a list of arguments:
CEIL(x)
FLOOR(x)
ROUND(x);
Returns:, respectively, x rounded up, x rounded down, and x rounded to the nearest integer.
SQRT(x)
Returns: x
ABS(x)
Returns: |x|
POW(x, y)
Returns: xy
EXP(x)
Returns: ex
LOG(x)
Returns: ln(x)
LOG2(x)
Returns: log2(x)
LOG10(x)
Returns: log10(x)
ARRAYSUM(a)
Returns: the sum of the elements in array a.
ARRAYOF(n, x)
Returns: an array of length n filled with x.
WRAPXM(v, m)
Returns: v mod m normalized to [0, m].
FIXAT(n, d)
Returns: Number n with at most d decimal places.
FACT(n)
Returns: The factorial of n, using Stirling's formula for n > 20.
GRAPHFUN([[x0, y0], [x1, y1], ...])
GRAPHFUN([x0, y0], [x1, y1], ...)
Returns: A function based on the graph defined by the ordered pairs in the argument, interpolated linearly. Acceptable input can be single argument consisting of an array of ordered pairs, or multiple arguments, each an ordered pair. The list need not be in increasing order of x. The returned function maps any value smaller (greater) than the smallest (largest) domain value xk to xk 's value in the range.

Matrix Primops

COLUMNSPLIT(tab)
tab is a 2-dimensional array derived from a table, where the first row contains column headers.
Returns: an object in which each property name is a column header with property value an array comprising the corresponding column.
CSVTOMAT(csv)
csv is a string where line is a comma separated sequence of values.
Returns: the matrix in which each row corresponds to a line in csv.
ROWSTOOBJS(tab)
tab is a 2-dimensional array derived from a table, where the first row contains column headers.
Returns: an array of objects, one for each non-header row. In each object properties are column headers bound to the entry for that column in the corresponding row.
TRANSPOSE(mat)
mat is a matrix (i.e. 2-dimensional array)
Returns: the transpose of mat.

Simulation Primops

CLOCK()
Returns the current clock as an object.
DT()
Returns: current delta value (dt).
SIMSTART()
SIMEND()
SIMMETHOD()
Returns: simulation start time, end time and integration method, respectively.
TIME()
Returns: current simulation time.
TICK()
Returns: the number of simulation steps since the start of the simulation.
SET_DT(dt)
Returns: nothing; sets the current DT value to dt.
DIMENSION(state)
Return: the dimension of the State component state. state should be a string naming a State component (Stock or Sequence).
TRAIL(state)
Returns: an array containing all values recorded for component state. state should be a string naming a State component (Stock or Sequence). Note: complete component history requires that the full history checkbox be selected for the component.

Miscellaneous Primops

_.XXX
The underscore.js library of useful functions. See http://underscorejs.org.
ASVALUE(v)
Required when supplying an array or function value to the input pin of an aggregator. Arrays supplied as input to aggregators are usually interpreted so that each array element is used as input for one of the elements of the aggregator. Similarly, functions are invoked on the id of each element to compute the input value for that element. An array or function wrapped with ASVALUE is sent intact to each element of the aggregator.
DEPENDSON(comp)
Returns: 0. This is used during model construction to assert dependencies.
DISTRIBUTE(a)
Returns: if a is an array of at most 3 dimensions, DISTRIBUTE returns a function f which takes as many arguments as the dimension of a and returns the selected value. Otherwise f is a function of no arguments that return a.
LOOKUP_AREA(term, lo, hi)
Returns: the integral of component term on the interval [lo, hi]. term is a string naming a Term.

Cell Properties and Primops

The following may only be used by capsules contained in a CellMatrix, or cell capsule in a SimWorld. row and col are integers representing row-column coordinates within the CellMatrix. coords is a Coords object All primops expecting coordinate pairs as parameters can either be called with separate row-column arguments or with a Coords object.

Cartesian coordinates will generally be automatically wrapped; i.e. if the coordinate space has dimension rows x cols, then a negative value for row or col is treated respectively as rows + row and cols + col. Values that exceed the dimensions respectively become row – rows and col – cols. This type of space is topologically equivalent to a torus.

Properties

coords
Object whose row and col properties respectively reference the caller’s row and column coordinates within the CellMatrix.
rows
cols
Bound to the total number of rows and columns, respectively.
matrix
Bound to the 2 dimensional array of cells in a CellMatrix

Primops

BLOCK(n, [wrap])
Returns: a list (array) of coordinate objects (i.e., containing row and col properties) comprising the square block of cells n units away from the caller or less. (if wrap is true, BLOCK treats the surface as a torus).
CELL(row, col)
CELL(coords)
Returns the scope for the cell at the given coordinates, which may be passed either as separate parameters or in a coords object. The fields of the scope bind each of the Stocks, Terms and Flows in the cell to the current value of the corresponding component.
CELLS()
Returns the entire matrix (i.e., 2-dimensional array) of scopes for the CellMatrix.
  CELLS()[row][col] == CELL(row, col).
CELL_VALUE(row, col, comp)
CELL_VALUE(coords, comp)
comp is a String naming a Stock, Flow or Term in the cell capsule.
Returns: the current value of that component in the cell with the given coordinates.
  CELL VALUE(row, col, comp) == CELL(row, col)[comp]
RING(n, [wrap])
Returns: a list (array) of coordinate objects (i.e., containing row and col properties) for all cells comprising the square exactly n units away from the caller. (if wrap is true, RING treats the surface as a torus).
WRAP(row, col)
WRAP(coords)
Performs a “wraparound” of the coordinates if they exceed the size of the matrix (or are negative). Returns an array containing the new row and column.

Hexagonal Primops

The following should only be used if the CellMatrix is in hexagonal mode.

HEXRING(n, [wrap])
Returns: a list (array) of coordinate objects (i.e., containing row and col properties) for all cells comprising the hexagon exactly n units away from the caller. (If wrap is true, HEXRING treats the surface as a torus.)
HEXBLOCK(n, [wrap])
Returns: a list (array) of coordinate objects (i.e., containing row and col properties) comprising the hexagonal block of cells n units away from the caller or less. (If wrap is true, HEXBLOCK treats the surface as a torus.)

Convenience Primops

These primops perform useful functions that could otherwise be programmed.

COUNT_CELLS(l, comp, value)
l is a list of cell scopes objects, comp is a string naming a component in those cells (stock, term, flow, etc.), and value is any JavaScript data element.
Returns: Returns the number of objects in l for which the current value of comp is value.
ALL_CELLS(l, comp, value)
NO_CELL(l, comp, value)
SOME_CELL(l, comp, value)
l is a list of cell scopes, comp is a string naming a component in those cells (stock, term, flow, etc.), and value is any JavaScript data element.
Returns: Respectively returns true if for all, none or some scopes in l the current value of comp is value; false otherwise.

Agent Properties and Primops

The following may only be used by capsules contained in an AgentVector. id is an integer representing agent id of an agent. The term “caller” is used to identify the agent in which the primop is being executed, or the property value is being looked up. loc is a location object with properties x and y.

Properties

birth
The point in model time at which the caller was created.
myId
The unique agent ID that has been assigned to the caller.
rows
cols
planes
Bound to the total number of rows and columns in the space occupied by this AgentVector. Planes returns 0

unless space is 3d.

vector
Bound to the object mapping agent ids to agents in an AgentVector

Primops

ADATA(s)
Returns: if s = "AGENTIDS", then ADATA returns the current list of agents; if s == "AGENTCOUNT", then ADATA returns the current agent count. Used to extract data from AgentVectors.
AGE(id)
MYAGE()
Returns: the age (i.e., time since birth) of agent id, or of the caller, respectively.
AGENT(id)
Returns: the scope of the agent identified by id, if it exists.
AGENTS()
Returns: the list of live agent scopes.
AGENTS_AT(row, col)
AGENTS_AT(coords)
Returns: a list of agents contained in the cell at specified coordinates.
AGENT_COUNT()
Returns: the total number of agents.
AGENT_IDS()
Returns: the array of ids for currently living agents.
AGENT_VALUE(id, comp)
comp is a String naming a Stock, Flow or Term in the agent capsule.
Returns: the current value of that component in agent id.
   AGENT VALUE(id, comp) == AGENT(id)[comp]
CELL_COORDS(id)
Returns: a coords object containing the row/col coordinates of the current position of the agent identified by id. If id is omitted, returns the row/col coordinates of the caller.
CREATE([init], [n])
Schedules the creation of a n new agents (n is assumed to be 1 if omitted). init is an initializer object containing bindings for properties in the new agent. These may include init_x, init_ y and init_heading, to indicate the new agent’s initial position and direction. It may also include alternate initialization expressions for Stocks, Local Variables and Properties. If init is omitted, the new agent is a clone of the caller. All new agents are created at the end of the cycle.
KILL(id)
Schedules the elimination of agent id. All agent eliminations are carried out at the end of the cycle.
LOCATION(id)
Returns: the cartesian location of the agent identified by id in an object with properties x and y (and z if the space is 3-dimensional), and the current heading of the agent with property theta. If id is omitted, returns these data for the caller.
LWRAP(x, y)
LWRAP(loc)
Performs a “wraparound” of the location if either coordinate exceeds the size of the agent coordinate space (or is negative).
Returns: an array containing the new x and y;
AGENTBLOCK(n, [sort])
Returns: a list of the scopes of all agents within a block of n units from the caller. If sort is true the list is sorted based on distance from the caller.
HEXAGENTBLOCK(n, [sort])
Returns: a list of the scopes of all agents within a block of n units from the caller on a hexagonal surface. If sort is true the list is sorted based on distance from the caller.
NEIGHBORS(n)
Returns: a sorted list (based on distance from the caller) of the scopes of all other agents within n units of the caller.
HEXNEIGHBORS(n)
Returns: a list of the scopes of all agents within n units of the caller on a hexagonal surface.
NEAREST_NEIGHBOR(n)
Returns: the scope of the nearest neighbor within n units of the caller.
MOVE(x, y, [z])
MOVETO(x, y, [z])
Sets the location of the caller to (x, y), or (x, y, z) in 3 dimensions. All moves occur at the end of the cycle.
MOVEPLUS(x, y, [z])
Sets the location of the caller to its current location plus (x, y), or (x, y, z) in 3 dimensions.
HEADTO(theta, [phi])
SET_HEADING(theta, [phi])
Sets the directional heading(s) of the caller to theta (and phi in 3 dimensions). Angles are given in radians.
HEADPLUS(theta, [phi])
Sets the directional heading(s) of the caller to its current direction(s) plus theta (and phi in 3 dimensions). Angles are given in radians.
GO(speed, theta, [,phi])
Move the location of the caller to its new location based the given speed using directional angle(s) theta (and phi in 3 dimensions). Angles are given in radians.
GO_BOUNCE(speed, theta)
Equivalent to GO(speed, theta) except that the agent bounces off the edge of the space like a billiard ball. Currently only available in 2 dimensions.
HEXMOVE(speed, theta)
Move the location of the caller to its new location based on the given speed and direction theta. Theta is one of N,NE,SE,S,SW,NW.

Convenience Primops

These primops perform useful functions that could otherwise be programmed.

COUNT_AGENTS(l, comp, value)
l is a list of agent scopes, comp is a string naming a component in those agents (stock, term, flow, etc.), and value is any JavaScript data element.
Returns: Returns the number of objects in l for which the current value of comp is value.
ALL_AGENTS(l, comp, value)
NO_AGENT(l, comp, value)
SOME_AGENT(l, comp, value)
l is a list of agent scopes, comp is a string naming a component in those agents, and value is any JavaScript data element.
Returns: Respectively returns true if for all, none or some scope in l the current value of comp is value; false otherwise.
ALL_NEIGHBORS(d, comp, value)
NO_NEIGHBOR(d, comp, value)
SOME_NEIGHBOR(d, comp, value)
Analogous to ALL_AGENTS, etc. except the agents of interest are those within a radius of d units from the agent making the call. Forms that list of agents and returns true if for all, none, or some agent scope in that list the current value of comp is value; false otherwise.
RANDOM_MOVE(loc, [wrap])
Returns: a location object (i.e., with fields x and y) representing a random move (wrapping if wrap is true) of one unit from the location object loc. If loc is omitted it defaults to the location of the caller.
HEX_RANDOM_MOVE(loc, [wrap])
Returns: a location object (i.e., with fields x and y) representing a random move (wrapping if wrap is true) of one unit from the location object loc on a hexagonal surface. If loc is omitted it defaults to the location of the caller.
INBOUNDS(x, y)
Returns: true if 0 ≤ x < columns and 0 ≤ y < rows, where [columns, rows] is the dimension of the agent landscape.

SimWorld Properties

cellmatrix
Bound to the CellMatrix component in a SimWorld
agentvector
Bound to the AgentVector component in a SimWorld

SimWorld Primops

Cell and agent capsules in a SimWorld may respectively use the Cell and Agent properties and primops described above. Also in a SimWorld, cell capsules may call some agent primops and agent capsules may call some cell primops, as detailed below.

Cell Primops in a SimWorld

Cell capsules may call the following agent primops:

AGENT
AGENTS AT
AGENT_COUNT
AGENT_IDS
AGENT_VALUE
AGENTS
CREATE
KILL

Cell capsules in a SimWorld may call the following new primops:

MYAGENTS()
Returns: the list of agents currently contained in the caller.
MYAGENT_COUNT()
Returns: the number of agents currently contained in the caller.

Agent Primops in a SimWorld

Agent capsules may call the following cell primops:

CELL
CELLS
CELL_VALUE

Agent capsules in a SimWorld may call the following new primop:

MYCELL()
Returns: the scope of the cell containing the caller.

Hexagonal Agent Primop

The following should only be used by an agent if the cell component of the SimWorld is in hexagonal mode.

HEXMOVE(dist, dir)
Moves the calling agent distance dist in the direction dir. Directions are denoted by compass directions; i.e., “N”, “NE”, “SE”, “S”, “SW”, “NW”.

Convenience Primops

These primops perform useful functions that could otherwise be programmed.

AGENTBLOCK(n, ["sort"])
AGENTWBLOCK(n, ["sort"])
AGENTRING(n, ["sort"])
AGENTWRING(n, ["sort"])
Returns: a list of scopes for all agents in the ring or block (wrapped or otherwise) specified by n. If “sort” is included, the list is sorted in order of increasing distance from the caller.

Node Properties and Primops

The following may only be used by capsules contained in a NodeNetwork. id is an integer representing node id of a node.

Properties

myId
Bound to the caller’s node id.
count
Bound to the number of nodes in the NodeNetwork.
nodes
Bound to the 1-dimensional array of Nodes in a NodeNetwork.

Primops

CONNECTION(id0, id1)
Returns: the connection from Node with id id0 to Node with id id1, or null if no such connection exists.
CONNECTIONS_IN([id])
Returns: the array of connections into the node id (if id is omitted, it is assumed to be the caller). Each connection is an object with 3 properties: id, the node id of the source; strength, the raw strength of the connection; and n_strength, the normalized strength of the connection, where the total normalized strength of all connections into the caller is 1.
CONNECTIONS_OUT([id])
Returns: the array of connections from the node id (if id is omitted, it is assumed to be the caller). Each connection is an object with 3 properties: id, the node id of the target; strength, the raw strength of the connection; and n_strength, the normalized strength of the connection, where the total normalized strength of all connections from the caller is 1.
NODE(id)
Returns: a scope for node id.
NODECOUNT()
Returns: the total number of nodes.
NODE_VALUE(id, comp)
comp is a String naming a Stock, Flow or Term in the node capsule.
Returns: the current value of that component in node id.
 NODE_VALUE(id, comp) == NODE(id)[comp]
NODES()
Returns: the array of node scopes.
INFLOW([id])
Returns: the total strength of connections into node id (if id is omitted, it is assumed to be the caller).
OUTFLOW([id])
Returns: the total strength of connections from node id (if id is omitted, it is assumed to be the caller).
NEIGHBORS_IN([id])
NEIGHBORS_OUT([id])
Returns: a list of all scopes of Nodes with input (output) connections to the Node with given id. If id is omitted, the caller's id is used.

NetWorld Primops

Cell and agent capsules in a NetWorld may respectively use the Node and Agent properties and primops described above. Also in a NetWorld, node capsules may call some agent primops and agent capsules may call some node primops, as detailed below.

Node Primops in a NodeWorld

Node capsules may call the following agent primops:

AGENT
AGENTS AT
AGENT_COUNT
AGENT_IDS
AGENT_VALUE
AGENTS
CREATE
KILL

Node capsules in a NetWorld may call the following new primops:

MYAGENTS()
Returns: the list of agents currently contained in the caller.
MYAGENT_COUNT()
Returns: the number of agents currently contained in the caller.

Agent Primops in a NetWorld

Agent capsules may call the following node primops:

NODE
NODES
NODE_VALUE

Agent capsules in a NetWorld may call the following new primops:

MYNODE()
Returns: the scope of the node containing the caller.
NETMOVE(nodeId)
Changes current location of caller to node indicated by nodeId. All moves occur at the end of the cycle.
NODE_NEIGHBORS(agentId)
Returns: a list of scopes corresponding to the the nodes to which the node currently occupied by agent agentId has outward links. If agentId is omitted, it is assumed to be the caller.