\chapter{Structured data types}
\label{chap:structypes}

Hansl possesses two kinds of ``structured data type'': associative
arrays, called \emph{bundles} and arrays in the proper sense of the
word. Loosely speaking, the main difference between the two is that in
a bundle you can pack together variables of different types, while
arrays can hold one type of variable only.

\section{Bundles}
\label{sec:bundles}

Bundles are \emph{associative arrays}, that is, generic containers for
any assortment of hansl types (including other bundles) in which each
element is identified by a string. Python users call these
\emph{dictionaries}; in C++ and Java, they are referred to as
\emph{maps}; they are known as \emph{hashes} in Perl. We call them
\emph{bundles}. Each item placed in the bundle is associated with a
key which can used to retrieve it subsequently.

To use a bundle you first either ``declare'' it, as in
%
\begin{code}
bundle foo
\end{code}
%
or define an empty bundle using the \texttt{null} keyword:
%
\begin{code}
bundle foo = null
\end{code}
%
These two formulations are basically equivalent, in that they both
create an empty bundle. The difference is that the second variant may
be reused---if a bundle named \texttt{foo} already exists the effect
is to empty it---while the first may only be used once in a given
gretl session; it is an error to declare a variable that already
exists.

To add an object to a bundle you assign to a compound left-hand value:
the name of the bundle followed by the key. The most common way to do
this is to join the key to the bundle name with a dot, as in
\begin{code}
  foo.matrix1 = m
\end{code}
which adds an object called \texttt{m} (presumably a matrix) to bundle
\texttt{foo} under the key \texttt{matrix1}. The key must satisfy the
rules for a gretl variable name (31 characters maximum, starting
with a letter and composed of just letters, numbers or underscore)

An alternative way to achieve the same effect is to give the key as a
quoted string literal enclosed in square brackets, as in
\begin{code}
  foo["matrix1"] = m
\end{code}
When using the more elaborate syntax, keys do not have to be valid as
variable names---for example, they can include spaces---but they are
still limited to 31 characters.

To get an item out of a bundle, again use the name of the bundle
followed by the key, as in

\begin{code}
matrix bm = foo.matrix1
# or using the long-hand notation
matrix m = foo["matrix1"]
\end{code}

Note that the key identifying an object within a given bundle is
necessarily unique. If you reuse an existing key in a new assignment,
the effect is to replace the object which was previously stored under
the given key. It is not required that the type of the replacement
object is the same as that of the original.

A quicker way, introduced in gretl 2017b, is to use the
\cmd{defbundle} function, as in
\begin{code}
  bundle b = defbundle("s", "Sample string", "m", I(3))
\end{code}
in which every odd-numbered argument must evaluate to a string (key)
and every even-numbered argument must evaluate to an object of a type
that can be included in a bundle.

Note that when you add an object to a bundle, what in fact happens is
that the bundle acquires a copy of the object. The external object
retains its own identity and is unaffected if the bundled object is
replaced by another. Consider the following script fragment:

\begin{code}
bundle foo
matrix m = I(3)
foo.mykey = m
scalar x = 20
foo.mykey = x
\end{code}

After the above commands are completed bundle \texttt{foo} does not
contain a matrix under \texttt{mykey}, but the original matrix
\texttt{m} is still in good health.

To delete an object from a bundle use the \texttt{delete} command,
with the bundle/key combination, as in

\begin{code}
delete foo.mykey
delete foo["quoted key"]
\end{code}

This destroys the object associated with the key and removes the key
from the hash table.\footnote{Internally, gretl bundles in fact take
  the form of \textsf{GLib} hash table.}

Besides adding, accessing, replacing and deleting individual items,
the other operations that are supported for bundles are union and
printing. As regards union, if bundles \texttt{b1} and \texttt{b2} are
defined you can say

\begin{code}
bundle b3 = b1 + b2
\end{code}

