# AlphaZ

### Site Tools

tutorial_subsystem

This is an old revision of the document!

# SubSystem in Alpha

In this tutorial, we will present how to write structured alpha programs with subsystems, and we will present the associated transformations.

### Syntax of Use Equation (without extension domain)

Let us assume that we want to compute the mean of the values of a vector. It is feasible through the following Alpha system:

affine mean {N | N>0}
input
float A {k | 0<=k<N};
output
float C {|};
local
float temp {|};
let
temp = reduce(+, [k], A[k]);
C = temp / N;
.


However, let us assume that you already have another Alpha system which computes the sum of the elements of a vector. It is possible to use this affine system (instead of rewriting its equation in the main system), by calling it through a “use equation”:

affine sum {P| P>0}	// Computes the sum of the elements of a vector of size P
input
float vect {i | 0<=i<P };
output
float Res;
let
Res = reduce(+, [k], vect[k]);
.

affine mean {N | N>0}
input
float A {k | 0<=k<N};
output
float C {|};
local
float temp {|};
let
use sum[N] (A) returns (temp);		// Compute "temp" using the system "sum"
C = temp / N;
.


The system “mean” is calling the system “sum” (which is called a subsystem). The subsystem is called with the parameter “N” and the input “A”. After doing its computation, the result of “sum” will be stored inside the local variable “temp”.

In general, the syntax of a use equation is the following:

use subsystem_name[list of parameters] (list of input expressions) returns (list of output variables);


If your subsystem have several parameters/inputs/outputs, you have to provide them in the order in which they are declared.

### Extension domain

Let us assume that you have a system which computes a dot product between two vectors:

affine dotProduct {N | N>0}
input
float v1 {k | 0<=k<N};
float v2 {k | 0<=k<N};
output
float Res {|};
let
Res = reduce(+, [k], v1[k]*v2[k]);
.


If you want to compute a matrix vector multiplication using this affine system, you will need to call it once per rows of the matrix. Thus, you will need a parametrised number of call to the “dotProduct” system.

It is possible to do it by using an extension domain:

affine dotProduct {N | N>0}
input
float v1 {k | 0<=k<N};
float v2 {k | 0<=k<N};
output
float Res {|};
let
Res = reduce(+, [k], v1[k]*v2[k]);
.

affine matrixVectorProduct {R,S | (R,S)>0}
input
float mat {i,j | 0<=i<R && 0<=j<S };
float vect {j | 0<=j<S};
output
float vectRes {i | 0<=i<R};
let
use {k | 0<=k<R} dotProduct[R] ( (k,j->k,j)@mat, (k,j->j)@vect) returns (vectRes);
.


The set “{k | 0⇐k<R}” before the subsystem name is called an extension domain. We are calling the system “dotProduct” once, for each instance of “k” in the extension domain. We can use the indexes of the extension domain to parametrize the parameters, inputs given to the subsystem and the outputs computed by the subsystem:

1. the indexes can be used to specify the parameters (ex: “R+k”)
2. the first dimensions of the input expressions correspond to the dimensions of the extension domain. For a given subsystem call kInst, the corresponding input sent is the one where the first dimensions are set to “kInst” (ex: in the previous example, the third call to “dotProduct” will obtain “(j→3,j)@mat” and “(j→j)@vect” as inputs).
3. the first dimensions of the output variables correspond to the dimensions of the extension domain. All the results from every subsystem call are gathered inside common variables (ex: “vectRes” is a vector whose corresponding data are produced by different instances of “dotProduct”)

Apart from the compatibility of dimensions, the input expressions must be defined at least on the points asked by the subsystem, and the output variable must be defined on a subset of the domain of the subsystem output.

### Transformations involving subsystems

(incoming, after the previous incoming)