%* glpk01.tex *%

\chapter{Introduction}

GLPK (\underline{G}NU \underline{L}inear \underline{P}rogramming
\underline{K}it) is a set of routines written in the ANSI C programming
language and organized in the form of a callable library. It is
intended for solving linear programming (LP), mixed integer programming
(MIP), and other related problems.

\section{LP problem}
\label{seclp}

GLPK assumes the following formulation of {\it linear programming (LP)}
problem:

\medskip\noindent
\hspace{.5in} minimize (or maximize)
$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (1.1)$$
\hspace{.5in} subject to linear constraints
$$
\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
x_1&=&a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n} \\
x_2&=&a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n} \\
\multicolumn{7}{c}
{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
x_m&=&a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n} \\
\end{array} \eqno (1.2)
$$
\hspace{.5in} and bounds of variables
$$
\begin{array}{r@{\:}c@{\:}c@{\:}c@{\:}l}
l_1&\leq&x_1&\leq&u_1 \\
l_2&\leq&x_2&\leq&u_2 \\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
l_{m+n}&\leq&x_{m+n}&\leq&u_{m+n} \\
\end{array} \eqno (1.3)
$$

\medskip\noindent
where: $x_1, x_2, \dots, x_m$ are auxiliary variables;
$x_{m+1}, x_{m+2}, \dots, x_{m+n}$ are structural variables;
$z$ is the objective function;
$c_1, c_2, \dots, c_n$ are objective coefficients;
$c_0$ is the constant term (``shift'') of the objective function;
$a_{11}, a_{12}, \dots, a_{mn}$ are constraint coefficients;
$l_1, l_2, \dots, l_{m+n}$ are lower bounds of variables;
$u_1, u_2, \dots, u_{m+n}$ are upper bounds of variables.

Auxiliary variables are also called {\it rows}, because they correspond
to rows of the constraint matrix (i.e. a matrix built of the constraint
coefficients). Similarly, structural variables are also called
{\it columns}, because they correspond to columns of the constraint
matrix.

Bounds of variables can be finite as well as infinite. Besides, lower
and upper bounds can be equal to each other. Thus, the following types
of variables are possible:

\begin{center}
\begin{tabular}{r@{}c@{}ll}
\multicolumn{3}{c}{Bounds of variable} & Type of variable \\
\hline
$-\infty <$ &$\ x_k\ $& $< +\infty$ & Free (unbounded) variable \\
$l_k \leq$ &$\ x_k\ $& $< +\infty$  & Variable with lower bound \\
$-\infty <$ &$\ x_k\ $& $\leq u_k$  & Variable with upper bound \\
$l_k \leq$ &$\ x_k\ $& $\leq u_k$   & Double-bounded variable \\
$l_k =$ &$\ x_k\ $& $= u_k$         & Fixed variable \\
\end{tabular}
\end{center}

\noindent
Note that the types of variables shown above are applicable to
structural as well as to auxiliary variables.

To solve the LP problem (1.1)---(1.3) is to find such values of all
structural and auxiliary variables, which:

\vspace*{-10pt}

\begin{itemize}\setlength{\itemsep}{0pt}
\item satisfy to all the linear constraints (1.2), and

\item are within their bounds (1.3), and

\item provide smallest (in case of minimization) or largest (in case of
maximization) value of the objective function (1.1).
\end{itemize}

\section{MIP problem}

{\it Mixed integer linear programming (MIP)} problem is an LP problem
in which some variables are additionally required to be integer.

GLPK assumes that MIP problem has the same formulation as ordinary
(pure) LP problem (1.1)---(1.3), i.e. includes auxiliary and structural
variables, which may have lower and/or upper bounds. However, in case
of MIP problem some variables may be required to be integer. This
additional constraint means that a value of each {\it integer variable}
must be only integer number. (Should note that GLPK allows only
structural variables to be of integer kind.)

\section{Using the package}

\subsection{Brief example}

In order to understand what GLPK is from the user's standpoint,
consider the following simple LP problem:

\medskip

\noindent
\hspace{.5in} maximize
$$z = 10 x_1 + 6 x_2 + 4 x_3$$
\hspace{.5in} subject to
$$
\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
x_1 &+&x_2 &+&x_3 &\leq 100 \\
10 x_1 &+& 4 x_2 & +&5 x_3 & \leq 600 \\
2 x_1 &+& 2 x_2 & +& 6 x_3 & \leq 300 \\
\end{array}
$$
\hspace{.5in} where all variables are non-negative
$$x_1 \geq 0, \ x_2 \geq 0, \ x_3 \geq 0$$

At first, this LP problem should be transformed to the standard form
(1.1)---(1.3). This can be easily done by introducing auxiliary
variables, by one for each original inequality constraint. Thus, the
problem can be reformulated as follows:

\medskip

