%\VignetteEngine{knitr::knitr} 
%\VignettePackage{doBy}
%\VignetteIndexEntry{doBy: Section functions to a smaller domain}

\documentclass[11pt]{article}

\usepackage{hyperref,url,color,Sweave,a4wide}
\usepackage[utf8]{inputenc}
\usepackage[authoryear,round]{natbib}
\bibliographystyle{plainnat}

\RequirePackage{color,fancyvrb,amsmath,amsfonts}

%\def\textasciigrave{'}
\def\proglang#1{{#1}}
\def\R{\proglang{R}}
\def\pkg#1{{\bf #1}}
\def\doby{\pkg{doBy}}
\def\code#1{\texttt{#1}}
\def\summaryby{\code{summaryBy}}

% reduce whitespace between R code and R output
% \let\oldknitrout\knitrout
% \renewenvironment{knitrout}{
%   \begin{oldknitrout}
%     \footnotesize
%     \topsep=0pt
% }{
%   \end{oldknitrout}
% }

<<echo=FALSE>>=
require( doBy )
prettyVersion <- packageDescription("doBy")$Version
prettyDate <- format(Sys.Date())
@

\title{Section functions to a smaller domain with \texttt{section\_fun()} in the \texttt{doBy} package}
\author{S{\o}ren H{\o}jsgaard}
\date{\pkg{doBy} version \Sexpr{prettyVersion} as of \Sexpr{prettyDate}}

\begin{document}
% \SweaveOpts{concordance=TRUE}


\maketitle
\tableofcontents
\parindent0pt
\parskip5pt

<<include=FALSE,echo=FALSE>>=
library(knitr)
@

% show R> prompt before R commands
<<r setup, echo=FALSE>>=
knitr::opts_chunk$set(prompt=TRUE) 
library(doBy)
if (!dir.exists("figures")) dir.create("figures")
opts_chunk$set(
               tidy=FALSE,fig.path='figures/doBy'
           )

oopt <- options()
options("digits"=4, "width"=90, "prompt"="> ", "continue"="  ")
options(useFancyQuotes="UTF-8")
@ %def



\definecolor{darkred}{rgb}{.7,0,0}
\definecolor{midnightblue}{rgb}{0.098,0.098,0.439}


\section{Introduction}
\label{sec:introduction}


The \doby{} package contains a variety of utility functions. This
working document describes some of these functions. The package
originally grew out of a need to calculate groupwise summary
statistics (much in the spirit of \code{PROC SUMMARY} of the
\proglang{SAS} system), but today the package contains many different
utilities.

<<echo=F>>=
library(doBy)
@ %def


\section{Section a functions domain: \code{section\_fun()}}
\label{sec:section}


Let $E$ be a subset of the cartesian product $X \times Y$ where $X$
and $Y$ are some sets. Consider a function $f(x,y)$ defined on
$E$. Then for any $x \in X$, the section of $E$ defined by $x$
(denoted $E_x$) is the set of $y$'s in $Y$ such that $(x, y)$ is in
$E$, i.e.
$$
 E_x = \{ y \in Y | (x,y) \in E\}
$$

Correspondingly, the section of $f(x,y)$ defined by $x$ is the
function $f_x$ defined on $E_x$ given by $f_x(y)=f(x,y)$.

For example, if $f(x,y)=x+y$ then $f_x(y)=f(10, y)$ is a
section of $f$ to be a function of $y$ alone.

There are two approaches: 1) replace the section values in the
function (default) or 2) store the section values
in an auxiliary environment.

\subsection{Replace section into function body}
\label{sec:subst-restr-valu}

Default is to replace section value in functions body:
<<>>=
f  <- function(a, b, c=4, d=9){
    a + b + c + d
}
fr_ <- section_fun(f, list(b=7, d=10))
fr_
f(a=10, b=7, c=5, d=10)
fr_(a=10, c=5)
@



\subsection{Using an auxiliary environment}
\label{sec:using-an-auxillary}

An alternative is to store the section values in an auxiliary environment:

<<>>=
fe_ <- section_fun(f, list(b=7, d=10), method = "env")
fe_
f(a=10, b=7, c=5, d=10)
fe_(a=10, c=5)
@

The section values are stored in an extra environment in the \code{scaffold} object and
the original function is stored in the scaffold functions environment:

<<>>=
get_section(fe_) 
## attr(fe_, "arg_env")$args ## Same result
get_fun(fe_) 
## environment(fe_)$fun ## Same result
@ 

\section{Example: Benchmarking}
\label{sec:exampl-benchm}


Consider a simple task: Creating and inverting Toeplitz matrices for increasing dimensions: 

<<>>=
n <- 4
toeplitz(1:n)
@ 

A naive implementation is
<<>>=
inv_toeplitz <- function(n) {
    solve(toeplitz(1:n))
}
inv_toeplitz(4)
@ 

We can benchmark timing for different values of $n$ as
<<>>=
library(microbenchmark)
microbenchmark(
    inv_toeplitz(4), inv_toeplitz(8), inv_toeplitz(16),
    inv_toeplitz(32), inv_toeplitz(64),
    times=5
)
@ 

However, it is tedious (and hence error prone) to write these function calls. 

A programmatic approach using \code{section\_fun} is as follows: First create a list of sectioned functions:
<<>>=
n.vec  <- c(4, 8, 16, 32, 64)
fun_list <- lapply(n.vec,
                  function(ni){
                      section_fun(inv_toeplitz, list(n=ni))}
                  )
@ 

Each element is a function (a scaffold object, to be precise) and we can evaluate each / all functions as:
<<>>=
fun_list[[1]]
fun_list[[1]]()
@ 

To use the list of functions in connection with microbenchmark we bquote all functions using

<<>>=
bquote_list <- function(fnlist){
    lapply(fnlist, function(g) {
        bquote(.(g)())
    }
    )
}
@ 

We get:
<<>>=
bq_fun_list <- bquote_list(fun_list)
bq_fun_list[[1]]
## Evaluate one:
eval(bq_fun_list[[1]])
## Evaluate all:
## sapply(bq_fun_list, eval)
@ 

To use microbenchmark we must name the elements of the list:
<<>>=
names(bq_fun_list) <- n.vec
microbenchmark(
  list  = bq_fun_list,
  times = 5
)
@ 


To summarize: to experiment with many difference values of $n$ we can do
% <<>>=
% n.vec <- seq(50, 700, by=50)
% fun_list <- lapply(n.vec,
%                   function(ni){
%                       section_fun(inv_toeplitz, list(n=ni))}
%                   )
% bq_fun_list <- bquote_list(fun_list)
% names(bq_fun_list) <- n.vec
% mb <- microbenchmark(
%   list  = bq_fun_list,
%   times = 5
% )
% doBy::mb_summary(mb)  %>% head(4)
% @ 

% Notice: Above, \code{doBy::mb\_summary} is a faster version of the
% \code{summary} method for \code{microbenchmark} objects than the
% method provided by the \code{microbenchmark} package.

% <<fig.height=3>>=
% par(mfrow=c(1,2))
% y <- mb_summary(mb)$mean
% plot(n.vec, y)
% plot(log(n.vec), log(y))
% mm <- lm(log(y) ~ log(n.vec))
% broom::tidy(mm)
% abline(mm)
% @ 


\end{document}

