# Sequences

Using template notation can be a powerful way to describe your model

## What is a sequence?

A sequence is a group of vertices that is repeated multiple times in the network. The vertices in one group can (optionally) depend on vertices in the previous group. They typically represent a concept larger than a vertex like an agent in an ABM, a time series or some observations that are associated.

# Examples

Here are some examples that will walk you through the process of developing with Sequences.

## Writing time series

This example shows you how you can write a simple time series model using Sequences

``````DoubleVertex two = new ConstantDoubleVertex(2);

// Define the labels of vertices we will use in our Sequence
VertexLabel x1Label = new VertexLabel("x1");
VertexLabel x2Label = new VertexLabel("x2");

// Define labels for the Proxy Vertices which stand in for a Vertex from the previous SequenceItem.
// They will be automatically wired up when you construct the Sequence.
// i.e. these are the 'inputs' to our SequenceItem
VertexLabel x1InputLabel = SequenceBuilder.proxyFor(x1Label);
VertexLabel x2InputLabel = SequenceBuilder.proxyFor(x2Label);

// Define a factory method that creates proxy vertices using the proxy vertex labels and then uses these
// to define the computation graph of the Sequence.
// Note we have labeled the output vertices of this SequenceItem
Consumer<SequenceItem> factory = sequenceItem -> {
DoubleProxyVertex x1Input = new DoubleProxyVertex(x1InputLabel);
DoubleProxyVertex x2Input = new DoubleProxyVertex(x2InputLabel);

DoubleVertex x1Output = x1Input.multiply(two).setLabel(x1Label);
DoubleVertex x2Output = x2Input.plus(x1Output).setLabel(x2Label);

};

// Create the starting values of our sequence
DoubleVertex x1Start = new ConstantDoubleVertex(4).setLabel(x1Label);
DoubleVertex x2Start = new ConstantDoubleVertex(4).setLabel(x2Label);
VertexDictionary dictionary = SimpleVertexDictionary.of(x1Start, x2Start);

Sequence sequence = new SequenceBuilder<Integer>()
.withInitialState(dictionary)
.count(5)
.withFactory(factory)
.build();

``````

Note: by using the `.withFactories` method on the builder, rather than the `.withFactory`, it is possible to have factories which use proxy input vertices which are defined in other factories. i.e. your vertices can cross factories.

## Observing many associated data points

This example shows you how you can repeat logic over many observed data points which are associated by having a dependency on a common global value. Here they are the intercept and weights of a linear regression model.

Letâ€™s say you have a class `MyData` that looks like this:

``````public static class MyData {
public double x;
public double y;

public MyData(String x, String y) {
this.x = Double.parseDouble(x);
this.y = Double.parseDouble(y);
}
}
``````

This is an example of how you could pull in data from a csv file and run linear regression, using a sequence to build identical sections of the graph for each line of the csv.

``````
/**
* Each sequence item contains a linear regression model:
* VertexY = VertexX * VertexM + VertexB
*
* @param dataFileName The input data file defines, for each sequence item:
*                     - the value of the input, VertexX
*                     - the value of the observed output, VertexY
*/
public Sequence buildSequence(String dataFileName) {
//Parse the csv data to MyData objects
.asRowsDefinedBy(MyData.class)

DoubleVertex m = new GaussianVertex(0, 1);
DoubleVertex b = new GaussianVertex(0, 1);
VertexLabel xLabel = new VertexLabel("x");
VertexLabel yLabel = new VertexLabel("y");

//Build sequence from each line in the csv
Sequence sequence = new SequenceBuilder<MyData>()
.fromIterator(allMyData.iterator())
.withFactory((item, csvMyData) -> {

ConstantDoubleVertex x = new ConstantDoubleVertex(csvMyData.x).setLabel(xLabel);
DoubleVertex y = m.multiply(x).plus(b).setLabel(yLabel);

DoubleVertex yObserved = new GaussianVertex(y, 1);
yObserved.observe(csvMyData.y);

// this labels the x and y vertex for later use
})
.build();

//now you have access to the "x" from any one of the sequence
DoubleTensor valueForXAtCSVLine1 = sequence.asList()
.get(1) // get sequence item 1 which is built from csv line 1
.<DoubleVertex>get(xLabel) //get the vertex that we labelled "x" in that item
.getValue(); //get the value from that vertex

//Now run an inference algorithm on vertex m and vertex b and you have linear regression

return sequence;
}
``````