\noindent
\hspace{.5in} maximize
$$z = 10 x_1 + 6 x_2 + 4 x_3$$
\hspace{.5in} subject to
$$
\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
p& = &x_1 &+&x_2 &+&x_3 \\
q& = &10 x_1 &+& 4 x_2 &+& 5 x_3 \\
r& = &2  x_1 &+& 2 x_2 &+& 6 x_3 \\
\end{array}
$$
\hspace{.5in} and bounds of variables
$$
\begin{array}{ccc}
\nonumber -\infty < p \leq 100 && 0 \leq x_1 < +\infty \\
\nonumber -\infty < q \leq 600 && 0 \leq x_2 < +\infty \\
\nonumber -\infty < r \leq 300 && 0 \leq x_3 < +\infty \\
\end{array}
$$

\medskip

where $p, q, r$ are auxiliary variables (rows), and $x_1, x_2, x_3$ are
structural variables (columns).

The example C program shown below uses GLPK API routines in order to
solve this LP problem.\footnote{If you just need to solve LP or MIP
instance, you may write it in MPS or CPLEX LP format and then use the
GLPK stand-alone solver to obtain a solution. This is much less
time-consuming than programming in C with GLPK API routines.}

\begin{footnotesize}
\begin{verbatim}
/* sample.c */

#include <stdio.h>
#include <stdlib.h>
#include <glpk.h>

int main(void)
{     glp_prob *lp;
      int ia[1+1000], ja[1+1000];
      double ar[1+1000], z, x1, x2, x3;
s1:   lp = glp_create_prob();
s2:   glp_set_prob_name(lp, "sample");
s3:   glp_set_obj_dir(lp, GLP_MAX);
s4:   glp_add_rows(lp, 3);
s5:   glp_set_row_name(lp, 1, "p");
s6:   glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0);
s7:   glp_set_row_name(lp, 2, "q");
s8:   glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0);
s9:   glp_set_row_name(lp, 3, "r");
s10:  glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0);
s11:  glp_add_cols(lp, 3);
s12:  glp_set_col_name(lp, 1, "x1");
s13:  glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);
s14:  glp_set_obj_coef(lp, 1, 10.0);
s15:  glp_set_col_name(lp, 2, "x2");
s16:  glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);
s17:  glp_set_obj_coef(lp, 2, 6.0);
s18:  glp_set_col_name(lp, 3, "x3");
s19:  glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0);
s20:  glp_set_obj_coef(lp, 3, 4.0);
s21:  ia[1] = 1, ja[1] = 1, ar[1] =  1.0; /* a[1,1] =  1 */
s22:  ia[2] = 1, ja[2] = 2, ar[2] =  1.0; /* a[1,2] =  1 */
s23:  ia[3] = 1, ja[3] = 3, ar[3] =  1.0; /* a[1,3] =  1 */
s24:  ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */
s25:  ia[5] = 3, ja[5] = 1, ar[5] =  2.0; /* a[3,1] =  2 */
s26:  ia[6] = 2, ja[6] = 2, ar[6] =  4.0; /* a[2,2] =  4 */
s27:  ia[7] = 3, ja[7] = 2, ar[7] =  2.0; /* a[3,2] =  2 */
s28:  ia[8] = 2, ja[8] = 3, ar[8] =  5.0; /* a[2,3] =  5 */
s29:  ia[9] = 3, ja[9] = 3, ar[9] =  6.0; /* a[3,3] =  6 */
s30:  glp_load_matrix(lp, 9, ia, ja, ar);
s31:  glp_simplex(lp, NULL);
s32:  z = glp_get_obj_val(lp);
s33:  x1 = glp_get_col_prim(lp, 1);
s34:  x2 = glp_get_col_prim(lp, 2);
s35:  x3 = glp_get_col_prim(lp, 3);
s36:  printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n",
         z, x1, x2, x3);
s37:  glp_delete_prob(lp);
      return 0;
}

/* eof */
\end{verbatim}
\end{footnotesize}

The statement \verb|s1| creates a problem object. Being created the
object is initially empty. The statement \verb|s2| assigns a symbolic
name to the problem object.

The statement \verb|s3| calls the routine \verb|glp_set_obj_dir| in
order to set the optimization direction flag, where \verb|GLP_MAX|
means maximization.

The statement \verb|s4| adds three rows to the problem object.

The statement \verb|s5| assigns the symbolic name `\verb|p|' to the
first row, and the statement \verb|s6| sets the type and bounds of the
first row, where \verb|GLP_UP| means that the row has an upper bound.
The statements \verb|s7|, \verb|s8|, \verb|s9|, \verb|s10| are used in
the same way in order to assign the symbolic names `\verb|q|' and
`\verb|r|' to the second and third rows and set their types and bounds.

The statement \verb|s11| adds three columns to the problem object.

The statement \verb|s12| assigns the symbolic name `\verb|x1|' to the
first column, the statement \verb|s13| sets the type and bounds of the
first column, where \verb|GLP_LO| means that the column has an lower
bound, and the statement \verb|s14| sets the objective coefficient for
the first column. The statements \verb|s15|---\verb|s20| are used in
the same way in order to assign the symbolic names `\verb|x2|' and
`\verb|x3|' to the second and third columns and set their types,
bounds, and objective coefficients.

