% ===> this file was generated automatically by noweave --- better not edit it
\section{Introduction}

The {\Tt{}matrix-lua\nwendquote} module adds simple matrix support to Lua.
Supported functions are
\begin{itemize}
  \item {\Tt{}matrix(m,n)\nwendquote}: create a new zero matrix of size $m$ by $n$
  \item {\Tt{}A(i,j)\nwendquote}:      get $A_{ij}$
  \item {\Tt{}A[k]\nwendquote}:        get or set the $k$th element (column-major 1-based)
  \item {\Tt{}C\ =\ A+B\nwendquote}:     add two matrices
  \item {\Tt{}C\ =\ A-B\nwendquote}:     subtract two matrices
  \item {\Tt{}C\ =\ -A\nwendquote}:      take the unary negation of a matrix
  \item {\Tt{}C\ =\ A*B\nwendquote}:     multiply two matrices
  \item {\Tt{}A.print()\nwendquote}:   print matrix
  \item {\Tt{}A.factor()\nwendquote}:  factor matrix
  \item {\Tt{}A.solve(x)\nwendquote}:  compute $x := A^{-1}x$
  \item {\Tt{}A.clone()\nwendquote}:   create a copy of the matrix
  \item {\Tt{}A.slice(i1,i2,j1,j2)\nwendquote}:   create a slice of the matrix
  \item {\Tt{}A.free()\nwendquote}:    free matrix
\end{itemize}
Supported variables are
\begin{itemize}
  \item {\Tt{}A.m\nwendquote}:  return number of rows in matrix
  \item {\Tt{}A.n\nwendquote}:  return number of columns in matrix
\end{itemize}

\section{Interface}

\nwfilename{matrix-lua.nw}\nwbegincode{1}\sublabel{NW49APAR-2XOU18-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-2XOU18-1}}}\moddef{matrix-lua.h~{\nwtagstyle{}\subpageref{NW49APAR-2XOU18-1}}}\endmoddef\nwstartdeflinemarkup\nwenddeflinemarkup
#ifndef MATRIX_LUA_H
#define MATRIX_LUA_H

#include <lua.h>

struct lua_matrix_struct \{
    int owns_data;  /* True if this matrix owns storage  */
    int m, n, ld;   /* Array size and leading dimension  */
    double* data;   /* Array data                        */
    int* ipiv;      /* Pivot array for factored matrices */
\};

typedef struct lua_matrix_struct* lua_matrix_t;

void         lua_matrix_register(lua_State* L);
void         lua_matrix_push(lua_State* L, lua_matrix_t A);
lua_matrix_t lua_matrix_get(lua_State* L, int index);

lua_matrix_t lua_matrix_create(int m, int n);
lua_matrix_t lua_matrix_slice(lua_matrix_t A, int i1, int i2, int j1, int j2);
void         lua_matrix_destroy(lua_matrix_t self);

#endif /* MATRIX_LUA_H */
\nwnotused{matrix-lua.h}\nwendcode{}\nwbegindocs{2}\nwdocspar

The {\Tt{}lua{\_}matrix{\_}register\nwendquote} function registers the functions of
the module with the Lua interpreter.  The {\Tt{}lua{\_}matrix{\_}push\nwendquote}
and {\Tt{}lua{\_}matrix{\_}get\nwendquote} functions add and get matrices
on the Lua stack.

The {\Tt{}lua{\_}matrix{\_}create\nwendquote} and {\Tt{}lua{\_}matrix{\_}destroy\nwendquote} functions create
new matrices.  The {\Tt{}lua{\_}matrix{\_}slice\nwendquote} function creates a ``parasite''
matrix that uses the same storage as the original matrix but which
has different indexing.  In Matlab parlance, the slice function returns
{\Tt{}A(i1:i2,\ j1:j2)\nwendquote}.

\section{Implementation}

\nwenddocs{}\nwbegincode{3}\sublabel{NW49APAR-VVNpW-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-VVNpW-1}}}\moddef{matrix-lua.c~{\nwtagstyle{}\subpageref{NW49APAR-VVNpW-1}}}\endmoddef\nwstartdeflinemarkup\nwenddeflinemarkup
#include <sugar.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <matrix_lua.h>

\LA{}macros~{\nwtagstyle{}\subpageref{NW49APAR-1VvxMr-1}}\RA{}
\LA{}static prototypes~{\nwtagstyle{}\subpageref{NW49APAR-4QyxLE-1}}\RA{}
\LA{}static data~{\nwtagstyle{}\subpageref{NW49APAR-IAwJm-1}}\RA{}
\LA{}static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}\RA{}
\LA{}functions~{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}\RA{}
\nwnotused{matrix-lua.c}\nwendcode{}\nwbegindocs{4}\nwdocspar

\subsection{Matrix tag}

Lua provides \emph{tags} for user data, with semantics known only
to the host program.  The {\Tt{}lua{\_}matrix{\_}tag\nwendquote} is the tag for
the Lua matrix type.  Note that you \emph{could} get into trouble
with this if multiple interpreters are simultaneously active,
since the different interpreters may not end up allocating the same
tag value.

\nwenddocs{}\nwbegincode{5}\sublabel{NW49APAR-IAwJm-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-IAwJm-1}}}\moddef{static data~{\nwtagstyle{}\subpageref{NW49APAR-IAwJm-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwenddeflinemarkup
static int lua_matrix_tag;

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{6}\nwdocspar

\subsection{Accessor macros}

We use a couple convenience macros for getting the matrix entries.
The macros use one-based indexing for consistence with the Lua
index conventions.

\nwenddocs{}\nwbegincode{7}\sublabel{NW49APAR-1VvxMr-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1VvxMr-1}}}\moddef{macros~{\nwtagstyle{}\subpageref{NW49APAR-1VvxMr-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwenddeflinemarkup
#define Mij(M,i,j) (M->data[((j)-1)*M->ld + ((i)-1)])
#define Mrow0(M,k) ( ((k)-1) % (M->m) )
#define Mcol0(M,k) ( ((k)-1) / (M->m) )
#define Mk(M,k)    ( M->data[Mcol0(M,k) * M->ld + Mrow0(M,k)] )

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{8}\nwdocspar

\subsection{Matrix call getter}

We use Lua tag methods to handle the case when the ``call'' syntax
is applied to a matrix object.  If there is one numeric argument $i$,
we get the $(i,1)$ matrix entry; if there are two numeric arguments,
we get the $(i,j)$ entry.

\nwenddocs{}\nwbegincode{9}\sublabel{NW49APAR-BzF6M-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{\relax}{NW49APAR-BzF6M-2}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_call, 0);
lua_settagmethod(L, lua_matrix_tag, "function");
\nwalsodefined{\\{NW49APAR-BzF6M-2}\\{NW49APAR-BzF6M-3}\\{NW49APAR-BzF6M-4}\\{NW49APAR-BzF6M-5}\\{NW49APAR-BzF6M-6}\\{NW49APAR-BzF6M-7}\\{NW49APAR-BzF6M-8}}\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{10}\nwdocspar

\nwenddocs{}\nwbegincode{11}\sublabel{NW49APAR-1duChy-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{\relax}{NW49APAR-1duChy-2}\nwenddeflinemarkup
static int lua_matrix_call(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,1);
    int n = lua_gettop(L);
    int i, j;

    if (n < 2 || n > 3)
        lua_error(L, "Wrong number of arguments");

    if (!lua_isnumber(L,2) || (n == 3 && !lua_isnumber(L,3)))
        lua_error(L, "Index must be a number");

    i = (int) lua_tonumber(L,2);
    j = (n == 3) ? (int) lua_tonumber(L,3) : 1;

    if (i <= 0 || i > A->m || j <= 0 || j > A->n)
        lua_error(L, "Index out of range");

    lua_settop(L,0);
    lua_pushnumber(L, Mij(A,i,j));
    return 1;
\}

\nwalsodefined{\\{NW49APAR-1duChy-2}\\{NW49APAR-1duChy-3}\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}\\{NW49APAR-1duChy-6}\\{NW49APAR-1duChy-7}\\{NW49APAR-1duChy-8}\\{NW49APAR-1duChy-9}\\{NW49APAR-1duChy-A}\\{NW49APAR-1duChy-B}\\{NW49APAR-1duChy-C}\\{NW49APAR-1duChy-D}\\{NW49APAR-1duChy-E}\\{NW49APAR-1duChy-F}\\{NW49APAR-1duChy-G}\\{NW49APAR-1duChy-H}}\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{12}\nwdocspar

\subsection{Matrix table getter}

The indexed read operation does two different things.  If the index
is a number $k$, we try to return the $k$th element of the matrix
(as arranged in column-major order with one-based indexing).
If the index is a string, then we probably have a method call,
which is handled by the {\Tt{}lua{\_}matrix{\_}getmethod\nwendquote} function described
later.  (Recall that the dot syntax in Lua is a type of indexing,
so that {\Tt{}A.print()\nwendquote} is equivalent to {\Tt{}A["print"]()\nwendquote}.)

The {\Tt{}gettable\nwendquote} tag method receives the tagged object and the index.

\nwenddocs{}\nwbegincode{13}\sublabel{NW49APAR-BzF6M-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-2}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-1}{NW49APAR-BzF6M-3}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_gettable, 0);
lua_settagmethod(L, lua_matrix_tag, "gettable");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{14}\nwdocspar

\nwenddocs{}\nwbegincode{15}\sublabel{NW49APAR-1duChy-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-2}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-1}{NW49APAR-1duChy-3}\nwenddeflinemarkup
static int lua_matrix_gettable(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,1);
    int k;

    if (!lua_isnumber(L,2)) \{
        if (lua_isstring(L,2))
            return lua_matrix_getmethod(L);
        else
            lua_error(L, "Index must be a number");
    \}
    k = (int) lua_tonumber(L,2);

    if (k <= 0 || k > A->m * A->n)
        lua_error(L, "Index out of range");

    lua_settop(L,0);
    lua_pushnumber(L, Mk(A,k));
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{16}\nwdocspar

\subsection{Matrix setter}

The indexed write operation can only do one thing: set a matrix
entry.  The {\Tt{}settable\nwendquote} tag method gets the tagged object,
the index, and the value to write on the stack.

\nwenddocs{}\nwbegincode{17}\sublabel{NW49APAR-BzF6M-3}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-3}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-2}{NW49APAR-BzF6M-4}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_settable, 0);
lua_settagmethod(L, lua_matrix_tag, "settable");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{18}\nwdocspar

\nwenddocs{}\nwbegincode{19}\sublabel{NW49APAR-1duChy-3}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-3}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-2}{NW49APAR-1duChy-4}\nwenddeflinemarkup
static int lua_matrix_settable(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,1);
    int k;

    if (!lua_isnumber(L,2))
        lua_error(L, "Index must be a number");

    if (!lua_isnumber(L,3))
        lua_error(L, "Value must be a number");

    k = (int) lua_tonumber(L,2);
    if (k <= 0 || k > A->m*A->n)
        lua_error(L, "Index out of range");

    Mk(A,k) = lua_tonumber(L,3);

    lua_settop(L,0);
    return 0;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{20}\nwdocspar

