Difference between revisions of "Component Guide I: Atomic Components"
(94 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=Overview= | ==Overview== | ||
Numerus models are constructed out of ''components'', which are visual tokens that are placed on the [[Frames, Menus, Toolbars#designframe | Model Canvas. ]] | |||
To place a component on the model canvas: | To place a component on the model canvas: | ||
* | * Press the left mouse button on the desired component in the menu obtained from the [[Frames, Menus, Toolbars#designframe | component tab]]. | ||
* | * Drag the component from the component menu onto the model canvas. | ||
* When prompted, provide a component name (a default name will be provided if you choose not to provide one). | * When prompted, provide a component name (a default name will be provided if you choose not to provide one). | ||
Line 12: | Line 12: | ||
* Connections must be made to components with which this component will interact; and | * Connections must be made to components with which this component will interact; and | ||
* The new component must be programmed; in the simplest case, this involves providing a ''component | * The new component must be programmed; in the simplest case, this involves providing a ''component formula'' that defines the value represented by this component. Specific programming tasks for each component type will be described below. | ||
==Component Types== | ==Component Types== | ||
;Atomic Components:Tranditional systems dynamic components State (subdivided into Stock Stock+Flow, Sequence, Sequence+Flow, and Store), Flow, and Term; along with Command and | ;Atomic Components:Tranditional systems dynamic components State (subdivided into Stock Stock+Flow, Sequence, Sequence+Flow, and Store), Flow, and Term; along with Command, Event and Discrete State. | ||
;Containers:Nova containers consist of Chips and 5 types of aggregators; a Chip holds a single instance of capsule used as a submodel while aggregators hold multiple | ;Containers:Nova containers consist of Chips and 5 types of aggregators; a Chip holds a single instance of [[Modeling_ in_Numerus#capsule|Capsule]], used as a submodel while aggregators hold multiple Capsule instances, possibly of different types. Each aggregator type implements a different topology for its elements. The aggregator components are AgentVector, CellMatrix, NodeNetwork, SimWorld and NetWorld. | ||
;Controls and Displays:These include Table, Linechart, Scatterchart, Barchart, Histogram, Slider, Spinner and Toggle. | ;Controls and Displays:These include Table, Linechart, Scatterchart, Barchart, Histogram, Slider, Spinner and Toggle. | ||
;Special:These are special purpose components consisting of Code Chip and Comment. | ;Special:These are special purpose components consisting of Code Chip and Comment. | ||
Line 22: | Line 22: | ||
==Component Properties== | ==Component Properties== | ||
Each component has an associated | Each component has an associated Properties Pane (PropPane) that provides the means for programming the component (and in some cases specifying connections.) The PropPane is opened by selecting the component. PropPanes allow you to define the value represented by a component, set pin connections, determine what is displayed (in the case of Graphs and Tables), calibrate (in the case of Sliders and Spinners) and set any other property required by the component. Specific properties are part of the component descriptions below. | ||
==Component Formulas== | |||
Most components require a formula or program to specify their values. This formula is a NovaScript expression or sequence of expressions entered into a text area on the PropPane. Component value formulas can make use of the underlying Javascript language to build somewhat complex algorithms for computing the value <ref>Discussion of Javascript is beyond the scope of this document; see [[Javascript References]] for more information about programming in Javascript.</ref>, however long and complex computations are becodeer relegated to code chips or global method definitions. | |||
===Simple Formulas=== | |||
In the simplest case this will be a constant number or string, or an arithmetic formula. Formulas may reference other value-producing components such as States or Terms, and may also reference any of the global elements known as [[Primitives]].<ref>A list of primitive operators and constants appears under the '''Primitives''' tab.</ref> | |||
;Examples | |||
<blockquote> | |||
{| class="wikitable" | |||
|- | |||
!Formula !! Notes | |||
|- | |||
|<code>27</code> | |||
|- | |||
|<code>x + 2</code> | |||
|- | |||
|<code>2 * PI</code>||<code>PI</code> is a primitive constant. | |||
|- | |||
|<code>COS(2*PI*x)</code>||<code>COS</code> is a primitive operator | |||
|} | |||
</blockquote> | |||
<big>''Important: the caret (^) operator is not supported in Javascript for exponentiation. Instead, use Math.pow; e.g.'' <code>2^3</code> ''becomes'' <code>Math.pow(2, 3)</code>.</big> | |||
===Programmatic Formulas=== | |||
You may wish to compute the component value over several steps involving conditionals and/or loops. NovaScript permits this according to the following schematic: | |||
:<code> statement; statement; .... statement; value</code> | |||
In other words, you may include a sequence of statements, separated by semi-colons, which include local variable declarations and any legal Javascript statement. Numerus will interpret the last entry in that sequence as the value. | |||
;Example | |||
<blockquote> | |||
<pre> | |||
var x = 0; | |||
for (var i = 1; i <= 100; i++) x = x + i; | |||
x | |||
</pre> | |||
This formula will produce <code>5050</code> | |||
</blockquote> | |||
==Atomic Components== | |||
<div id="State"> | |||
===State=== | |||
The State component comes in 5 versions. | |||
{| class="wikitable" | |||
|- | |||
! Symbol || Component !! Description | |||
|- | |||
|<center>[[File:stock.png|link=]]</center>|| Stock || A '''Stock''' represents a value that is changing over time. Changes to the stock are specified using one or more Flows, which are connected to it. Flows are either inflows or outflows, which respectively represent values being added to or subtracted from the current stock value. The value of a Stock at the end of each time step is equal to the value at the previous time step, plus the total inflow (i.e. the total flow value flowing into the stock) minus the total outflow (i.e., the total flow value flowing out of the stock). Stock values must be numerical. | |||
|- | |||
|[[File:stocknflow.png|link=]]|| Stock+Flow || A stock with a single inflow, for convenience. May be preferred when modeling differential equations. | |||
|- | |||
|<center>[[File:sequence.png|link=]]</center>|| Sequence || A '''Sequence''' is a type of Stock in which the total flow value replaces rather than adds to the current stock value. A sequence value may be any legal NovaScript data type. | |||
|- | |||
|[[File:sequencenflow.png|link=]]|| Sequence+Flow || A sequence with a single inflow, which is generally all that is required. | |||
|- | |||
|<center>[[File:store.png|link=]]</center>|| Store || A '''Store''' is a type of Stock without flows. It is used to hold values that may not require updating at each timestep of the simulation. Stores are used by Commands and Code Chips to store values across simulation timesteps. A Store may be any legal NovaScript data type. Previous versions of Numerus (i.e. Nova 2) called these '''Local Variables'''. | |||
|} | |||
;Properties | |||
*'''Initial Value'''. The initial value is expressed as a component formula. | |||
*'''Non-Negative'''. Check this box if the State must be non-negative. Negative values are mapped to 0. This option is not available for Stores. | |||
*'''Full History'''. Specifies how long values are retained by this Stock. If selected, values are maintained for the entire length of the simulation; otherwise they are only kept for the previous 100 time units. Check this box only if your simulation requires a longer or complete history of the Stock's value. | |||
*'''Dimension'''. Used with [[Array-Based Modeling]]. | |||
*'''Unit'''. Optional specification of a unit for this State value. | |||
;Examples | |||
<gallery> | |||
File:simplepop_ex.png|frame|Stock | |||
File:stocknflow_ex.png|frame|Stock+Flow | |||
File:sequence_ex.png|frame|Sequence | |||
File:seqnflow_ex.png|frame|Sequence+Flow | |||
File:store_ex.png|frame|Store | |||
</gallery> | |||
</div> | |||
<div id="Flow"> | |||
===Flow=== | |||
[[File: flow.png|left]] A '''Flow''' can be imagined as a pipe that moves content into or out of a Stock. Flows are always connected to Stocks. The Flow's value reprensents the quantity moved by the Flow at each timestep. Positive Flow values move from left to right, or from the black or "negative" end to the red or "positive" end of the connectors. A biflow Flow will flow in the opposite direction when when its value is negative. Flows can be connected at both ends, in which case the Stock at the negative end is decremented and the Stock at the positive end is incremented by the same amount (or vice verse for a biflow Flow with a negative value). Alternatively, a Flow may only be connected at one end (either as an inflow or outflow) in which case the "cloud" symbol represents the unmodeled source or sink of the content. Flow values must be numerical when used with Stocks, but may be any NovaScript data type when used with a Sequence. | |||
;Properties | |||
*'''Value'''. The amount moved in our out of the connected Stock. The value is a component formula. | |||
*'''Biflow/Uniflow'''. A Uniflow Flow will only support non-negative values (i.e., a negative value acts as a zero). Content only moves in one direction. | |||
*'''Flow In From / Flow Out To'''. These list boxes show the current connections to this Flow. They can be used to disconnect the Flow from one or both sides. | |||
*'''Unit'''. See [[#State|State]]. | |||
;Examples | |||
<gallery widths=200px> | |||
File:flow2stocks.png|Frame|Biflow between 2 Stocks | |||
File:uniflow1stock.png|Frame|Uniflow into a single Stock | |||
</gallery> | |||
</div> | |||
<div id="Term"> | |||
===Term=== | |||
The Term component has 6 variations | |||
{| class="wikitable" | |||
|- | |||
! Symbol || Component !! Description | |||
|- | |||
| <center>[[File:term.png|link=]]</center> || Term || A Term computes a value based on the current state of the simulation. The value is specified as a [[#component_formula|component formula]]. | |||
|- | |||
| || Graph Term || A Graph Term is a function specified using a graph. See [[Graph Term]] for details. | |||
|- | |||
| || External Term || An External Term is obtained from data read into the runtime simulation. See [[Including External Data]]. | |||
|- | |||
| <center>[[File:const.png|link=]]</center> || Constant || A Term designated as a constant will evaluate its formula only once (the first time the value is required) and continue to use the resulting value for the remainder of the simulation. | |||
|- | |||
| <center>[[File:inpin.png|link=]]</center> || Inpin || A Term used as an input pin to a submodel See [[Chips]]. | |||
|- | |||
| <center>[[File:outpin.png|link=]]</center> || Outpin || A Term used as an output pin to a submodel See [[Chips]]. | |||
|- | |||
| <center>[[File:spy.png|link=]]</center> || Spy || An ordinary term whose value will be displayed on the runtime canvas. | |||
|} | |||
;Properties | |||
*'''Value'''. The value represented by this Term, expressed as a [[#Component_Formulas|Component Formula]]. Not used by Graph Terms. | |||
*'''Unit'''. See [[#State|State]]. | |||
;Examples | |||
<gallery widths=300px> | |||
File:constant_ex.png|frame|Constants to hold coordinates and neighbor list in Game of Life simulation. | |||
File:spy_ex.png|frame|Spy used to display live count in Game of Life simulation. | |||
</gallery> | |||
</div> | |||
===Command=== | |||
[[File:command.png]] A command contains code that is executed once per timestep (init and final commands are the exception; see below). Commands do not return values; rather they operate by side-effecting simulation state, often through the execution of some primitive operator. One common use for a Command is during program development, where the PRINT primop is used to print useful values to the console. Another important role is in the agent life cycle, where Commands may contain code used to create or terminate agents, or move them in their environment. | |||
If the Command name starts with '''init''' then the command is an initializer and is only run once during simulation startup. Similarly, a Command with a name that starts with '''final''' will only execute at the end of the run. | |||
<br clear=all> | |||
;Properties | |||
* '''Value'''. The [[#Component_Formulas|Component Formula]] code executed by this command. | |||
* '''PreUpdate / PostUpdate'''. Determines if the Command runs in the timestep before or after Stocks, Sequences, etc. have been updated to their new values. | |||
;Example | |||
[[File:command_ex.png|left|frame|"born" and "die" commands in the Agent Motion simulation]] | |||
<br clear="all"> | |||
===Event=== | |||
[[File:event.png]] An Event is a special type of Command that "fires" when a specified condition is met. When the event fires, action code specifies the action that is undertaken. Each event contains 2 useful fields. In the example shown, <code>x_less_than_0.occured</code> returns true or false depending on whether the event has fired. <code>x_less_than_0.howMany</code> returns the number of times the event has fired. These fields may be referred to by other component formulas. | |||
;Properties | |||
*'''Condition'''. A [[#Component_Formulas|Component Formula]] evaluating to a truth value. This value must be true in order for the event to fire. | |||
*'''Action'''. A [[#Component_Formulas|Component Formula]] specifying the action to take when the event fires. | |||
*'''PreUpdate / PostUpdate'''. Determines if the Command runs in the timestep before are after Stocks, Sequences, etc. have been updated to their new values. | |||
*'''Repeated'''. If selected the event will fire each time the condition is true; otherwise it only fires at most once. | |||
===<span id="DiscreteState"></span>Discrete State=== | |||
[[File: discretestate.png|left]] | |||
A Discrete State is an alternative to a Sequence in which a fixed number of named discrete states serve as possible values. The possible values for a Discrete State are drawn from some [[NovaScript Introduction#dsv|Discrete Value Set]]. A Discrete State is initialized with one such value, and transitions are structured as rules based on the current value. | |||
<br clear="all"> | |||
{| | |||
| | |||
;Properties | |||
*'''Discrete Value Set'''. Each Discrete State assumes values from a Discrete Value Set (DVS). The '''Open DV Set List''' button can be used to view and select from the currently defined DVS's (or to extend with a newly defined DVS). Once a DVS is selected its constituents are listed in the subsequent window. | |||
*'''Next'''. A tab is provided for each state to indicate the transition from that state to another of the DVS elements. Code implementing the transition from that state is entered into each tab. The rules for this code are identical to the rules specifying the value of a [[Component_Guide_I:_Atomic_Components#Component_Formulas|Component Formula]]. The result produced by the code must be another state in the DVS. | |||
*'''Init'''. Code entered here determines the initial value of the Discrete State. This code must also evaluate to some legal DVS state. | |||
|[[File:discretestateprop.png|250px]] | |||
|} | |||
==Notes== | |||
<references/> |
Latest revision as of 17:05, 14 October 2019
Overview
Numerus models are constructed out of components, which are visual tokens that are placed on the Model Canvas.
To place a component on the model canvas:
- Press the left mouse button on the desired component in the menu obtained from the component tab.
- Drag the component from the component menu onto the model canvas.
- When prompted, provide a component name (a default name will be provided if you choose not to provide one).
A new component requires two actions to integrate it into the model:
- Connections must be made to components with which this component will interact; and
- The new component must be programmed; in the simplest case, this involves providing a component formula that defines the value represented by this component. Specific programming tasks for each component type will be described below.
Component Types
- Atomic Components
- Tranditional systems dynamic components State (subdivided into Stock Stock+Flow, Sequence, Sequence+Flow, and Store), Flow, and Term; along with Command, Event and Discrete State.
- Containers
- Nova containers consist of Chips and 5 types of aggregators; a Chip holds a single instance of Capsule, used as a submodel while aggregators hold multiple Capsule instances, possibly of different types. Each aggregator type implements a different topology for its elements. The aggregator components are AgentVector, CellMatrix, NodeNetwork, SimWorld and NetWorld.
- Controls and Displays
- These include Table, Linechart, Scatterchart, Barchart, Histogram, Slider, Spinner and Toggle.
- Special
- These are special purpose components consisting of Code Chip and Comment.
- Plugins
- These are extensions to the component set and have various functions.
Component Properties
Each component has an associated Properties Pane (PropPane) that provides the means for programming the component (and in some cases specifying connections.) The PropPane is opened by selecting the component. PropPanes allow you to define the value represented by a component, set pin connections, determine what is displayed (in the case of Graphs and Tables), calibrate (in the case of Sliders and Spinners) and set any other property required by the component. Specific properties are part of the component descriptions below.
Component Formulas
Most components require a formula or program to specify their values. This formula is a NovaScript expression or sequence of expressions entered into a text area on the PropPane. Component value formulas can make use of the underlying Javascript language to build somewhat complex algorithms for computing the value [1], however long and complex computations are becodeer relegated to code chips or global method definitions.
Simple Formulas
In the simplest case this will be a constant number or string, or an arithmetic formula. Formulas may reference other value-producing components such as States or Terms, and may also reference any of the global elements known as Primitives.[2]
- Examples
Formula Notes 27
x + 2
2 * PI
PI
is a primitive constant.COS(2*PI*x)
COS
is a primitive operator
Important: the caret (^) operator is not supported in Javascript for exponentiation. Instead, use Math.pow; e.g. 2^3
becomes Math.pow(2, 3)
.
Programmatic Formulas
You may wish to compute the component value over several steps involving conditionals and/or loops. NovaScript permits this according to the following schematic:
statement; statement; .... statement; value
In other words, you may include a sequence of statements, separated by semi-colons, which include local variable declarations and any legal Javascript statement. Numerus will interpret the last entry in that sequence as the value.
- Example
var x = 0; for (var i = 1; i <= 100; i++) x = x + i; xThis formula will produce
5050
Atomic Components
State
The State component comes in 5 versions.
Symbol | Component | Description |
---|---|---|
Stock | A Stock represents a value that is changing over time. Changes to the stock are specified using one or more Flows, which are connected to it. Flows are either inflows or outflows, which respectively represent values being added to or subtracted from the current stock value. The value of a Stock at the end of each time step is equal to the value at the previous time step, plus the total inflow (i.e. the total flow value flowing into the stock) minus the total outflow (i.e., the total flow value flowing out of the stock). Stock values must be numerical. | |
Stock+Flow | A stock with a single inflow, for convenience. May be preferred when modeling differential equations. | |
Sequence | A Sequence is a type of Stock in which the total flow value replaces rather than adds to the current stock value. A sequence value may be any legal NovaScript data type. | |
Sequence+Flow | A sequence with a single inflow, which is generally all that is required. | |
Store | A Store is a type of Stock without flows. It is used to hold values that may not require updating at each timestep of the simulation. Stores are used by Commands and Code Chips to store values across simulation timesteps. A Store may be any legal NovaScript data type. Previous versions of Numerus (i.e. Nova 2) called these Local Variables. |
- Properties
- Initial Value. The initial value is expressed as a component formula.
- Non-Negative. Check this box if the State must be non-negative. Negative values are mapped to 0. This option is not available for Stores.
- Full History. Specifies how long values are retained by this Stock. If selected, values are maintained for the entire length of the simulation; otherwise they are only kept for the previous 100 time units. Check this box only if your simulation requires a longer or complete history of the Stock's value.
- Dimension. Used with Array-Based Modeling.
- Unit. Optional specification of a unit for this State value.
- Examples
Flow
A Flow can be imagined as a pipe that moves content into or out of a Stock. Flows are always connected to Stocks. The Flow's value reprensents the quantity moved by the Flow at each timestep. Positive Flow values move from left to right, or from the black or "negative" end to the red or "positive" end of the connectors. A biflow Flow will flow in the opposite direction when when its value is negative. Flows can be connected at both ends, in which case the Stock at the negative end is decremented and the Stock at the positive end is incremented by the same amount (or vice verse for a biflow Flow with a negative value). Alternatively, a Flow may only be connected at one end (either as an inflow or outflow) in which case the "cloud" symbol represents the unmodeled source or sink of the content. Flow values must be numerical when used with Stocks, but may be any NovaScript data type when used with a Sequence.- Properties
- Value. The amount moved in our out of the connected Stock. The value is a component formula.
- Biflow/Uniflow. A Uniflow Flow will only support non-negative values (i.e., a negative value acts as a zero). Content only moves in one direction.
- Flow In From / Flow Out To. These list boxes show the current connections to this Flow. They can be used to disconnect the Flow from one or both sides.
- Unit. See State.
- Examples
Term
The Term component has 6 variations
Symbol | Component | Description |
---|---|---|
Term | A Term computes a value based on the current state of the simulation. The value is specified as a component formula. | |
Graph Term | A Graph Term is a function specified using a graph. See Graph Term for details. | |
External Term | An External Term is obtained from data read into the runtime simulation. See Including External Data. | |
Constant | A Term designated as a constant will evaluate its formula only once (the first time the value is required) and continue to use the resulting value for the remainder of the simulation. | |
Inpin | A Term used as an input pin to a submodel See Chips. | |
Outpin | A Term used as an output pin to a submodel See Chips. | |
Spy | An ordinary term whose value will be displayed on the runtime canvas. |
- Properties
- Value. The value represented by this Term, expressed as a Component Formula. Not used by Graph Terms.
- Unit. See State.
- Examples
Command
A command contains code that is executed once per timestep (init and final commands are the exception; see below). Commands do not return values; rather they operate by side-effecting simulation state, often through the execution of some primitive operator. One common use for a Command is during program development, where the PRINT primop is used to print useful values to the console. Another important role is in the agent life cycle, where Commands may contain code used to create or terminate agents, or move them in their environment.
If the Command name starts with init then the command is an initializer and is only run once during simulation startup. Similarly, a Command with a name that starts with final will only execute at the end of the run.
- Properties
- Value. The Component Formula code executed by this command.
- PreUpdate / PostUpdate. Determines if the Command runs in the timestep before or after Stocks, Sequences, etc. have been updated to their new values.
- Example
Event
An Event is a special type of Command that "fires" when a specified condition is met. When the event fires, action code specifies the action that is undertaken. Each event contains 2 useful fields. In the example shown, x_less_than_0.occured
returns true or false depending on whether the event has fired. x_less_than_0.howMany
returns the number of times the event has fired. These fields may be referred to by other component formulas.
- Properties
- Condition. A Component Formula evaluating to a truth value. This value must be true in order for the event to fire.
- Action. A Component Formula specifying the action to take when the event fires.
- PreUpdate / PostUpdate. Determines if the Command runs in the timestep before are after Stocks, Sequences, etc. have been updated to their new values.
- Repeated. If selected the event will fire each time the condition is true; otherwise it only fires at most once.
Discrete State
A Discrete State is an alternative to a Sequence in which a fixed number of named discrete states serve as possible values. The possible values for a Discrete State are drawn from some Discrete Value Set. A Discrete State is initialized with one such value, and transitions are structured as rules based on the current value.
|
Notes
- ↑ Discussion of Javascript is beyond the scope of this document; see Javascript References for more information about programming in Javascript.
- ↑ A list of primitive operators and constants appears under the Primitives tab.