The statements \verb|s21|---\verb|s29| prepare non-zero elements of the
constraint matrix (i.e. constraint coefficients). Row indices of each
element are stored in the array \verb|ia|, column indices are stored in
the array \verb|ja|, and numerical values of corresponding elements are
stored in the array \verb|ar|. Then the statement \verb|s30| calls
the routine \verb|glp_load_matrix|, which loads information from these
three arrays into the problem object.

Now all data have been entered into the problem object, and therefore
the statement \verb|s31| calls the routine \verb|glp_simplex|, which is
a driver to the simplex method, in order to solve the LP problem. This
routine finds an optimal solution and stores all relevant information
back into the problem object.

The statement \verb|s32| obtains a computed value of the objective
function, and the statements \verb|s33|---\verb|s35| obtain computed
values of structural variables (columns), which correspond to the
optimal basic solution found by the solver.

The statement \verb|s36| writes the optimal solution to the standard
output. The printout may look like follows:

\begin{footnotesize}
\begin{verbatim}
*     0:   objval =   0.000000000e+00   infeas =   0.000000000e+00 (0)
*     2:   objval =   7.333333333e+02   infeas =   0.000000000e+00 (0)
OPTIMAL SOLUTION FOUND

z = 733.333; x1 = 33.3333; x2 = 66.6667; x3 = 0
\end{verbatim}
\end{footnotesize}

Finally, the statement \verb|s37| calls the routine
\verb|glp_delete_prob|, which frees all the memory allocated to the
problem object.

\subsection{Compiling}

The GLPK package has the only header file \verb|glpk.h|, which should
be available on compiling a C (or C++) program using GLPK API routines.

If the header file is installed in the default location
\verb|/usr/local/include|, the following typical command may be used to
compile, say, the example C program described above with the GNU C
compiler:

\begin{verbatim}
   $ gcc -c sample.c
\end{verbatim}

If \verb|glpk.h| is not in the default location, the corresponding
directory containing it should be made known to the C compiler through
\verb|-I| option, for example:

\begin{verbatim}
   $ gcc -I/foo/bar/glpk-4.15/include -c sample.c
\end{verbatim}

In any case the compilation results in an object file \verb|sample.o|.

\subsection{Linking}

The GLPK library is a single file \verb|libglpk.a|. (On systems which
support shared libraries there may be also a shared version of the
library \verb|libglpk.so|.)

If the library is installed in the default
location \verb|/usr/local/lib|, the following typical command may be
used to link, say, the example C program described above against with
the library:

\begin{verbatim}
   $ gcc sample.o -lglpk -lm
\end{verbatim}

If the GLPK library is not in the default location, the corresponding
directory containing it should be made known to the linker through
\verb|-L| option, for example:

\begin{verbatim}
   $ gcc -L/foo/bar/glpk-4.15 sample.o -lglpk -lm
\end{verbatim}

Depending on configuration of the package linking against with the GLPK
library may require optional libraries, in which case these libraries
should be also made known to the linker, for example:

\begin{verbatim}
   $ gcc sample.o -lglpk -lgmp -lm
\end{verbatim}

For more details about configuration options of the GLPK package see
Appendix \ref{install}, page \pageref{install}.

%* eof *%


\subsection{Kaplan-Meier Survival Analysis}
\label{sec:kaplan-meier}

\noindent{\bf Description}
\smallskip

Survival analysis examines the time needed for a particular event of interest to occur.
In medical research, for example, the prototypical such event is the death of a patient but the methodology can be applied to other application areas, e.g., completing a task by an individual in a psychological experiment or the failure of electrical components in engineering.
Kaplan-Meier or (product limit) method is a simple non-parametric approach for estimating survival probabilities from both censored and uncensored survival times.\\

\smallskip
\noindent{\bf Usage}
\smallskip

{\hangindent=\parindent\noindent\it%
{\tt{}-f }path/\/{\tt{}KM.dml}
{\tt{} -nvargs}
{\tt{} X=}path/file
{\tt{} TE=}path/file
{\tt{} GI=}path/file
{\tt{} SI=}path/file
{\tt{} O=}path/file
{\tt{} M=}path/file
{\tt{} T=}path/file
{\tt{} alpha=}double
{\tt{} etype=}greenwood$\mid$peto
{\tt{} ctype=}plain$\mid$log$\mid$log-log
{\tt{} ttype=}none$\mid$log-rank$\mid$wilcoxon
{\tt{} fmt=}format

}