\subsection{Matrix arithmetic operations}

The {\Tt{}lua{\_}matrix{\_}add\nwendquote} and {\Tt{}lua{\_}matrix{\_}sub\nwendquote} methods are attached
to the add and subtract events.  The {\Tt{}lua{\_}matrix{\_}unm\nwendquote} method is
attached to the unary negation event.

\nwenddocs{}\nwbegincode{21}\sublabel{NW49APAR-BzF6M-4}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-4}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-3}{NW49APAR-BzF6M-5}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_add, 0);
lua_settagmethod(L, lua_matrix_tag, "add");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{22}\nwdocspar

\nwenddocs{}\nwbegincode{23}\sublabel{NW49APAR-1duChy-4}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-4}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-3}{NW49APAR-1duChy-5}\nwenddeflinemarkup
static int lua_matrix_add(lua_State* L)
\{
    int i, j;
    \LA{}get binary operands~{\nwtagstyle{}\subpageref{NW49APAR-1rgxbt-1}}\RA{}

    \LA{}check summand conformality~{\nwtagstyle{}\subpageref{NW49APAR-2op4lt-1}}\RA{}
    C = lua_matrix_create(A->m, A->n);

    for (i = 1; i <= A->m; ++i)
        for (j = 1; j <= A->n; ++j)
            Mij(C,i,j) = Mij(A,i,j) + Mij(B,i,j);

    \LA{}return \code{}C\edoc{}~{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}\RA{}
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{24}\nwdocspar

\nwenddocs{}\nwbegincode{25}\sublabel{NW49APAR-BzF6M-5}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-5}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-4}{NW49APAR-BzF6M-6}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_sub, 0);
lua_settagmethod(L, lua_matrix_tag, "sub");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{26}\nwdocspar

\nwenddocs{}\nwbegincode{27}\sublabel{NW49APAR-1duChy-5}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-5}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-4}{NW49APAR-1duChy-6}\nwenddeflinemarkup
static int lua_matrix_sub(lua_State* L)
\{
    int i, j;
    \LA{}get binary operands~{\nwtagstyle{}\subpageref{NW49APAR-1rgxbt-1}}\RA{}

    \LA{}check summand conformality~{\nwtagstyle{}\subpageref{NW49APAR-2op4lt-1}}\RA{}
    C = lua_matrix_create(A->m, A->n);

    for (i = 1; i <= A->m; ++i)
        for (j = 1; j <= A->n; ++j)
            Mij(C,i,j) = Mij(A,i,j) - Mij(B,i,j);

    \LA{}return \code{}C\edoc{}~{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}\RA{}
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{28}\nwdocspar

\nwenddocs{}\nwbegincode{29}\sublabel{NW49APAR-BzF6M-6}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-6}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-5}{NW49APAR-BzF6M-7}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_unm, 0);
lua_settagmethod(L, lua_matrix_tag, "unm");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{30}\nwdocspar

\nwenddocs{}\nwbegincode{31}\sublabel{NW49APAR-1duChy-6}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-6}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-5}{NW49APAR-1duChy-7}\nwenddeflinemarkup
static int lua_matrix_unm(lua_State* L)
\{
    int i, j;
    \LA{}get unary operand~{\nwtagstyle{}\subpageref{NW49APAR-2Wr2g8-1}}\RA{}

    C = lua_matrix_create(A->m, A->n);

    for (i = 1; i <= A->m; ++i)
        for (j = 1; j <= A->n; ++j)
            Mij(C,i,j) = -Mij(A,i,j);

    \LA{}return \code{}C\edoc{}~{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}\RA{}
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{32}\nwdocspar

\nwenddocs{}\nwbegincode{33}\sublabel{NW49APAR-BzF6M-7}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-7}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-6}{NW49APAR-BzF6M-8}\nwenddeflinemarkup
lua_pushcclosure(L, lua_matrix_mul, 0);
lua_settagmethod(L, lua_matrix_tag, "mul");
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{34}\nwdocspar

\nwenddocs{}\nwbegincode{35}\sublabel{NW49APAR-1duChy-7}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-7}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-6}{NW49APAR-1duChy-8}\nwenddeflinemarkup
static int lua_matrix_mul(lua_State* L)
\{
    extern int dgemm_(char* transA, char* transB, int* m, int* n, int* k,
                      double* alpha, double* A, int* ldA,
                      double* B, int* ldB,
                      double* beta, double* C, int* ldC);
#ifdef HAVE_LAPACK
    double one  = 1;
    double zero = 0;
#endif

    \LA{}get binary operands~{\nwtagstyle{}\subpageref{NW49APAR-1rgxbt-1}}\RA{}

    if (A->n != B->m)
        lua_error(L, "Nonconformal matrices");

    C = lua_matrix_create(A->m, B->n);

#ifdef HAVE_LAPACK

    dgemm_("N", "N", &(C->m), &(C->n), &(A->m),
           &one, A->data, &(A->ld),
           B->data, &(B->ld),
           &zero, C->data, &(C->ld));

#else
    lua_error(L, "Dense linear algebra routines not linked\\n");
#endif /* HAVE_LAPACK */

    \LA{}return \code{}C\edoc{}~{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}\RA{}
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{36}\nwdocspar

\nwenddocs{}\nwbegincode{37}\sublabel{NW49APAR-1rgxbt-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1rgxbt-1}}}\moddef{get binary operands~{\nwtagstyle{}\subpageref{NW49APAR-1rgxbt-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}\\{NW49APAR-1duChy-7}}\nwenddeflinemarkup
lua_matrix_t A, B, C;

if (lua_tag(L,1) != lua_matrix_tag || lua_tag(L,2) != lua_matrix_tag)
    lua_error(L, "Invalid operands");

A = lua_touserdata(L,1);
B = lua_touserdata(L,2);
\nwused{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}\\{NW49APAR-1duChy-7}}\nwendcode{}\nwbegindocs{38}\nwdocspar

\nwenddocs{}\nwbegincode{39}\sublabel{NW49APAR-2Wr2g8-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-2Wr2g8-1}}}\moddef{get unary operand~{\nwtagstyle{}\subpageref{NW49APAR-2Wr2g8-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-6}}\nwenddeflinemarkup
lua_matrix_t A = lua_touserdata(L,1);
lua_matrix_t C;
\nwused{\\{NW49APAR-1duChy-6}}\nwendcode{}\nwbegindocs{40}\nwdocspar

\nwenddocs{}\nwbegincode{41}\sublabel{NW49APAR-2op4lt-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-2op4lt-1}}}\moddef{check summand conformality~{\nwtagstyle{}\subpageref{NW49APAR-2op4lt-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}}\nwenddeflinemarkup
if (A->m != B->m || A->n != B->n)
    lua_error(L, "Noncomformal matrices");

\nwused{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}}\nwendcode{}\nwbegindocs{42}\nwdocspar

\nwenddocs{}\nwbegincode{43}\sublabel{NW49APAR-EyHPB-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}}\moddef{return \code{}C\edoc{}~{\nwtagstyle{}\subpageref{NW49APAR-EyHPB-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}\\{NW49APAR-1duChy-6}\\{NW49APAR-1duChy-7}}\nwenddeflinemarkup
lua_settop(L,0);
lua_pushusertag(L, C, lua_matrix_tag);
return 1;
\nwused{\\{NW49APAR-1duChy-4}\\{NW49APAR-1duChy-5}\\{NW49APAR-1duChy-6}\\{NW49APAR-1duChy-7}}\nwendcode{}\nwbegindocs{44}\nwdocspar

\subsection{{\Tt{}matrix\nwendquote} command}

The {\Tt{}matrix\nwendquote} command creates a new matrix of a specified size.
The user is allowed to leave off the second argument $n$;
if it is not explicitly specified, $n$ is assumed to be $1$.
The sizes are only somewhat sanity checked -- there is no
check to make sure that $mn$ is not humongous, and we fail
gracelessly if the memory allocations fail.

After the numeric arguments, the user may also specify a table
of array contents in \emph{row-major} order.  The idea is that
\begin{verbatim}
  A = matrix(2,2, {1, 2,
                   3, 4})
\end{verbatim}
is probably the most natural way to initialize a little two-by-two
example matrix.  It should also be possible to write
\begin{verbatim}
  A = matrix{1, 2, 3}
\end{verbatim}
to get a three-element vector.

\nwenddocs{}\nwbegincode{45}\sublabel{NW49APAR-BzF6M-8}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-8}}}\moddef{register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-nRuDO-4}}\nwprevnextdefs{NW49APAR-BzF6M-7}{\relax}\nwenddeflinemarkup
lua_register(L, "matrix", lua_matrix);
\nwused{\\{NW49APAR-nRuDO-4}}\nwendcode{}\nwbegindocs{46}\nwdocspar