to create a new bundle that is the union of the two others. The
algorithm is: create a new bundle that is a copy of \texttt{b1}, then
add any items from \texttt{b2} whose keys are not already present in
the new bundle. (This means that bundle union is not necessarily
commutative if the bundles have one or more key strings in common.)

If \texttt{b} is a bundle and you say \texttt{print b}, you get a
listing of the bundle's keys along with the types of the corresponding
objects, as in

\begin{code}
? print b
bundle b:
 x (scalar)
 mat (matrix)
 inside (bundle)
\end{code}

\subsection{Bundle usage}
\label{sec:bundle-usage}

To illustrate the way a bundle can hold information, we will use the
Ordinary Least Squares (OLS) model as an example: the following code
estimates an OLS regression and stores all the results in a bundle.

\begin{code}
/* assume y and X are given T x 1 and T x k matrices */

bundle my_model = null               # initialization
my_model.T = rows(X)                 # sample size
my_model.k = cols(X)                 # number of regressors
matrix e                             # will hold the residuals
b = mols(y, X, &e)                   # perform OLS via native function
s2 = meanc(e.^2)                     # compute variance estimator
matrix V = s2 .* invpd(X'X)          # compute covariance matrix

/* now store estimated quantities into the bundle */

my_model.betahat = b
my_model.s2 = s2
my_model.vcv = V
my_model.stderr = sqrt(diag(V))
\end{code}

The bundle so obtained is a container that can be used for all sort of
purposes. For example, the next code snippet illustrates how to use
a bundle with the same structure as the one created above to perform
an out-of sample forecast. Imagine that $k=4$ and the value of
$\mathbf{x}$ for which we want to forecast $y$ is
\[
  \mathbf{x}' = [ 10 \quad 1  \quad -3 \quad 0.5 ]
\]
The formulae for the forecast would then be
\begin{eqnarray*}
  \hat{y}_f & = & \mathbf{x}'\hat{\beta} \\
  s_f & = & \sqrt{\hat{\sigma}^2 + \mathbf{x}'V(\hat{\beta})\mathbf{x}} \\
  CI & = & \hat{y}_f \pm 1.96 s_f 
\end{eqnarray*}
where $CI$ is the (approximate) 95 percent confidence interval. The
above formulae translate into
\begin{code}
  x = { 10, 1, -3, 0.5 }
  scalar ypred    = x * my_model.betahat
  scalar varpred  = my_model.s2 + qform(x, my_model.vcv)
  scalar sepred   = sqrt(varpred)
  matrix CI_95    = ypred + {-1, 1} .* (1.96*sepred)
  print ypred CI_95
\end{code}

\section{Arrays}
\label{sec:arrays}

A gretl array is a container which can hold zero or more objects of a
certain type, indexed by consecutive integers starting at 1. It is
one-dimensional. This type is implemented by a quite ``generic''
back-end. The types of object that can be put into arrays are strings,
matrices, bundles and lists; a given array can hold only one of these
types.

\subsection{Array operations}

The following is, we believe, rather self-explanatory:

\begin{code}
strings S1 = array(3)
matrices M = array(4)
strings S2 = defarray("fish", "chips")
S1[1] = ":)"
S1[3] = ":("
M[2] = mnormal(2,2)
print S1
eval inv(M[2])
S = S1 + S2
print S
\end{code}

The \texttt{array()} takes an integer argument for the array size; the
\texttt{defarray()} function takes a variable number of arguments (one
or more), each of which may be the name of a variable of the given
type or an expression which evaluates to an object of that type.  The
corresponding output is

\begin{code}
Array of strings, length 3
[1] ":)"
[2] null
[3] ":("

     0.52696      0.28883 
    -0.15332     -0.68140 

Array of strings, length 5
[1] ":)"
[2] null
[3] ":("
[4] "fish"
[5] "chips"
\end{code}

In order to find the number of elements in an array, you can use the
\texttt{nelem()} function.

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "hansl-primer"
%%% End: 