\smallskip
\noindent{\bf Arguments}
\begin{Description}
\item[{\tt X}:]
Location (on HDFS) to read the input matrix of the survival data containing:
\begin{Itemize}
	\item timestamps,
	\item whether event occurred (1) or data is censored (0),
	\item a number of factors (i.e., categorical features) for grouping and/or stratifying
\end{Itemize}
\item[{\tt TE}:]
Location (on HDFS) to read the 1-column matrix $TE$ that contains the column indices of the input matrix $X$ corresponding to timestamps (first entry) and event information (second entry)
\item[{\tt GI}:]
Location (on HDFS) to read the 1-column matrix $GI$ that contains the column indices of the input matrix $X$ corresponding to the factors (i.e., categorical features) to be used for grouping
\item[{\tt SI}:]
Location (on HDFS) to read the 1-column matrix $SI$ that contains the column indices of the input matrix $X$ corresponding to the factors (i.e., categorical features) to be used for grouping
\item[{\tt O}:]
Location (on HDFS) to write the matrix containing the results of the Kaplan-Meier analysis $KM$
\item[{\tt M}:]
Location (on HDFS) to write Matrix $M$ containing the following statistics: total number of events, median and its confidence intervals; if survival data for multiple groups and strata are provided each row of $M$ contains the above statistics per group and stratum.
\item[{\tt T}:]
If survival data from multiple groups is available and {\tt ttype=log-rank} or {\tt ttype=wilcoxon}, location (on HDFS) to write the two matrices that contains the result of the (stratified) test for comparing these groups; see below for details.
\item[{\tt alpha}:](default:\mbox{ }{\tt 0.05})
Parameter to compute $100(1-\alpha)\%$ confidence intervals for the survivor function and its median
\item[{\tt etype}:](default:\mbox{ }{\tt "greenwood"})
Parameter to specify the error type according to "greenwood" or "peto"
\item[{\tt ctype}:](default:\mbox{ }{\tt "log"})
Parameter to modify the confidence interval; "plain" keeps the lower and upper bound of the confidence interval unmodified,	"log" corresponds to logistic transformation and "log-log" corresponds to the complementary log-log transformation
\item[{\tt ttype}:](default:\mbox{ }{\tt "none"})
If survival data for multiple groups is available specifies which test to perform for comparing
survival data across multiple groups: "none", "log-rank" or "wilcoxon" test
\item[{\tt fmt}:] (default:\mbox{ }{\tt "text"})
Matrix file output format, such as {\tt text}, {\tt mm}, or {\tt csv};
see read/write functions in SystemML Language Reference for details.
\end{Description}

\noindent{\bf Details}
\smallskip

The Kaplan-Meier estimate is a non-parametric maximum likelihood estimate (MLE) of the survival function $S(t)$, i.e., the probability of survival from the time origin to a given future time.
As an illustration suppose that there are $n$ individuals with observed survival times $t_1,t_2,\ldots t_n$ out of which there are $r\leq n$ distinct death times $t_{(1)}\leq t_{(2)}\leq t_{(r)}$---since some of the observations may be censored, in the sense that the end-point of interest has not been observed for those individuals, and there may be more than one individual with the same survival time.
Let $S(t_j)$ denote the probability of survival until time $t_j$, $d_j$ be the number of events at time $t_j$, and $n_j$ denote the number of individual at risk (i.e., those who die at time $t_j$ or later).
Assuming that the events occur independently, in Kaplan-Meier method the probability of surviving from $t_j$ to $t_{j+1}$ is estimated from $S(t_j)$ and given by
\begin{equation*}
\hat{S}(t) = \prod_{j=1}^{k} \left( \frac{n_j-d_j}{n_j} \right),
\end{equation*}
for $t_k\leq t<t_{k+1}$, $k=1,2,\ldots r$, $\hat{S}(t)=1$ for $t<t_{(1)}$, and $t_{(r+1)}=\infty$.
Note that the value of $\hat{S}(t)$ is constant between times of event and therefore
the estimate is a step function with jumps at observed event times.
If there are no censored data this estimator would simply reduce to the empirical survivor function defined as $\frac{n_j}{n}$. Thus, the Kaplan-Meier estimate can be seen as the generalization of the empirical survivor function that handles censored observations.

The methodology used in our {\tt KM.dml} script closely follows~\cite[Sec.~2]{collett2003:kaplanmeier}.
For completeness we briefly discuss the equations used in our implementation.