\nwenddocs{}\nwbegincode{47}\sublabel{NW49APAR-1duChy-8}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-8}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-7}{NW49APAR-1duChy-9}\nwenddeflinemarkup
static int lua_matrix(lua_State* L)
\{
    int nargs = lua_gettop(L);
    lua_matrix_t A;
    int i,j;
    int m = 0, n = 0;
    int init_table = 0;

    \LA{}get \code{}matrix\edoc{} parameters~{\nwtagstyle{}\subpageref{NW49APAR-JzBPi-1}}\RA{}

    A = lua_matrix_create(m,n);

    \LA{}initialize matrix from table~{\nwtagstyle{}\subpageref{NW49APAR-3n1EGq-1}}\RA{}

    lua_settop(L,0);
    lua_pushusertag(L, A, lua_matrix_tag);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{48}\nwdocspar

\nwenddocs{}\nwbegincode{49}\sublabel{NW49APAR-JzBPi-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-JzBPi-1}}}\moddef{get \code{}matrix\edoc{} parameters~{\nwtagstyle{}\subpageref{NW49APAR-JzBPi-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-8}}\nwprevnextdefs{\relax}{NW49APAR-JzBPi-2}\nwenddeflinemarkup
for (i = 1; i <= nargs; ++i) \{
    if (lua_isnumber(L,i)) \{
        int val = (int) lua_tonumber(L,i);
        if (val <= 0)
            lua_error(L, "Size out of bounds");

        if      (m == 0)  m = val;
        else if (n == 0)  n = val;
        else              lua_error(L, "Too many size parameters");

    \} else if (lua_istable(L,i)) \{
        if (init_table == 0)
            init_table = i;
        else
            lua_error(L, "Too many initializers");
    \}
\}

\nwalsodefined{\\{NW49APAR-JzBPi-2}}\nwused{\\{NW49APAR-1duChy-8}}\nwendcode{}\nwbegindocs{50}\nwdocspar

\nwenddocs{}\nwbegincode{51}\sublabel{NW49APAR-JzBPi-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-JzBPi-2}}}\moddef{get \code{}matrix\edoc{} parameters~{\nwtagstyle{}\subpageref{NW49APAR-JzBPi-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-8}}\nwprevnextdefs{NW49APAR-JzBPi-1}{\relax}\nwenddeflinemarkup
if (m == 0) \{
    if (init_table) \{
        m = lua_getn(L,init_table);
        if (m == 0)
            lua_error(L, "Insufficient initializer entries");
    \}
\}

if (n == 0)
    n = 1;

if (init_table && lua_getn(L,init_table) > m*n)
    lua_error(L, "Initializer too large");

\nwused{\\{NW49APAR-1duChy-8}}\nwendcode{}\nwbegindocs{52}\nwdocspar

\nwenddocs{}\nwbegincode{53}\sublabel{NW49APAR-3n1EGq-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-3n1EGq-1}}}\moddef{initialize matrix from table~{\nwtagstyle{}\subpageref{NW49APAR-3n1EGq-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-8}}\nwenddeflinemarkup
if (init_table) \{
    int k = 1;
    for (i = 1; i <= m; ++i) \{
        for (j = 1; j <= n; ++j) \{
            lua_rawgeti(L,init_table, k++);
            if (lua_isnumber(L,-1))
                Mij(A,i,j) = lua_tonumber(L,-1);
            lua_pop(L,1);
        \}
    \}
\}
\nwused{\\{NW49APAR-1duChy-8}}\nwendcode{}\nwbegindocs{54}\nwdocspar

\subsection{Matrix {\Tt{}print\nwendquote} method}

Matlab's wrapped matrix output format is \emph{really} nice when you
have to inspect matrices of moderate size.  The {\Tt{}print{\_}matrix\nwendquote} routine
emulates Matlab's behavior for {\Tt{}format\ short\ e\nwendquote}.

\nwenddocs{}\nwbegincode{55}\sublabel{NW49APAR-2e3CeC-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-2e3CeC-1}}}\moddef{call Lua print for buffer~{\nwtagstyle{}\subpageref{NW49APAR-2e3CeC-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-9}}\nwenddeflinemarkup
lua_pushvalue(L, -1);
lua_pushstring(L, buf);
lua_rawcall(L, 1, 0);
\nwused{\\{NW49APAR-1duChy-9}}\nwendcode{}\nwbegindocs{56}\nwdocspar

\nwenddocs{}\nwbegincode{57}\sublabel{NW49APAR-1duChy-9}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-9}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-8}{NW49APAR-1duChy-A}\nwenddeflinemarkup
static void print_matrix(lua_State* L, lua_matrix_t A)
\{
    int i, j, c;
    int m = A->m;
    int n = A->n;
    char buf[256];

    lua_getglobal(L, "print");
    for (c = 1; c <= n; c += 6) \{

        if (n > 6) \{
            sprintf(buf, "  Columns %d through %d\\n",
                    c, (c+5 > n) ? n : c+5);
            \LA{}call Lua print for buffer~{\nwtagstyle{}\subpageref{NW49APAR-2e3CeC-1}}\RA{}
        \}

        for (i = 1; i <= m; ++i) \{
            char num[64];

            *buf = '\\0';
            for (j = c; j <= n && j < c+6; ++j) \{
                if (Mij(A,i,j))
                    sprintf(num, "  % .4e", Mij(A,i,j));
                else
                    sprintf(num, "            0");
                strcat(buf, num);
            \}
            \LA{}call Lua print for buffer~{\nwtagstyle{}\subpageref{NW49APAR-2e3CeC-1}}\RA{}

        \}
        buf[0] = ' ';
        buf[1] = '\\0';
        \LA{}call Lua print for buffer~{\nwtagstyle{}\subpageref{NW49APAR-2e3CeC-1}}\RA{}
    \}
    lua_pop(L,1);
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{58}\nwdocspar

The {\Tt{}matrix{\_}print\nwendquote} routine (also known as the {\Tt{}print\nwendquote} method
for a matrix object) uses {\Tt{}print{\_}matrix\nwendquote} to output a reasonably
pretty representation of the matrix.

\nwenddocs{}\nwbegincode{59}\sublabel{NW49APAR-1duChy-A}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-A}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-9}{NW49APAR-1duChy-B}\nwenddeflinemarkup
static int lua_matrix_print(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);

    if (lua_gettop(L) != 1)
        lua_error(L, "Wrong number of arguments");

    print_matrix(L, A);
    lua_settop(L, 0);
    return 0;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{60}\nwdocspar

\subsection{Matrix {\Tt{}factor\nwendquote} method}

The {\Tt{}matrix{\_}factor\nwendquote} function computes $A = PLU$ using LAPACK's %'
{\Tt{}DGETRF\nwendquote} routine.

\nwenddocs{}\nwbegincode{61}\sublabel{NW49APAR-1duChy-B}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-B}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-A}{NW49APAR-1duChy-C}\nwenddeflinemarkup
static int lua_matrix_factor(lua_State* L)
\{
    extern int dgetrf_(int* m, int* n, double* A, int* ldA,
                       int* ipiv, int* info);

    lua_matrix_t A = lua_touserdata(L,-1);

    if (A->m != A->n)
        lua_error(L, "Matrix must be square");

#ifdef HAVE_LAPACK
    if (A->ipiv == NULL) \{
        int info;
        A->ipiv = calloc(A->m, sizeof(int));
        dgetrf_(&(A->m), &(A->n), A->data, &(A->ld), A->ipiv, &info);
        if (info != 0) \{
            printf("dgetrf failed with error code %d\\n", info);
            lua_error(L, "Error during factorization");
        \}
    \}
#else
    lua_error(L, "Dense linear algebra not linked\\n");
#endif

    lua_settop(L,0);
    lua_pushusertag(L, A, lua_matrix_tag);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{62}\nwdocspar

\subsection{Matrix {\Tt{}solve\nwendquote} method}

The {\Tt{}matrix{\_}solve\nwendquote} function computes $x := A^{-1} x$ given a factored
matrix $A$.  If the matrix has not already been factored, we will factor
it.

\nwenddocs{}\nwbegincode{63}\sublabel{NW49APAR-1duChy-C}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-C}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-B}{NW49APAR-1duChy-D}\nwenddeflinemarkup
static int lua_matrix_solve(lua_State* L)
\{
    extern int dgetrs_(char* trans, int* n, int* nrhs, double* A, int* ldA,
                       int* ipiv, double* B, int* ldB, int* info);

    lua_matrix_t A = lua_touserdata(L,-1);
    lua_matrix_t B;

#ifdef HAVE_LAPACK
    int info;
#endif

    if (lua_gettop(L) != 2)
        lua_error(L, "Wrong number of arguments");

    if (lua_tag(L,1) != lua_matrix_tag)
        lua_error(L, "Argument must be a matrix");
    B = lua_touserdata(L,1);

    if (A->ipiv == NULL) \{
        lua_matrix_factor(L);
    \}

    if (A->n != B->m)
        lua_error(L, "Dimension mismatch");

#ifdef HAVE_LAPACK
    dgetrs_("N", &(A->n), &(B->n), A->data, &(A->ld), A->ipiv,
            B->data, &(B->ld), &info);
    if (info != 0)
        printf("Solve failed with error code %d\\n", info);

#else
    lua_error(L, "Dense linear algebra libraries not linked\\n");
#endif

    lua_settop(L,0);
    lua_pushusertag(L, B, lua_matrix_tag);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{64}\nwdocspar

\subsection{Matrix {\Tt{}clone\nwendquote} method}

The {\Tt{}matrix{\_}clone\nwendquote} function ({\Tt{}clone\nwendquote} method) makes a full
copy of a matrix object.

\nwenddocs{}\nwbegincode{65}\sublabel{NW49APAR-1duChy-D}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-D}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-C}{NW49APAR-1duChy-E}\nwenddeflinemarkup
static int lua_matrix_clone(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);
    lua_matrix_t B;
    int j;

    if (lua_gettop(L) != 1)
        lua_error(L, "Too many arguments");

    B = lua_matrix_create(A->m, A->n);
    for (j = 1; j <= A->n; ++j)
        memcpy(&Mij(B,1,j), &Mij(A,1,j), A->m * sizeof(double));

    if (A->ipiv) \{
        B->ipiv = calloc(A->m, sizeof(int));
        memcpy(B->ipiv, A->ipiv, A->m * sizeof(int));
    \}

    lua_settop(L,0);
    lua_pushusertag(L, B, lua_matrix_tag);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{66}\nwdocspar

\subsection{Matrix {\Tt{}slice\nwendquote} method}

The matrix {\Tt{}slice\nwendquote} command returns a copy of a subscripted slice
of the matrix $A$.

\nwenddocs{}\nwbegincode{67}\sublabel{NW49APAR-1duChy-E}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-E}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-D}{NW49APAR-1duChy-F}\nwenddeflinemarkup
static int lua_matrix_slice_method(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);
    lua_matrix_t B;
    int n = lua_gettop(L);
    int i1, i2, j1 = 1, j2 = 1;

    \LA{}get slice subscript arguments~{\nwtagstyle{}\subpageref{NW49APAR-1xpjei-1}}\RA{}

    B = lua_matrix_slice(A,i1,i2,j1,j2);

    lua_settop(L,0);
    lua_pushusertag(L, B, lua_matrix_tag);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{68}\nwdocspar

\nwenddocs{}\nwbegincode{69}\sublabel{NW49APAR-1xpjei-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1xpjei-1}}}\moddef{get slice subscript arguments~{\nwtagstyle{}\subpageref{NW49APAR-1xpjei-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-1duChy-E}}\nwenddeflinemarkup
if (n != 3 && n != 5)
    lua_error(L, "Wrong number of arguments");

if (!lua_isnumber(L,1) || !lua_isnumber(L,2) ||
    (n == 5 && (!lua_isnumber(L,3) || !lua_isnumber(L,4))))
    lua_error(L, "Subscripts must be numeric");

i1 = (int) lua_tonumber(L,1);
i2 = (int) lua_tonumber(L,2);
if (n == 5) \{
    j1 = (int) lua_tonumber(L,3);
    j2 = (int) lua_tonumber(L,4);
\}

if (i1 <= 0 || i2 < i1 || i2 > A->m ||
    j1 <= 0 || j2 < j1 || j2 > A->n)
    lua_error(L, "Bad subscripts");

\nwused{\\{NW49APAR-1duChy-E}}\nwendcode{}\nwbegindocs{70}\nwdocspar

\subsection{Matrix {\Tt{}free\nwendquote} method}

The {\Tt{}matrix{\_}free\nwendquote} function (also known as the {\Tt{}free\nwendquote} method)
deallocates the object memory.  It should probably be called on
Lua garbage collection, but it isn't yet.

\nwenddocs{}\nwbegincode{71}\sublabel{NW49APAR-1duChy-F}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-F}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-E}{NW49APAR-1duChy-G}\nwenddeflinemarkup
static int lua_matrix_free(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);

    if (lua_gettop(L) != 1)
        lua_error(L, "Too many arguments");

    lua_matrix_destroy(A);

    lua_settop(L,0);
    return 0;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{72}\nwdocspar

\subsection{{\Tt{}m\nwendquote} and {\Tt{}n\nwendquote} fields}

\nwenddocs{}\nwbegincode{73}\sublabel{NW49APAR-1duChy-G}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-G}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-F}{NW49APAR-1duChy-H}\nwenddeflinemarkup
static int lua_matrix_m(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);
    lua_settop(L,0);
    lua_pushnumber(L, A->m);
    return 1;
\}

static int lua_matrix_n(lua_State* L)
\{
    lua_matrix_t A = lua_touserdata(L,-1);
    lua_settop(L,0);
    lua_pushnumber(L, A->n);
    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{74}\nwdocspar

\subsection{Method recall}

When a matrix object is indexed by a method name string,
we return a Lua closure that implements the method.
So when the user requests {\Tt{}A.print\nwendquote}, for instance,
the returned closure object will have {\Tt{}A\nwendquote} as its final
argument when it is called.

On entry, the Lua stack contains the matrix object
and the name string.

\nwenddocs{}\nwbegincode{75}\sublabel{NW49APAR-4QyxLE-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-4QyxLE-1}}}\moddef{static prototypes~{\nwtagstyle{}\subpageref{NW49APAR-4QyxLE-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwenddeflinemarkup
static int lua_matrix_getmethod(lua_State* L);

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{76}\nwdocspar

\nwenddocs{}\nwbegincode{77}\sublabel{NW49APAR-1duChy-H}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-1duChy-H}}}\moddef{static functions~{\nwtagstyle{}\subpageref{NW49APAR-1duChy-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-1duChy-G}{\relax}\nwenddeflinemarkup
static int lua_matrix_getmethod(lua_State* L)
\{
    const char* name = lua_tostring(L,2);

    lua_pop(L,1);
    if (strcmp(name, "print") == 0)
        lua_pushcclosure(L, lua_matrix_print, 1);
    else if (strcmp(name, "free") == 0)
        lua_pushcclosure(L, lua_matrix_free, 1);
    else if (strcmp(name, "factor") == 0)
        lua_pushcclosure(L, lua_matrix_factor, 1);
    else if (strcmp(name, "solve") == 0)
        lua_pushcclosure(L, lua_matrix_solve, 1);
    else if (strcmp(name, "clone") == 0)
        lua_pushcclosure(L, lua_matrix_clone, 1);
    else if (strcmp(name, "slice") == 0)
        lua_pushcclosure(L, lua_matrix_slice_method, 1);
    else if (strcmp(name, "m") == 0)
        lua_matrix_m(L);
    else if (strcmp(name, "n") == 0)
        lua_matrix_n(L);
    else
        lua_error(L, "Invalid method name");

    return 1;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{78}\nwdocspar

\subsection{Public matrix manipulation}

\nwenddocs{}\nwbegincode{79}\sublabel{NW49APAR-nRuDO-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}}\moddef{functions~{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{\relax}{NW49APAR-nRuDO-2}\nwenddeflinemarkup
lua_matrix_t lua_matrix_create(int m, int n)
\{
    lua_matrix_t C;

    C = calloc(1, sizeof(*C));
    C->owns_data = 1;
    C->ld = m;
    C->m  = m;
    C->n  = n;
    C->data = calloc(m*n, sizeof(double));
    return C;
\}

void lua_matrix_destroy(lua_matrix_t self)
\{
    if (self->ipiv)
        free(self->ipiv);

    if (self->owns_data)
        free(self->data);

    free(self);
\}

\nwalsodefined{\\{NW49APAR-nRuDO-2}\\{NW49APAR-nRuDO-3}\\{NW49APAR-nRuDO-4}}\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{80}\nwdocspar

\nwenddocs{}\nwbegincode{81}\sublabel{NW49APAR-nRuDO-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-2}}}\moddef{functions~{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-nRuDO-1}{NW49APAR-nRuDO-3}\nwenddeflinemarkup
lua_matrix_t lua_matrix_slice(lua_matrix_t A, int i1, int i2, int j1, int j2)
\{
    lua_matrix_t C;

    C = calloc(1, sizeof(*C));
    C->owns_data = 0;
    C->ld   = A->ld;
    C->m    = (i2-i1)+1;
    C->n    = (j2-j1)+1;
    C->data = &Mij(A,i1,j1);
    return C;
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{82}\nwdocspar

\subsection{Setting and removing vectors}

The {\Tt{}lua{\_}matrix{\_}push\nwendquote} function is a thin wrapper around
{\Tt{}lua{\_}pushusertag\nwendquote}.  Similarly, {\Tt{}lua{\_}matrix{\_}get\nwendquote} is a
thin wrapper around {\Tt{}lua{\_}touserdata\nwendquote}.  The only reason we
don't want the user to directly use the {\Tt{}lua{\_}pushusertag\nwendquote} and
{\Tt{}lua{\_}touserdata\nwendquote} functions is that then we would have
to expose the matrix tag value to the world.  That wouldn't
be a tragedy, but it would be nice to keep it private.

\nwenddocs{}\nwbegincode{83}\sublabel{NW49APAR-nRuDO-3}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-3}}}\moddef{functions~{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-nRuDO-2}{NW49APAR-nRuDO-4}\nwenddeflinemarkup
void lua_matrix_push(lua_State* L, lua_matrix_t matrix)
\{
    lua_pushusertag(L, matrix, lua_matrix_tag);
\}

lua_matrix_t lua_matrix_get(lua_State* L, int index)
\{
    if (index > lua_gettop(L))
        lua_error(L, "Index out of range");

    if (lua_tag(L,index) != lua_matrix_tag)
        lua_error(L, "Variable is not a matrix");

    return lua_touserdata(L,index);
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}\nwbegindocs{84}\nwdocspar

\subsection{Registration functions}

\nwenddocs{}\nwbegincode{85}\sublabel{NW49APAR-nRuDO-4}\nwmargintag{{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-4}}}\moddef{functions~{\nwtagstyle{}\subpageref{NW49APAR-nRuDO-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW49APAR-VVNpW-1}}\nwprevnextdefs{NW49APAR-nRuDO-3}{\relax}\nwenddeflinemarkup
void lua_matrix_register(lua_State* L)
\{
    lua_matrix_tag = lua_newtag(L);
    \LA{}register functions~{\nwtagstyle{}\subpageref{NW49APAR-BzF6M-1}}\RA{}
\}

\nwused{\\{NW49APAR-VVNpW-1}}\nwendcode{}

\nwixlogsorted{c}{{call Lua print for buffer}{NW49APAR-2e3CeC-1}{\nwixd{NW49APAR-2e3CeC-1}\nwixu{NW49APAR-1duChy-9}}}%
\nwixlogsorted{c}{{check summand conformality}{NW49APAR-2op4lt-1}{\nwixu{NW49APAR-1duChy-4}\nwixu{NW49APAR-1duChy-5}\nwixd{NW49APAR-2op4lt-1}}}%
\nwixlogsorted{c}{{functions}{NW49APAR-nRuDO-1}{\nwixu{NW49APAR-VVNpW-1}\nwixd{NW49APAR-nRuDO-1}\nwixd{NW49APAR-nRuDO-2}\nwixd{NW49APAR-nRuDO-3}\nwixd{NW49APAR-nRuDO-4}}}%
\nwixlogsorted{c}{{get \code{}matrix\edoc{} parameters}{NW49APAR-JzBPi-1}{\nwixu{NW49APAR-1duChy-8}\nwixd{NW49APAR-JzBPi-1}\nwixd{NW49APAR-JzBPi-2}}}%
\nwixlogsorted{c}{{get binary operands}{NW49APAR-1rgxbt-1}{\nwixu{NW49APAR-1duChy-4}\nwixu{NW49APAR-1duChy-5}\nwixu{NW49APAR-1duChy-7}\nwixd{NW49APAR-1rgxbt-1}}}%
\nwixlogsorted{c}{{get slice subscript arguments}{NW49APAR-1xpjei-1}{\nwixu{NW49APAR-1duChy-E}\nwixd{NW49APAR-1xpjei-1}}}%
\nwixlogsorted{c}{{get unary operand}{NW49APAR-2Wr2g8-1}{\nwixu{NW49APAR-1duChy-6}\nwixd{NW49APAR-2Wr2g8-1}}}%
\nwixlogsorted{c}{{initialize matrix from table}{NW49APAR-3n1EGq-1}{\nwixu{NW49APAR-1duChy-8}\nwixd{NW49APAR-3n1EGq-1}}}%
\nwixlogsorted{c}{{macros}{NW49APAR-1VvxMr-1}{\nwixu{NW49APAR-VVNpW-1}\nwixd{NW49APAR-1VvxMr-1}}}%
\nwixlogsorted{c}{{matrix-lua.c}{NW49APAR-VVNpW-1}{\nwixd{NW49APAR-VVNpW-1}}}%
\nwixlogsorted{c}{{matrix-lua.h}{NW49APAR-2XOU18-1}{\nwixd{NW49APAR-2XOU18-1}}}%
\nwixlogsorted{c}{{register functions}{NW49APAR-BzF6M-1}{\nwixd{NW49APAR-BzF6M-1}\nwixd{NW49APAR-BzF6M-2}\nwixd{NW49APAR-BzF6M-3}\nwixd{NW49APAR-BzF6M-4}\nwixd{NW49APAR-BzF6M-5}\nwixd{NW49APAR-BzF6M-6}\nwixd{NW49APAR-BzF6M-7}\nwixd{NW49APAR-BzF6M-8}\nwixu{NW49APAR-nRuDO-4}}}%
\nwixlogsorted{c}{{return \code{}C\edoc{}}{NW49APAR-EyHPB-1}{\nwixu{NW49APAR-1duChy-4}\nwixu{NW49APAR-1duChy-5}\nwixu{NW49APAR-1duChy-6}\nwixu{NW49APAR-1duChy-7}\nwixd{NW49APAR-EyHPB-1}}}%
\nwixlogsorted{c}{{static data}{NW49APAR-IAwJm-1}{\nwixu{NW49APAR-VVNpW-1}\nwixd{NW49APAR-IAwJm-1}}}%
\nwixlogsorted{c}{{static functions}{NW49APAR-1duChy-1}{\nwixu{NW49APAR-VVNpW-1}\nwixd{NW49APAR-1duChy-1}\nwixd{NW49APAR-1duChy-2}\nwixd{NW49APAR-1duChy-3}\nwixd{NW49APAR-1duChy-4}\nwixd{NW49APAR-1duChy-5}\nwixd{NW49APAR-1duChy-6}\nwixd{NW49APAR-1duChy-7}\nwixd{NW49APAR-1duChy-8}\nwixd{NW49APAR-1duChy-9}\nwixd{NW49APAR-1duChy-A}\nwixd{NW49APAR-1duChy-B}\nwixd{NW49APAR-1duChy-C}\nwixd{NW49APAR-1duChy-D}\nwixd{NW49APAR-1duChy-E}\nwixd{NW49APAR-1duChy-F}\nwixd{NW49APAR-1duChy-G}\nwixd{NW49APAR-1duChy-H}}}%
\nwixlogsorted{c}{{static prototypes}{NW49APAR-4QyxLE-1}{\nwixu{NW49APAR-VVNpW-1}\nwixd{NW49APAR-4QyxLE-1}}}%
\nwbegindocs{86}\nwdocspar
\nwenddocs{}


\chapter*{Calculation of the ChiSquare ($\chi^2$)}
\setcounter{chapter}{1}
\emph{Get the ChiSquare}

\section{Introduction}
The purpose of the \emph{ChiSquare} plugin is to calculate the ChiSquare and the reduced ChiSquare for two sets of data.

\section{Plugin Properties}
Table \ref{table:PluginProperties} lists available plugin property names, along with their data type and purpose.

\begin{table}[ht]
\centering % used for centering table
\begin{tabular}{l l p{7.5cm}} % centered columns (4 columns)

Parameter Name & Data Type & Purpose \\ [0.5ex] % inserts table
%heading
\hline % inserts single horizontal line
ExperimentalData		& 	TelluriumData   	& Data representing Experimental data. \\
ModelData 				& 	TelluriumData   	& Data representing Model data. \\
NrOfModelParameters		& 	int   				& Number of model parameters used to create the model data. \\
ChiSquare     			& 	double		   		& The calculated ChiSquare. \\
ReducedChiSquare 		& 	double		   		& The calculated reduced ChiSquare. \\

\hline %inserts single line
\end{tabular}
\caption{Plugin Properties}
\label{table:PluginProperties}
\end{table}

\section{Plugin Events}
This plugin does not use any plugin events.

\section{The \texttt{execute()} function}
The \verb|execute()| function will attempt to calculate the ChiSquare, and the reduced ChiSquare, using data supplied by the user.

\section{Python examples}

\subsection{Usage of the ChiSquare plugin}
The python script below shows how to use the plugin.

\begin{singlespace}
\lstinputlisting[label=chisquare_plugin_header,caption={ChiSquare plugin example.},language=Python]{Examples/telChiSquare.py}
\end{singlespace}


\documentclass{article}
\usepackage{graphicx, amssymb, amsmath}

\begin{document}

\title{Extended Gravitational Lens: Thin Approximation Inadequacy}

\maketitle

\section{-}

Let $O$, $S$ and $L$ to denote the Observer, Source and Lens respectively. $P$ denotes some arbitrary point on the ray of light. The lens is assumed to be spherically symmetric, neglecting pressure and energy density, the Schwarzschild orbital equation for massless particles (the lensing equation) is then:
\begin{equation}
    \label{eq1}
    \frac{d^2u}{d\theta^2}+u=3r_gu^2
\end{equation}
where $u\equiv1/r$, the radius $r\equiv \overline{LP}$, and $\theta\equiv \angle SLP$.
The gravitational radius
\begin{equation}
    \label{eq2}
    r_g(r) \equiv \frac{M(r)G}{c^2}
\end{equation}
is a function of $r$, here $c$ is the speed of light and $M(r)$ the lens mass enclosed by a sphere of radius $r$. The angle between $\vec{SL}$ and the ray tangent is called the "ray angle":
\begin{equation}
    \label{eq3}
    \alpha \equiv \arctan \left( \frac{-u^{-1}u'\sin \theta + \cos \theta}{-u^{-1}u'\cos \theta - \sin \theta} \right) \;.
\end{equation}
$\alpha(0)$ and $\alpha(\theta_O)$ are the incoming and outgoing angles respectively, $\theta_O\equiv \angle SLO$. We define the impact point $B$ where the straight line from the source tangent to the actual light ray hits the lens plane. The impact parameter is then $b \equiv \overline{LB}$.

For thin lens approximation light is assumed to travel in a straight line from $S$ to $B$, where it is deflected by an angle $\gamma=4r_g/b$, the mass used to calculate $r_g$ is the lens projected mass in a circle of radius $b$.

Calculating the time of travel is done as follows:
\begin{equation}
    \label{eq4}
    \Delta t_{ray} = \int_{0}^{\theta_O} \left( \frac{u^{-4}u'^2+u^{-2}}{1-2ur_g} \right)^{\frac{1}{2}} {\rm d}  \theta \;,
\end{equation}
where the denominator accounts for gravitational time dilation.

\section{The harmonic solution to the lensing equation}

We are interested in solving the lensing equation (eq. \ref{eq1}) inside an isothermal sphere sharply truncated at $R$. The total mass is $M_0$ and the enclosed mass $M(r)=M_0r/R$. Plugging this into the lens equation (eq. \ref{eq1}) gives:
\begin{equation}
    \label{eq5}
    \frac{d^2u}{d\theta^2}=\left( \frac{3M_0G}{Rc^2} -1 \right) u \;.
\end{equation}
This is the equation of a harmonic oscillator with $m=1$ and
\begin{equation}
    \label{eq6}
    k=\left( 1-\frac{3M_0G}{Rc^2} \right) u \;.
\end{equation}
The general solution is $u=A\cos \left( \omega \theta+\phi \right)$ with $\omega=\sqrt{k/m}$ i.e.
\begin{equation}
    \label{eq7}
    u= A \cos \left( \theta\sqrt{1-\frac{3M_0G}{Rc^2}} +\phi \right)
\end{equation}
where $\phi$ and $A$ are decided by the boundary conditions. We are interested in a symmetric configuration around the lens, in this case $rmin=u(\pi/2)^{-1}$ is the minimal distance between the ray and the lens, hence the $\cos$ term has to be maximal at $\theta=\pi/2$
\begin{equation}
    \label{eq8}
    \phi = -\frac{\pi}{2}\sqrt{1-\frac{3M_0G}{Rc^2}}
\end{equation}
And $A=1/rmin$. The symmetric solution is then
\begin{equation}
    \label{eq9}
    u= \frac{1}{rmin} \cos \left( \sqrt{1-\frac{3M_0G}{Rc^2}} \left( \theta-\frac{\pi}{2}\right) \right)\;.
\end{equation}
The solution is uniquely defined by the total halo mass $M_0$, its radius $R$ and the minimum approach radius $rmin$.

\section{One specific example}

We compare three solutions to a lensing configuration: analytical (harmonic), numerical, and thin approximation. The configuration is symmetric, cosmologically driven, the lens mass $M_0=2\times 10^{12} M_s/h$ in a radius $R=200 Kpc/h$. The ray minimal approach radius $rmin=4 Kpc/h$. We solve analytically inside the halo, and fit it with a numerical solution to the general lensing equation. The numerical solution fits the analytical one very good, it is defined outside the halo and it preserves symmetry. We put a source at $rs = u_{num}(0)^{-1}=3.5477249 Gpc/h$ and run a thin lens ray with the same incoming angle as the numerical one. The impact parameter fo this ray is $b=4.00000287 Kpc/h$. To calculate the projected mass inside a cylinder or radius $b$ we first calculate the projected density of the lens:
\begin{align}
    \rho &= \frac{   {\rm d}M(r)   }{   {\rm d}r   } \frac{1}{4\pi r^2}\\
    &= \frac{M_0}{4\pi Rr^2}\\
    \Psi&=2\int_0^{\sqrt{R^2-r_p^2}} \rho(\sqrt{r_p^2+z^2}) {\rm d}z \\
    &=\frac{M_0}{2\pi R} \int_0^{\sqrt{R^2-r_p^2}} \frac{{\rm d} z}{r_p^2+z^2} \\
    &=\left[ \frac{M_0}{2\pi R r_p} \arctan \frac{z}{r_p} \right] _0^{\sqrt{R^2-r_p^2}}\\
    &=\frac{M_0}{2\pi R r_p}\arctan \sqrt{\frac{R^2}{r_p^2}-1}
\end{align}
where $r_p\equiv \sqrt{x^2+y^2}$ is a projected radius. The mass inside a cylinder of radius $b$ is then a simple 1D integral of the cylindrical shells:
\begin{align}
    M_{projected}(b) &= \int_0^b 2\pi r_p \Psi(r_p) {\rm d} r_p \\
    &= \frac{M_0}{R} \int_0^b \arctan \left( \sqrt{\frac{R^2}{r_p^2}-1} \right) {\rm d} r_p\;.
\end{align}
This has an analytical solution, but we just integrate this with a simple 1D quadrature. For our configuration, $M_{projected}(4 Kpc/h) = 6.24318\times 10^{10} M_s/h$ (this is 56\% higher than the enclosed mass in a similar radius sphere). We run the thin ray with the above configuration and we find that it diverges significantly from the numerical and analytical solutions, see figures below. To test that our solution for the thin ray is good, we compare it to the numerical solution in a different scenario in which the rays miss the halo, see last figure in this document (the source is on the left). This configuration consists of a black hole lens of mass $2\times 10^{12}M_s/h$, a source at a distance of $3.3 Gpc/h$ and an impact parameter $b=20 Kpc/h$ (yea, this is less cosmologically driven but it should get the idea across, that thin lens matches our numerics for non extended configurations)

\includegraphics[width=300pt]{zoom_1.png}

\includegraphics[width=300pt]{zoom_2.png}

\includegraphics[width=300pt]{zoom_3.png}

\includegraphics[width=300pt]{u1.png}

\includegraphics[width=300pt]{u2.png}

\includegraphics[width=300pt]{missing_the_lens.png}

\includegraphics[width=300pt]{missing_the_lens_zoom.png}

\end{document}


% Created 2015-11-13 Fri 09:36
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{fixltx2e}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{float}
\usepackage{wrapfig}
\usepackage{soul}
\usepackage{textcomp}
\usepackage{marvosym}
\usepackage{wasysym}
\usepackage{latexsym}
\usepackage{amssymb}
\usepackage{hyperref}
\tolerance=1000
\usepackage[margin=18mm]{geometry}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{subfigure}
\usepackage{parskip}
\usepackage{standalone}
\usepackage{tikz,pgf,pgfplots}
\usetikzlibrary{decorations.pathmorphing,patterns}
\usetikzlibrary{arrows,snakes,backgrounds,patterns,matrix,shapes,fit,calc,shadows,plotmarks,decorations.markings,datavisualization,datavisualization.formats.functions,intersections,external}
\usetikzlibrary{decorations.pathmorphing,patterns}
\pgfplotsset{compat=1.9}
\newcommand*{\mexp}[1]{\ensuremath{\mathrm{e}^{#1}}}
\newcommand*{\laplace}[1]{\ensuremath{\mathcal{L} \{#1\}}}
\newcommand*{\laplaceinv}[1]{\ensuremath{\mathcal{L}^{-1} \{#1\}}}
\newcommand*{\realpart}[1]{\ensuremath{\operatorname{Re}(#1)}}
\newcommand*{\impart}[1]{\ensuremath{\operatorname{Im}(#1)}}
\newcommand*{\vsp}[1]{\rule{0pt}{#1}}
\newcommand*{\tderiv}[1]{\ensuremath{\frac{d^{#1}}{dt^{n}}}}
\newcommand*{\bbm}{\begin{bmatrix}}
\newcommand*{\ebm}{\end{bmatrix}}
\newcommand*{\obsmatrix}{\mathcal{O}}
\newcommand*{\contrmatrix}{\mathcal{C}}
\newcommand*{\cwh}{\ensuremath{\cos \omega h}}
\newcommand*{\swh}{\ensuremath{\sin \omega h}}
\providecommand{\alert}[1]{\textbf{#1}}

\title{Computerized control - homework 2}
\author{Kjartan Halvorsen}
\date{Due 2015-09-03}
\hypersetup{
  pdfkeywords={},
  pdfsubject={},
  pdfcreator={Emacs Org-mode version 7.9.3f}}

\begin{document}

\maketitle

\section{Exercises}
\label{sec-1}
\subsection{Sample the continuous-time transfer function}
\label{sec-1-1}

   The harmonic oscillator from Homework 1
\begin{align*}
\dot{x} &= \begin{bmatrix} 0 & \omega\\-\omega & 0 \end{bmatrix} x + \begin{bmatrix}1\\0\end{bmatrix} u\\
y &= \begin{bmatrix} 1 & 0 \end{bmatrix} x.
\end{align*}
has the transfer function
\[ G(s) = C(sI-A)^{-1}B + D = \frac{s}{s^2 + \omega^2}. \]
Sampling the state space system with zero-order-hold gives the discrete-time state space system ($x(kh) = x(k)$)
\begin{align*}
x(k+1) &= \bbm \cos \omega h & \sin \omega h\\ -\sin \omega h & \cos \omega h \ebm x(k) +
          \frac{1}{\omega} \bbm \sin \omega h \\ \cos \omega h - 1 \ebm u(k), \\
y(k) &= \bbm 1 & 0 \ebm x(k).
\end{align*}

\begin{enumerate}
\item \textbf{Compute the pulse-transfer function} for the discrete-time system from the state-space representation using the expression \[ H(z) = C(zI-\Phi)^{-1}\Gamma. \]
\item \textbf{Compute the pulse-transfer function} by sampling the transfer function $G(s)$.
\end{enumerate}
\subsection{Simulation of the continuous- and discrete-time harmonic oscillator}
\label{sec-1-2}
\subsubsection{Simulate step responses}
\label{sec-1-2-1}

Use matlab's control toolbox or the \href{http://python-control.sourceforge.net/}{python control module}  to simulate the systems. Use $\omega=1$.

First, define the continuous-time system \texttt{sys\_c} and the sampled system \texttt{sys\_d} using the \texttt{ss} function. The example below uses the python control toolbox. Using the matlab control toolbox is very similar.

\begin{verbatim}
import numpy as np
import control.matlab as cm
import matplotlib.plot as plt

omega = 1.0
h = omega / 10

A = np.array([[0, omega], [-omega, 0]])
B = np.array([[1],[0]])
C = np.array([[1, 0]])
D = np.array([[0]])
sys_c = cm.ss(A,B,C,D)

wh = omega*h
F = np.array([[np.cos(wh), np.sin(wh)], [-np.sin(wh), np.cos(wh)]])
G = 1.0/omega* np.array([[np.sin(wh)], [np.cos(wh)-1]])
sys_d = cm.ss(F,G,C,D, h)

Tc = np.linspace(0,4/omega,200)
(yc,tc) = cm.step(sys_c, Tc)
Td = h*np.arange(40)
(yd,td) = cm.step(sys_d, Td)

plt.plot(tc,yc)
plt.plot(td,yd[0], '*')
\end{verbatim}

\textbf{Verify that the step response of the discrete-time system is equal to that of the continuous-time system at the sampling instants. Explain why this is so!}
\subsubsection{Sampling the system with help of the computer}
\label{sec-1-2-2}

Use the function \texttt{c2d} to sample your continuous-time system \texttt{sys\_c}. \textbf{Verify that you get the same discrete-time system as your} \texttt{sys\_d} \textbf{above}. \emph{Hint}: Look at the system matrices returned by \texttt{ssdata}.
\subsubsection{Compute the discrete step response yourself}
\label{sec-1-2-3}

    Write some lines of code that solves the difference equation
    \begin{align*}
    x(k+1) &= \Phi x(k) + \Gamma u(k)\\
    y &= Cx(k)
    \end{align*}

given an initial state $x(0)=x_0$ and an input sequence $\{u(k)\}$. Use a step signal ($u(k)=1$) and verify that your solution is the same as when using the \texttt{step} function.

\end{document}


\section{Refinement Type Driven Synthesis}
\label{sec:rtypes}

In order to find an initial value for gradient descent, we could use refinement types~\cite{freeman1991refinement}.
In this section we explore a possible optimization for selecting an initial DSP program for gradient descent.
This has not yet been implemented, but we present the theory behind the approach.

\subsection{Refinement Types for DSP}
\label{sec:rtypeSearch}
Refinement types are a way of giving an abstract description of the behavior of a function.
For example, using a similar syntax to the refinement type system for Haskell, LiquidHaskell~\cite{vazou2014refinement}, given the function
%
\texttt{map :: [a]} $\to$ \texttt{[b]}
%
we can further provide a refinement types that captures some properties of the behavior of this function over values:
%
\begin{align*}
\texttt{f :: xs:[a]} \to\ \texttt{ys:[b]}\ \mid \texttt{ length xs == length ys}
\end{align*}

\noindent In this case, the refinement type describes that the length of the lists are still equal after applying the \texttt{map} function.

In a similar style for DSP, we can write predicates about the filters available to us during synthesis.
For example, a low-pass filter could be described as the refinement type that says the amplitude of the frequencies greater than the threshold frequency have decreased in the output Audio.
For brevity in notation, we will only treat a single time slice from the waterfall plot here, but the concept generalizes when quantified over all time slices as well.
%
\begin{align*}
  &\texttt{lpf :: t:Float} \to  \texttt{xs:Audio} \to\ \texttt{ys:Audio}\ \mid \\
  &\forall f_1 \in  \texttt{spectrogram(xs)}.\ \forall f_2 \in \texttt{spectrogram(ys)}. \\
  &(f_1 > \texttt{t}  \land  f_2 > \texttt{t}  \land f_1 == f_2) \implies \texttt{amp}(f_1) > \texttt{amp}(f_2)
\end{align*}

Where \texttt{t} represents the level at which the lowpass filter is applied, \texttt{spectrogram} represents the spectrogram of the sound sample, $f_i$ represents a frequency, and \texttt{amp()} represents the amplitude of the frequency.

Additionally, a high-pass filter could be described as the refinement type that says the amplitude of the frequencies less than the threshold frequency have decreased in the output Audio.
%
\begin{align*}
  &\texttt{hpf :: t:Float} \to\ \texttt{xs:Audio} \to\ \texttt{ys:Audio}\ \mid \\
  &(\forall f_1 \in \texttt{spectrogram(xs)}. \forall f_2 \in \texttt{spectrogram(ys)}). \\
  &(f_1 < \texttt{t} \land f_2 < \texttt{t} \land f_1 == f_2) \implies \texttt{amp(}f_1\texttt{)} > \texttt{amp(} f_2 \texttt{)}
\end{align*}

Notice that in these refinement types, we only need to calculate the spectrogram for the input and output statically.
As opposed to the current technique of generating filters, applying them, and the calculating the aural distance, this approach is relatively static.
We could quickly check many threshold values over the input and output examples.
This will only yield a rough boolean estimation of whether this threshold should even be considered, but this is enough information for us to select an initial program to pass to our gradient descent algorithm.
As the search for an initial filter takes roughly 40 seconds out of our current benchmarks, this could dramatical increase the speed of synthesis.

\subsection{Combination of Search Algorithms}

Beyond just using the refinement types to select an initial program for gradient descent, we can use refinement types in as part of the main search strategy as well.
We briefly describe here a way to use refinement types in combination with gradient descent to handle more complex combinations of DSP filters.
So far in our work (\textit{c.f.} Sec.~\ref{sec:eval}) we have synthesized filters with a fixed form - all our solutions use a single low-pass filter, and a single high-pass filter.
Ideally, we would be able to synthesize solutions that use any arbitrary combination of filters.
In order to do this, we would need an iterative solution that can find one filter at a time.

In this approach, given input example \texttt{x:Audio} and output example \texttt{y:Audio}, we would first find a filter \synthFilter' using the approach described in Sec.~\ref{sec:search} and Sec.~\ref{sec:rtypeSearch}.
We will say that this \synthFilter' has the refinement type $r_1$.
However, this filter might not return a satisfactory result.
We could then continue the search using the output of \synthFilter'\texttt{(x)} as the new input example, \texttt{z:Audio}.
Now the synthesis task is to find a filter \synthFilter'' (with refinement type $r_2$) using input example \texttt{z:Audio} and output example \texttt{y:Audio}.
Essentially, \synthFilter' has gotten us the first half of the way, and \synthFilter'' will get us the second half of the way.
With this, we can start to use more information rich refinement types, such as below:
%
\begin{align*}
\synthFilter \texttt{:: } & \texttt{x:Audio} \to\ \texttt{y:Audio}\ \mid \\
   & \exists \ \texttt{z:Audio}.\ r_1\texttt{(x,z)} \land r_2\texttt{(z,y)}
\end{align*}


\chapter{Neural Networks: Representation}
\label{chap:neural_net_repr}

Let's start by discussing the motivation for neural networks. We already have seen and coded two powerful machine learning algorithms, so we do we need another?

\section{Non-linear Hypotheses}
If we have a fairly messy dataset with three terms, $x_1$, $x_2$, and $x_3$, we can classify them using logistic regression, but we'll probably need to introduce polynomial terms to get an accurate classifier. This would give us a hypothesis in the following form:
$$
h_\theta\left(x\right) = g\left(\theta_0, \theta_1 x_1^2 + \theta_2 x_1 x_2 + \theta_3 x_1 x_3 + \theta_4 x_2^2 + \theta_5 x_2 x_3 + \theta_6 x_3^2\right)
$$

Simply by including quadratic terms, we created six features. We can determine this number of features mathematically from combinatorics, and we can model it after sampling with replacement:
\begin{equation}
\text{num. quadratic features } = \binom{n+k-1}{k} = \frac{\left( n + k - 1\right) !}{k! \left(n-1\right)!} = \frac{\left(3 + 2 - 1\right)!}{2! \cdot \left(3-1\right)!} = \frac{4!}{4} = 6
\end{equation}

If we think back to our housing example, and want to perform classification instead of regression using 100 features, that would give us 5050 polynomial terms to include, in addition to the 100 linear terms. We can approximate the growth of the number of new features we get with all quadratic terms with $\mathcal{O}\left(n^2 / 2\right)$. If we wanted to include cubic terms in our hypothesis too, the features would grow asymptotically as $\mathcal{O}\left(n^3\right)$. Since the number of features grows so rapidly, the number of quadratic and cubic features very quickly becomes impractical.

Consider a collection of $50\times 50$ pixel black-and-white photograph, where we want to determine which photographs are of cars. Then the length of our feature vector is $2500$\footnote{If we were using RGB values, this would be $7500$.}, since we have $2500$ individual pixels. Each features here represents the brightness of the pixel. Now if we want to include quadratic features, we have approximately $2500^2 / 2 = 3,125,000$ features.

\section{Neurons and the Brain}
Neural networks originated when people thought to build algorithms to mimic how the human brain learns. They were popular in the 1980s, but somewhat fell out of use in the 90s; however, there has been a pretty big surge in neural network use lately due to the massive advances in computer hardware and processing speed.

While it might seem like the human brain learns different things in different brain regions, there is a hypothesis that the brain only uses a single learning algorithm for all its different functions. This was motivated by an experiment where scientists rewired the optical nerve to the auditory cortex in animals, and the auditory cortex actually learned to see. This was repeated with other areas of the brain as well. The principle behind this is called neuroplasticity.

\section{Model Representation I}
Neural networks were developed to simulate neurons and networks of neurons in the brain. Very simplistically, the neuron takes inputs via the dendrites as electrical inputs (called spikes) and then channels the output via the axon.

For an artificial neural network, we'll use a very simple model of what a neuron does, we'll model a neuron as a logistic unit. In our model, our inputs are the input features $x_1$, $x_2$, etc. and the output is the result of our hypothesis function. Just like with logistic regression, we have two parameter vectors $\vec{x}$ and $\vec{\theta}$
$$
\vec{x} = \left[\begin{array}{c}x_0 \\ x_1 \\ x_2 \\ x_3 \end{array}\right] ~~\mbox{ \;\;\;\;\;\;\;\;\;\; }~~ \vec{\theta} = \left[\begin{array}{c}\theta_0 \\ \theta_1 \\ \theta_2 \\ \theta_3 \end{array}\right]
$$
where $x_0 = 1$ is the bias term. When representing neural networks, we always have the $\theta_0$ bias term, but we sometimes omit it for notational convenience. Additionally, when representing neural networks, we'll typically use $3$ features, though in reality the number of features is a parameter of the problem.

$$
\left[\begin{array}{c} x_0 \\ x_1 \\ x_2 \\ x_3 \end{array}\right] \to \left[ {\;\;} \right] \to h_\theta\left(x\right)
$$

We use the same logistic function in the hypothesis as logistic regression. However, in neural networks, it is often called the sigmoid function, or the sigmoid/logistic activation function.
\begin{equation}
\frac{1}{1 + e^{-\theta^{{}^\intercal} x}}
\end{equation}
We sometimes call the $\theta$ parameters \textbf{weights} for neural networks, as is traditional in the neural network literature, so now we might refer to $\vec{\theta}$ as either parameters or weights. Now, let's look at a very simple model of a neural network. The first layer, $\vec{x}$, is called the \textbf{input layer}. The output of the hypothesis function is called the \textbf{output layer}, which gives the our final value for the hypothesis. In between the input layer and the final layer, there are one or more hidden layers.
\begin{figure}[h] %  figure placement: here, top, bottom, or page
	\centering
	\graphicspath{{./Figures/}} %Use this to import an image from a subfolder.
	\includegraphics[scale=0.8]{nn_repr_3_layer_neural_netw.pdf}
	\caption[]{A sample artificial neural network, with three inputs and one hidden layer.}
	\label{nn_repr_3_layer_neural_netw.pdf}
\end{figure}
The hidden layer nodes are labeled $a_1^{(2)}$, $a_2^{(2)}$, etc. and called activation units, where $a_i^{(j)}$ is the activation of unit $i$ in layer $j$. The matrix $\Theta^{(j)}$ is the matrix of weights controlling the function mapping from layer $j$ to layer $j + 1$. Mathematically, we might represent this as
$$
\left[\begin{array}{c} x_0 \\ x_1 \\ x_2 \\ x_3 \end{array}\right] \to \left[\begin{array}{c} a_1^{(2)} \\ a_2^{(2)} \\ a_3^{(2)} \end{array}\right] \to h_\Theta\left(x\right)
$$

Now, let's break out the computations that are represented by this diagram
\begin{subequations}
\begin{align}
a_1^{(2)} &= g\left(	\Theta_{10}^{(1)} x_0 + \Theta_{11}^{(1)} x_1 + \Theta_{12}^{(1)} x_2 + \Theta_{13}^{(1)} x_3   	\right) \\
a_2^{(2)} &= g\left(	\Theta_{20}^{(1)} x_0 + \Theta_{21}^{(1)} x_1 + \Theta_{22}^{(1)} x_2 + \Theta_{23}^{(1)} x_3   	\right) \\
a_3^{(2)} &= g\left(	\Theta_{30}^{(1)} x_0 + \Theta_{31}^{(1)} x_1 + \Theta_{32}^{(1)} x_2 + \Theta_{33}^{(1)} x_3   	\right) \\
h_\Theta\left(x\right) = a_1^{(3)} &= g\left(	\Theta_{10}^{(2)} a_0^{(2)} + \Theta_{11}^{(2)} a_1^{(2)} + \Theta_{12}^{(2)} a_2^{(2)} + \Theta_{13}^{(2)} a_3^{(2)}   	\right)
\end{align}
\label{chapnnrepr-sectmodelrepr1-definehiddenlayeractivations}
\end{subequations}
This is saying that we compute our activation nodes using a $3\times 4$ matrix or parameters. We apply each row of parameters to our inputs to obtain the value for one activation node. Our hypothesis output is the sigmoid function applied to the sum of the values from the activation nodes, which have been multiplied by yet another parameter matrix, $\Theta^{(2)}$, containing the weights for our second layer of nodes.

More generally, the dimension of the matrix of weights $\Theta^{(j)}$ is given by the following: if a network has $s_j$ units in layer $j$, and $s_{j+1}$ units in later $j+1$, then $\Theta^{(j)}$ will have dimensions
\begin{equation}
\| \Theta^{(j)} \| = \left(s_{j+1}\right)\times\left(s_j + 1\right)
\end{equation}
The $+1$ for layer $j$ comes from the bias nodes, $x_0$ and $\Theta_0^{(j)}$, and it's only applied to the input nodes since the output of a layer doesn't include a bias node.

For example, if layer one has $2$ input nodes and layer two has $4$ activation nodes, then $\Theta^{(1)}$ will be a $4\times 3$ matrix, since $s_j = s_1 = 2$ and $s_{j+1} = s_2 = 4$.

\section{Model Representation II}
Now, we're going to go through the neural network model again, but this time with a vectorized implementation. We begin by defining a new variable $z_k^{(j)}$ that encompasses the parameters inside of our sigmoid function $g$. As such, we can now rewrite equations \ref{chapnnrepr-sectmodelrepr1-definehiddenlayeractivations} as
\begin{align*}
a_1^{(2)} &= g\left(	\Theta_{10}^{(1)} x_0 + \Theta_{11}^{(1)} x_1 + \Theta_{12}^{(1)} x_2 + \Theta_{13}^{(1)} x_3   	\right) & &\implies &  a_1^{(2)} &= g\left(z_1^{(2)}\right) \\
a_2^{(2)} &= g\left(	\Theta_{20}^{(1)} x_0 + \Theta_{21}^{(1)} x_1 + \Theta_{22}^{(1)} x_2 + \Theta_{23}^{(1)} x_3   	\right) & &\implies &  a_2^{(2)} &= g\left(z_1^{(2)}\right) \\
a_3^{(2)} &= g\left(	\Theta_{30}^{(1)} x_0 + \Theta_{31}^{(1)} x_1 + \Theta_{32}^{(1)} x_2 + \Theta_{33}^{(1)} x_3   	\right) & &\implies &  a_3^{(2)} &= g\left(z_1^{(2)}\right)
\end{align*}
So the $z$ values are just a weighted linear combination of the input values $x_0$, $x_1$, etc. going to a particular neuron. In other words, for layer $j=2$ and node $k$,
\begin{equation}
z_k^{(2)} = \Theta_{k, 0}^{(1)} x_0 + \Theta_{k, 1}^{(1)} x_1 + \cdots + \Theta_{k, n}^{(1)} x_n
\end{equation}
The vector representations of $x$ and $z^{(j)}$ are
$$
x = \left[\begin{array}{c} x_0 \\ x_1 \\ x_2 \\ x_3 \end{array}\right] ~~\mbox{ \;\;\;\;\;\;\;\;\;\; }~~ z^{(j)} = \left[\begin{array}{c} z_1^{(j)} \\ z_2^{(j)} \\ z_3^{(j)} \end{array}\right]
$$
From these vectors, we have $z^{(2)} = \Theta^{(1)} x$ and $a^{(2)} = g\left(z^{(2)}\right)$, where $z^{(2)} \in \mathbb{R}^3$ and $a^{(2)} \in \mathbb{R}^3$. We define $x$ to be $a^{(1)}$, which makes sense because $x$ is our input vector and $a^{(1)}$ implies that we're looking at our first layer, which is the input layer. Then, we can write the general definition for $z$ as
\begin{equation}
z^{(j)} = \Theta^{(j-1)} a^{(j-1)}
\end{equation}
Here, we are multiplying our matrix $\Theta^{(j-1)}$, with dimensions $s_j \times (n+1)$, by our vector $a^{j-1}$, with length $(n+1)$. This yields our vector $z^{(j)}$ with length $s_j$.\footnote{Recall that $s_j$ is the number of activation nodes.}

From this, we can create a vector of our activation nodes for layer $j$ as
\begin{equation}
a^{(j)} = g\left(z^{(j)}\right)
\end{equation}
where the sigmoid function $g$ is applied element-wise to $z^{(j)}$. Next, to get our hypothesis, we need to add a bias term to the layer $j=2$, $a_0^{(2)} = 1$. In fact, we can generalize going forward that we will need to add bias terms, and they'll all equal one $a_0^{(j)} = 1$. Now, we have $a^{(2)} \in \mathbb{R}^4$, since we just added the bias term to the previously length-three vector. Now, we can compute
$$
z^{(3)} = \Theta^{(2)} a^{(2)}
$$
and
$$
h_\Theta\left(x\right) = a^{(3)} = g\left(z^{(3)}\right)
$$

This process for computing $h_\Theta\left(x\right)$ is called \textbf{forward propagation}, because we start off with the activations of the input units, then forward propagate that to compute the activations of the hidden layer, then again forward propagate that to compute the activations of the output layer.

Let's step back for a minute. What we're doing here is very similar to logistic regression, though it might not seem like it. Previously, we have the input feed directly into the logistic regression; now instead, we have the nodes from layer $j=2$ (the hidden layer) feeding into the logistic regression. However, those nodes $a_k^{(2)}$ are themselves learned from the input data

We've been specifically talking about the neural network architecture described in Figure \ref{nn_repr_3_layer_neural_netw.pdf}, but there can be other neural network architectures too. Consider the example shown in Figure \ref{nn_repr_4_layer_neural_netw.pdf}.
\begin{figure}[h] %  figure placement: here, top, bottom, or page
	\centering
	\graphicspath{{./Figures/}} %Use this to import an image from a subfolder.
	\includegraphics[scale=1]{nn_repr_4_layer_neural_netw.pdf}
	\caption[]{A sample artificial neural network, with three inputs and two hidden layer.}
	\label{nn_repr_4_layer_neural_netw.pdf}
\end{figure}
Here, we have the same input layer, but there are two hidden layers. The first hidden layer has three hidden units, which are computed as some complex function of the input layer. The second hidden layer can take the first hidden layer's features and compute even more complex features, so the output layer can have very complex features.

\section{Examples and Intuitions}
Let's say we have inputs $x_1, x_2 \in \{0, 1\}$. In this case, our target label $y = x_1 \text{ AND } x_2$. This is a logical \textit{and}. Can we make a neural network that can recreate this \textit{and} operator? The graph of our function will look something like this
$$
\left[\begin{array}{c} x_0 \\ x_1 \\ x_2 \end{array}\right] \to \left[g\left(z^{(2)}\right)\right] \to h_\Theta\left(z\right)
$$
where $x_0 = 1$ is our bias variable. For this example, let's define our first $\Theta^{(1)}$ matrix as
$$
\Theta^{(1)} = \left[\begin{array}{ccc}\Theta_{1,0}^{(1)} & \Theta_{1,1}^{(1)} & \Theta_{1,2}^{(1)} \end{array}\right] = \left[\begin{array}{ccc}-30 & 20 & 20 \end{array}\right]
$$
This means our hypothesis is given by
$$
h_\Theta\left(x\right) = g\left(	-30 + 20x_1 + 20x_2	\right)
$$
Let's figure out what our hypothesis evaluates to for different combinations of $x_1$ and $x_2$\footnote{Keep in mind that the sigmoid function evaluates to about $0.99$ for an input of $4.6$, and about $0.01$ for an input value of $-4.6$.}

\begin{center}
\begin{tabular}{c c | r}
$x_1$ & $x_2$ & $h_\Theta\left(x\right)$ \\
\hline
$0$ & $0$ & $g\left(-30\right) \approx 0$ \\
$0$ & $1$ & $g\left(-10\right) \approx 0$ \\
$1$ & $0$ & $g\left(-10\right) \approx 0$ \\
$1$ & $1$ & $g\left(10\right) \approx 1$
\end{tabular}
\end{center}

This is exactly the truth table for the logical \textit{and}, so $h_\Theta\left(x\right) \approx x_1 \text{ AND } x_2$. Using a small neural network, we have just constructed one of the most fundamental operations in computing: the \textit{and} gate.

\subsection{Building Logical Gates Using Neural Networks}
We are also able to build neural networks to simulate all other logical gates. Let's start with a super-simple example. If we have a single input variable $x_1$, let's use a neural network to build the logical \textit{not} gate. We could do this with
$$
\Theta^{(1)} = \left[\begin{array}{cc}\Theta_{1,0}^{(1)} & \Theta_{1,1}^{(1)} \end{array}\right] = \left[\begin{array}{cc}10 & -20 \end{array}\right]
$$
giving us a hypothesis of
$$
h_\Theta\left(x\right) = g\left(10 - 20x\right)
$$
If we fill out the table of values for this, we get
\begin{center}
\begin{tabular}{c | r}
$x_1$ & $h_\Theta\left(x\right)$ \\
\hline
$0$ & $g\left(10\right) \approx 1$ \\
$1$ & $g\left(-10\right) \approx 0$
\end{tabular}
\end{center}
As a reminder, here is a truth table for some additional logic gates.
\begin{center}
\begin{tabular}{| c | c | c | c | c | c | c | c |} \hline
\multicolumn{2}{| c |}{\textbf{Input}} & \multicolumn{6}{ c |}{\textbf{Output}} \\ \hline
A & B & A and B & A or B & A nand B & A nor B & A xor B & A xnor B \\ \hline \hline
0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 \\ \hline
0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 \\ \hline
1 & 0 & 0 & 1 & 1 & 0 & 1 & 0 \\ \hline
1 & 1 & 1 & 1 & 0 & 0 & 0 & 1 \\ \hline
\end{tabular}
\end{center}

We can similarly construct $\Theta$ for the \textit{or} gate as
$$
\Theta^{(1)} = \left[\begin{array}{ccc}\Theta_{1,0}^{(1)} & \Theta_{1,1}^{(1)} & \Theta_{1,2}^{(1)} \end{array}\right] = \left[\begin{array}{ccc}-10 & 20 & 20 \end{array}\right]
$$
and $\Theta$ for the \textit{nor} gate as
$$
\Theta^{(1)} = \left[\begin{array}{ccc}\Theta_{1,0}^{(1)} & \Theta_{1,1}^{(1)} & \Theta_{1,2}^{(1)} \end{array}\right] = \left[\begin{array}{ccc}10 & -20 & -20 \end{array}\right]
$$

\subsection{Logical XNOR Gate}
Having defined the \textit{not}, \textit{and}, \textit{or}, and \textit{nor} gates, let's try and build a logical \textit{xnor} gate. We'll start by building a hidden layer with two nodes, one built with the \textit{and} gate and the other with the \textit{nor} gate. Using
$$
\Theta^{(1)} = \left[\begin{array}{ccc} -30 & 20 & 20 \\ 10 & -20 & -20 \end{array}\right]
$$
we can build $a_1^{(2)}$ from the \textit{and} gate and build $a_2^{(2)}$ from the \textit{or} gate. This gives us the following
\begin{center}
\begin{tabular}{c c | c c | c}
$x_1$ & $x_2$ & $ a_1^{(2)}$ & $a_2^{(2)}$ & $h_\Theta\left(x\right)$ \\ \hline
0 & 0 & 0 & 1 & {} \\
0 & 1 & 0 & 0 & {} \\
1 & 0 & 0 & 0 & {} \\
1 & 1 & 1 & 0 & {}
\end{tabular}
\end{center}
Now, to finish our \textit{xnor} gate, we can use the $\textit{or}$ gate between our two existing nodes on the second layer.
$$
\Theta^{(2)} = \left[\begin{array}{ccc} -10 & 20 & 20 \end{array}\right]
$$
Writing this out formally, we find
\begin{align*}
a^{(2)} &= g\left(\Theta^{(1)} x\right) \\
h_\Theta\left(x\right) = a^{(3)} &= g\left(\Theta^{(2)} a^{(2)}\right)
\end{align*}
Filling in the rest of our table, we find we've built the \textit{xnor} gate!
\begin{center}
\begin{tabular}{c c | c c | c}
$x_1$ & $x_2$ & $ a_1^{(2)}$ & $a_2^{(2)}$ & $h_\Theta\left(x\right)$ \\ \hline
0 & 0 & 0 & 1 & 1 \\
0 & 1 & 0 & 0 & 0 \\
1 & 0 & 0 & 0 & 0 \\
1 & 1 & 1 & 0 & 1
\end{tabular}
\end{center}

\section{Multiclass Classification}
Similar to logistic regression, we can do multiclass classification with neural networks, and the way we do it is essentially an extension of the one-vs-all method. Let's say we have a computer vision example, where we're trying to classify an image into a pedestrian, a car, a motorcycle, or a truck. We would do this buy building a neural network with an output of four numbers, meaning the output $h_\Theta$ will actually be a $4$-vector. In our example, when we have a pedestrian or car, we'd want our output to be
$$
\text{(pedestrian) } h_\Theta\left(x\right) \approx \left[\begin{array}{c} 1 \\ 0 \\ 0 \\ 0 \end{array}\right] ~~\mbox{ \;\;\;\;\;\;\;\;\;\; }~~ \text{(car)} h_\Theta\left(x\right) \approx \left[\begin{array}{c} 0 \\ 1 \\ 0 \\ 0 \end{array}\right]
$$
Our training set will look similar
$$
\left(x^{(1)}, y^{(1)}\right), \left(x^{(2)}, y^{(2)}\right), \left(x^{(3)}, y^{(3)}\right), \cdots, \left(x^{(m)}, y^{(m)}\right)
$$
but instead of representing $y \in \{1, 2, 3, 4\}$, we'll represent $y^{(i)}$ as one of the following:
$$
y^{(i)} \in \left\{	 \left[\begin{array}{c} 1 \\ 0 \\ 0 \\ 0 \end{array}\right],  	\left[\begin{array}{c} 0 \\ 1 \\ 0 \\ 0 \end{array}\right],
			\left[\begin{array}{c} 0 \\ 0 \\ 1 \\ 0 \end{array}\right], 	 \left[\begin{array}{c} 0 \\ 0 \\ 0 \\ 1 \end{array}\right]		\right\}
$$
where both $h_\Theta\left(x\right)$ and $\vec{y}$ will be in $\mathbb{R}^4$.

Let's write this out a bit. Sticking with the image classification problem with four output classes, our artificial neural network can be represented by
$$
\left[\begin{array}{c} x_0 \\ x_1 \\  x_2 \\ x_3 \\ \vdots \\ x_n\end{array}\right] \to
\left[\begin{array}{c} a_0^{(2)} \\ a_1^{(2)} \\ a_2^{(2)} \\ a_3^{(2)} \\ \vdots \end{array}\right] \to
\left[\begin{array}{c} a_0^{(3)} \\ a_1^{(3)} \\ a_2^{(3)} \\ a_3^{(3)} \\ \vdots \end{array}\right] \to
\left[\begin{array}{c} h_\Theta\left(x\right)_1 \\ h_\Theta\left(x\right)_2 \\ h_\Theta\left(x\right)_3 \\ h_\Theta\left(x\right)_1 \end{array}\right]
$$
The final hidden layer of nodes, when multiplied by its $\Theta$ matrix, will result in another vector, on which we can apply the sigmoid function $g$ to get a vector of hypothesis values, which will be (asymptotically) equal to one of the four $y^{(i)}$ vectors.