% standard error of the survivor function
\textbf{Standard error of the survivor function.}
The standard error of the estimated survivor function (controlled by parameter {\tt etype}) can be calculated as
\begin{equation*}
\text{se} \{\hat{S}(t)\} \approx \hat{S}(t) {\bigg\{ \sum_{j=1}^{k} \frac{d_j}{n_j(n_j -   d_j)}\biggr\}}^2,
\end{equation*}
for $t_{(k)}\leq t<t_{(k+1)}$.
This equation is known as the {\it Greenwood's} formula.
An alternative approach is to apply the {\it Petos's} expression %~\cite{PetoPABCHMMPS1979:kaplanmeier}
\begin{equation*}
\text{se}\{\hat{S}(t)\}=\frac{\hat{S}(t)\sqrt{1-\hat{S}(t)}}{\sqrt{n_k}},
\end{equation*}
for $t_{(k)}\leq t<t_{(k+1)}$.
%Note that this estimate is known to be conservative producing larger standard errors than they ought to be. The Greenwood estimate is therefore recommended for general use.
Once the standard error of $\hat{S}$ has been found we compute the following types of confidence intervals (controlled by parameter {\tt cctype}):
The ``plain'' $100(1-\alpha)\%$ confidence interval for $S(t)$ is computed using
\begin{equation*}
\hat{S}(t)\pm z_{\alpha/2} \text{se}\{\hat{S}(t)\},
\end{equation*}
where $z_{\alpha/2}$ is the upper $\alpha/2$-point of the standard normal distribution.
Alternatively, we can apply the ``log'' transformation using
\begin{equation*}
\hat{S}(t)^{\exp[\pm z_{\alpha/2} \text{se}\{\hat{S}(t)\}/\hat{S}(t)]}
\end{equation*}
or the ``log-log'' transformation using
\begin{equation*}
\hat{S}(t)^{\exp [\pm z_{\alpha/2} \text{se} \{\log [-\log \hat{S}(t)]\}]}.
\end{equation*}

% standard error of the median of survival times
\textbf{Median, its standard error and confidence interval.}
Denote by $\hat{t}(50)$ the estimated median of $\hat{S}$, i.e.,
$\hat{t}(50)=\min \{ t_i \mid \hat{S}(t_i) < 0.5\}$,
where $t_i$ is the observed survival time for individual $i$.
The standard error of $\hat{t}(50)$ is given by
\begin{equation*}
\text{se}\{ \hat{t}(50) \} = \frac{1}{\hat{f}\{\hat{t}(50)\}} \text{se}[\hat{S}\{ \hat{t}(50) \}],
\end{equation*}
where $\hat{f}\{ \hat{t}(50) \}$ can be found from
\begin{equation*}
\hat{f}\{ \hat{t}(50) \} = \frac{\hat{S}\{ \hat{u}(50) \} -\hat{S}\{ \hat{l}(50) \} }{\hat{l}(50) - \hat{u}(50)}.
\end{equation*}
Above, $\hat{u}(50)$ is the largest survival time for which $\hat{S}$ exceeds $0.5+\epsilon$, i.e., $\hat{u}(50)=\max \bigl\{ t_{(j)} \mid \hat{S}(t_{(j)}) \geq 0.5+\epsilon \bigr\}$,
and $\hat{l}(50)$ is the smallest survivor time for which $\hat{S}$ is less than $0.5-\epsilon$,
i.e., $\hat{l}(50)=\min \bigl\{ t_{(j)} \mid \hat{S}(t_{(j)}) \leq 0.5+\epsilon \bigr\}$,
for small $\epsilon$.

% comparing two or more groups of data
\textbf{Log-rank test and Wilcoxon test.}
Our implementation supports comparison of survival data from several groups using two non-parametric procedures (controlled by parameter {\tt ttype}): the {\it log-rank test} and the {\it Wilcoxon test} (also known as the {\it Breslow test}).
Assume that the survival times in $g\geq 2$ groups of survival data are to be compared.
Consider the {\it null hypothesis} that there is no difference in the survival times of the individuals in different groups. One way to examine the null hypothesis is to consider the difference between the observed number of deaths with the numbers expected under the null hypothesis.
In both tests we define the $U$-statistics ($U_{L}$ for the log-rank test and $U_{W}$ for the Wilcoxon test) to compare the observed and the expected number of deaths in $1,2,\ldots,g-1$ groups as follows:
\begin{align*}
U_{Lk} &= \sum_{j=1}^{r}\left( d_{kj} - \frac{n_{kj}d_j}{n_j} \right), \\
U_{Wk} &= \sum_{j=1}^{r}n_j\left( d_{kj} - \frac{n_{kj}d_j}{n_j} \right),
\end{align*}
where $d_{kj}$ is the of number deaths at time $t_{(j)}$ in group $k$,
$n_{kj}$ is the number of individuals at risk at time $t_{(j)}$ in group $k$, and
$k=1,2,\ldots,g-1$ to form the vectors $U_L$ and $U_W$ with $(g-1)$ components.
The covariance (variance) between $U_{Lk}$ and $U_{Lk'}$ (when $k=k'$) is computed as
\begin{equation*}
V_{Lkk'}=\sum_{j=1}^{r} \frac{n_{kj}d_j(n_j-d_j)}{n_j(n_j-1)} \left( \delta_{kk'}-\frac{n_{k'j}}{n_j} \right),
\end{equation*}
for $k,k'=1,2,\ldots,g-1$, with
\begin{equation*}
\delta_{kk'} =
\begin{cases}
1 & \text{if } k=k'\\
0 & \text{otherwise.}
\end{cases}
\end{equation*}
These terms are combined in a {\it variance-covariance} matrix $V_L$ (referred to as the $V$-statistic).
Similarly, the variance-covariance matrix for the Wilcoxon test $V_W$ is a matrix where the entry at position $(k,k')$ is given by
\begin{equation*}
V_{Wkk'}=\sum_{j=1}^{r} n_j^2 \frac{n_{kj}d_j(n_j-d_j)}{n_j(n_j-1)} \left( \delta_{kk'}-\frac{n_{k'j}}{n_j} \right).
\end{equation*}

Under the null hypothesis of no group differences, the test statistics $U_L^\top V_L^{-1} U_L$ for the log-rank test and  $U_W^\top V_W^{-1} U_W$ for the Wilcoxon test have a Chi-squared distribution on $(g-1)$ degrees of freedom.
Our {\tt KM.dml} script also provides a stratified version of the log-rank or Wilcoxon test if requested.
In this case, the values of the $U$- and $V$- statistics are computed for each stratum and then combined over all strata.

\smallskip
\noindent{\bf Returns}
\smallskip

Blow we list the results of the survival analysis computed by {\tt KM.dml}.
The calculated statistics are stored in matrix $KM$ with the following schema:
\begin{itemize}
	\item Column 1: timestamps
	\item Column 2: number of individuals at risk
	\item Column 3: number of events
	\item Column 4: Kaplan-Meier estimate of the survivor function $\hat{S}$
	\item Column 5: standard error of $\hat{S}$
	\item Column 6: lower bound of $100(1-\alpha)\%$ confidence interval for $\hat{S}$
	\item Column 7: upper bound of $100(1-\alpha)\%$ confidence interval for $\hat{S}$
\end{itemize}
Note that if survival data for multiple groups and/or strata is available, each collection of 7 columns in $KM$ stores the results per group and/or per stratum.
In this case $KM$ has $7g+7s$ columns, where $g\geq 1$ and $s\geq 1$ denote the number of groups and strata, respectively.

Additionally, {\tt KM.dml} stores the following statistics in the 1-row matrix $M$ whose number of columns depends on the number of groups ($g$) and strata ($s$) in the data. Below $k$ denotes the number of factors used for grouping and $l$ denotes the number of factors used for stratifying.
\begin{itemize}
	\item Columns 1 to $k$: unique combination of values in the $k$ factors used for grouping
	\item Columns $k+1$ to $k+l$: unique combination of values in the $l$ factors used for stratifying
	\item Column $k+l+1$: total number of records
	\item Column $k+l+2$: total number of events
    \item Column $k+l+3$: median of $\hat{S}$
    \item Column $k+l+4$: lower bound of $100(1-\alpha)\%$ confidence interval for the median of $\hat{S}$
    \item Column $k+l+5$: upper bound of $100(1-\alpha)\%$ confidence interval for the median of $\hat{S}$.
\end{itemize}
If there is only 1 group and 1 stratum available $M$ will be a 1-row matrix with 5 columns where
\begin{itemize}
	\item Column 1: total number of records
	\item Column 2: total number of events
	\item Column 3: median of $\hat{S}$
	\item Column 4: lower bound of $100(1-\alpha)\%$ confidence interval for the median of $\hat{S}$
	\item Column 5: upper bound of $100(1-\alpha)\%$ confidence interval for the median of $\hat{S}$.
\end{itemize}

If a comparison of the survival data across multiple groups needs to be performed, {\tt KM.dml} computes two matrices $T$ and $T\_GROUPS\_OE$ that contain a summary of the test. The 1-row matrix $T$ stores the following statistics:
\begin{itemize}
	\item Column 1: number of groups in the survival data
 	\item Column 2: degree of freedom for Chi-squared distributed test statistic
	\item Column 3: value of test statistic
	\item Column 4: $P$-value.
\end{itemize}
Matrix $T\_GROUPS\_OE$ contains the following statistics for each of $g$ groups:
\begin{itemize}
	\item Column 1: number of events
	\item Column 2: number of observed death times ($O$)
	\item Column 3: number of expected death times ($E$)
	\item Column 4: $(O-E)^2/E$
	\item Column 5: $(O-E)^2/V$.
\end{itemize}

\smallskip
\noindent{\bf Examples}
\smallskip

{\hangindent=\parindent\noindent\tt
	\hml -f KM.dml -nvargs X=/user/biadmin/X.mtx TE=/user/biadmin/TE
	GI=/user/biadmin/GI SI=/user/biadmin/SI O=/user/biadmin/kaplan-meier.csv
	M=/user/biadmin/model.csv alpha=0.01 etype=greenwood ctype=plain fmt=csv

}\smallskip

{\hangindent=\parindent\noindent\tt
	\hml -f KM.dml -nvargs X=/user/biadmin/X.mtx TE=/user/biadmin/TE
	GI=/user/biadmin/GI SI=/user/biadmin/SI O=/user/biadmin/kaplan-meier.csv
	M=/user/biadmin/model.csv T=/user/biadmin/test.csv alpha=0.01 etype=peto
	ctype=log ttype=log-rank fmt=csv

}

%
%\smallskip
%\noindent{\bf References}
%\begin{itemize}
%	\item
%	R.~Peto, M.C.~Pike, P.~Armitage, N.E.~Breslow, D.R.~Cox, S.V.~Howard, N.~Mantel, K.~McPherson, J.~Peto, and P.G.~Smith.
%	\newblock Design and analysis of randomized clinical trials requiring prolonged observation of each patient.
%	\newblock {\em British Journal of Cancer}, 35:1--39, 1979.
%\end{itemize}

%@book{collett2003:kaplanmeier,
%	title={Modelling Survival Data in Medical Research, Second Edition},
%	author={Collett, D.},
%	isbn={9781584883258},
%	lccn={2003040945},
%	series={Chapman \& Hall/CRC Texts in Statistical Science},
%	year={2003},
%	publisher={Taylor \& Francis}
%}


\documentclass[12pt,letterpaper]{article}
\usepackage{fullpage}
\usepackage[top=2cm, bottom=4.5cm, left=2.5cm, right=2.5cm]{geometry}
\usepackage{amsmath,amsthm,amsfonts,amssymb,amscd}
\usepackage{lastpage}
\usepackage{enumerate}
\usepackage{fancyhdr}
\usepackage{mathrsfs}
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{mcode}
\usepackage{hyperref}
\usepackage{movie15}
\usepackage{hyperref}

% \hypersetup{%
%   colorlinks=true,
%   linkcolor=blue,
%   linkbordercolor={0 0 1}
% }

% \renewcommand\lstlistingname{Algorithm}
% \renewcommand\lstlistlistingname{Algorithms}
% \def\lstlistingautorefname{Alg.}

% \lstdefinestyle{Python}{
%     language        = Python,
%     frame           = lines,
%     basicstyle      = \footnotesize,
%     keywordstyle    = \color{blue},
%     stringstyle     = \color{green},
%     commentstyle    = \color{red}\ttfamily
% }

\setlength{\parindent}{0.0in}
\setlength{\parskip}{0.05in}

% Edit these as appropriate
\newcommand\course{Mobile Robotics}
\newcommand\hwnumber{1}                  % <-- homework number
\newcommand\NetIDa{mk05198}           % <-- NetID of person #1
\newcommand\NetIDb{}           % <-- NetID of person #2 (Comment this line out for problem sets)

\pagestyle{fancyplain}
\headheight 35pt
\lhead{\NetIDa}
\lhead{\NetIDa\\\NetIDb}                 % <-- Comment this line out for problem sets (make sure you are person #1)
\chead{\textbf{\Large Homework \hwnumber}}
\rhead{\course \\ \today}
\lfoot{}
\cfoot{}
\rfoot{\small\thepage}
\headsep 1.5em

\begin{document}

\section*{Task 1}

\begin{enumerate}
  \item
   \textbf{Velocities}: \\
   Velocities for the robot are taken as derivative of its trajectory. The following listing shows generation of trajectory and velocity calculations. The velocity vectors are augmented with a zero to match the size of the trajectory vectors.
\begin{lstlisting}
clc;close all
N = 500;
t = linspace(-pi, pi, N);

x = 8*(sin(t)).^3;
y = 8*(sin(2*t)).^3;

vx = gradient(x, 2*pi/N);
vy = gradient(y, 2*pi/N);
\end{lstlisting}
  \item
\textbf{Acceleration}:\\
Taking time derivatives of the velocity vectors, we get acceleration as:

\begin{lstlisting}
ax = gradient(vx, 2*pi/N);
ay = gradient(vy, 2*pi/N);
\end{lstlisting}

\item
\textbf{Robot Velocities}:\\
Using expression (1) and (3) from the assignment prompt, we calculate velocities as follows:
\begin{lstlisting}
%orientation
phi = atan2(vy, vx);

%robot velocities
v = vx.*cos(phi) + vy.*sin(phi);
omega = (vx.*ay - vy.*ax)./(vx.^2+vy.^2);

%Plotting
subplot(2, 1, 1)
plot(v, 'linewidth', 4)
xlabel('time',  'FontSize', 14)
ylabel('velocity',  'FontSize', 14)
title('Linear velocity', 'FontSize', 18)

subplot(2, 1, 2)
plot(omega, 'linewidth', 4)
title('Angular velocity', 'FontSize', 18)
xlabel('time',  'FontSize', 14)
ylabel('velocity',  'FontSize', 14)
print -deps figures/task1
\end{lstlisting}

Run the above presented code in chronological order, we get the following velocity plots:

\begin{figure} [h]
    \centering
    \includegraphics[]{figures/task1_velocities.eps}
    \caption{velocities}
    \label{fig:my_label}
\end{figure}

\item
\textbf{Trajectory traversal}:\\
The following code creates an animated gif with the point mobile node traversing the given trajectory:
\begin{lstlisting}
h = figure;
axis tight manual % this ensures that getframe() returns a consistent size
filename = 'figures/task1_trajectory.gif';
plot(x, y, 'b', 'linewidth', 3)
hold on
for i=1:10:N
    plot(x(1:i), y(1:i), 'g-', 'linewidth', 6)
    legend('Given Trajectory', "Robot's Path");
    drawnow;

    %create GIF
    frame = getframe(h);
    im = frame2im(frame);
    [imind,cm] = rgb2ind(im,256);
    % Write to the GIF File
    if i == 1
      imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
    else
      imwrite(imind,cm,filename,'gif','WriteMode','append');
    end

end
hold off
\end{lstlisting}
\end{enumerate}
The animation can be found here: \href{https://github.com/mehhdiii/Robot-External-Kinematics/blob/main/figures/output.gif}{/mehhdiii/Robot-External-Kinematics/figures}

\section*{Task 2}
Wheel velocities are obtained using the following script:
\begin{lstlisting}
W = 1/2; r = 1/4; T=0.1;

%initialize Inverse kinematics velocities
omega = zeros(1, N); v = zeros(1, N);
vL = zeros(1, N); vR = zeros(1, N);
omegaL = zeros(1, N); omegaR = zeros(1, N);

%initialize resulting forward kinematic variables:
x_f = zeros(1, N); y_f = zeros(1, N); phi_f = zeros(1, N);

for n = 2:N-1
    %calculating inverse kinematics variables:
    mu = 1/2*(sin(phi(n))*(y(n+1)-y(n))+cos(phi(n)*(x(n+1)-x(n))))...
        /(cos(phi(n))*(y(n+1)-y(n))-sin(phi(n))*(x(n+1)-x(n)));
    x_m = (x(n)+x(n+1))/2;
    y_m = (y(n)+y(n+1))/2;

    x_star = x_m - mu/2 * (y(n+1) - y(n));
    y_star = y_m + mu/2 * (x(n+1)-x(n));

    R_n = sqrt((x(n) - x_star)^2 + (y(n)-y_star)^2);
    theta_1 = atan2((y(n)-y_star), (x(n)-x_star));
    theta_2 = atan2((y(n+1)-y_star), (x(n+1)-x_star));
    del_phi = wrapToPi(theta_1 - theta_2);

    %resulting Inv-Kinematics velocities:
    omega(n) = del_phi/T;
    v(n) = R_n*abs(omega(n));
    vL(n) = (R_n-1/2 *W)*omega(n);
    vR(n) = (R_n+1/2 *W)*omega(n);
    omegaL(n) = vL(n)/r;
    omegaR(n) = vR(n)/r;

end

figure()
subplot 221
plot(t,vL,'linewidth', 2)
xlabel('time',  'FontSize', 10)
ylabel('velocity',  'FontSize', 10)
title('Left Wheel velocity', 'FontSize', 14)
xlim([-pi  pi])

subplot 222
plot(t,vR, 'linewidth', 2)
xlabel('time',  'FontSize', 10)
ylabel('velocity',  'FontSize', 10)
title('Right Wheel velocity', 'FontSize', 14)
xlim([-pi  pi])

subplot 223
plot(t,omegaL, 'linewidth', 2)
xlabel('time',  'FontSize', 10)
ylabel('velocity',  'FontSize', 10)
xlim([-pi  pi])

title('Left Wheel angular velocity', 'FontSize', 14)
subplot 224
plot(t,omegaR, 'linewidth', 2)
xlabel('time',  'FontSize', 10)
ylabel('velocity',  'FontSize', 10)
title('Right Wheel angular velocity', 'FontSize', 14)
xlim([-pi  pi])

print -deps figures/task2
\end{lstlisting}
\begin{figure} [h]
    \centering
    \includegraphics[]{figures/task2.eps}
    \caption{Wheel velocities}
    \label{fig:my_label}
\end{figure}
Complete code can be found at: \href{https://github.com/mehhdiii/Robot-External-Kinematics}{github.com/mehhdiii/Robot-External-Kinematics}
\end{document}