From 9a9315376516a6dfd728b20c54783c4bc6bb2fce Mon Sep 17 00:00:00 2001 From: Charles Determan Date: Tue, 21 Jul 2015 09:20:37 -0500 Subject: [PATCH 1/5] move examples in to roxygen docs so use \dontrun, add knitr and testthat to DESCRIPTION, restructured vignette to vignettes directory (no built quickly with devtools::build_vignettes()) --- .gitignore | 2 + DESCRIPTION | 2 + examples/attach.big.matrix_examples.R | 2 + examples/core_examples.R | 5 + examples/mwhich_examples.R | 1 + examples/test_example.R | 1 + examples/write.big.matrix_examples.R | 1 + inst/doc/Overview.R | 78 +++ inst/doc/{vignette => }/Overview.Rnw | 827 +++++++++++------------ inst/doc/{vignette => }/Overview.pdf | Bin 140354 -> 158790 bytes man-roxygen/attach.big.matrix_template.R | 25 +- man-roxygen/core_template.R | 57 +- man-roxygen/deepcopy_template.R | 4 +- man-roxygen/flush_template.R | 3 +- man-roxygen/morder_template.R | 10 +- man-roxygen/mwhich_template.R | 41 +- man-roxygen/sub.big.matrix_template.R | 3 +- man-roxygen/write.big.matrix_template.R | 37 +- man/attach.big.matrix.Rd | 4 + man/big.matrix.Rd | 9 +- man/bigmemory-package.Rd | 1 + man/deepcopy.Rd | 2 + man/flush.Rd | 2 + man/morder.Rd | 2 + man/mwhich.Rd | 4 +- man/sub.big.matrix.Rd | 2 + man/write.big.matrix.Rd | 3 + vignettes/Overview.Rnw | 409 +++++++++++ 28 files changed, 1107 insertions(+), 430 deletions(-) create mode 100644 examples/test_example.R create mode 100644 inst/doc/Overview.R rename inst/doc/{vignette => }/Overview.Rnw (81%) rename inst/doc/{vignette => }/Overview.pdf (55%) create mode 100644 vignettes/Overview.Rnw diff --git a/.gitignore b/.gitignore index a899df2..869c0d6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ src/*.dll src/Makevars tests/testthat/*bin tests/testthat/*desc +*.bin +*.desc diff --git a/DESCRIPTION b/DESCRIPTION index ebed6e2..f77867a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -18,3 +18,5 @@ License: LGPL-3 | Apache License 2.0 URL: http://www.bigmemory.org LazyLoad: yes Biarch: yes +VignetteBuilder: knitr +Suggests: knitr, testthat diff --git a/examples/attach.big.matrix_examples.R b/examples/attach.big.matrix_examples.R index 6d9e528..5fd5a21 100644 --- a/examples/attach.big.matrix_examples.R +++ b/examples/attach.big.matrix_examples.R @@ -3,6 +3,8 @@ # via SNOW, foreach, or even by a simple file read/write, # then the attach of the second R process would give access to the # same object in memory. Please see the package vignette for real examples. + +# Not run z <- big.matrix(3, 3, type='integer', init=3) z[,] dim(z) diff --git a/examples/core_examples.R b/examples/core_examples.R index 24ba421..ed87cbc 100644 --- a/examples/core_examples.R +++ b/examples/core_examples.R @@ -1,3 +1,5 @@ +# Not Run +library(bigmemory) x <- big.matrix(10, 2, type='integer', init=-5) options(bigmemory.allow.dimnames=TRUE) colnames(x) <- c("alpha", "beta") @@ -17,6 +19,7 @@ x[,] # second R process would give access to the same object in memory. # Please see the package vignette for real examples. +# Not run z <- big.matrix(3, 3, type='integer', init=3) z[,] dim(z) @@ -33,8 +36,10 @@ y[,] z[,] # A short filebacked example, showing the creation of associated files: +# Not run files <- dir() files[grep("example.bin", files)] + z <- filebacked.big.matrix(3, 3, type='integer', init=123, backingfile="example.bin", descriptorfile="example.desc", diff --git a/examples/mwhich_examples.R b/examples/mwhich_examples.R index 0d7fba3..4e11c92 100644 --- a/examples/mwhich_examples.R +++ b/examples/mwhich_examples.R @@ -31,6 +31,7 @@ mwhich(x, 2, 15, 'le') # No NAs in either column, and column 2 strictly less than 15: mwhich(x, c(1:2,2), list(NA, NA, 15), list('neq', 'neq', 'lt'), 'AND') +gc() x <- big.matrix(4, 2, init=1, type="double") x[1,1] <- Inf mwhich(x, 1, Inf, 'eq') diff --git a/examples/test_example.R b/examples/test_example.R new file mode 100644 index 0000000..d08d7ff --- /dev/null +++ b/examples/test_example.R @@ -0,0 +1 @@ +test() \ No newline at end of file diff --git a/examples/write.big.matrix_examples.R b/examples/write.big.matrix_examples.R index 9a9b469..e0c65d7 100644 --- a/examples/write.big.matrix_examples.R +++ b/examples/write.big.matrix_examples.R @@ -1,4 +1,5 @@ # Without specifying the type, this big.matrix x will hold integers. + x <- as.big.matrix(matrix(1:10, 5, 2)) x[2,2] <- NA x[,] diff --git a/inst/doc/Overview.R b/inst/doc/Overview.R new file mode 100644 index 0000000..4ca182d --- /dev/null +++ b/inst/doc/Overview.R @@ -0,0 +1,78 @@ +## ----include=FALSE------------------------------------------------------- +library(knitr) +opts_chunk$set( +fig.path='graphics/stat' +) + +## ----setup,include=FALSE,echo=FALSE-------------------------------------- +options(keep.source = TRUE, width = 75) + +## ----read, eval = FALSE-------------------------------------------------- +# library(bigmemory) +# library(biganalytics) +# x <- read.big.matrix("airline.csv", type="integer", header=TRUE, +# backingfile="airline.bin", +# descriptorfile="airline.desc", +# extraCols="Age") +# summary(x) +# +# # min max mean NA's +# #Year 1987 2008 1998.62 0 +# #Month 1 12 6.55 0 +# #DayofMonth 1 31 15.72 0 +# #DayOfWeek 1 7 3.94 0 +# #ArrDelay -1437 2598 7.05 2587529 +# #DepDelay -1410 2601 8.17 2302136 +# #... (other variables omitted here) ... + +## ----birth, eval = FALSE------------------------------------------------- +# birthmonth <- function(y) { +# minYear <- min(y[,'Year'], na.rm=TRUE) +# these <- which(y[,'Year']==minYear) +# minMonth <- min(y[these,'Month'], na.rm=TRUE) +# return(12*minYear + minMonth - 1) +# } + +## ----run_birth, eval = FALSE--------------------------------------------- +# allplanes <- unique(x[,'TailNum']) +# planeStart <- rep(0, length(allplanes)) +# for (i in allplanes) { +# planeStart[i] <- birthmonth( x[mwhich(x, 'TailNum', i, 'eq'), +# c('Year', 'Month'), drop=FALSE] ) +# } + +## ----bigsplit, eval = FALSE---------------------------------------------- +# library(bigtabulate) +# planeindices <- bigsplit(x, 'TailNum') + +## ----split, eval = FALSE------------------------------------------------- +# planeindices <- split(1:nrow(x), x[,'TailNum']) + +## ----sapply, eval = FALSE------------------------------------------------ +# planeStart <- sapply(planeindices, +# function(i) birthmonth(x[i, c('Year','Month'), +# drop=FALSE])) + +## ----parallel, eval = FALSE---------------------------------------------- +# library(doMC) +# registerDoMC(cores=2) +# planeStart <- foreach(i=planeindices, .combine=c) %dopar% { +# return(birthmonth(x[i, c('Year','Month'), drop=FALSE])) +# } + +## ----ages, eval = FALSE-------------------------------------------------- +# x[,'Age'] <- x[,'Year']*as.integer(12) + +# x[,'Month'] - as.integer(planeStart[x[,'TailNum']]) + +## ----biglm, eval = FALSE------------------------------------------------- +# blm <- biglm.big.matrix(ArrDelay ~ Age + Year, data=x) +# summary(blm) + +## ----biglm_output, eval = FALSE------------------------------------------ +# #Large data regression model: biglm(formula = formula, data = data, ...) +# #Sample size = 84216580 +# # Coef (95% CI) SE p +# #(Intercept) 91.6149 87.6509 95.5789 1.9820 0 +# #Age 0.0144 0.0142 0.0146 0.0001 0 +# #Year -0.0424 -0.0444 -0.0404 0.0010 0 + diff --git a/inst/doc/vignette/Overview.Rnw b/inst/doc/Overview.Rnw similarity index 81% rename from inst/doc/vignette/Overview.Rnw rename to inst/doc/Overview.Rnw index 0ce7b76..39ce880 100644 --- a/inst/doc/vignette/Overview.Rnw +++ b/inst/doc/Overview.Rnw @@ -1,418 +1,409 @@ -% \VignetteIndexEntry{The Bigmemory Project Overview} -% \VignetteDepends{bigmemory} -% \VignettePackage{bigmemory} -\documentclass[12pt]{article} - -\usepackage{graphics} -\usepackage{graphicx} -\usepackage{Sweave} -\usepackage{accents} - -% New from euler: -\usepackage{ae} -\usepackage{color} -\usepackage{url} - -\topmargin=-0.85in -\textheight=9.5in -\textwidth=6.5in -\oddsidemargin=0in -%-0.25in - -%\usepackage{CJK} -%\usepackage{pinyin} -\def\E{\mathord{I\kern-.35em E}} -\def\R{\mathord{I\kern-.35em R}} -\def\P{\mathord{I\kern-.35em P}} -\def\I{\mathord{1\kern-.35em 1}} -\def\wt{\mathord{\widehat{\theta}}} - -\newcommand{\proglang}[1]{\textbf{#1}} -\newcommand{\pkg}[1]{\texttt{\textsl{#1}}} -\newcommand{\code}[1]{\texttt{#1}} -\newcommand{\mg}[1]{{\textcolor {magenta} {#1}}} -\newcommand{\gr}[1]{{\textcolor {green} {#1}}} -\newcommand{\bl}[1]{{\textcolor {blue} {#1}}} - -\newtheorem{thm}{Theorem}[section] -\newtheorem{myexplore}[thm]{Explore} -\newtheorem{mybackground}[thm]{Background} -\newtheorem{myquestion}[thm]{Question} -\newtheorem{myexample}[thm]{Example} -\newtheorem{mydefinition}[thm]{Definition} -\newtheorem{mytheorem}[thm]{Theorem} - -%\pagestyle{myheadings} % Go for customized headings -%\markboth{notused left title}{John W. Emerson, Department of Statistics, Yale University \copyright 2009} -%\newcommand{\sekshun}[1] % In 'article' only the page -% { % number appears in the header. -% \section{#1} % I want the section name AND -% \markboth{#1 \hfill}{#1 \hfill} % the page, so I need a new kind -% } % of '\sekshun' command. - -\begin{document} - -\setkeys{Gin}{width=1.0\textwidth} -\SweaveOpts{prefix.string=graphics/stat} - -<>= -options(keep.source = TRUE, width = 75) -@ - -\begin{center} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -{\Large\bf The Bigmemory Project} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\vspace*{0.5cm} -{\bf Michael J. Kane and John W. Emerson\\ -Yale University\\ -April 29, 2010} - -\vspace*{0.25cm} - -\end{center} - -%\begin{raggedright} -\parindent=0.5in - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{quotation} -Multi-gigabyte data sets often challenge and frustrate \proglang{R} -users. \proglang{C/C++} programming can provide efficiencies, -but is cumbersome for interactive data analysis and -lacks the flexibility and power of \proglang{R}'s rich statistical -programming environment. The package \pkg{bigmemory} and sister -packages \pkg{biganalytics}, \pkg{synchronicity}, \pkg{bigtabulate}, -and \pkg{bigalgebra} bridge this gap, implementing massive matrices -and supporting their manipulation and exploration. -The data structures may be allocated to shared memory, allowing separate -processes on the same computer to share access to a single copy of the -data set. The data structures may also be file-backed, allowing users -to easily manage and analyze data sets larger than available RAM and -share them across nodes of a cluster. -These features of the Bigmemory Project open the door for powerful and -memory-efficient parallel analyses and data mining of massive data sets, -even on modest hardware. -\end{quotation} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\vspace*{0.5cm} -\noindent -{\bf Introductory Example: the 2009 JSM Data Expo} -\vspace*{0.5cm} - -Consider the complete airline on-time performance data -from the 2009 JSM Data Expo. The processed data set, \texttt{airline.csv}, -is approximately 11 GB (about 120 million rows and 29 columns) -with factors coded as integers (see \url{http://www.bigmemory.org/} for -processing information). -The \texttt{read.big.matrix()} call creates the binary -file-backing \texttt{airline.bin} -associated with the \texttt{big.matrix} object \texttt{x}. -Subsequent \proglang{R} sessions can attach instantly to \texttt{airline.bin} -without incurring the one-time overhead (about 25 minutes) -associated with creating the backing. -A summary of the entire data set is easily obtained using the new -\texttt{summary()} method. Note the surprising -presence of negative arrival and departure delays: exploratory data analysis -in action via \pkg{bigmemory}. The summary -only takes 3-4 minutes to process the 11 GB of data on a laptop with only -4 GB of RAM. -\begin{Schunk} -\begin{Sinput} -> library(bigmemory) -> library(biganalytics) -> x <- read.big.matrix("airline.csv", type="integer", header=TRUE, -+ backingfile="airline.bin", -+ descriptorfile="airline.desc", -+ extraCols="Age") -> summary(x) - min max mean NA's -Year 1987 2008 1998.62 0 -Month 1 12 6.55 0 -DayofMonth 1 31 15.72 0 -DayOfWeek 1 7 3.94 0 -ArrDelay -1437 2598 7.05 2587529 -DepDelay -1410 2601 8.17 2302136 -... (other variables omitted here) ... -\end{Sinput} -\end{Schunk} - - -\noindent -{\bf Overview} -\vspace*{0.5cm} - -Data frames and matrices in \proglang{R} are easy to use, -with typical manipulations executing quickly on -data sets much smaller than available RAM. They suit the needs of many -\proglang{R} users and work seamlessly with existing \proglang{R} functions -and packages. However, problems arise with larger data sets and when -increased memory requirements of parallel programming strain the system. - -The Bigmemory Project offers packages -for two purposes. First, \pkg{bigmemory}, \pkg{biganalytics}, and -\pkg{bigtabulate} have been designed to provide a minimalist, -elegant framework for users to manage and explore large data sets, even -on modest hardware (expensive workstations or clusters are not required). -The interface is designed to mimic \proglang{R}'s familiar \code{matrix} -syntax. Matthew Keller, Assistant Professor of -Psychology, University of Colorado at Boulder offered the following -testimonial about \pkg{bigmemory}: ``I love that it's intuitive and -doesn't require a lot of learning new ways to code things.'' - -Second, the packages of the Bigmemory Project provide a foundation for -memory-efficient parallel programming and can serve as building blocks -for developers of new high-performance computing tools in \proglang{R}. -When used in conjunction with a parallel package (such as \pkg{foreach}, -\pkg{snow}, \pkg{Rmpi}, or \pkg{multicore}, for example), -even shared-memory parallel-computing becomes -accessible to non-experts. -The programming interface is stable, and offers the flexibility to support -the development of -algorithms working seamlessly on both \texttt{big.matrix} and traditional -\texttt{matrix} objects. For examples of this, look first -at the function \texttt{mwhich()}; it offers flexible \texttt{which()}-like -functionality that is computationally efficient and avoids memory overhead. -In addition, all the functions provided by \pkg{bigtabulate} may be used -with \texttt{matrix} and \texttt{big.matrix} objects alike. - -\vspace*{0.5cm} -\noindent -{\bf Underneath the Hood of the Bigmemory Project} -\vspace*{0.5cm} - -The packages of the Bigmemory Project use the Boost Interprocess -\proglang{C++} library to provide platform-independent support for -massive matrices that may be shared across \proglang{R} processes. -Innovative use of \proglang{C++} accessors supports matrices of -\texttt{double}, \texttt{integer}, \texttt{short}, and \texttt{char}, -as well as the development of algorithms working seamlessly on -\texttt{big.matrix} objects or traditional \proglang{R} matrices. - -\vspace*{0.5cm} -\noindent -{\bf Example: Airplane Ages and Parallel Processing} -\vspace*{0.5cm} - -We would like to approximate the age of each plane at the time of -each flight. This first requires calculation of an approximate -``birthmonth'' for each plane: the month of the first -appearance in the data set. Given a matrix -\texttt{y} containing \texttt{Year} and \code{Month} for all flights -of a given plane, \texttt{birthmonth(y)} returns the -month (in months AD) of the earliest flight: -\begin{Schunk} -\begin{Sinput} -> birthmonth <- function(y) { -+ minYear <- min(y[,'Year'], na.rm=TRUE) -+ these <- which(y[,'Year']==minYear) -+ minMonth <- min(y[these,'Month'], na.rm=TRUE) -+ return(12*minYear + minMonth - 1) -+ } -\end{Sinput} -\end{Schunk} -A traditional approach to calculating all the birthmonths might use a \code{for()} loop: -\begin{Schunk} -\begin{Sinput} -> allplanes <- unique(x[,'TailNum']) -> planeStart <- rep(0, length(allplanes)) -> for (i in allplanes) { -+ planeStart[i] <- birthmonth( x[mwhich(x, 'TailNum', i, 'eq'), -+ c('Year', 'Month'), drop=FALSE] ) -+ } -\end{Sinput} -\end{Schunk} -With about 13,000 flights this takes about 9 hours, even with the relative -fast and memory-efficient use of \texttt{mwhich()}. - -A far more efficient alternative is to first obtain a list of row indices -for each plane: -\begin{Schunk} -\begin{Sinput} -> library(bigtabulate) -> planeindices <- bigsplit(x, 'TailNum') -\end{Sinput} -\end{Schunk} -Here, the use of the new function \code{bigsplit()} is equivalent to -\begin{Schunk} -\begin{Sinput} -> planeindices <- split(1:nrow(x), x[,'TailNum']) -\end{Sinput} -\end{Schunk} -but is faster (16 versus 29 seconds) and more memory efficient (with -peak memory usage of 2 versus 3 GB). -Either way, -\texttt{planeindices[i]} contains all row indices corresponding to flights -with \texttt{TailNum} equal to \texttt{i}. This requires several hundred MB, -but is computationally more efficient in this problem. For example, -\texttt{planeindices} may be used with \code{sapply()} in the obvious way, -completing the task in a mere 30 seconds: -\begin{Schunk} -\begin{Sinput} -> planeStart <- sapply(planeindices, -+ function(i) birthmonth(x[i, c('Year','Month'), -+ drop=FALSE])) -\end{Sinput} -\end{Schunk} - -The looping structure \texttt{foreach()} of package \pkg{foreach} -can be a powerful and flexible alternative to \texttt{for()} or -functions like -\texttt{lapply()} and \texttt{sapply()}. It can also -take advantage of the shared-memory -capability of \pkg{bigmemory}. Package \pkg{doMC} provides one of several -available ``parallel backends'' for the function \texttt{foreach()}, allowing -the work to be automatically distributed to available processor cores: -\begin{Schunk} -\begin{Sinput} -> library(doMC) -> registerDoMC(cores=2) -> planeStart <- foreach(i=planeindices, .combine=c) %dopar% { -+ return(birthmonth(x[i, c('Year','Month'), drop=FALSE])) -+ } -\end{Sinput} -\end{Schunk} -The syntax of a \code{foreach()} loop is slightly different from the -syntax of a traditional loop, but its benefits are clear: -in this example, it takes only 14 seconds -to calculate the plane birthmonths using two processor cores.\footnote{We -should note that \pkg{doMC} and \pkg{multicore} are particularly well-suited -for this. When other parallel backends are used, one additional command is -required in the \code{birthmonth()} function: \code{x <- attach.big.matrix(xdesc)} -where \code{xdesc <- describe(x)} would be required just prior to the -\code{foreach()} loop, providing explicit shared-memory access across processes. -In contrast, \code{multicore} automatically operates on shared memory, -avoiding the need for this extra step.} -Both cores share access to the same master copy -of the airline data (with \texttt{Year} and \texttt{Month} cached in RAM); -individual calls to \texttt{birthmonth()} are relatively small in size. -Without the \texttt{registerDoMC()} -initialization, the \code{foreach()} loop would run on a single processor core, much -like \code{sapply()}, but taking about 24 seconds in this problem -with lower memory overhead than \code{sapply()}. - -Finally, the plane ages at the time of all flights may be calculated: -\begin{Schunk} -\begin{Sinput} -> x[,'Age'] <- x[,'Year']*as.integer(12) + -+ x[,'Month'] - as.integer(planeStart[x[,'TailNum']]) -\end{Sinput} -\end{Schunk} -This arithmetic is conducted on \proglang{R} vectors extracted from -the \code{big.matrix}; use of -\code{as.integer()} helps keep the memory consumption under control. - -\vspace*{0.5cm} -\noindent -{\bf Concluding Example: a Big Regression} -\vspace*{0.5cm} - -In addition to providing basic functions for exploratory data analysis, the -package \pkg{biganalytics} provides a wrapper for Thomas Lumley's -\pkg{biglm} package, supporting massive -linear and generalized linear models.\footnote{Package \pkg{biganalytics} -also provides \code{bigkmeans()}, and other analytics may be added to the -package in the future.} The following toy example examines -the airline arrival delays as a linear function of the age of the plane -at the time of the flight and the year of the flight. About 85 million -flights are used (because of missing airplane tailcodes). -We estimate that use of \proglang{R}'s \texttt{lm()} -function would require more than 10 GB of RAM of memory overhead, while -this example runs in about 3 minutes with only several hundred MB of memory -overhead. -\begin{Schunk} -\begin{Sinput} -> blm <- biglm.big.matrix(ArrDelay ~ Age + Year, data=x) -> summary(blm) -\end{Sinput} -\begin{Soutput} -Large data regression model: biglm(formula = formula, data = data, ...) -Sample size = 84216580 - Coef (95% CI) SE p -(Intercept) 91.6149 87.6509 95.5789 1.9820 0 -Age 0.0144 0.0142 0.0146 0.0001 0 -Year -0.0424 -0.0444 -0.0404 0.0010 0 -\end{Soutput} -\end{Schunk} -From this, we might conclude that older planes are associated with increased predicted -delays, and predicted delays in recent years are lower. However, this -exercise is merely for illustrative purposes; a serious study of airline delays would -quickly reject this oversimplification and discover problems with this particular -regression. - -\vspace*{0.5cm} -\noindent -{\bf Additional Information and Supporting Material} -\vspace*{0.5cm} - -These examples were tested both in Linux 64-bit and Windows 7 Enterprise 64-bit -environments. -Older versions of Windows operating systems (including Vista 64-bit) seem -to suffer from extremely inefficient caching behavior with filebackings and -are not recommended for use with -\pkg{bigmemory}; 32-bit environments will be limited by approximately 2 GB -of addressable memory. - -The packages are available via R-Forge and on CRAN as of -late April, 2010; please see -\url{http://www.bigmemory.org/} for more information. -There is a short vignette available in the Documentation area, -as well as presentation slides introducing \pkg{bigmemory} -and providing some benchmarks and shared-memory parallel programming -examples. Please do not use the older version of \pkg{bigmemory} -archived on CRAN (versions <= 3.12). - -\newpage - -\noindent -{\bf Citations} -\vspace*{0.5cm} - -\begin{enumerate} -\item The Bigmemory Project, \url{http://www.bigmemory.org/}, the home of \proglang{R} packages -\pkg{bigmemory}, \pkg{biganalytics}, \pkg{bigtabulate}, \pkg{bigalgebra}, and -\pkg{synchronicity}. Packages available from CRAN or R-Forge. - -\item 2009 JSM Data Expo: Airline on-time performance. \url {http://stat-computing.org/dataexpo/2009/}. - -\item Thomas Lumley (2009). \pkg{biglm}: bounded memory linear and generalized - linear models. \proglang{R} package version 0.7, - \url{http://CRAN.R-project.org/package=biglm}. - -\item \proglang{R} Development Core Team (2009). \proglang{R}: A language and environment for - statistical computing. \proglang{R} Foundation for Statistical Computing, - Vienna, Austria. ISBN 3-900051-07-0, \url{http://www.R-project.org}. - -\item Luke Tierney, A. J. Rossini, Na Li and H. Sevcikova (). \pkg{snow}: Simple - Network of Workstations. \proglang{R} package version 0.3-3, - \url{http://CRAN.R-project.org/package=snow}. - -\item Simon Urbanek (2009). \pkg{multicore}: Parallel processing of \proglang{R} code on - machines with multiple cores or CPUs. \proglang{R} package version 0.1-3, - \url{http://www.rforge.net/multicore/}. - -\item Stephen Weston and REvolution Computing (2009). \pkg{doMC}: Foreach parallel adaptor for the - \pkg{multicore} package. \proglang{R} package version 1.2.0, - \url{http://CRAN.R-project.org/package=doMC}. - -\item Stephen Weston and REvolution Computing (2009). \pkg{foreach}: Foreach looping -construct for \proglang{R}. \proglang{R} package version 1.3.0, -\url{http://CRAN.R-project.org/package=foreach}. - -\item Hao Yu (2010). \pkg{Rmpi}: Interface (Wrapper) to MPI (Message-Passing Interface). - \proglang{R} package version 0.5-8, \url{http://www.stats.uwo.ca/faculty/yu/Rmpi}. -\end{enumerate} - - -%\end{raggedright} - -\end{document} +% \VignetteIndexEntry{The Bigmemory Project Overview} +% \VignetteDepends{bigmemory} +% \VignettePackage{bigmemory} +% \VignetteEngine{knitr::knitr} +\documentclass[12pt]{article} + +\usepackage{graphics} +\usepackage{graphicx} + +\usepackage{accents} + +% New from euler: +\usepackage{ae} +\usepackage{color} +\usepackage{url} + +\topmargin=-0.85in +\textheight=9.5in +\textwidth=6.5in +\oddsidemargin=0in +%-0.25in + +%\usepackage{CJK} +%\usepackage{pinyin} +\def\E{\mathord{I\kern-.35em E}} +\def\R{\mathord{I\kern-.35em R}} +\def\P{\mathord{I\kern-.35em P}} +\def\I{\mathord{1\kern-.35em 1}} +\def\wt{\mathord{\widehat{\theta}}} + +\newcommand{\proglang}[1]{\textbf{#1}} +\newcommand{\pkg}[1]{\texttt{\textsl{#1}}} +\newcommand{\code}[1]{\texttt{#1}} +\newcommand{\mg}[1]{{\textcolor {magenta} {#1}}} +\newcommand{\gr}[1]{{\textcolor {green} {#1}}} +\newcommand{\bl}[1]{{\textcolor {blue} {#1}}} + +\newtheorem{thm}{Theorem}[section] +\newtheorem{myexplore}[thm]{Explore} +\newtheorem{mybackground}[thm]{Background} +\newtheorem{myquestion}[thm]{Question} +\newtheorem{myexample}[thm]{Example} +\newtheorem{mydefinition}[thm]{Definition} +\newtheorem{mytheorem}[thm]{Theorem} + +%\pagestyle{myheadings} % Go for customized headings +%\markboth{notused left title}{John W. Emerson, Department of Statistics, Yale University \copyright 2009} +%\newcommand{\sekshun}[1] % In 'article' only the page +% { % number appears in the header. +% \section{#1} % I want the section name AND +% \markboth{#1 \hfill}{#1 \hfill} % the page, so I need a new kind +% } % of '\sekshun' command. + +\begin{document} + +\setkeys{Gin}{width=1.0\textwidth} + +<>= +library(knitr) +opts_chunk$set( +fig.path='graphics/stat' +) +@ + + +<>= +options(keep.source = TRUE, width = 75) +@ + +\begin{center} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{\Large\bf The Bigmemory Project} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\vspace*{0.5cm} +{\bf Michael J. Kane and John W. Emerson\\ +Yale University\\ +April 29, 2010} + +\vspace*{0.25cm} + +\end{center} + +%\begin{raggedright} +\parindent=0.5in + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{quotation} +Multi-gigabyte data sets often challenge and frustrate \proglang{R} +users. \proglang{C/C++} programming can provide efficiencies, +but is cumbersome for interactive data analysis and +lacks the flexibility and power of \proglang{R}'s rich statistical +programming environment. The package \pkg{bigmemory} and sister +packages \pkg{biganalytics}, \pkg{synchronicity}, \pkg{bigtabulate}, +and \pkg{bigalgebra} bridge this gap, implementing massive matrices +and supporting their manipulation and exploration. +The data structures may be allocated to shared memory, allowing separate +processes on the same computer to share access to a single copy of the +data set. The data structures may also be file-backed, allowing users +to easily manage and analyze data sets larger than available RAM and +share them across nodes of a cluster. +These features of the Bigmemory Project open the door for powerful and +memory-efficient parallel analyses and data mining of massive data sets, +even on modest hardware. +\end{quotation} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\vspace*{0.5cm} +\noindent +{\bf Introductory Example: the 2009 JSM Data Expo} +\vspace*{0.5cm} + +Consider the complete airline on-time performance data +from the 2009 JSM Data Expo. The processed data set, \texttt{airline.csv}, +is approximately 11 GB (about 120 million rows and 29 columns) +with factors coded as integers (see \url{http://www.bigmemory.org/} for +processing information). +The \texttt{read.big.matrix()} call creates the binary +file-backing \texttt{airline.bin} +associated with the \texttt{big.matrix} object \texttt{x}. +Subsequent \proglang{R} sessions can attach instantly to \texttt{airline.bin} +without incurring the one-time overhead (about 25 minutes) +associated with creating the backing. +A summary of the entire data set is easily obtained using the new +\texttt{summary()} method. Note the surprising +presence of negative arrival and departure delays: exploratory data analysis +in action via \pkg{bigmemory}. The summary +only takes 3-4 minutes to process the 11 GB of data on a laptop with only +4 GB of RAM. +<>= +library(bigmemory) +library(biganalytics) +x <- read.big.matrix("airline.csv", type="integer", header=TRUE, + backingfile="airline.bin", + descriptorfile="airline.desc", + extraCols="Age") +summary(x) + +# min max mean NA's +#Year 1987 2008 1998.62 0 +#Month 1 12 6.55 0 +#DayofMonth 1 31 15.72 0 +#DayOfWeek 1 7 3.94 0 +#ArrDelay -1437 2598 7.05 2587529 +#DepDelay -1410 2601 8.17 2302136 +#... (other variables omitted here) ... +@ + + +\noindent +{\bf Overview} +\vspace*{0.5cm} + +Data frames and matrices in \proglang{R} are easy to use, +with typical manipulations executing quickly on +data sets much smaller than available RAM. They suit the needs of many +\proglang{R} users and work seamlessly with existing \proglang{R} functions +and packages. However, problems arise with larger data sets and when +increased memory requirements of parallel programming strain the system. + +The Bigmemory Project offers packages +for two purposes. First, \pkg{bigmemory}, \pkg{biganalytics}, and +\pkg{bigtabulate} have been designed to provide a minimalist, +elegant framework for users to manage and explore large data sets, even +on modest hardware (expensive workstations or clusters are not required). +The interface is designed to mimic \proglang{R}'s familiar \code{matrix} +syntax. Matthew Keller, Assistant Professor of +Psychology, University of Colorado at Boulder offered the following +testimonial about \pkg{bigmemory}: ``I love that it's intuitive and +doesn't require a lot of learning new ways to code things.'' + +Second, the packages of the Bigmemory Project provide a foundation for +memory-efficient parallel programming and can serve as building blocks +for developers of new high-performance computing tools in \proglang{R}. +When used in conjunction with a parallel package (such as \pkg{foreach}, +\pkg{snow}, \pkg{Rmpi}, or \pkg{multicore}, for example), +even shared-memory parallel-computing becomes +accessible to non-experts. +The programming interface is stable, and offers the flexibility to support +the development of +algorithms working seamlessly on both \texttt{big.matrix} and traditional +\texttt{matrix} objects. For examples of this, look first +at the function \texttt{mwhich()}; it offers flexible \texttt{which()}-like +functionality that is computationally efficient and avoids memory overhead. +In addition, all the functions provided by \pkg{bigtabulate} may be used +with \texttt{matrix} and \texttt{big.matrix} objects alike. + +\vspace*{0.5cm} +\noindent +{\bf Underneath the Hood of the Bigmemory Project} +\vspace*{0.5cm} + +The packages of the Bigmemory Project use the Boost Interprocess +\proglang{C++} library to provide platform-independent support for +massive matrices that may be shared across \proglang{R} processes. +Innovative use of \proglang{C++} accessors supports matrices of +\texttt{double}, \texttt{integer}, \texttt{short}, and \texttt{char}, +as well as the development of algorithms working seamlessly on +\texttt{big.matrix} objects or traditional \proglang{R} matrices. + +\vspace*{0.5cm} +\noindent +{\bf Example: Airplane Ages and Parallel Processing} +\vspace*{0.5cm} + +We would like to approximate the age of each plane at the time of +each flight. This first requires calculation of an approximate +``birthmonth'' for each plane: the month of the first +appearance in the data set. Given a matrix +\texttt{y} containing \texttt{Year} and \code{Month} for all flights +of a given plane, \texttt{birthmonth(y)} returns the +month (in months AD) of the earliest flight: +<>= +birthmonth <- function(y) { + minYear <- min(y[,'Year'], na.rm=TRUE) + these <- which(y[,'Year']==minYear) + minMonth <- min(y[these,'Month'], na.rm=TRUE) + return(12*minYear + minMonth - 1) +} +@ +A traditional approach to calculating all the birthmonths might use a \code{for()} loop: +<>= +allplanes <- unique(x[,'TailNum']) +planeStart <- rep(0, length(allplanes)) +for (i in allplanes) { + planeStart[i] <- birthmonth( x[mwhich(x, 'TailNum', i, 'eq'), + c('Year', 'Month'), drop=FALSE] ) +} +@ +With about 13,000 flights this takes about 9 hours, even with the relative +fast and memory-efficient use of \texttt{mwhich()}. + +A far more efficient alternative is to first obtain a list of row indices +for each plane: +<>= +library(bigtabulate) +planeindices <- bigsplit(x, 'TailNum') +@ +Here, the use of the new function \code{bigsplit()} is equivalent to +<>= +planeindices <- split(1:nrow(x), x[,'TailNum']) +@ +but is faster (16 versus 29 seconds) and more memory efficient (with +peak memory usage of 2 versus 3 GB). +Either way, +\texttt{planeindices[i]} contains all row indices corresponding to flights +with \texttt{TailNum} equal to \texttt{i}. This requires several hundred MB, +but is computationally more efficient in this problem. For example, +\texttt{planeindices} may be used with \code{sapply()} in the obvious way, +completing the task in a mere 30 seconds: +<>= +planeStart <- sapply(planeindices, + function(i) birthmonth(x[i, c('Year','Month'), + drop=FALSE])) +@ + +The looping structure \texttt{foreach()} of package \pkg{foreach} +can be a powerful and flexible alternative to \texttt{for()} or +functions like +\texttt{lapply()} and \texttt{sapply()}. It can also +take advantage of the shared-memory +capability of \pkg{bigmemory}. Package \pkg{doMC} provides one of several +available ``parallel backends'' for the function \texttt{foreach()}, allowing +the work to be automatically distributed to available processor cores: +<>= +library(doMC) +registerDoMC(cores=2) +planeStart <- foreach(i=planeindices, .combine=c) %dopar% { + return(birthmonth(x[i, c('Year','Month'), drop=FALSE])) +} +@ +The syntax of a \code{foreach()} loop is slightly different from the +syntax of a traditional loop, but its benefits are clear: +in this example, it takes only 14 seconds +to calculate the plane birthmonths using two processor cores.\footnote{We +should note that \pkg{doMC} and \pkg{multicore} are particularly well-suited +for this. When other parallel backends are used, one additional command is +required in the \code{birthmonth()} function: \code{x <- attach.big.matrix(xdesc)} +where \code{xdesc <- describe(x)} would be required just prior to the +\code{foreach()} loop, providing explicit shared-memory access across processes. +In contrast, \code{multicore} automatically operates on shared memory, +avoiding the need for this extra step.} +Both cores share access to the same master copy +of the airline data (with \texttt{Year} and \texttt{Month} cached in RAM); +individual calls to \texttt{birthmonth()} are relatively small in size. +Without the \texttt{registerDoMC()} +initialization, the \code{foreach()} loop would run on a single processor core, much +like \code{sapply()}, but taking about 24 seconds in this problem +with lower memory overhead than \code{sapply()}. + +Finally, the plane ages at the time of all flights may be calculated: +<>= +x[,'Age'] <- x[,'Year']*as.integer(12) + + x[,'Month'] - as.integer(planeStart[x[,'TailNum']]) +@ +This arithmetic is conducted on \proglang{R} vectors extracted from +the \code{big.matrix}; use of +\code{as.integer()} helps keep the memory consumption under control. + +\vspace*{0.5cm} +\noindent +{\bf Concluding Example: a Big Regression} +\vspace*{0.5cm} + +In addition to providing basic functions for exploratory data analysis, the +package \pkg{biganalytics} provides a wrapper for Thomas Lumley's +\pkg{biglm} package, supporting massive +linear and generalized linear models.\footnote{Package \pkg{biganalytics} +also provides \code{bigkmeans()}, and other analytics may be added to the +package in the future.} The following toy example examines +the airline arrival delays as a linear function of the age of the plane +at the time of the flight and the year of the flight. About 85 million +flights are used (because of missing airplane tailcodes). +We estimate that use of \proglang{R}'s \texttt{lm()} +function would require more than 10 GB of RAM of memory overhead, while +this example runs in about 3 minutes with only several hundred MB of memory +overhead. +<>= +blm <- biglm.big.matrix(ArrDelay ~ Age + Year, data=x) +summary(blm) +@ +<>= +#Large data regression model: biglm(formula = formula, data = data, ...) +#Sample size = 84216580 +# Coef (95% CI) SE p +#(Intercept) 91.6149 87.6509 95.5789 1.9820 0 +#Age 0.0144 0.0142 0.0146 0.0001 0 +#Year -0.0424 -0.0444 -0.0404 0.0010 0 +@ +From this, we might conclude that older planes are associated with increased predicted +delays, and predicted delays in recent years are lower. However, this +exercise is merely for illustrative purposes; a serious study of airline delays would +quickly reject this oversimplification and discover problems with this particular +regression. + +\vspace*{0.5cm} +\noindent +{\bf Additional Information and Supporting Material} +\vspace*{0.5cm} + +These examples were tested both in Linux 64-bit and Windows 7 Enterprise 64-bit +environments. +Older versions of Windows operating systems (including Vista 64-bit) seem +to suffer from extremely inefficient caching behavior with filebackings and +are not recommended for use with +\pkg{bigmemory}; 32-bit environments will be limited by approximately 2 GB +of addressable memory. + +The packages are available via R-Forge and on CRAN as of +late April, 2010; please see +\url{http://www.bigmemory.org/} for more information. +There is a short vignette available in the Documentation area, +as well as presentation slides introducing \pkg{bigmemory} +and providing some benchmarks and shared-memory parallel programming +examples. Please do not use the older version of \pkg{bigmemory} +archived on CRAN (versions <= 3.12). + +\newpage + +\noindent +{\bf Citations} +\vspace*{0.5cm} + +\begin{enumerate} +\item The Bigmemory Project, \url{http://www.bigmemory.org/}, the home of \proglang{R} packages +\pkg{bigmemory}, \pkg{biganalytics}, \pkg{bigtabulate}, \pkg{bigalgebra}, and +\pkg{synchronicity}. Packages available from CRAN or R-Forge. + +\item 2009 JSM Data Expo: Airline on-time performance. \url {http://stat-computing.org/dataexpo/2009/}. + +\item Thomas Lumley (2009). \pkg{biglm}: bounded memory linear and generalized + linear models. \proglang{R} package version 0.7, + \url{http://CRAN.R-project.org/package=biglm}. + +\item \proglang{R} Development Core Team (2009). \proglang{R}: A language and environment for + statistical computing. \proglang{R} Foundation for Statistical Computing, + Vienna, Austria. ISBN 3-900051-07-0, \url{http://www.R-project.org}. + +\item Luke Tierney, A. J. Rossini, Na Li and H. Sevcikova (). \pkg{snow}: Simple + Network of Workstations. \proglang{R} package version 0.3-3, + \url{http://CRAN.R-project.org/package=snow}. + +\item Simon Urbanek (2009). \pkg{multicore}: Parallel processing of \proglang{R} code on + machines with multiple cores or CPUs. \proglang{R} package version 0.1-3, + \url{http://www.rforge.net/multicore/}. + +\item Stephen Weston and REvolution Computing (2009). \pkg{doMC}: Foreach parallel adaptor for the + \pkg{multicore} package. \proglang{R} package version 1.2.0, + \url{http://CRAN.R-project.org/package=doMC}. + +\item Stephen Weston and REvolution Computing (2009). \pkg{foreach}: Foreach looping +construct for \proglang{R}. \proglang{R} package version 1.3.0, +\url{http://CRAN.R-project.org/package=foreach}. + +\item Hao Yu (2010). \pkg{Rmpi}: Interface (Wrapper) to MPI (Message-Passing Interface). + \proglang{R} package version 0.5-8, \url{http://www.stats.uwo.ca/faculty/yu/Rmpi}. +\end{enumerate} + + +%\end{raggedright} + +\end{document} diff --git a/inst/doc/vignette/Overview.pdf b/inst/doc/Overview.pdf similarity index 55% rename from inst/doc/vignette/Overview.pdf rename to inst/doc/Overview.pdf index f49394713b69bcdccb514a821fe001e2e05e64e2..13ce8b51ac5d58cd3df29c73eabf1d03278a8eeb 100644 GIT binary patch delta 71146 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 delta 52744 zcmc$`1zeR)(=ZN5OLubw={Ufl8W8omQ~ z-`>yj-p}(s|L^~MzgIcSp557*Yi4I=XRh6)YYOE<4>B!{@?%LBc2-VQnvu^Rr%)jv zHjurEHAqkp6)bOVXX)}31YzTWBvX^V8}f?9ZxL z^a=JBQXmx+j`OB9R5@%$oQSlv^a`ggk`PAM1y!q}~|< zUOx{=zq8tyXRsVZC`}TwIv3RK<{k{4%outJ(9^xQ>ZC^V*^dWP7syMaDEvY^z560q!muXz9Sq z5n;IAOn9jwF)-jqiEiBPOT=x82Y{CdYNK!*s__oΜL$h3cGlm!nQR2tIiBk;_SF zK~}BkJ@X=Ss)r{ZMgx-e4k;&Q3A6kvVg(S&jRN4l?mmt$anL_`ZiI&0#=Yc|s}OJA zmIFT}9EIztjyShR#0ML#`O zFy-)w+cA{LG6NURMLgO5Y>B3AQ9uN?-X;>6yJcmJ%ogNjuT-QhM%Z0?EX> z6H4^zXFB)k3C8ueDZIY)?!Mm{Kcz?eP&#?eMNJgo_$|HLrtN;A2|CfH^PV4bZY4Wu ztIo41y7Bb~pQpw09?FCgjJhxx30euNz6fr{IyW<_Ak;V)c60|tS*(oM0LxK9dDM-j zkMdTFAH^uoj^d9`=eFT1e5QlFe2k!nLq=)n@I>|lzR;W0j*k6h|1i_k6|n1Z_hASA z3VL_}$~=rlsJ_6vaxiyC+y8d%RxaRV9^Wr^QrdJN(eUDfga#x$j&GOge+iy3C^oSQO<_{^_xH zrL$VTne?GXh16{AdT@w&m-meJ+S8*8MGoXd5#NbM4!erxRH$`oUGfXhE_yHbVV-c* zp2DM-Y~ar0q(`kU1jg%I!-wW9U%s09Sb}*$#&jReYp{DbQ+nzJ@*s{TnwN{mz#^92 zw=|^$Nj_a1>>8)q_`pd~V9-j!fZlE7qGc&c7z(jor54__uee97xduE#doje^E3 z!`1R;u%qW;#2XmSd*}*oLoyG7;=+kfV&k3i6-r8w96Dd|rbl*A$OEy1L3ump?6c(! z6azRh{@=IRy-;egCV@{Vbh?)f=&!Ev3{y&G4boW)mPcoRHo%+lCk_*>nN!$MwB065I#($ z1n@KP=xDrIB`6(nbp#FIN-g?SJA``n*o>G`j2C^!ugl3aZvsC_ut~W}W9)ix(D4Dl zSF~f%A!W6f3b4%p0C%2O{axN4DSRdeGvCOSIKvP6*(e%zP;M`@bY}XVicbY}I!6*U zlq|$VS#C| z&kr8s(+ec2!;ql+sAN{hJwqzioCXR+jTazzS(Gt7gy>NYP;Gm2b%AC&WiKJr&1<81 z8u39@-*a?!gkrik$oWfUf(eoG8_6e?=_hyJD3H~zl=T$9ZScoWr%wqI z1C8JFv8IAsbI*$oS4dV|v3GnFEh`EJKWX-EHwvoWBNQv5wiR_sH&#q4j~o^s6&c1! zKp}%QiE@pI0i2f0d5xMWJUqUM{>IqHWqSLCrih<=k9= z%vi?RA*57QMvGF~@YqMRo-CILhqj2I9dGMx{}Y*GKLFq0nccR0E^^sNkSg1klzVV* zloP|#r2>+oWzT0OI!dd?^QyjdeT1C4%fSW@R4(QL_Gxy9w*YIY)AFXr{MLh+qI`DC?-U-?Sf7ebpQ0#c{$eGOw6#esa?&$5cTa1Qws3u=kyC<2Bm8Z z4(dwjhx7ZB*$l9+yQ>T5WnVp`6<5eOkeq)gE87;{vdLHMgz;hK@tF_786mUJOWTYW zM_`W9ek9__Y|5dHgTcq1G-BM^87494z&P**a9uqDWf`)TvVa1jWJ-Oo2FqTfvT7a_ z33a3V&{DF_IXlk%$agjkVx9CY=T^H?diJ@O9TQvdYbdS2V&0gcM99(jr=IVx16)O7 zE}By!f-cI-io09zJ?bsYTnJm;7w7k;-1C^|y15;f%KV7Tx(!1tf$Zua@<#&aqqJ`* z0g`zAD?AzD*L>9j@jNyQY8`Lj-l!+xyH~8JsXeMdagmJ(2|<@eDkza{>sj4Cd%!69 zQRE5I#Opc<^ZQGioyhqPEWGc%GfLcocfnjb)y{Egb1?xeygqYT_z!~XE;FF0V<9vSe+=ezGckNQa;tLd%JP7#e|7&astvluz# zLjV(YhD=s;$Qzg1?S>rv-f{z#lC(N^K25qnHMcW!c5yN{w!NuAvjor^Q*Ce2Vq1*@7n+q*iMnmdEo?-~@$&8&>Y?L9!cY|sX7b`B5^ABR3F zbhwkb9pD1uy9E;#2K^#*GwhFaMG}e}nzw+!k`N9M=M5mV%FYGi`c>uR1abdSU-U?!oI#)HH^n~^BrZPQy98-m zSI2p-3)}a&+~^xkzx4fkf$#G>i{i-o-BgPU$(r<7XE8@ulky~X$0G6{YcgI7`3(7! zzl_{T7F3Qfjn2y2EpOZPKZrk!zgX#4ays>K{n`7bT+Ue)Pe)5*b;ZVcEG52xQ)fDf z&T=cBlHgj9g@95~uA1m4<-!5ZRd5XOMkMp{^3$XQz8mvae7;q6(|W`5*Bo=89Z*a* z&jNElZ(=2wFzecua(XvLG;nAI3f8ya0%`?9A8rivlS3j*R(5*mct|O2%5l5;qT&ogDbe~#H zGU(rAwIZ-%3&(RWOdKy|zEYjfT7IIKBr$2G@acWf;M-CU?6#f?PNBX-gH^xUlrB~` z-79@0*`0kAg!m6;NLl3H%as)5Ohh*rDSRqN{eKzo!c>PBAAILpUtg@EN5T~JZP%3 z-b}=x&sSCS7wcUJzMXR4=i@$S2g^EAcomcoWQZ5?x*O*_vGI7?P={7Zsp2p2^;omu z9c&1aYxEGt;%;rRA>l~|`TH4qL0C9Z8(b-mHxZx6;|<$7Uw}0h>=Gk@2faGhdv)Ag zVKeip?Rf(b-GpwV4?PQk?Xs{>86!(MOs&Cag~e#hf)7Z=jWY3eu|RHkh0>6)-gJ&< zCE_8u+U@LqAQ&pM`=*PE=u0LiW-MM5R!@SCxY`ohBa$(AJfsPnS>D6UA79{leayEp z1SEJQcl;7KUWQ~kw^OwNFRr5Yu)laq+6CK6Qh@MjUd+(1@C&e{(TldFL!Ebc8=z;alQ87wOeb&jYueS0H&EWwM+sc)t`SY zBz(W;#bip>phglp3I9mLpI#*aW2WLd-wA=IH@Ka_gQc23(=%QFFweTeb(wj8=G2Bt zJJ~f};|KLauHge!-HTDV%8kI$@|9$sh|88}qhk21C69sHu{|NTCOL)sPu0yNbmZ%{ zg+HqTQeyY~pY2OlE&>jVEg@)&l#fL5r>_?_`W;=o3yw|4n(ImSxaA|=p4+#RT8RfB zvw!o^is5S$v5itZEQRx@qk2u9*g5fr8rba``)szO-*6m#U`@DSGS)KL7d=ab0hqDa zV(;rTeAzCW;}9jL3|ucOMe4pTyBE`F_A*fOG}kgzV-Z7U01Uu<6udqs|1f_)qs8Dt zJAr`TJIcMQ{IM}CWfSLOdx@&`o8T`5{?uMq-?>N8@%Fg4Ycz-Nk=vTL+zYI;+GMtG z_Hd3~d|#cL1(XTqfSkYBo+LA;Uf7VTv3WOslh^hXc@nwu;zK?ch3Kq?U;D)iz3v#~ zOpcQ^Om?RD!b311i|(#?e??~^Wu%xHo}XsBuYz|E8KpMsMbc)2%OxX6D0P-D>%0>i zL6-ZT^B{s%#@jUuQX3~y>3O8*E!4ZVdg>oBDzT2U*cFO4VT3iQ+4RE61+@(DT0)V3w8laAS~(>9T3i|AC`zOcZ^|iea)G3w%WY>fC6yqPtl1?FQTytK5m( zN70_j@PE@O?1);{cy3i1ikLh^yLd*m_alODA#Ri&ezVRHq88_Yj7yF5MIR|Bk{6QC z%}U0KJR|ALZ&+2dakl?-U7D5vLsago)mSi({QC*-4(HKt)**41%wt`rWt=FV>>hm% zfzRS1vwKhVGL>7*m@R^e9k^R$Sp{3DXs2Lw@##vCiIhcD2gEM`GPY#MT#EnD}( ztej)1Ir2M!Fm%N7*{x^TX{Xt^_(%Hq z*zGfj?e|jE+AnNBA*!jZXg%P(RSPx4-f18v)`v7xf|%GrC1iD`Q8p_A+O>o0AF z=EGF3DFdwKFNT`YuZzhuz6bCpM|+o&(PvMfnVLzcAZdt9VoGT(+2(ha^#0skaHLX1 zu`#erRGN~JLDo-YYKZrPO#8b;^U4qr-Dj9O7JHjMK?p04>s0Hhss8QyW$~0?iQw7x z(++ZW<7agh_~qa82A(3J9EPR4F<)l8P9;tCNiZwo z%-8^2MiS~{p@;?T0tz2brSjaC7cpWatAWjam=W+Qb>CE3rlLQXx$4UweTH2O(Lr{Mhh}xI7prPczj| zM`m(4ltC=`=(6njV9q--hsU@xv)4xVdesZ)t@%mPT-QtT>4Nd1wB&6Krf3#zmGEjM zra8krdZlpxz95ZY(Io+mA?A7Mfr8*S<{x-=3tQzioFB|R;jScA&0U1;ENL>2m}M~0 z77}UWY9H7|ABZfHO=rra?7laJ_b8RNYdSf4oi69JfmS9o4zskkW7HYjJ#%JYWsd5-6l)1S%e`+HqCz=OmYj$) zE&pIzo;`W+MG+cjxLPV(jDNCO-<1HelaTon37+9_xe=95Q-*{BERUNv{ihg0DkUcB zQ0!WcgXZ>LEI4^Zf9#WKurRHfTjK$$DW9fr7jQMvD&{ei%5)usqtdF>Tr9EnOxl+P z6T%4S*L%pgekYaqSqlFnS)Gc4Pw>-ylr8)H2(aOh!?#bM@MOk}tSXz~Y@DGs0bAlR zo8_Hv6B@D`r<}y?mQNJw^{yIX+k`5|n)lF%#tB`<8luRDFKe9;`dwcc$hoxxwYi`M z^d`!a9}kE)1oJ#U^u+0(HZgmV1P7PtWCZnEHmwUO2yCSd^8;bg+zukoqJ=)Dt3X-Us=ti${HX95Vd z!No1RTNWHu-r@*8?o}z>s8X>2qXPchl=VOeP#R=PTEy`QTk*nQ!9^Iee4`mWqwA0l z7HXT`G&^!$*>mq@Q~CC?wHXT#(PDL{Zwx;g3;8MopB=9-6t(rXgk0O_`_Q|%%EH07 z-7DQ{l#@qMs|6tu#7Rref|j5{)-db*%2-_e6L2X}zcbq54ttV)?!7kPa6QFwOGG=u zhE)dViII;jVbE(IqWi9{WpGX+T5wkVZ}$nJ$?csu&0{1A_!I-xmO{ zE&^G37K;>fM+#*p$8cTG0C!Z_tW4I3;;@pLuSjoL&tEroB)u0DIk6w=ql(@^$N%w# zki2&pPf2!p8uwlr>dE8tb&sI}-z6%nzA{0Y`--Q+fg+Lo9^ru!e&7Hvay$J*e1&w) zw0ivHJo$tl?8uhJu!q;;R@uE@TWke&)E2SqDY(8P$!}|ab0&dzv;ho6bOO6oX%G>j z_0kS{O|NMC1HD203ds|1C?XYKsn!HpdLmw3xttYRiU??)4j}ff;=M}n%vkL;x|V_U zVLhS4JNfpo)MH`5?1S8kFbOl6lu%zQj^UF4do6EHpl)_O$%j^q6 z^Su#{cy@GL;IFys-zLeox#mA+$v0UswB_HX$$yh2-wgZbG#U6G%ad=?RQU(=9J{dS@Y_?JZO|Hb@DU5O>Vn{eq znpyd14p))MMDO5Teig`A+^cM^GN*$*5SvG8Tye;1BOV)Hxy(!RJ}pL_oU|+#_B9=N zEIaz7gw~QU{)vKh=?lA~6&t=&yR)_UR1GhFk=Rcqd(9|X*SjRXEJ8_^`+L7xUmqVuQb`WydMg(sr>^OZOK|R;af+Jp%$n-vK6#J^~$xcTz%lt8MExM3B zjx(bfTAe|VrpWv`+XP^~d0L|fw?9o%EZV{p+UCbf`Vfb*K{XYw;A+=hyBw zT_PC+d8OZCFQ|m}@mfgtb_Hu}AVY6E#LLd-K7h5qdzUwlY)WY-c(;n=r4{?1%aWH0 z4Nnd%cMB_gAkNp2dzC2c)qug`IzX0KQ7q(@kz@bHjID`FT*D41gmtB6sUp`A?y}Bl zvzr?|yb>tHDjJ&d(^RkHn=i?@f*Uxo$cYj$RE~X5e`P*$t-#i!w0Ml@oBjT~{rlW^ z(i8D|sffOXbrjNF$7htIFwPd7e#9lR+LNl2^(74jsb!lR7Z+v)WMhtUS&CYNpVf+E zpX@zbncKTOPONzku+A?N6~BM)_O3B1sd-6D!R0=sqWYj%cN=APJx%TfQTl9qE_sE# z+*ll?XTq~hfRJ`JWSk9_oa=S6g=MYbC=7bN!AX6y&q84GkGS2|^o@zp+P;krn*nOK zcJ#H@5yqzHW=K6fi@9$8IBi1_Ih19gv$Yk$`0$yePGI+E0Q2cPZ3QN?8V<3hQO(>p zMA@U;gl75%o;{!JaLpa@{S)<{1Z57D2h_RD8etsnnIz`<3+b$|Em81=)U(wYvj;zb zZb-vVRR^|WsEvLL9}j6Z9FaC-?u#JH*7DDy2?=1ucBowZ#(%(aUum5Noj24lJ5py? zUZ5(yDYRbx3*f1Zhtv{+_hJZgZuCtA^NDXFd&P79rkJ3a_f424jTtZX367^>1@Sq} z)gm-!4cVXeEw`RMfTS>(J|6#^AAgQIUMoNowx;OMQq5FbG8vRg?y?hLydS`o9ncXf z(NEI3PBl$`4^MRE>I$X9P4g)(ivXk~8kR3Ls}_44pB8BT8o60LR{FHqOTGxmN)yU` zA{_3GgScemu4QdNj88cTPOyVP>G>Kgyn6aknGRcMBVck(C+Ar@{bU`&+O|%^_kiI5 z9^!Md)>jolc1PSkMGJNLvzgc4mBz6&g5OEkR8n}|v0-yOiFVh8JPVmSCAglE=2eEi z+uKEa#P0>nVOkY)9^Gs0#P>*>cMm$e@0t32a}Wnl?=(V21!%snH>c8E(4V}w>N@gJ zEZe)X4=2n{4*dOs*SRe;Bwn&I=?B`BjB)(rqe00li4tw6P|4@*oNHfFNNN;`i2b)r z;$h(SLUx`>B@8m~b(~X;=?LI#e2}`2M}_L-jytLj%qJcwZOhxis*eR|)i*`*ysj7; zHgUnIl$=7Cvv$!9e;~OEA;5~4nRguUN42sMmxO$p z+R%xXRgnJb49M!`b?GM$u#Dw}GSw4@)azF;oUEo#u6*?Fp8Fg%^hSb48!5!IALbPr zV_f2UVD>?{e3LBir$=t1g)P|W1xS*w^V4Wem_MQIHCn~Sv6xmdacdc+m*SZ{G@?Z- z$Z>Y3)UF!J@a3_V62|a6)~{-ZmJhkYdZ#4mMFCJyidTC85&E-}SOnj6xQlinV?nSB z;%V!5onx#vw%s`&=>@@%>1Z-Y31-U#zP|exDtD@86$d@?2&$~I*E`}{3U%#h@*% zUKk|9Bws30+G0uV5rGok0JtPg1B1JPNd`re6X zLe$H9o*sAy zwqG>oZ0Lht#HS?@10o9>CPOKvQN1MuwJa4S9G?IXv$h9Ldjk6Yat;^M;!I&vKiez! z5r9}@R#v?j#_GX&p%`k79}V?##m}uyz~F6`2RC8-srDAG4~%&+&EL`Dr%?x=W>OZU8rak^G#b&cujT|r6U&T;^V5WY z_og)0`^uQFk2b@^Wogd@P%`$`BmsRxg9U`7t=Y#Ik*unz1^cOHjw> z8`g<1t$dNg)~qlkh86->5A{0h0``w8ukW9*&K!DJv3A~o13vKv_9WE~%~50STRm0E zIei`ZrE$ZTv+li3Ke~m1RCIP($PeI$AyQ1gq`0+*pzLM--buW}+!bniGFWVRc&?R< z!VD%5X^K9(EpS?Dh0Cl2Q$l5DzKshn$(qust33f%!4@D`Ez?cxU_UTUCr!(cW6I+H zDf4|Pr9sRw&g{8<&I41r}ONE=}|+2$*#R)y^)1J=@xz|al+e$ z#QOU4SVp{uVH!CIy?rpN(et2P3*z=_E%`@*7^v%KY8vr>~2@hId(Z>(o!CU$DVyywvQlZ4>K0_#He|gYNT!~@ZH#>%COPu+raD^iEZ`Y(so*dS45Y`G_r&|@ zGAfw1Nf;E&k2YUEWo4O_U6;hS8cj;V8W$E6TJ+pdj*IVbp^QjL6!e%|X3Y0&cFiR- zWP4O>WGUjRe#H&*`0FZ=E}iZnPoo5piifA$#EXul?|j*O!TfOzn_swcy8xdxpR8ot zk2dg>Z);D8RXw{ULxVPND;!bKa1{w$PLDv(O!J1CU?nQZSz`C$FcxIUO!T~?y0 zicn>8zli=!<39R~t#i@G6{ASv=Tzb=YN+nd=7+*U9z`>D(d(iBMRQ;kdXyI{?>{$g zx2x+Iy0AV}?U_39&t!Zw>AR8ju9ur0^nkFqa+wrwS}d@qFQEn-12(>)KPH9&5uGfi zX**IyOI>?!0n;K_kEX$FrG;6^Y56IhHH%1i=h29t*;@Ly-jt&{> zH_J$}!8#f}FDmWufoXnBD$=iIIv@E}=IEQGzgBhx^d7d(EM4eNjfd%)^;samW}8!f zV9NuiSa&~KHOy!|TTHB9x2C$>cVf_eWe(AKYv^-amd3m&1Vj32*1{>Ib;83yx=z@= zDb4$QGuuV6HJCHE)HN_`0QH`(IfXZ4_7-tss0yb{jn zfU7%uJEr~uUVM2Ds2O-YM{5&h3OR6TU44{(HO@H5G56(rpYNp0Y(!XDUuSMUoRH1= zw>jz(j9&C_xo%wRF7YALvx{}@bkvV6GXgg~bm-eX<;WRsa=#z(pC>MAb~ z_OlriQd4Xy?NoqD+N^gpdK`t@i;ZuNb8M<(vGVk z2b&RfrttGAURUg#v>9t!F~RCyb&#GszebDo3)?4H6L@hEY!B|90B6D>HoS3P$QogN z*^HOyk`K&PEA*4183xCAA6Z|Ncw~rv3f2|;Tp#LzOUhoFe(a_`!7x^`;f?L2?E9Eg zEXIqhXweX}`8}q$kHS|LRmql2h=(wFwMOaVOx_b5I=w}IA-4}jcEXe;Da#z(i#4;{ zvm;Mi9?oU~bI!7F6YCusetLwmJcHNqkHFehEHV|G65VgS5>;-RBlDAT$q_X1+m{fL z^yKg19S;d*F0=m{3WvVu`m)=4q+y1V(N^LUXN}PpB%Es`lyJXUXckQg{C(zpyXX54 z`^&#}od3UO&VM}*`+I}=_f|3>`R4}mKW;Yv-eKl|fY|@oc;*4I|FQAR3xcM@cbnAQ zY#{dAoozX^S_yZ)Cw=vb2b$rU=V3_w1~w9{PIzP@24m;r1G<_t`IzeueSM?EX6 z6HQ&Y;`sw{D!)3IgwqRtTWpN1#cqmp)CSFi3o{q!c0|>G*3|S}-)aI<}D&7qh z&zMjj3h&WoXR*kxedtCpw#`Zm@&Pzk%V9A@aOHT=QT&sHj1nUGgi`1h|t-ZCs*y#GDcS}@cK_gqiDy!a3^&DQc z1O^&Ut&t1Mx{GDRoaV;KRwq*@hO|rE5Y4cfTvBX36W?H*blZnfRU+tdWF(-5NuD5_ zKlj=T)e@`b15M&{AW7>mDTn&AX}3U4PwpobX@RMW1A6EB3ks!&s~v=agJf7Oip}~9 z{wf|-rG5oM6O;v5EH;He}3v)=1qC>wVb$uu~>L#yfFaxW~Xg zocVL(y7POOjS5n1&z$7`h*JT8%2Y0M1bdZ^7Ns_9@}#<3=z9aiv7s5;kr&x(D{qE# zUs47R#1i4&uqXrn44j*-(E9>*@om+Ia0lP0LwC6h-|8pd%V3N)*1*EZB6Ub)Rw78G zMrcPPP&(nXA*atcU>h7G5Ob+txU0dtd~`TWcA&L4ev?S{)aQC&e$^Qukg}#2BVKI( zZoVlyoyU|Fk~{9wD(<-@%5OvUmBY5$v~Dq1F3!^~zDJ6wE?GZ4kH|gpl+lg5g)yyJ zl3-o}uW8sQz*$xZIscJ*QFRM^5sLqO*$jhRjp%_@Z?m*_#W9a&g5DSk-HFPCPAuJ^ zavlp(p6w{=3%KEw5GP+C;*jJOMh{Pq04mi`D10Y(YU?F;quP^mpQ^4%iwF}h_*LFs%D=q2sc`;_pe#>uvq)Hyq*dp1jWetff4O+xyw%pT= zVIOVpwa0r=hn?%U$tm-EBhg`6;tnX&srBu@tG>c_Danqz<|eQI+S){wf`+^ zlsO@)LD3N;n@@|~_Y`kq^KFd-2G@?>V|<>LNDFgZ^A)$pv?(s(rtTN>;m_^sWYgh| znC^K3!U;GP^s+KkqYizJq7lAmR_VbjuZs0GwZ17o(;PM6>FE?;hn`q-et&(k zCiOzZY3-ZO`GW#tMBq3XP4w09p7iUYK}Bn8P1F>(j>I>;(~ifsUlT`JXLIsylB=3KJ8INZ~`3WVq!a`cb_LI|fyW4s+0ZsdJw^)~*;Ni6gEpOqj?KRfx zh&|zmCMs|jqPx>fV*=q3UDynyvNG%KlA~hTb~r85@k|2~*~5lZm~ApK{B7}JqCSWs>$W3$3!-tR zsuYRYzYN(Y?OH;?nqK%CmfHTMnLl+oWE^R)O~QBA{)IPvEY>)-5`gQ5z4NU`_gfO( zIyGDDdT{zz;Yl+fcXi9MJnwrI(u{SFyNR@T>^IX#R1ZQ6d-nNhUo**?6TIU%oP92O}!SUG}k(<>T6?aGdGq*6^*-uy*m=aN#^E;qX1S*&ZVT5~5^~ z5rGW_fVJ)orxW@6k1$8{VK5l)yjT}#Z9C!38C0Vmznwxb0Hnb6o6D2N@O_(EIj<#$ER+YXO42F!?E{$daSx0bpkzi)~I!T1~erl z8-}qQ*|VsT2Mn*xWpfDGLReoj+sJH?&L1&dEx#`%bNPfk2&0*sYQVOxs0J~%`-vs= z_2Ea{(no&eNJjTu7-J+TIOz}sUr{v&z-$Rt8{r@+GZa}*53L}Y81p$q$z6*tIx55) zIQ53ke{EUF#ISKHSU^olPH5~3=#Lv4P%{MJh`9LD#Q|%zcS(>0@n|Znvrw$qu)Pnk z+u#!4_Pzj;bEgiY0l$}G8tAEJKjzHfzEX`}On)FzcA#!YTYSs~;ljFa_3ouU6f1iP#1FZl z2lDK=1Fe9ByOt_m`m9;Gt4Huwl399kE)Neo<+21F{{4lOOUXopie&@zvgIIl(0aRX%!?>in4g24{^Q68{;r>b8yq< zV_u&{PlmR2qSUxd?^3x61=VXLkPRunf?y-fFn$8UFi@#@?fXvMSL#!OT93tt2!e^L zcg5nKzd`A*osyr)8HulRRAee6ihVan+4$;_N%*N^6BWCxjFgLDPnv1=8V>3gLZaG< zgzujz=B`ven(@RDj{6^nSGjllu!k0R1Wpr2D>$cjhk7`c5beWK@K43p2nEqKL_a;s zPD1blyd<&lmwAwxnraz~B?KQNiv}5TH?7y0KJ=PS2R+4Wx8s`%mUS!&#km9{2$5r2 z>*p3PAUhfjJ~&%YZ)sF{!kkW)h`Z}TzQv9&QuDcF{47Dxy?U`~Ue3EQ(zVx?N)ByQ zPKHox&ez$weW^fR1bZ!?>V%OvcA0;ii$VnxSaAwm4=F)KiIi%21X*Ro&iOetEc|hN zlx^Xyuzd83@;LqW)#GL5(|gB+OL+u@MXWNH{HDQ^*%ORp7Oz3;i5JIIi59ad+!TrU zqAgY>LE$n=syZa&=Tjc7S~B$PK1{M*q^>4;Z!@nU3`r+1at;&i)L{l6^+i?i`Bd;S z0Ew5K#%RUn<1Nh*+>GHOtO)7dBw?;vqhUyP=_Ol2M=^FJ6MwR_W&BiQlnWA8 z_L%H~%O{`LYZowddJL`}FW`OJFXL$guG(Lt#{ql3-%8Z zahW6nfCmdDr_B^~FSQu4nG6zJv=^+-ae?D%!nu;quN0C|;_FxwJ0BU^wAYC{Z;rhk z^43upw|!kPFIUxF_aH%s_{c{Irep0OR?=(XM4DwuqEC}uio;gyIW;j$i&WM~zht7p zL|^0rEukKBp6B4=00x*!cs+MeMh1g*&=Y@x(p%Y_1jGp+)kvBcZTho099DCZixJ3v zHm!tqxFLYX+j}zHB}tv=aL+I+^dbYn%}J~1-FH=j=`JlQrX=;rJ|u?6SgYr*>SNwl zB#n>W+nenq4vbam^_Y$$r5i5iT8bPIxo~`oyXFbYySUoU!8uYuYm#m9OXmGD_QOc$ zh~o9enW;(xzo&rb@B-C_V#D#G^NA-Ajycg{Z*Pk3pT{3oQxVYJ!(h{v;FK6v98yZW5o- zK3?h`T%YjaNXW&$WC)Dq+e3jj|c)h9l> z-#9RRfkvN$eqD&J7|$N3=AMNI|w z=@3_u?2R91;u~obdWwC$YJXU9j4_6}cp4)eMQeahcqsX$<9JK7QqEAZaxd0>k0dO& zhcVtS*3O8%iobO-ju3xnR836Qu>7iY@wmUk^YTx=j7HeM(h9*&zn9&QLLABdZmjg=e3&BXzI2p(QeRvr)! zls*W;&CbdW;$pu6xf{+6l?op__YJ@eqFW+&gMXoiaNmsJ;)0_4Mc@Vw`eA3|xMA^j z81ySQ`wi;5C%)nGpKBbzE$&+Z++yS8w zJyAzqoO5G_VB=8-J{o%Ck&xe#-dWZ=R2qr=BE2(3*dbI=6~dsWIR)CRN`wd&h*yZG z_YN>uD5og>IuNnmB8edqy)`{S3I=j20^a-i_m9Ujy}S=oZ@`dz=gWYFIRgr>IOFyD>!ui|0}@niTEAz@IZY7hzlA@-F$eVn;17A4jv8=2OrdMOp)#!g!@<9C%Cxq)yI36~h+f|pH6{`PtgLru%(1nqYj{}MZ8hAm=TjWpzzxtu% ze%F3OK%k2@)TQ2*cm03qM20%j)D7VmVXehu7;^n&)3>4rF z;oZ<*$T@DplN<5>LVg1U{Xo|osK|bOfnGoS2bO;`|Ht#+@pOacW=4R!Nxhq#zfR>1 z!0nLR>E(h(JG{5wZ>Ifr@U7r(YIl8q%)m%lLH;pMzhu^T!!@d#A@cfrX`125-I5W@rI7&;TT zz`RhR&>4c<2=$H&UT9zlfeyb_cj!(X7ccbE=&kl~^Kd~UCw4Y&9%xK=2fzyr*Y0Nh z2Kh~$7s3bay$K+BcyF`^;N`wq`|c>SvqOV|yXsxZ&C7EmiQ7lHA@r+uD~Z4I#Kp-C z#eIYICbYZ#4GmWz(B&Tj4eahDchmZ7%v~!~PkBMwcTIed8$!1OZ;{{DZUH#CZe+p< z9l{G$m_MOz`|f1Kbz8qJ|8yLjY}LGy2*Q7JuK6YudTj1&>SX2MV()Yp8r{WHnvzOl z8q!RU6vVaJIiMXj#+J??&c6mvEL;!}3kMfFh@Jh$n7G)W0hE}tDfAXG)asy+kBl9p z&8;k-Lcj8ILqimE;I5N}{iavO#n{HmRLsuO#vH^34eDIXZ8f3O1r4RNe~p4h)KDbQ zQ0eC0FFjZcEDnAIehiiXOM_*=vS2x|0$2&G3|0lJfz`npU@fo?*ciIMYHDv|ZwD=H zZH>WZU~{kq*b@8{Yz4Lk>)C*9!FFIfD?4+rJ=h*vI)EL_oviH5zz#O9&R{37GuYY2 z*!d~g1?=K(4|WB+f!)C#U{A1@xsyG^9q-Wd(dIV+<3EN^oE+6}DlA9=&cE(T{|;LJ zUc?fb@=Ee@P!TK0{3{Vdx3HlizRgsiUgh747#aybHi1s%jr{+sh*{X7!n_kQH`iZe zd=oYQma&bwv-3aj`Oje@CucS0K#~B!`Cnf&{A*QG71NMc)qwJ;$_}0BztbeBJb$st z_TOpJ4V(XgCUO5&k^YfM8K}}|K~=@%Unrsj0xUjDFQN3f%-y^Fb-iOns* zA77v_#!#T!uXpgbc5ZHKb>}IZ&E24L?QG?7WA#s+%+3GV_W!H(-@QZoojh^!*1PDy z?m*4|*UI@H&9kJAl!WrFS@8V5RdDe9vI=(S3(^1H_|2WQ|GRnS`PWu);|`%t?;lk8 z_7u!bk{F*=L7p6{1B+E3;tD%L3QZI4B82~lPi1W-X$jREedhgpKB2kiFYD*IeJ}I> zU!QrP>&>6b$Uj>D-|z|bum9-Hx&CsD=hxrbgT5EyVuQ}p?Ts1aryS6OL(upj8MYM` zAD)Mcn>T)+j1GvbcXr8$I71|@in{peQs*4Jh%nX*D9gnLDY)3efMnAJ$Nmh^=AMjkjuciduFBQLi;C;tHZ$~G* zk+I3rRr#w{Tujl=J%eL-pl+C#b@li7sb5A+33%}9r0F*Jaa! z5bYsYH?uM^LwX5us)U&d;7B8yhEd;EVD@Lty2cIId>s@KaSxOFb#t>oU~DNQur;1f zgp0iW%NXzxE(gs8k-rgE0TviV>>-_oyQb;(6U9)jt#G-L$~UoJU9ww&hxdc$PNEeR zuzVR`lF2ZF0@H`792_cLR(8&Mut8TFP5J@X36xU%^7;maV22#OyIe@ z!1u3H17kyzR`P9f7z+@isG%GLw2m22UmZ(|wXn2;di3K;ZNClKKb6?X+G+`o z4KYo3=D|fY2F|^~tM@r94pm1m>uml>FNxcaCWqUyk3^qaSle4JpUz%<7lWYoS~C>( zjacUp+hhhA6a!_n(e$*OZBO0-@3CEAa_k5&i>e5gReL%b@Tf>AZae(}sUs|r1VC*E^LnZ+ zG#;g${)*HQhR7VCR>o`mii{_5#RDgyazf}>2}6_!P;0`x?z8ViG*Z8e5_K)Ul*~aR zX~U*3m}mW{277&lY!$ey`wAWx_-NWc$@up0o7(^>GnsAztr}w zPJcLnOw4~r1nJHHdJzKuGyxTA@w;qLe|s!E9V~!$e^`KImVZFdh^+sBAnLzMp_jO{S85nKE~g%*+H@FK&SGD9>m)IcR3(u`~OjcC^-C9gMvALUX*tKGcz{k z|49FLVyvKC4nQZ+3-J$Aj=yD=_P^)C25Omujq4u_Kwl>q9e;-b^~=%K-UVoCfBeT} zm_gD%n#v4n+3yJKe<7gTA3bFUnLC5tA-^3!h5RlH^vGp&v2X(ZFoA8EM)rEBYtP#RU5dw+cgK~K zC8{`L!C$2VDF+E2`UOucn$z8yTey<}77hIq8iZs7?kPk4M|qximvB^*S4`h<sm)~oV^NWn3sf5~N_!IopJ~(t#fWadyFQ|l9IGm^E#(WAoe^-#S@l)b~ znH}m9WwHtiOF@+GZkl?el-5RUI(_ju1o9`D!V)vg7l|XQ*yEMkrD&^$q8tZ0x zvgni%>;mthD~imeJh-7N8hTigg^c$jCF67ARKjeJ1i1Dk7K@6{pN+A!-AP3&=sCFa zPt4MU@XWtUwSqTu4?HQde~>(n@yg~bJsAq%n31Hq$U&R#wwxX{B;A9`k^lS=Gc-?% zEKFokBXYw0Nb-|VYx612{hLkPo;XLGzCi;Hyw>wv;(*I0GQwbhs$CC+O*8DBh#kly4X_yNvrKH<~Vj5IZ{vYQwg z1;g?%ym9-RD)Y(N#k=n_lHk6r+Pz?JWkRD=o*hv9Rfr}j6$rEf`;XI5rYn>bCW|^B zba74BULuZAG=o#Pe+CDIAusYKFe~7Y zkQ*7Wp<(x@(UCllRegwSDm-*kel!qu2Gi3N5jRreuY~(F?4fX@^dch`UdgksX8cE_kUGdswDLyoP&U^;8#JRnP! z+SQfLhRpPO!AVS5K0+OSR~$-@wzuhJj_%6Je$hc<&W7v28?P3R=kzVWlPtgLTWh%WWArg^~zfMGZa=E9#v=$dda_LJTIkB-p5?sTgozzGG47@V3Y z0M*Oy^9qVG8Z3W?9!mR`f1~3!w0{*h?bkd*Cxr2Ot_Cu%6hn&$cZGycN7XA0bR{xa z#+D$asRUl^H(8yPl)l}_ceZxmX9_gEmi4m36^BPTlcqZHG3J5mnswTaT6{)!(ixjE zU0bkwe||q2j($^D-=NAA9l}jVbM}b{Pg>E);Ua)9WjP-X8^W1flMcr0C?VkFUMb{y z>K?op*SHF0w&h>3t$2F>1wg%*~;x6!ZI- z!zgoiZAgP9MIohDJw%~2esxx}&ZD%-fdtZ@f8w0cB^yRkWCCg;o_t~Ndz+xHwG)xK zO(bNQHEv1t^Gk4GVDFhpk9FS*pkPG-38}gq*1Jxxmo>lRaKCQ+{L!$Ls<7IgR^ow^ zmPtlmu*^mcH!`L5aKhjvM1wo`0U{5=|I3f3MK=@8!`MefGFlZxsM2q_$#EwBhMN}m-E&Nf8i|?N6kpG zL-JU@dSWR)iN}SbKB?(q&#kJ8Bl;}!G-;Ek2KzH8`63+-)kwF zlpk4RXb3Lo0f9*==yHzO0hm5~TNe;D=BCHZ&UffW%< zg>%b|{Z3a(di$D)8p>P#Tg%>8(QAO(Uf_!gKM*X80(lKz&-pHt*ajf1^uly&qD|+NnMLz#-1c zuAYhuooUzNmsPhNkuMn}gKpC1=EJue7Ms4=8avY2M+AkuDif@a-9g(-Z2fJ6+jftUY2zgg*v85` zAqVQ{EEcixMm)rfFyB7wSm+z*I#L>!7j`GNiYMN#;eFX1nqd2aDh(?^jI``jx?8T8 zW?ZVwau>vVl2zW@l0^&8MwGpj7df}4gUTGrh;8*yf39fvp0;57X?jsf(?re%F(nsL zAkG|*g_D&NL4!38B9+N}Z}_0(6zS)6gy{^Qm_d1(Fk3|8%s5A&_ICgym=m6s1z6G& z?Ty^zUTN-k2}IE*9F3pO#tRJW>k>pk?OHQO9Mo#`8;}o^U5v@i+TEz~GzAK$(l)B- zcYM%2f3N7_dK3(SCPS~r_a!a_t&xcD`s;#?KFO@pe&H#@6hA&)#g7Ny<+chGRE+wl z``I|18j7QFqd0UbF*8ZM7uO)$69U|cP=+;08>J6;_vR|a57ROpMbaW>x*iIKZ$krT zVmMu+HyrbG6rvXKh>v)+IxQvNcUE#hw7p!Ce=scJ1o!iYq#e2t-mktc1B@H1Ua05M z&XR5<@Urh5@~9lN+}VRomb{JDY4%M!IIlKY>uKQuNbnkO%*A~uyP{!!;G`Z09}2cY zpeBQizrqc!iKRU_0)1S5MhoG5PY{^8PRLK}-n4}ob|atdTLNpXTX&*VIDf@dBI-0E ze|VLj$ozG5=)F19-S&)^3Oh}Wk5-^$EJi2w4vHa^)yE-|j%`Okwc;tXeq@O4$2DFdBoi=> zsQ4MJH4QHvN4Cvty5ZgMJDyjUxD}UYe}lAMk4~vQ#6+%y!GPj`I7Ah!n_%}eD9#So z-P&V;;ZK3N6jD2@yHXpu-lyagKy3oKlG?bYwTe@>9K z_^GMc44v)eJqq0Yby84LsRETTIzDz5rEdOq#Sh;pj&-moOe0%u z?o|8kmmQ4i32C;x9}TLnPBDJVmBadE|4$(cEG^(-b3!pNOF%aE;AyLh%&HcgU#q1Q z^#~i&V&aMx_8lMiufjKLTxfwve}9hp<;4W4iG}`ywLq02vY8|j@_nLY#jC^$ywtH5 z?Q8JhMM19u8)Vb2Rw>-jji1@7sTICG~2iRbhTWbIIM2| zz{#4i(OEvn5vg_F1ilx~$_m7X?(YmGERVQ*^&2C$RrQSUF}TcnC*om#6`)-bfw*uz3Ro7e{!-zw7i7yk!rI{ z?5o+kg$>?ni;W~L;89V`kn852pK?rciy(Nb(&^QiJ?Db$O~(pE^t`h@7FGO4H)P-{ zg;&7>9@sw0POi5ujph}%<4u?%?RO0KV^T+<1p?j7Mb9w|+v+!(c@n+6lU{X3VQ5-l z8$TYqkr$1OXgwDhe?J@!=LfI`9H+PX`aCnoIfVl>46!e|(4HI$ADp}5PdAr_y>%Tg zXUF56MCi3^-Lkn3k*^YH@#O9y++?DE+6vqV*|?^aZN!%o);2~vIa0|fb%6~Y0e1Pa zd7!pkrWfGDXy~P42WR%|Nn(O;E+*ukABRJ}H!7FZeu~UrIz2)#_o>lMuJ@cT zajRO}qJ~usf7`&YTs|T7ru!MD0@Y2-y|f4i4O5YI#P9Acg3-K$bCC}H^-$Mw%+&R- zYY?bkOQX5i#A>=pP5Oe1qgo_9jPx_I^X~M)g%o3mnHhhkg5uk_?k!##7W0PY(+Chj z%7LG`--7OP=Wt9VZj6 zJPrv248nF%hmnYwjBUC^dPJ9azcygZBlH(m$h;fZ32&{3HAb#cMnhDtghS(wxG}yD|iGK=xM#v_@ym_m|+q!d| z;H`Ya`^82g6R^Qu4nbX!UeR~7eCQP}0;t)s26H5Fnar~D7FaB;#*qPk*Bl2nJWm%n ze`e1G1tpM!K$J>CFP1=SB}^=JkIP;*D%eBt<7m7Pc-+8!ye0gAMMuY*>&^r8Fbc6! z5md5ix#=JwfjcHjo%Cc;25i~>T)EH~LiJA8HFxJMPwV&En~<=V3KXv$*Qc3?XFz0I zLYN;^U*C^-uV$l~Btq;y8*7h=Em^l$e{zen>jfm86t%+Ot$j%8kq&v@A~z^T7IY0O7mdX)3HekjJXE4{6o zYG;2c#!6rde(d+%b6D>$I_Zd;1=JB^yof_J88M5os8kPF36wOO$9Ntf0`dQ z<;^dqdWqgG57oe5!fqZ3R7{N3+H0iYyCXn2{z%;w|LkW_;L7UN|MB%9bMZqEmL`Pz z$QPAD#L8k6l_G!;_5Ozv)gKcCym64~?ug|v)iA`Yn%{KeH5miDdLxqdmn*}#y}875 zeV@Ls#;$Razhe$!*B^>-`w_S;e{1NdHku9kc3B>*v_Hm|h3|f;1Rk(aMSswZjvWEp zXwJCMyJjcl4wzjFFfB2>?I4H?|l|Tbypt3*#270rV--0MHPdLLX z3qLy+@&%7GhV-65W=~mIjY>>!MvCHkg?9;ab`j;i6BnwigvlRqy@hxvBHml(wR7Lp zWO`Y1PZF1fprSWbx@V!wik;obH)Z0%wiXqHDzn+c*?V`a8h;zif1jm+*OX#4g6d_q z>NWB5oUr}+M2~4k8skiF`N)4A<*(?k_r;3gRJQ<0rB@*8;3_O#oQ7|&V_=5r)GbFw zmOH*0?gY3ZD~XTtnYku&$GgT6Os_-YT~Lt0HEj&T7SC8&0Pza~?6nzO;Rkkhc!U8V zuc4wI_~-Zhb8AR9e=55OT=5YQ7qqPPO7U!CIOfK+-Vm|nD)U!#LI}=3CZE*d-~B2T zd8k;vo`i&ye_RpW=NU9o8+Z_3#g|{MdUiOr<)})`7*l(?&^wP9Y^m;u%J{-|;+eS2 zV>`)97USm%-mx3}uF!t6Zv3Q+8I$*`vY=&$1f!a3Eyt;Oe_zO?hLlpMq~)uLVHt&& zt8Zny?rX5rcLPtEBxAbAfV7DtQ>*RmjlgXWvZN|))18GI7}j=ZUM&bjzt!aw(>uG~ zgrMsdt9hkiTJV*Kv_zt^Z4)i26l9I2@T@7=`=F&&bpx)s5eZSS4>w39A8nA@66&?1 zChOJA);CEie+*E3NAe-)%4S0G@3DV`l*y3Ee?{SA=kt#a)^Jn2F=tL$ANjlL zApeJm($&Db+R9KF=vDR`j=K8-dbCqs448LnbsAD+_3^Y_ucwgR^k4~3KFSZcEF7^~ z!q&RO0g1Ug-~fr2k;KfFbQ}y}xNPE>TWA#tN*c<3@Wa-w%o$z`N6m=+p%3Yo1d@Db zw7G|~f24?pd>-Ynb~5&#O682v&g0Ew376wiY|2}vy=Bb3@`2RU0a^r;>u_FQQwL=y zr6~1#15RSjaP2||P<(r4n%(wxEpxY^&{lZ8z$%P6b#d7Dkvj#M_%r;Pe!b`*RrE+= zO>4*7hTwCp3t}HaYUNJeFp*$Km7ba~VrtXMf6Dy2AjD-TaEgEDL}@`)y7y>Aj_|0L zr0FF{B(8-cNb!Cr<@npPG)^ zq=*A@62vk+3Sc6$VvD|ilc`l{<0yHmKZ!SS(nRAw@~?FYf8fFJ20yIDt6`M&9VuyI ze+_dP&9CR3-u6^Pb&_!NLig8OS~Kd0Wr{muw_W&IYhaTjPWI7a$cEn==XJr0*}Cu| zkkb3Kl(eE5h7Cr8M$N9@rVHif5sO*o8tbiOY9FtqoXu!546Q;I`BS*p=+>%ZS35z< zUYG4^$`y*ga>7dkev11e{5ObCg7$DGf4QKV%94TV;m(^$2UB4tAt>qDIpy{kOcG9( zGc|5}_ds?+Pw10z=3*S$A@1n}JA{lU^I1g-+A0AH>f}<&L5-HqRe3RK5~B1fWEg4H zK?f#i1Mw;xL*$QqMo6C_o>s!wwQh}iGEGtLLSL@c=Bkn<4jp@AVaGMuSJ|ye_X?=u=ikYpt38Y)6`18$^zwtaEqS6s7;l-C7Js!WyT3V zUTui#HXDM18q>}6K;FRWt!@0gL6m3C2E_r|Z=!=PC|@}3_CE^tjca{A7_RVKJ;R#z z`mn(I^+ay2fBs%2#~KHB zoxZ8Dq_*w(UBj7pJ(&hvy?EHP25xZrHtQTjf>gG7u@{LeXiZZIS)tev^cXTRX~X^U?L&e>S}ZzM%C!4H+VUj4`F z4r0d1u0$w{f3|XHWC)6bf9qw&O8?sNAv##Qf(zcAD(sh$_MPl7&YB?2m06L>lxlbu zWb3wuS#GMJh*T_tf0nzdjmv`>bN>)0q2mUAv~KjTd{26FJxK*d-{D^{s8!7;=~OlA zaaj)DjX0X&`KyM;p3vo-ffCY>T-9!+ertj<;188g(oiQKLM-68S(csQqYc-yp&W7n zeM-pvm3y9N)!43tibtpW-WMb(vhFqv>HYFfITTUy)LY; zUrvf2avg^qqnJQ#l3nq>)d6Lx&Ar0$!R`ejH7`%o!(Gu=75wR2vxdq&*j6HtTNOgt zqdRNY)<8@3f4qQKk}^*PmUS)TFzK~VB;DSZcX}{9xWp1Jmki6(?B?2jy!WC|4lfqb z-PI7DX%zG?8m^74^h{0cYEBPy_W7~7;xz|zHl4XFY|UV;)8bc;Ne2-eqW}cuha*#nb8yS z&t9Vxo0u2_1WuHMZ(@eV!Vt)h#ZJc^y9kwjykDhHYE-3cRMxsAjsi-j?0YNo3;%2~ zAWk2uf6*uZy1)+ggI!<)BFcFR)iP*(Dk=Lbs%1eCZL7^Y7L)twS6yZ&%&P8(ubc&YWG?`qh@2!z7#8qkFI?Nc> zS)!E|I%DTp8sK)n(x}SJZjWHQw3R8*!d~NIDuWR8&;3y4I0Ccsh7lXHkTI2OE#Adx z?aMne_)R6P-*rQ}wMBMZsrLP?(=Z*0+^UQG{2n*01NWHBX&J8Tnc?p7uTf_mOAI)u ze!6 z;pCdlWsj~aS|-MKQLt~nf*WxALwp^NOGQCs#`TE$Aee3`COWT9ySHud6J0{~emE+O z!9ap;6!nG8AO`fr=bRaN8$1j0+xM}wf8DjIpC@Blst|z|<2}wrLo^u@x5uKvgD=Cc zU*JB+wGBKI?xUMm(xH_h)Zg>cS+{iVG%D!mzF#hew1A*J_->$S zMPr+rY@Ef-=>Taz*k-X@lXcw;A#hP8^*wX9lp)h9*A`PXCcOc79h_!Jag7yMe;qGe zXotZ7$Xi|CM~9#2sIN_Sc1uFAw%N_ubWa^a(%cqAEY24jwTz{f(IlFHonNpyMZ zy?Rs378>aF%&6W`y2^9sWn7-D-9_YM@5{61-TVtCZ{m^Oky$Gfs`aSP(hKd_WIrfA z_K^mdOW8i=tstwGP*WHR*G_(sfBmp~N+u{nZ5sRua$4tl(`ceP@OZ9=_ySH)=l$c> za|hr{JT@fmiA_e+IL6_a3~QScz~cE-EW^HLr0n`!w=QfoU2Dg_iFG>bO~C)1(1Ubn zI6{;TjQ!W2qRx*5QXjxQzxYXD=~Ld&e$*Z}9;4717bO%t(<0+eBJudRe>gytRov*% zAckIHj-!6l8~v*WeM`d~_QVVsU&F~oC^+%OYOfv(-$C}qqvqL2*>cV79qOPG+OYB^)@n}hHOlaYq)MvQ6cs0y`;;@eMD3sh5?^(4Rg+1Wx0QkuQ z1T002&n!*=yO~EHw{q)ZfA!!k9!1C8eRPz_w{)PAP96V5-BBq;Z;NBCD)gfUMxql> zXq-1jQMdAJ)@|^+)*-liHiyZaNP5E6S!xM0QX>6*= z)+DmBsh0?L2nWTbMW5SJ5K{QWuFl32B}v*woryBdlLJicX+f1^Tti4LcNNm`ai z@|IqQB4dxef zv+oUh$Cgu4PZ1tzZn){WS1te8?4wD!_uC5Dxrz za67~9N!|M0R*e=be=5Gw2yiqdB1GR!CU9VEn2g~`9 z9X2ax$hXleToXyl+O{b-*k|a#3>@!nt*RE;qFB~tQTz8(eSwO#T_$NuYbb+ z01w5(qpDdfD5Y44r?x!?BmFG>P8;m~m=3Y0g@FN`FaM>%HO6$1*EV*KSBb?-q6|vv z``z%Lvspax5_I>KaX8$&r~WCq50&Mr3}|T^os@0E7j#lE)?w*aV%z%qn`ZMj{AUmg z*h)u|(FH!Ge?Hch!I{(Jo9WOTkI#Yl0n{@)@is>rTJ&ATabEpTlgewOV!`k6nrd9O zxAS4%6kIt1!T8@H@t!EsnS|}8@>zF}G}xOIv-W+Jyof^er9RemLq+!bW}j8bS5ccD z@+i5#g|he@E&-A6EA^3CDEVXi)~p6C>(zInDy12he|~V{roDAbm9h)?MrFAHi|RY{ z$AxD8r%stSQShD&TsjU9e~E_Zg_!v8QG$IcBG{Um6NK?--$fY}aoGd$iOnB%w+c6w zFlo=ZQFY6vvShco-@c&Ar7vj1o8Gk$XD9o)R^n)WWt#F_#&q8*)VzB{QNqR6O-X#6 z9J9Dof5%sC7zUFOcorL#65xThBk12^&2;_%rU0(Xee}h6f;MC#ST&hVS3pm z0)8~I`1Dl!y`F+oPukbZQSm~MS8OdOe-k;f}mBw&V{YYRG8e^2vP z%B{#u2-S%HP5wo1)8^;=AnsBQ+N3CDiskf{s?Ner02SI4OciF#r*Ej!Z>y&ZLk;aV zVPdORfdW{(j1_brv%Z(_AQO%=bW3y})z?qSG6fOYIzoTe)8{2p4#}r@4Qrt7w#elk z>4l`=AzYkqgSIXAbWlGg2)TzG~(k8BHnWTY2tjLY`vLzt5!^34oNo1N*`;m~*Jlhv5gqgXEo zotSh%+imbu>BT0DX~7GAol9_+#OQ0tek^4l7do&#at z67~9e5}LgG6nrgvcA>)|QxAGi&7-$Mjhq&xh88e~A_jPVV1FFElCK zC)c9O#JiXm&;dNSzb)w~l-2`83HI7nDHKs>a=gj(?Qdj)MHs66_K|I#WapODW4_Ik zYvj>lw{kNzP9!nJjO;|xrisa-++`Av?=SG$%y#z-9>ccqg;k5I2ew~`)!U1w-=f)T zF2uJKX=~+W(p760e~oZ))h#)-9etdv*P5LsB+AVUZowRa5V$6CRAc|4M0w3p5eP-g z=8aT{^!2U8$kQ7yQ6Mhazf%c8AzKzWs}i(| z`ffRorn6C1iYUBcLZSpT>9gkFn(4b~v+>UyvYwh&+MRV+h6DNuFR;?HlkAwNC{PO& z^-#8H%Drk41gi$FwluJ6N#OGMm4AeNeUE!EPN* zY@6mZibl~9s=Cm4eZFd~P!&P(J!!v^FjuuixK?6hnyoYpqTY@Sd751mtPXQ*v5Wam zST}jJvEbpBPga=z!pg?B>gzN3zt!M) z;bVKtlFg(Aoqy{;=ul8;g_;ez(eJTgWZMI|GOC_i(ey~t7b$oKHZEFszzqdLKkwe207wu;%h ze~jB-M1G}y%@K@_s&(RP#-y#qqj|tDuq4uHc-C{s+j$cdo-kIXMuY0)d)b>uTx#{Z zbZ%%ZzFEu_H72%>oS*SMbnA7=S?caT*|RoGh7Ti~*KK*moAG=do4mp2;tZz?W;>hQ4S<2%`})MzMO zlH>kVOu&ni{&f=J&GzE=m!ZafL5P)ulnQd; zni(SZ$syCSuD2(zW_HoE&(+1Q!py1#pL(wJ3#^B#c(hGNLJm%Ybwjo$$x>Dye>mFD z%drze5r2qCV$1z7-3w)^ok3bvo4!S=eG1sn-{#z##!|7{WUJc$`stU0X!lEjQ4l29 z?AwZ&WL-w1^sf*SA$OE8VjWD}vhu59fA5{-=)<@OPi8q^wI@6XI$mZTU3|b z6~W%)HE2M^%sMYwy2OA{u_p&)a!;vE`bn7W9y7P)B7J;-vcIy4pV0lOLRI0}=!j$O zYG0NVn7!Hr4wI~=baNe_!c!V%y55^hT=3wBjB!9 zCwF<5v|c10Rn~{aL^dj`jawi!w=BqdZT%gB05v!j*N}p25eP{o_BQhQcq@6M#4a5p zIEcefe^(i!svmcOg9%=Y;P}#@&>HgM$Qxr8axMmcO+drmnUS@0Xd8P4fUG@wpgf5V z-}7(~_yU_5sN&X5%VcK3f7RgZZ&d(3lAHFW=w##B)x~?XvArR5PD{>_p>gWtmk1$^ z-r>dqBRL_*J1|y;@O`ZhZ(T%6un0`n9)|-JWnguZL!(JKba_#zY>2az6lh#cU2-wC zzC;|xQPsX$IP!wuyi}VbYYYn>hav{n9iHIe+-`fviGYc`g&ZBEf54rsb<7pILztP9 zEMm0Ng1$Z5x8b;)E0K(O^hHmk2%2Nu^3j-IuuurjEMT=8U zN4HrmrN?UfZm23qJqeV|uIcOHhmITFg?;wW1y?S6Tw0rZW7#&Q_cCN2-(SQKMcL`h z&L2_b(vF0Cf$=zle;auTQ1j`|<@7RoMn3!LG3hhcyqi~KkT39er?szB$EO_OrPCQ! z+1eIwGE{>9_&9_2bE>&AC?~09p3-`{R{lcH(~~?0=P`l>!Q9o(G)y;9J>(Lb$u(`^ zWHBy{(!fyn(d@-k&6(Bi+Qv{L6nSbb!@cha4y} zB2DaO`3+H(*LfXx-p*EqQ>zqIHPjaCpNLh;JJ6)1Ta@=JI4}3eq>CigCEe8e-^II-6{I4t6&2HqNBF766nD& z%mT3K@c<>}=z087ow#Q_Q_Cj#t!AI=j95h>9!$b3t>8YOu)U_4)z#Vxyw~0SvSunB zfhz48_<`;{Ziwch$Ao!nHUzO(Su6> z9g-P=$2d*rJ#8^NV*^cpj3GX}X+p5SGCHgIf5`-6zS~JIJ}JgnOF4bqFx+@8Gi@Nr ztR7+-y&~FuV2-~PpbT^D^XAjwmg>njHy7!XUjg$}+QDPD5x!xfYe0!?S889)AjAxy z62c}6ge~Yhxjhn%pIO_BfIgCuoZFA4!v6~C9cQ^#PdTVG>khZenkuZw{F#l+Cf-`<-6N?qqn#T@H0QMGE$_+d z8&A@VuxksFyaN;UYEg3WF@Mkp*VUJ(e*|#tdk(@$$2TBrik}mc-FTm``uLA&ZpT$} zQ-uYu8w@ro+Eo%Z2N&A>+K9B7G58We>M7mC<#1kyT7lf4pwf(%(f{<&lJJ~41wQV$ z)VGg=%1f43!ff@#OS1aSc3K$I=o&d9?Y^icl*BI%*vP@+V0Ra`ukzW=wUgr%f2xEM zQ1vXv_A1~5A?Uwk8M;X+C#SwFpkISLs>x5YQm(Dq9`o@hfh3)WgmEd-@#yKr`&Lob z&rZTYrI8=TL;wMZB)9lOlL__597FJDIa(@hjD0o{^(zIlBYxD)jpDX0q$W3!8}oQc z($_cV1mao4rlib`89Cb)!+3a%T_?FY<{z zymU0FVP((cJStr`M~F6$4*bb%8-l0iYkp%OiNvT6zL9VxT7jZkwz0rSe?z<)cz$>) zpFTF^`5wvRcVKBp%oNT{j2N9E*T6`G`CFBRD1LG&vAhM0&w9QY{FA*ZMr?Nl-%$xz zxEoPcGNki%-8}4cW-O~~{-U&ovliOTLwX4PkvtYG0cveB`cJfZ&2YTZhofB+lZr6y zT`(```F?I@G8~|#B({@Uf6GL^{5ImDTbq0K&bttfhOMq`ZzeVPXiBgch(|KvoKCrv zvm8HmC84@gScfe+Czi!Q{{g2sw5Lx^-4C`FW*Pnhdwi+zRu3f~v%ERugj;5>+k%Fl zpC#Zf8$Tfu*(YS$$bnTd_^9UQX-MosV+G81s~^KE9+nL#T?$TWe>9I!43_|&7puY( ziFp0o8)+UC^t=v>T#caCtEL_5VaA?q&s&+tNgS=UH{Yo!!Z~*8F>m4W&y37e zdO^+oAx?)|J+$nOv@9Xv^duwdEM%XQF8#7YZ}jef-KHu|(H zE=vmEq$6`E*17PI%4OesX53Qi3*JAbTNdpn4H{(0W4K_~tjwD*<cyc?m#S^G$@w zvSR1{(oVOHC;w60s-f9aWBWPCSwMy8-soT}oyB>OfBZASuQ?dP3C)$E>B-k36bXTi zpif%YxEPHjTc~TEKE{E`SufMGuOZ)aISa&Y3H_%6*j!d$ZqNYHq{uXp1uvFkeVFdO zWP+Jn>3ZXm%uQL-qZhIY?+`T&T*Bh?tbC9v=E}(04KqTeK3h4qr%UUWH8TliMN`ovwY0h?N6!U$V{gLBhTfsqgasFy3I(i*Q5uyf;mp9ELU|O}9VP;A;+2jhZ ze=~xdwN(g#jX!s?mj~g+m)#VIIr^Z6yx01(R^r94aWLqDhz;VYu6a$F{xFRIJX#+U zl>l5+Ycz24g9x?*<;hRB=l9oIk}v}d=T%kWBFtl%{__bdxPd;OEK!Qk*Vunue5C0> zkqXeJYO^j{V0Lif;mr{}ivl)$7DyoBf4T88+Jwx*o-iUooSQ<9l<%|gQ5>2+UstmT zW7GR6dgswTL9tTiJ%ce?w)&V2-yx;ywq4lTf*EAUei(vAp*~BP!&Nt#S0sg3UZyS_ z{Jv0_>kJER18%@3YpjdM`68h4TBynNnj7PiLA%MqgV&^OZN@N^HsJZa_%H2Cf75>6 zHVi!b#bRi43CXkX{#o*V=_@_?^#@20%(_jBN&tc6$L*8NW8CgN(N+P)^P|0LaZKv4 zs9wp~8`$u%mNQgv#;K+30Rd88Z-dgnqwgOO_yxZ)NF_AXt@+ZXqKE~sy=b;3;ioI3qf9*^3rob<5#wAzVE)+Pj_UuU`h`Bj+S|MY$vxwGZ z`P4wEBONleQPUlmd6}pxbCI#u1qPFTO551{Q4SAoD_&HhKX@Bgv?mi%yfoLC5P)`} z*Maqv-PGcY?s*pck)W!jTe}_q&PROyh z85bX|?1Ze@PWfT$380OMU6sj7`1wf^JFg(@Gvb%#yHV1QTam9dW>dgc}cF=`jZZFAe*H;c6@=m>MHA%0dpv2&1by{$|rV68cSIW zirP0g5(>N^;Q9c*q-Z6)qofUXS6JAZ#h1+G++H9w)xkv-e};m5e?o@RGT3gF4gc3! zdSdI|_ms~P#qjktVr!agQlB}R__(95ua8d=ed3b`#*#i{uRpM;kL#%l&l1C#v3rQ? z_qvy%>0#&WRE{s-VT?cVRj3nhU)HouIf)S!>^z~(Me8~I^gWAna^qf&SNbWzTq%>q z7QVC2BBzN^S6jm&e~t)?Wo@-GBJfM|5Vay}qR8df zOu0*Z5jI1kX$kOh^qMmFCZDGNC*A@f{iZcKDtN<-^zC#Xy>2UV1i?nukmXwe4gcFf zuPw%C9BohwT1F^1G9FwMHY%;|;q;ciErB^I%KJafNY$HPf7QWXDagG_;rmQZuZW}h z{{n3QtC5zBCv!eB{OR&Pzg;RbU9SVcmH`Y5z2=`u8VDwrTMY|FZMr?)uKK)Sz=;|U zA~im!QC(M*)4(DUvJ$;X378foo`sLU7^Cnq-?>Q8iwmxV{2vlrJHQaxAd?YDQEe(n zX+Pq411o=Se`tQQ+_pny-J!1$A-QqqE$D>KcP>wPH!!APp~_tWRKqZ5i#)h0exJyk z3jIx8*PTRaHX4g!tHMz^Cyd4kV3U$Q<7ZbLV`=g+EV~i78mSE|l@X;19|H9IO?gy{fAxFi&=oEzH%Cx-v6*U?{br5p zfqq2xm3L4u$IT3I(;TT&xLy`q6ZKuj6CjaRc2CTW^7TwV1eR2~mdRjtFx19P+K|h` zFzs@&-19^KnUU=cFkryh&kwP4+JBU9(J`tg%?n|#+1wA+10L;4RI>kpyvXjpzLV;I zocuF+e__6ci+h!MZ;EgUU=)XoFsDwHL~yZ|)Ty%l?A`RlrZ?fMclD5+y>(nvU)MfN zN;gWk(lJAKNJy7-hjdCwAL;Iv1_h)Wl~%e00i{8@yYn6N8;bY+ywCHSKm43o?z8vW zYpuP{FmvteTBIY_3=AwHAWh6T_~?!~Rgnefqhxr%$yMqr-Z!YieSuV#Z@FDK=`iCO zF&zX8eBrnMeEjsukRe&9HLJttJkl$xnhXp4xz#5K^7v*()5Zq`f!IkE8~v{d##S zJ=GC4K{fCwV*X`)^3uyPiuV9c-05(-uht(bLvj=vI`(c{wbH%{vUnq#&qtgVwTC$3 z)S4WTglK#HNn8z~68k|p_rD^P5s}qYP`TyJdMc};@(ZOD0HK%phuW11!u`#}3Sm>_ zgy=eP@<52A{~;#>-*R64OHOwC_Lhn12XPiFD};0DS8g&U2xZP+yjlO9JV)dQGZ`Sx zBEj-EGt%$0WQLB$78Xtx*3V2>AVjec&M`+T2>+CkgQ2m>53-^kS3lW_ZZEA&oc=LG zu7Cc=pVVe|Xq5nqTQ;SiR7z$LCSAxl5azRgD3xxhtZoUu{sRfxe_>U+4awi^NXf zEBO+~KRjYdR+`Yn*sQEPkjnfi*v(4L17hR&Nj?O*;7ZDNhNcDT;1%Q1h?r&Rr@wT4 znVy~|L6+`f zPlM!ore<&-+F?95T`*d~z1LN+w(js8mYc_IjECp_(CVsF>p*Q5uxJiByDhI+E+BS_ zfkHroIY>Yq2haNnKpowrfHJ|;hQh;m8K$2sBb*$E)6(BfcNmr37zYx5u!_uyP*4FI zzePb#OPC(s=of@D_N9m5!AfQnlmr_!R8n*_)P~)Qm+>TBNY?lKp+;T~sFCw&h_Pic z33tw*qBRm23ghAgP1k*G1B;U_ z(8VY+03|3dFE2t$3e|-L<-k=ne|lf|+b8Hl?d~HPRG_G}v$u5y+5nmXb`iD~s`Wa{ zO~j{^{AE=fN>}HGLOXy(h=sY&z&cd~sv~HL zYjJUb-S2At91!%GWxfGYZ^D*tK3v|U#x#VLY}pAc=-;~`6BtCd-q@>yw@%efGfc`h z#i+;Vx_PzkbIohU5zRB!z75n!4+xJ1NQyAp05>)d@#!&K5K^ps)BB6P?fQg_Usg=| zQjp7e(4KxfxYyFr-hC#-JJy{t-jYG5I9BdmBwQYLZYRbQoYHt!HoUOBfB==A_L9^b za&TgPc>&h-d8_RR@#3{d4K(p4riWQF3Y1zpM$5+;q^)m~XJ=5v%FSW`1vFGpA1pSU zJM`H-cSnSr=&D8S;O2&y1D^U zo13IC*Mw+6XJnWUun$|H7|0GY5igq$BLU`eFK>GvRolHenBIPv&2xlKmYT+}VKQ_O zPOlI-BVADtuAyVqzI{22$aVS4?iN5;L+vZ%9|W80m*s^wedu4Y>k+!(8BTmsFqV;h zN*2i6HN1{7x?9q=ZgK0ba4os_4gN%&w!T<=xi4?DCb(=J;}uqBi-+ItH>vd{A<^--5kM)r~0H zf&Cfm$McnQ1pk_rEog^N4bwL-%e4d`J{`LXzJ@X0hvT`rzb@2ivpf&C5p}S$!m_!4 z)7q?GNgmDDg=%9vF(do1>)coo=&h5cW96#t$FkMyo2lAG!EHq2!Tx4b0!1*C>X?xh ztob&wyCgWZ%=Ka_Kxo6}5Q)boT)iQV${%UPQY)HC_M2v7^IVA6Y*66`d%L&QbUAaML0A>M8Mg9ow&;VuaK-B#zIDr{9N+p(jT@Ir+&+@xA0Ej>5#+JdG;& z3??~iay6E!DZ&)>ojKCJ8G8V_l?3DI6C~*Dv;fEXQqhpF&#bY$TB-5Qmujj_&Q^-}kzU~`cFR6uxjKFt zm`^p#_PGhfx_4@Sws0^`Y^ji<6zJ<{q`(qc$q*wtTbkjOd32qzM4nPwtf*Tj80>}a z@hMF=W5@}$)O3cKEwa9hBDG0!zM4BP{7dt|fL`CcYqySDbeX;}_jBMt0+(wlUBlb| z^5qOag%@v&($|nzJW`+JHn$jtc9CshN^PCmaq3FTz930yRimxQ^wk}&;3OlrpBj?T zt=Tq!QSzS(KEjh1ElVWyjgX;PCF}ta3E<%{V-}_J-J^0*q=-@1Dud|Zx@SDqt*$ce zi&NvE-_f0`4j`pcemf6*^-|C;k{vB0MMqKXA^5Zs`xbgDX2^H25!;RIe!zl2cG$EbVeP%h=70>(wE|CXxB9W`! zY^K@cyuFY4#y+x?;VToNP?vY~sUa%XO^yuITJEqQXYlDV+kVIbWaA1=5eZJ~Pooo9 zbG|&`9ldxfai%}=E_AAFne!A%^OC~$`U9`I{kZWHSz@vWxI3$6ieegCgduNq)P>!mD=zSjaYqkl3J!zX#XeGW9Wq1=GG6F$;chvQEhNpl(vpOTp zh9v95v-(8ytjbiRv6q^KPd~g-NoiwaNC*=P89;Q^1gqZIv;lQF4Hd9(yDXKD6(1Ik z={&7tQO>WiQP$J1C(+YWNnb46tpPEh)+0;Np4Q@&F`J*^BtXw0!r&|xl0HEiC|~*# z)%FZR#Nr7)2&K!!VETyBMd^k|kaN9;E&-pd9&% z=JO2|3mXHfJA<;z2U@2Uk}b$JG&k+;v2xT<(oy66zMz1AW>yl8f8 z{5p@u!9sQETPbm?U|GoM5JOE(Y{G}^%$Ta7g5up-XToUqMHcdR&5NDYD9MKBn2+nE zJJdL$8!$#jxCJ?xcq`$Onf94G8T)0eo zv2!k5t+t8lQD&NY@t+$?$1@&OMAm>%;bf`>`w70Op!JiPX_mG=OmGY4h)UZTe%JTN z1(&xmCnb64`-$8DI};|T6)B?K(YQfCToE*0CvuC(*j3kqEn$Zzr4qkMm z!vFzJ$^I6cvBGs%XYWvV)0>`JQ%909laztR$M)DtIq=h33HB)l_Db2}bFUzL!3FT9ANA)u@7b;{(idiwORSHHQ> zs}5D^O_gM%{2EAeQ=aYF2^VEsKoy4@O&PGH!#7ebI{$sFj7Vp&+=kba!tB%kzU3Wor+vS0!U-fpO&T4?&T(Apnp&8s083bl;Ja$~Uxjy6vk&k)- z5q_VqHWO5o18zlfRcjjW{hc)Nj$agTdhJj0jV) zXBA3cKe#&m@?`F;h**|JgnPcW+hfK*6v#|<|GLG}EH%DW@wJ%CB9cNYwQ*HT-?ix) ze&)hM>w2x8pKDpd_sQqbnV3z4Z!6xe6M{30Ib&f6Cr@oH%Wg)5)tRtS>iif%J&!6$ zHa3yrFY+66yIXjBInl*8LEWkc8IdFg1o% z1EbUDs+zp=6&Y{bub+%(9bz~$E4=}^jx4^6xZ=Vc(s-fw$ZEmzXjp`f&S-YKl=Vhz zoe!^YS4Mmj8Mmj4E+3fDS}M3p@pogoDfOboM{V+keV@0)J?_VrN!nc;>GUOjlk|WN zCyn)_mHhZVZ~9ij%}imzuGr@AJu%4w>nuN8QYpq6!D9u~`p1O+;D+aC+m$=OiS9)* zmi0D&^6G=arcfN}rH|x~(`oQ|s$=lw*TS3@R0o0<0;%|7PB{qpptV`jBXj4Tw*}GF zH{o)&?0t#KrBu6+g)r`5QHC8?ytbuhU|K5OecoqTq(sW3VW{Exm0wKMgXpQ*s%oOj zwkR!EyVw?D47>YOL4tdIa2PZIAk^)Y;BB-!8Kr)rB=pB5?_a}9<=zcsQrq6YhgCKZ z(^GP}K&P&X9m&lp(l14)J4+cyIWb7|xt4CNi{+C^aiTk!C-%Hl`pG$8h4hA>>b|TN zks|%vTgNl}M53Zl?`Y83rvFT%;cnyxc$^?bVXfT} zydcxPBO=c$p3q zTH_uH3D_uiti6E;bdV(CT}{0AS)uN?y~thGvyqV@%w2`cElK&@A9mCX4rdq@mgr@& zM|W*i<&%`mBKF3ucwgRh4e(Ct8CxMOAbs`7lU*1!@v#%x+<)0edwm+^02d_tH>=Pp^_J$686cFmX=eVZ!1h$rl^Iu_GF^cldXBKqwYM_{w_;@S;x97hz+*gfs4P2 zmzhdfobSAp++Z_#bK?w5-PE^WuFJn~T1#+W{kSCa|{+|4&64jt?K zkH@Uom$V4WdS5S$2zXr(^sj%oZgU8q>a*oooHrh{N@%NA%T^}=6b%*D%e|F)9=0NC+RviO9~ zSS=%lPsjMQ-!nr=2gs|O8MjLVFUN)zn9k>U1p`!9>Y9Aw8b>y_G{oGlr^=lC-^yI9 zDYDw+Fz2*r^is*8@FDncP8_mAr(|7m)t9z^gh|ilZsL%Xi*BM-HT@%bt{5UO19 zP8t}-L6)z7F)B1_8uAiWmF<3FI+04`xP+3dJD=$BycHI_DbVya#O)Ov7O86D;nObb zHY4cyn003QvRQ-%yDQp{(i?ITPN~ET<|pBj;+{9V2T0V@FNRv3(y{WA=Sc@j8C_-X zWt|&4jPS(0rUUMBI#K(jQ9^g%pxmSlB3GH!J9 zlc*|l9efLTs?*}N`>%_q8ZxQc@Do)Q3l_XyjV69b4updI`ut9B!FlFe%SGXsO89rt zG46DZjIne(qi6Iaab1o3Drb)s+i+p|!noP=afYxutSJ*=ZkZJ^Vo5xnYV@d?(n5~Qq_ja4Tx84oO(tXdhoop&1 zn^8lP%dD&cY+w0wwPh#0f*$H6J|=ga<-3F%e%V1QOCyxAyHJ~(O-qa);$>w1q6QU< zx|UVZ0oA#ix+FuB8p(vP3C^88Hp;nRgQC(&Y6W@zJa79OHIozw!4fCx;pdRxQnz@Xj;}rKhmk{^iWYfH?x?WVl{L&#hfWv zsI7|g2Il+2Co3$Qx#pMJL!~JX?p;Xg>@AMUc6P|m78k>!JW7?D8264|C}MnCk}1!h z{1qO-u&pufHTQiw>n1lmm-@^I&yhZ-la@!7`9h6*&B+YUoDP~BGhR{lod;7KNr}!H z%+<&Zep9%oVWD~dIuptvsY7MrbDDmQi`mm?%Xg+Tw zkGe+PR6ECWjnu{;f^@?Yb5&j}|6_xwnO;C)C8!?N3CZxAK>sF7lFz zV)?7yxIB9GF|N#{<zJa%;L?yC-KV5`+{2*=Sf;LU?ZkDR5l9=yQ}xZxJznVj2S z0@9dc&7ipaCeP-)Vz7&-Exym>^_%s_yg3?rZ*1mevSn_U^Xe$}b-`rbNJSp&2%1k) z@GdH;Q3$8EP+3wvQbs_@n-`m=weC`jh4*P5(XUF}N6N;M-oko^r^N4K>naE|M)X|a zI#MCcicEaQ)iN?PCk0F{a3|L&n>rVj4gpzur4qymGi!FlnJArsyieeC4oT7kb;LSz zKSta7^_R^h(cs2_B6|t`=dZodaPEOaso>3~HFR4!&U?Rk?I23yveoG$poFD7Ko-am zOxsV7_I5D-#M!RZm@5#}j}?p8S}V&?d>neI#}%>EwJDBS(XDt)*jYqRsob_bcmiM- z)O+n$<~)(F$alNIJ^S{l>`iC}R_{CFi7!mvZ8q}08bP}F9f7m8iz0m=y2C~7B+FFd zkh`a%UT;Lu9C(j>n{921&+yuJj+{y*3<+Fdi$VG*$o;@1_(NOA7gr`5e>}T>8-o?H z`z=QNDOn+AJxd!{^6_S=3bU9SPe&MlQyY_@_7lRLhn6$^=kh0&BlyFFaWZu>>D;!% zWCvb3brh#7Zvz)mYkLZ*N+!7YOkW?DMxSuL8_bh`^7+k&Iu`2S@?O;^1Qbier>2wX zE={WnZDV5z8eNW2ff~|D(_5i3=fVEz+xOkQo`_YA_Zj!6YT%oJrV+m)7&hS4h1LMloM*oy2p6-VCz>*SSAW+ zB1PRx=_K?Xa6R<`-6O*pE4ueSRDf5A-e%BzU3DqNVwX!X?hI)7I6BIFKDV_V{s^sg zgO&f@%(DZg$9M-_B&8Xmji`ab%zVwQm~t|hCnFNXEh!f~!yjuWE4{?`*S?AS$IUr% zo^%;A4u4A%UuVw9r&>(y(U484`Y6&%b-G_HO7$#DjjPP3?{t}|uN@mF>K@<{3;(4i zKxdSxTwQIT@gmqpsP4RuC9TC_^LvMB9Q)9IUs0BsKfdgd)gimtuAP?L_ME4caDfPAE9f4F8&Z0vM?XMI>A`~X2`E|;drKGnnSJ&(M6Sl>OKp-<9{X#@oOkBm zTFW>(jt$DTNqvR#JyZJx58FPb2gV*3sf0gzVclepaQ^O{?=II!KtWlZT1N(KjPX6? zNs-x@xv7*TP5Be2WE4M)XfMFLjXqnA17~i&0p|5a^mlw2_(4Z?A97}(uxuLijVb=^ z{5-17h7n~bwTimL%DHL`+r{9~WH}0jrw~hUhXAoLqKX(QF4L6 zbKIbNE*~8qKFdtD);LX7f|2B}em`X{haLVn5tGT?H!IRCqpK~b33}G^sSq~~r7)uu zKPk;4Vp|SSg;HolNN_wueu*CMAz20{(VVV(!K%=c*aYzbvo8zsz{vCWdLyNMO++PP zm;@-(2}+m+ETuRn?=i9=u#|$6@Hr7uYm!EDhLIyB%fJI9=EjFuRG-)-{hw-uyz_E* zFE&_n#4)Rwzudptx2B$cBL zv>Phsii+1tN=t{aK)ZZt|? zAu$!(L(7}gikG~K%il%VUEFX4lR2jLb`S`*WnnnI&>ZKZ1Rx2NU}-){b&6)WJY9b) zI(mVTTg^;Yb0IF4#5XOvFlNc6Pmb%)>ofQ^T@h|GNeQij1)<GhLNpK-$Bqd_zkc|vo=u$KX&xNhBGW>b$fmtYU%m1yqrV$-D0nhV?ispXL{M9{6kb z;k6huE>~)+%f{`Jwigyre;D9erDLQIG3?(<7_X?5cH^|w$9zAc-1&rMv0tDy$SIrf zlveloO4gpa$M(VuHx>H*Aj0nNyvG@4EN&RxmVsJGuSR!McWoDz(MvgUsh4EqPzwjy zK3Y-Wqyww$Rs}>PZ=MAX5278_lYL3$Q2o1&eTzagZH$_DPIIIy$en|04`CWh-I8_=fh&|4|sPPz$8 ztq2*f71_Fuo|_P_PeoH>WkEaJqa3|cR9|$|;l0yB ze3GYnj%Tz$Sx(+|);JAo*lQNhGT(-c&T?Dlv%Kw7j5Wxw^tm|!uGb;Xv~(IV6?O5X zOhNz}i!r?tt4>3&@rphAvrex!&Ac0~V8$EVp(iY&H5cE@XhqgV%NJATF(gz7M7yQ= ziS6fe=v75rY9EF;CoxgSHV=R5eHTu8QTpj3g!xThWn1efeP&?VNY~0ZET=EkRzV5^ z33p2vRR3V=NZUR)wRS|Tl34gPqJ4~7u(u09z}KD5qXx_SH#vN$aH*@Zi9QhIQD&$? zM&8Udal&<`J$F5dww z!j<6Y_Ct@Uj||QSDV0nNuL4x*h9k{J#pw7yhn~>{RhMs`>I9AYDR`1(-j|DMHRR6$ z<_B~*%arKZDJ-*S_B!9aYF~*Xi7S6veWKkliXtAk*lL`~Xj2fT>CQ**oMkfaGT0r{ zd$D19q>aO`_Lfxo(D+3YBk~LFV=`8%B*}KreW^04k@qz5VQOm|h%VAZE7zR$S^_~r z3Ok)Kb&*|3rHSe`?h`6c8hUU(O(-9g0>y^Jq(b`eikc#PZT!%+f9b33u&owV!fsCClhHC75@!F7%kM=7CvD z^7n2;VpCr68lE&Rl>2BiPewi><_ktd%`f(H`&jn(7wDQb1P72_6myJ99DE2el7GUG zv9A#sRp=ZvgO+pT${p}fO}h%JUHi2!~*>e|@On(&1nlbl_A$JDku zC8~4v60(D=aW}EH&sEmj%{p^+OF96ak*Y zNg|j)k?zgWP!)sd$x`p9-mm zVctI(V)N-&HcojYRG$K*D0N>Kh{vwL)^33}4696sjKYtTKLS*31TzsllQTV?7tpCt z;??iE;~H=>C3UXGhmW$paQ1BjnR^F@(y1`qc0 z=^4V>txB(aL2X2EZX^*DkfA@@3w6~XY#hyvd-^(N+5hS?^`)jEH35x~hn))lTa369 z@pnki`N9MjO7y=KV@$M5rF-~Zes0-S=kt1~qOwv=C1lI?{=2(q`DNey5rEJ*ec^|- z$Pc1dXjbvosvu&LR{2J>QAZ`jV2}SQHnoPGFT~^VyDQq(FCuVsM;Ea;lL(p$qNu(t zbAt4YI%oK;7o^a0Mo)OZVD0hP<6T&`d$O435Q%@^ida|bcZPqIl=vCLGdlwE?R6#* zw)583d)p3QSQqn0rJHa8?`43%m;-voPo0@f0=`exGZ;0(P>z!I2qa_>Uw4(;ri%+w zlf+Y`n}46_3%XKhMSc6)?8RCH$!P0D*0xa$T&^M(y&Rcf$of^Yf+fTc~cE= zF>S6I%SRI7w#^AW$0c5tA+z}N?#A&U_qKBf$!Fs7hx{Fmq8b=&*a~2P$6sL|5p>XX zj#r-Rnb}ki>Z{0~F&#P@a+n$Gzj*e2DWDZLY(9rT?l?s?#DR6{z3+qUmw-zm;`YFs9yO}#y)tf{Q$GZp;gH4QXH72+Gp30!i8$Lb~n#HrLqNeF9( z0uBoSYmto11~mygY27U&AO(1thNyX6(SB;yO30Giy$em`btuVft^aAtpt6jDegGxp zVna+s>p>h!BX2cZ4iC6HrY6EE73#urJfeX{3(jLgp{S`3?u?PNqT8itQXrBHF8^zE|v6gI8@ZikQFHiPbS$fjq zY}3uy(I{a~=Sio#Afp8MQ&)Pbn2454eLX3k3eL9Jil+BnwGGBJM5UZJl_)K)sx@2S zZ+hD={r(6{qL2MH8t~?TYniwv^ua_F#FRb6PboM^hDwdGLD-pKB!u@bcho{Rv$}99 zMgQIqAZodR|AB6Sh2g@(g{3vy)T`px0&BtaQcXwR)cyf& z7LANWdzkLThz<0o*yEA)%Q&AHzG+iLIVWMtnY; zha*Ij=6Fw$hqqAhE#=V)R@$PvG_^>)+<8WDv@0Vx_3h4S;F&O<8z?b?Y zxw*pNQOo7^JToxpQD06R^L9i?+AQtUV{V${4{zVE@97{8e@6{nyLz2m+8WB`^mX%q z=ea@Ul*r*R+7>&JrSc2G{T8l7Hr4jfr_REQ^EAR8@gCD8SIY>+6wo(suZlTR6>w$6 zVUs_Gz~1i`?>{}nD#m%7Qrk~>NXgY%*d+@2`_~6~$FJEMz$FUpJ<|C=U?7@V8NEbR zpRs*W-A?DB&W7i>6Jfyw;xs*e)ww{qsVt_w9L;##%!Uo>@VF4kr=GWkGE@)LRX3VsX$MDf&xxY7 zIaBl?Xg(7mK$rjIh{r^o6b}7te76B>Om_Sn4vBc=;DK@^#PQ`7y43KoZ`75@YU|AYkJsucf({{FwAe18G? z{sQi`WC3pRy*7X78~+#J>95e`?eP&w|XpaRIZh*diy2=^^NGRwc( z#}N3mvyqdVJtRH1Mo5Gn8#s!@=Np7Rm2Axp#c|IoV%)VTXXV|M7+6 zHYdPeC308g6?|L3|F?SmUCQ=%SAJ;X{+^SZxgMiOb-45<|k+Uk#~ra@a+tBZ-tfr3OL8@oPRGxQ9~y~ zYdbS!mLL6--(A!kJV`nRFqF`sB)|aX5f}{OV&w$0vT?9+GJ)7>Kp+~(Spqq`XJU{; zAmp@SysV%*O_D|pV59*sGdqYG3}RwsW+kUpG0`BGg*;uzSwSEk$cY#u3qxBvaw~g7 z$Oda-NbX|d;AmlIOU}UzVg}Lu;=HSai77IO9I_jN{&|sea&WM5keibKWn*LIg3SH) zMQ;0#4GeHXGV!|+1Oh{%^Q#Ta#>ECX$#K`lb(_WC+i`=rAYs2_W4|rEUu_^TH`}dz zJ>&&>Wc=j~n2no*=Was~7nl>0nBQ&&ae+AhoCzB@WV!v;4iau|NbUS?1MzS{^7yX} zxV_|J<-XG)#2FCeBg!ugAyHxD;^w*2A;fljxam$iZnoQMyM6sVIS`ng>-KSY$HobX z|6L=bgznr78HAnd&LAK#7ntjAw7`(a+>I8Potx)Qe~^1w|Lza?*F!Eg(48ni8gjD# z;Wami`%aD_`2>UigN^-98wdAq;fLfOax>?j;o|1x`on8(F3=yd<6-@C5FSppy92X= zSpS#^E2NM(fIH!5wZ-QnN;@o;edQ42hf=-+7vK!)Jpy3-*T%ntg) z2HD*HTC@LDHJBAr9(M{842c%_PR&486DRkbfgv_X!9hMU{=Foe91Jb2O&pN<`N>(H zTDY6s?q)2?c6N{*9pc{YCod^mQ#*2wpW85tlo+`-KMzPmj8g){%_YGF0&#%Y#MmKO x5fPOT6Ng-gh_DKh|Nk{1WfjyV7ZgNxbTV{s`mv2d9OL2PM1J&0TtNc){{!m*7w!N6 diff --git a/man-roxygen/attach.big.matrix_template.R b/man-roxygen/attach.big.matrix_template.R index 05079d5..2164d01 100644 --- a/man-roxygen/attach.big.matrix_template.R +++ b/man-roxygen/attach.big.matrix_template.R @@ -30,5 +30,28 @@ #' \email{} #' @seealso \code{\link{bigmemory}}, \code{\link{big.matrix}}, or the class #' documentation \code{\linkS4class{big.matrix}}. -#' @example examples/attach.big.matrix_examples.R +#' @examples \dontrun{ +#' # The example is quite silly, as you wouldn't likely do this in a +#' # single R session. But if zdescription were passed to another R session +#' # via SNOW, foreach, or even by a simple file read/write, +#' # then the attach of the second R process would give access to the +#' # same object in memory. Please see the package vignette for real examples. +#' +#' # Not run +#' z <- big.matrix(3, 3, type='integer', init=3) +#' z[,] +#' dim(z) +#' z[1,1] <- 2 +#' z[,] +#' zdescription <- describe(z) +#' zdescription +#' y <- attach.big.matrix(zdescription) +#' y[,] +#' y +#' z +#' zz <- attach.resource(zdescription) +#' zz[1,1] <- -100 +#' y[,] +#' z[,] +#' } #' @keywords classes methods diff --git a/man-roxygen/core_template.R b/man-roxygen/core_template.R index 6b28c34..44f9c8d 100644 --- a/man-roxygen/core_template.R +++ b/man-roxygen/core_template.R @@ -118,5 +118,60 @@ #' \code{\linkS4class{big.matrix}}; \code{\link{attach.big.matrix}} and #' \code{\link{describe}}. Sister packages \pkg{biganalytics}, \pkg{bigtabulate}, #' \pkg{synchronicity}, and \pkg{bigalgebra} provide advanced functionality. -#' @example examples/core_examples.R +#' @examples \dontrun{ +#' # Not Run +#' library(bigmemory) +#' x <- big.matrix(10, 2, type='integer', init=-5) +#' options(bigmemory.allow.dimnames=TRUE) +#' colnames(x) <- c("alpha", "beta") +#' is.big.matrix(x) +#' dim(x) +#' colnames(x) +#' rownames(x) +#' x[,] +#' x[1:8,1] <- 11:18 +#' colnames(x) <- NULL +#' x[,] +#' +#' # The following shared memory example is quite silly, as you wouldn't +#' # likely do this in a single R session. But if zdescription were +#' # passed to another R session via SNOW, foreach, or even by a +#' # simple file read/write, then the attach.big.matrix() within the +#' # second R process would give access to the same object in memory. +#' # Please see the package vignette for real examples. +#' +#' # Not run +#' z <- big.matrix(3, 3, type='integer', init=3) +#' z[,] +#' dim(z) +#' z[1,1] <- 2 +#' z[,] +#' zdescription <- describe(z) +#' zdescription +#' y <- attach.big.matrix(zdescription) +#' y[,] +#' y +#' z +#' y[1,1] <- -100 +#' y[,] +#' z[,] +#' +#' # A short filebacked example, showing the creation of associated files: +#' +#' files <- dir() +#' files[grep("example.bin", files)] +#' +#' z <- filebacked.big.matrix(3, 3, type='integer', init=123, +#' backingfile="example.bin", +#' descriptorfile="example.desc", +#' dimnames=list(c('a','b','c'), c('d', 'e', 'f'))) +#' z[,] +#' files <- dir() +#' files[grep("example.bin", files)] +#' zz <- attach.big.matrix("example.desc") +#' zz[,] +#' zz[1,1] <- 0 +#' zzz <- attach.big.matrix(describe(z)) +#' zzz[,] +#' } #' @keywords classes methods diff --git a/man-roxygen/deepcopy_template.R b/man-roxygen/deepcopy_template.R index b1c6cd8..3cd26e2 100644 --- a/man-roxygen/deepcopy_template.R +++ b/man-roxygen/deepcopy_template.R @@ -36,11 +36,11 @@ #' @seealso \code{\link{big.matrix}} #' @keywords methods #' @examples -#' -#' +#' \dontrun{ #' x <- as.big.matrix(matrix(1:30, 10, 3)) #' y <- deepcopy(x, -1) # Don't include the first column. #' x #' y #' head(x) #' head(y) +#' } diff --git a/man-roxygen/flush_template.R b/man-roxygen/flush_template.R index 19423cb..544b4d4 100644 --- a/man-roxygen/flush_template.R +++ b/man-roxygen/flush_template.R @@ -11,9 +11,10 @@ #' on flushing creates a bottleneck (likely near the threshold of available \acronym{RAM}). #' @return \code{TRUE} or \code{FALSE} (invisible), indicating whether or not the flush was successful. #' @author John W. Emerson and Michael J. Kane -#' @examples +#' @examples \dontrun{ #' x <- big.matrix(nrow=3, ncol=3, backingfile='flushtest.bin', #' descriptorfile='flushtest.desc', type='integer') #' x[1,1] <- 0 #' flush(x) +#' } #' @keywords methods diff --git a/man-roxygen/morder_template.R b/man-roxygen/morder_template.R index ad1790a..5319188 100644 --- a/man-roxygen/morder_template.R +++ b/man-roxygen/morder_template.R @@ -42,4 +42,12 @@ #' #' @author Michael J. Kane \email{} #' @seealso \code{\link{order}} -#' @example examples/morder_examples.R +#' @examples \dontrun{ +#' m = matrix(as.double(as.matrix(iris)), nrow=nrow(iris)) +#' morder(m, 1) +#' order(m[,1]) +#' +#' m[order(m[,1]), 2] +#' mpermute(m, cols=1) +#' m[,2] +#' } diff --git a/man-roxygen/mwhich_template.R b/man-roxygen/mwhich_template.R index 947dcbf..a94a4bb 100644 --- a/man-roxygen/mwhich_template.R +++ b/man-roxygen/mwhich_template.R @@ -38,5 +38,44 @@ #' @return a vector of row indices satisfying the criteria. #' @author John W. Emerson \email{} #' @seealso \code{\link{big.matrix}}, \code{\link{which}} -#' @example examples/mwhich_examples.R +#' @examples \dontrun{ +#' x <- as.big.matrix(matrix(1:30, 10, 3)) +#' options(bigmemory.allow.dimnames=TRUE) +#' colnames(x) <- c("A", "B", "C") +#' x[,] +#' x[mwhich(x, 1:2, list(c(2,3), c(11,17)), +#' list(c('ge','le'), c('gt', 'lt')), 'OR'),] +#' +#' x[mwhich(x, c("A","B"), list(c(2,3), c(11,17)), +#' list(c('ge','le'), c('gt', 'lt')), 'AND'),] +#' +#' # These should produce the same answer with a regular matrix: +#' y <- matrix(1:30, 10, 3) +#' y[mwhich(y, 1:2, list(c(2,3), c(11,17)), +#' list(c('ge','le'), c('gt', 'lt')), 'OR'),] +#' +#' y[mwhich(y, -3, list(c(2,3), c(11,17)), +#' list(c('ge','le'), c('gt', 'lt')), 'AND'),] +#' +#' +#' x[1,1] <- NA +#' mwhich(x, 1:2, NA, 'eq', 'OR') +#' mwhich(x, 1:2, NA, 'neq', 'AND') +#' +#' # Column 1 equal to 4 and/or column 2 less than or equal to 16: +#' mwhich(x, 1:2, list(4, 16), list('eq', 'le'), 'OR') +#' mwhich(x, 1:2, list(4, 16), list('eq', 'le'), 'AND') +#' +#' # Column 2 less than or equal to 15: +#' mwhich(x, 2, 15, 'le') +#' +#' # No NAs in either column, and column 2 strictly less than 15: +#' mwhich(x, c(1:2,2), list(NA, NA, 15), list('neq', 'neq', 'lt'), 'AND') +#' +#' x <- big.matrix(4, 2, init=1, type="double") +#' x[1,1] <- Inf +#' mwhich(x, 1, Inf, 'eq') +#' mwhich(x, 1, 1, 'gt') +#' mwhich(x, 1, 1, 'le') +#' } #' @keywords methods diff --git a/man-roxygen/sub.big.matrix_template.R b/man-roxygen/sub.big.matrix_template.R index 404107d..385d096 100644 --- a/man-roxygen/sub.big.matrix_template.R +++ b/man-roxygen/sub.big.matrix_template.R @@ -24,11 +24,12 @@ #' It is not a physical copy. Only contiguous blocks may form a submatrix. #' @author John W. Emerson and Michael J. Kane #' @seealso \code{\link{big.matrix}} -#' @examples +#' @examples \dontrun{ #' x <- big.matrix(10, 5, init=0, type="double") #' x[,] <- 1:50 #' y <- sub.big.matrix(x, 2, 9, 2, 3) #' y[,] #' y[1,1] <- -99 #' x[,] +#' } #' @keywords methods diff --git a/man-roxygen/write.big.matrix_template.R b/man-roxygen/write.big.matrix_template.R index beca85f..7a162d0 100644 --- a/man-roxygen/write.big.matrix_template.R +++ b/man-roxygen/write.big.matrix_template.R @@ -64,5 +64,40 @@ #' @author John W. Emerson and Michael J. Kane #' \email{} #' @seealso \code{\link{big.matrix}} -#' @example examples/write.big.matrix_examples.R +#' @examples \dontrun{ +#' # Without specifying the type, this big.matrix x will hold integers. +#' +#' x <- as.big.matrix(matrix(1:10, 5, 2)) +#' x[2,2] <- NA +#' x[,] +#' write.big.matrix(x, "foo.txt") +#' +#' # Just for fun, I'll read it back in as character (1-byte integers): +#' y <- read.big.matrix("foo.txt", type="char") +#' y[,] +#' +#' # Other examples: +#' w <- as.big.matrix(matrix(1:10, 5, 2), type='double') +#' w[1,2] <- NA +#' w[2,2] <- -Inf +#' w[3,2] <- Inf +#' w[4,2] <- NaN +#' w[,] +#' write.big.matrix(w, "bar.txt") +#' w <- read.big.matrix("bar.txt", type="double") +#' w[,] +#' w <- read.big.matrix("bar.txt", type="short") +#' w[,] +#' +#' # Another example using row names (which we don't like). +#' x <- as.big.matrix(as.matrix(iris), type='double') +#' rownames(x) <- as.character(1:nrow(x)) +#' head(x) +#' write.big.matrix(x, 'IrisData.txt', col.names=TRUE, row.names=TRUE) +#' y <- read.big.matrix("IrisData.txt", header=TRUE, has.row.names=TRUE) +#' head(y) +#' +#' # The following would fail with a dimension mismatch: +#' if (FALSE) y <- read.big.matrix("IrisData.txt", header=TRUE) +#' } #' @keywords methods diff --git a/man/attach.big.matrix.Rd b/man/attach.big.matrix.Rd index 1afac00..7f1caad 100644 --- a/man/attach.big.matrix.Rd +++ b/man/attach.big.matrix.Rd @@ -44,11 +44,14 @@ A descriptor file is automatically created when a new filebacked \code{big.matrix} is created. } \examples{ +\dontrun{ # The example is quite silly, as you wouldn't likely do this in a # single R session. But if zdescription were passed to another R session # via SNOW, foreach, or even by a simple file read/write, # then the attach of the second R process would give access to the # same object in memory. Please see the package vignette for real examples. + +# Not run z <- big.matrix(3, 3, type='integer', init=3) z[,] dim(z) @@ -65,6 +68,7 @@ zz[1,1] <- -100 y[,] z[,] } +} \author{ Michael J. Kane and John W. Emerson \email{} diff --git a/man/big.matrix.Rd b/man/big.matrix.Rd index 38b01f5..4e3b8a3 100644 --- a/man/big.matrix.Rd +++ b/man/big.matrix.Rd @@ -175,6 +175,9 @@ factors numeric before forming the \code{big.matrix}. Level labels are not preserved and must be managed by the user if desired. } \examples{ +\dontrun{ +# Not Run +library(bigmemory) x <- big.matrix(10, 2, type='integer', init=-5) options(bigmemory.allow.dimnames=TRUE) colnames(x) <- c("alpha", "beta") @@ -194,6 +197,7 @@ x[,] # second R process would give access to the same object in memory. # Please see the package vignette for real examples. +# Not run z <- big.matrix(3, 3, type='integer', init=3) z[,] dim(z) @@ -210,8 +214,10 @@ y[,] z[,] # A short filebacked example, showing the creation of associated files: + files <- dir() files[grep("example.bin", files)] + z <- filebacked.big.matrix(3, 3, type='integer', init=123, backingfile="example.bin", descriptorfile="example.desc", @@ -224,8 +230,7 @@ zz[,] zz[1,1] <- 0 zzz <- attach.big.matrix(describe(z)) zzz[,] - -is.nil(z@address) +} } \author{ John W. Emerson and Michael J. Kane diff --git a/man/bigmemory-package.Rd b/man/bigmemory-package.Rd index 9bf1c53..11acaaa 100644 --- a/man/bigmemory-package.Rd +++ b/man/bigmemory-package.Rd @@ -99,6 +99,7 @@ matrix. # Our examples are all trivial in size, rather than burning huge amounts # of memory. +gc() x <- big.matrix(5, 2, type="integer", init=0, dimnames=list(NULL, c("alpha", "beta"))) x diff --git a/man/deepcopy.Rd b/man/deepcopy.Rd index 99687f8..6dc4207 100644 --- a/man/deepcopy.Rd +++ b/man/deepcopy.Rd @@ -58,6 +58,7 @@ traditional syntax would only copy the object (the pointer to the It can also make a copy of only a subset of columns. } \examples{ +\dontrun{ x <- as.big.matrix(matrix(1:30, 10, 3)) y <- deepcopy(x, -1) # Don't include the first column. x @@ -65,6 +66,7 @@ y head(x) head(y) } +} \seealso{ \code{\link{big.matrix}} } diff --git a/man/flush.Rd b/man/flush.Rd index d6047a4..03ab834 100644 --- a/man/flush.Rd +++ b/man/flush.Rd @@ -23,11 +23,13 @@ This function flushes any modified data (in \acronym{RAM}) of a file-backed on flushing creates a bottleneck (likely near the threshold of available \acronym{RAM}). } \examples{ +\dontrun{ x <- big.matrix(nrow=3, ncol=3, backingfile='flushtest.bin', descriptorfile='flushtest.desc', type='integer') x[1,1] <- 0 flush(x) } +} \author{ John W. Emerson and Michael J. Kane } diff --git a/man/morder.Rd b/man/morder.Rd index 60fb1bf..ce0abdb 100644 --- a/man/morder.Rd +++ b/man/morder.Rd @@ -62,6 +62,7 @@ this function has side-effects, that is \code{x} is changed when this function is called. } \examples{ +\dontrun{ m = matrix(as.double(as.matrix(iris)), nrow=nrow(iris)) morder(m, 1) order(m[,1]) @@ -70,6 +71,7 @@ m[order(m[,1]), 2] mpermute(m, cols=1) m[,2] } +} \author{ Michael J. Kane \email{} } diff --git a/man/mwhich.Rd b/man/mwhich.Rd index 4c45d78..4bfdb8a 100644 --- a/man/mwhich.Rd +++ b/man/mwhich.Rd @@ -53,6 +53,7 @@ and \code{\link{intersect}}, for example) on the results of multiple pointer trick (accessor) in \acronym{C++}. } \examples{ +\dontrun{ x <- as.big.matrix(matrix(1:30, 10, 3)) options(bigmemory.allow.dimnames=TRUE) colnames(x) <- c("A", "B", "C") @@ -60,7 +61,7 @@ x[,] x[mwhich(x, 1:2, list(c(2,3), c(11,17)), list(c('ge','le'), c('gt', 'lt')), 'OR'),] -x[mwhich(x, c("A","B"), list(c(2,3), c(11,17)), +x[mwhich(x, c("A","B"), list(c(2,3), c(11,17)), list(c('ge','le'), c('gt', 'lt')), 'AND'),] # These should produce the same answer with a regular matrix: @@ -92,6 +93,7 @@ mwhich(x, 1, Inf, 'eq') mwhich(x, 1, 1, 'gt') mwhich(x, 1, 1, 'le') } +} \author{ John W. Emerson \email{} } diff --git a/man/sub.big.matrix.Rd b/man/sub.big.matrix.Rd index 7942efb..04d3a28 100644 --- a/man/sub.big.matrix.Rd +++ b/man/sub.big.matrix.Rd @@ -42,6 +42,7 @@ object that references a contiguous set of columns and rows of another otherwise. } \examples{ +\dontrun{ x <- big.matrix(10, 5, init=0, type="double") x[,] <- 1:50 y <- sub.big.matrix(x, 2, 9, 2, 3) @@ -49,6 +50,7 @@ y[,] y[1,1] <- -99 x[,] } +} \author{ John W. Emerson and Michael J. Kane } diff --git a/man/write.big.matrix.Rd b/man/write.big.matrix.Rd index 3b86d78..08d4e98 100644 --- a/man/write.big.matrix.Rd +++ b/man/write.big.matrix.Rd @@ -96,7 +96,9 @@ Or perhaps to specify columns targeted for factor or character conversion to numeric values. Would you use such features? Email us and let us know! } \examples{ +\dontrun{ # Without specifying the type, this big.matrix x will hold integers. + x <- as.big.matrix(matrix(1:10, 5, 2)) x[2,2] <- NA x[,] @@ -130,6 +132,7 @@ head(y) # The following would fail with a dimension mismatch: if (FALSE) y <- read.big.matrix("IrisData.txt", header=TRUE) } +} \author{ John W. Emerson and Michael J. Kane \email{} diff --git a/vignettes/Overview.Rnw b/vignettes/Overview.Rnw new file mode 100644 index 0000000..39ce880 --- /dev/null +++ b/vignettes/Overview.Rnw @@ -0,0 +1,409 @@ +% \VignetteIndexEntry{The Bigmemory Project Overview} +% \VignetteDepends{bigmemory} +% \VignettePackage{bigmemory} +% \VignetteEngine{knitr::knitr} +\documentclass[12pt]{article} + +\usepackage{graphics} +\usepackage{graphicx} + +\usepackage{accents} + +% New from euler: +\usepackage{ae} +\usepackage{color} +\usepackage{url} + +\topmargin=-0.85in +\textheight=9.5in +\textwidth=6.5in +\oddsidemargin=0in +%-0.25in + +%\usepackage{CJK} +%\usepackage{pinyin} +\def\E{\mathord{I\kern-.35em E}} +\def\R{\mathord{I\kern-.35em R}} +\def\P{\mathord{I\kern-.35em P}} +\def\I{\mathord{1\kern-.35em 1}} +\def\wt{\mathord{\widehat{\theta}}} + +\newcommand{\proglang}[1]{\textbf{#1}} +\newcommand{\pkg}[1]{\texttt{\textsl{#1}}} +\newcommand{\code}[1]{\texttt{#1}} +\newcommand{\mg}[1]{{\textcolor {magenta} {#1}}} +\newcommand{\gr}[1]{{\textcolor {green} {#1}}} +\newcommand{\bl}[1]{{\textcolor {blue} {#1}}} + +\newtheorem{thm}{Theorem}[section] +\newtheorem{myexplore}[thm]{Explore} +\newtheorem{mybackground}[thm]{Background} +\newtheorem{myquestion}[thm]{Question} +\newtheorem{myexample}[thm]{Example} +\newtheorem{mydefinition}[thm]{Definition} +\newtheorem{mytheorem}[thm]{Theorem} + +%\pagestyle{myheadings} % Go for customized headings +%\markboth{notused left title}{John W. Emerson, Department of Statistics, Yale University \copyright 2009} +%\newcommand{\sekshun}[1] % In 'article' only the page +% { % number appears in the header. +% \section{#1} % I want the section name AND +% \markboth{#1 \hfill}{#1 \hfill} % the page, so I need a new kind +% } % of '\sekshun' command. + +\begin{document} + +\setkeys{Gin}{width=1.0\textwidth} + +<>= +library(knitr) +opts_chunk$set( +fig.path='graphics/stat' +) +@ + + +<>= +options(keep.source = TRUE, width = 75) +@ + +\begin{center} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{\Large\bf The Bigmemory Project} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\vspace*{0.5cm} +{\bf Michael J. Kane and John W. Emerson\\ +Yale University\\ +April 29, 2010} + +\vspace*{0.25cm} + +\end{center} + +%\begin{raggedright} +\parindent=0.5in + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{quotation} +Multi-gigabyte data sets often challenge and frustrate \proglang{R} +users. \proglang{C/C++} programming can provide efficiencies, +but is cumbersome for interactive data analysis and +lacks the flexibility and power of \proglang{R}'s rich statistical +programming environment. The package \pkg{bigmemory} and sister +packages \pkg{biganalytics}, \pkg{synchronicity}, \pkg{bigtabulate}, +and \pkg{bigalgebra} bridge this gap, implementing massive matrices +and supporting their manipulation and exploration. +The data structures may be allocated to shared memory, allowing separate +processes on the same computer to share access to a single copy of the +data set. The data structures may also be file-backed, allowing users +to easily manage and analyze data sets larger than available RAM and +share them across nodes of a cluster. +These features of the Bigmemory Project open the door for powerful and +memory-efficient parallel analyses and data mining of massive data sets, +even on modest hardware. +\end{quotation} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\vspace*{0.5cm} +\noindent +{\bf Introductory Example: the 2009 JSM Data Expo} +\vspace*{0.5cm} + +Consider the complete airline on-time performance data +from the 2009 JSM Data Expo. The processed data set, \texttt{airline.csv}, +is approximately 11 GB (about 120 million rows and 29 columns) +with factors coded as integers (see \url{http://www.bigmemory.org/} for +processing information). +The \texttt{read.big.matrix()} call creates the binary +file-backing \texttt{airline.bin} +associated with the \texttt{big.matrix} object \texttt{x}. +Subsequent \proglang{R} sessions can attach instantly to \texttt{airline.bin} +without incurring the one-time overhead (about 25 minutes) +associated with creating the backing. +A summary of the entire data set is easily obtained using the new +\texttt{summary()} method. Note the surprising +presence of negative arrival and departure delays: exploratory data analysis +in action via \pkg{bigmemory}. The summary +only takes 3-4 minutes to process the 11 GB of data on a laptop with only +4 GB of RAM. +<>= +library(bigmemory) +library(biganalytics) +x <- read.big.matrix("airline.csv", type="integer", header=TRUE, + backingfile="airline.bin", + descriptorfile="airline.desc", + extraCols="Age") +summary(x) + +# min max mean NA's +#Year 1987 2008 1998.62 0 +#Month 1 12 6.55 0 +#DayofMonth 1 31 15.72 0 +#DayOfWeek 1 7 3.94 0 +#ArrDelay -1437 2598 7.05 2587529 +#DepDelay -1410 2601 8.17 2302136 +#... (other variables omitted here) ... +@ + + +\noindent +{\bf Overview} +\vspace*{0.5cm} + +Data frames and matrices in \proglang{R} are easy to use, +with typical manipulations executing quickly on +data sets much smaller than available RAM. They suit the needs of many +\proglang{R} users and work seamlessly with existing \proglang{R} functions +and packages. However, problems arise with larger data sets and when +increased memory requirements of parallel programming strain the system. + +The Bigmemory Project offers packages +for two purposes. First, \pkg{bigmemory}, \pkg{biganalytics}, and +\pkg{bigtabulate} have been designed to provide a minimalist, +elegant framework for users to manage and explore large data sets, even +on modest hardware (expensive workstations or clusters are not required). +The interface is designed to mimic \proglang{R}'s familiar \code{matrix} +syntax. Matthew Keller, Assistant Professor of +Psychology, University of Colorado at Boulder offered the following +testimonial about \pkg{bigmemory}: ``I love that it's intuitive and +doesn't require a lot of learning new ways to code things.'' + +Second, the packages of the Bigmemory Project provide a foundation for +memory-efficient parallel programming and can serve as building blocks +for developers of new high-performance computing tools in \proglang{R}. +When used in conjunction with a parallel package (such as \pkg{foreach}, +\pkg{snow}, \pkg{Rmpi}, or \pkg{multicore}, for example), +even shared-memory parallel-computing becomes +accessible to non-experts. +The programming interface is stable, and offers the flexibility to support +the development of +algorithms working seamlessly on both \texttt{big.matrix} and traditional +\texttt{matrix} objects. For examples of this, look first +at the function \texttt{mwhich()}; it offers flexible \texttt{which()}-like +functionality that is computationally efficient and avoids memory overhead. +In addition, all the functions provided by \pkg{bigtabulate} may be used +with \texttt{matrix} and \texttt{big.matrix} objects alike. + +\vspace*{0.5cm} +\noindent +{\bf Underneath the Hood of the Bigmemory Project} +\vspace*{0.5cm} + +The packages of the Bigmemory Project use the Boost Interprocess +\proglang{C++} library to provide platform-independent support for +massive matrices that may be shared across \proglang{R} processes. +Innovative use of \proglang{C++} accessors supports matrices of +\texttt{double}, \texttt{integer}, \texttt{short}, and \texttt{char}, +as well as the development of algorithms working seamlessly on +\texttt{big.matrix} objects or traditional \proglang{R} matrices. + +\vspace*{0.5cm} +\noindent +{\bf Example: Airplane Ages and Parallel Processing} +\vspace*{0.5cm} + +We would like to approximate the age of each plane at the time of +each flight. This first requires calculation of an approximate +``birthmonth'' for each plane: the month of the first +appearance in the data set. Given a matrix +\texttt{y} containing \texttt{Year} and \code{Month} for all flights +of a given plane, \texttt{birthmonth(y)} returns the +month (in months AD) of the earliest flight: +<>= +birthmonth <- function(y) { + minYear <- min(y[,'Year'], na.rm=TRUE) + these <- which(y[,'Year']==minYear) + minMonth <- min(y[these,'Month'], na.rm=TRUE) + return(12*minYear + minMonth - 1) +} +@ +A traditional approach to calculating all the birthmonths might use a \code{for()} loop: +<>= +allplanes <- unique(x[,'TailNum']) +planeStart <- rep(0, length(allplanes)) +for (i in allplanes) { + planeStart[i] <- birthmonth( x[mwhich(x, 'TailNum', i, 'eq'), + c('Year', 'Month'), drop=FALSE] ) +} +@ +With about 13,000 flights this takes about 9 hours, even with the relative +fast and memory-efficient use of \texttt{mwhich()}. + +A far more efficient alternative is to first obtain a list of row indices +for each plane: +<>= +library(bigtabulate) +planeindices <- bigsplit(x, 'TailNum') +@ +Here, the use of the new function \code{bigsplit()} is equivalent to +<>= +planeindices <- split(1:nrow(x), x[,'TailNum']) +@ +but is faster (16 versus 29 seconds) and more memory efficient (with +peak memory usage of 2 versus 3 GB). +Either way, +\texttt{planeindices[i]} contains all row indices corresponding to flights +with \texttt{TailNum} equal to \texttt{i}. This requires several hundred MB, +but is computationally more efficient in this problem. For example, +\texttt{planeindices} may be used with \code{sapply()} in the obvious way, +completing the task in a mere 30 seconds: +<>= +planeStart <- sapply(planeindices, + function(i) birthmonth(x[i, c('Year','Month'), + drop=FALSE])) +@ + +The looping structure \texttt{foreach()} of package \pkg{foreach} +can be a powerful and flexible alternative to \texttt{for()} or +functions like +\texttt{lapply()} and \texttt{sapply()}. It can also +take advantage of the shared-memory +capability of \pkg{bigmemory}. Package \pkg{doMC} provides one of several +available ``parallel backends'' for the function \texttt{foreach()}, allowing +the work to be automatically distributed to available processor cores: +<>= +library(doMC) +registerDoMC(cores=2) +planeStart <- foreach(i=planeindices, .combine=c) %dopar% { + return(birthmonth(x[i, c('Year','Month'), drop=FALSE])) +} +@ +The syntax of a \code{foreach()} loop is slightly different from the +syntax of a traditional loop, but its benefits are clear: +in this example, it takes only 14 seconds +to calculate the plane birthmonths using two processor cores.\footnote{We +should note that \pkg{doMC} and \pkg{multicore} are particularly well-suited +for this. When other parallel backends are used, one additional command is +required in the \code{birthmonth()} function: \code{x <- attach.big.matrix(xdesc)} +where \code{xdesc <- describe(x)} would be required just prior to the +\code{foreach()} loop, providing explicit shared-memory access across processes. +In contrast, \code{multicore} automatically operates on shared memory, +avoiding the need for this extra step.} +Both cores share access to the same master copy +of the airline data (with \texttt{Year} and \texttt{Month} cached in RAM); +individual calls to \texttt{birthmonth()} are relatively small in size. +Without the \texttt{registerDoMC()} +initialization, the \code{foreach()} loop would run on a single processor core, much +like \code{sapply()}, but taking about 24 seconds in this problem +with lower memory overhead than \code{sapply()}. + +Finally, the plane ages at the time of all flights may be calculated: +<>= +x[,'Age'] <- x[,'Year']*as.integer(12) + + x[,'Month'] - as.integer(planeStart[x[,'TailNum']]) +@ +This arithmetic is conducted on \proglang{R} vectors extracted from +the \code{big.matrix}; use of +\code{as.integer()} helps keep the memory consumption under control. + +\vspace*{0.5cm} +\noindent +{\bf Concluding Example: a Big Regression} +\vspace*{0.5cm} + +In addition to providing basic functions for exploratory data analysis, the +package \pkg{biganalytics} provides a wrapper for Thomas Lumley's +\pkg{biglm} package, supporting massive +linear and generalized linear models.\footnote{Package \pkg{biganalytics} +also provides \code{bigkmeans()}, and other analytics may be added to the +package in the future.} The following toy example examines +the airline arrival delays as a linear function of the age of the plane +at the time of the flight and the year of the flight. About 85 million +flights are used (because of missing airplane tailcodes). +We estimate that use of \proglang{R}'s \texttt{lm()} +function would require more than 10 GB of RAM of memory overhead, while +this example runs in about 3 minutes with only several hundred MB of memory +overhead. +<>= +blm <- biglm.big.matrix(ArrDelay ~ Age + Year, data=x) +summary(blm) +@ +<>= +#Large data regression model: biglm(formula = formula, data = data, ...) +#Sample size = 84216580 +# Coef (95% CI) SE p +#(Intercept) 91.6149 87.6509 95.5789 1.9820 0 +#Age 0.0144 0.0142 0.0146 0.0001 0 +#Year -0.0424 -0.0444 -0.0404 0.0010 0 +@ +From this, we might conclude that older planes are associated with increased predicted +delays, and predicted delays in recent years are lower. However, this +exercise is merely for illustrative purposes; a serious study of airline delays would +quickly reject this oversimplification and discover problems with this particular +regression. + +\vspace*{0.5cm} +\noindent +{\bf Additional Information and Supporting Material} +\vspace*{0.5cm} + +These examples were tested both in Linux 64-bit and Windows 7 Enterprise 64-bit +environments. +Older versions of Windows operating systems (including Vista 64-bit) seem +to suffer from extremely inefficient caching behavior with filebackings and +are not recommended for use with +\pkg{bigmemory}; 32-bit environments will be limited by approximately 2 GB +of addressable memory. + +The packages are available via R-Forge and on CRAN as of +late April, 2010; please see +\url{http://www.bigmemory.org/} for more information. +There is a short vignette available in the Documentation area, +as well as presentation slides introducing \pkg{bigmemory} +and providing some benchmarks and shared-memory parallel programming +examples. Please do not use the older version of \pkg{bigmemory} +archived on CRAN (versions <= 3.12). + +\newpage + +\noindent +{\bf Citations} +\vspace*{0.5cm} + +\begin{enumerate} +\item The Bigmemory Project, \url{http://www.bigmemory.org/}, the home of \proglang{R} packages +\pkg{bigmemory}, \pkg{biganalytics}, \pkg{bigtabulate}, \pkg{bigalgebra}, and +\pkg{synchronicity}. Packages available from CRAN or R-Forge. + +\item 2009 JSM Data Expo: Airline on-time performance. \url {http://stat-computing.org/dataexpo/2009/}. + +\item Thomas Lumley (2009). \pkg{biglm}: bounded memory linear and generalized + linear models. \proglang{R} package version 0.7, + \url{http://CRAN.R-project.org/package=biglm}. + +\item \proglang{R} Development Core Team (2009). \proglang{R}: A language and environment for + statistical computing. \proglang{R} Foundation for Statistical Computing, + Vienna, Austria. ISBN 3-900051-07-0, \url{http://www.R-project.org}. + +\item Luke Tierney, A. J. Rossini, Na Li and H. Sevcikova (). \pkg{snow}: Simple + Network of Workstations. \proglang{R} package version 0.3-3, + \url{http://CRAN.R-project.org/package=snow}. + +\item Simon Urbanek (2009). \pkg{multicore}: Parallel processing of \proglang{R} code on + machines with multiple cores or CPUs. \proglang{R} package version 0.1-3, + \url{http://www.rforge.net/multicore/}. + +\item Stephen Weston and REvolution Computing (2009). \pkg{doMC}: Foreach parallel adaptor for the + \pkg{multicore} package. \proglang{R} package version 1.2.0, + \url{http://CRAN.R-project.org/package=doMC}. + +\item Stephen Weston and REvolution Computing (2009). \pkg{foreach}: Foreach looping +construct for \proglang{R}. \proglang{R} package version 1.3.0, +\url{http://CRAN.R-project.org/package=foreach}. + +\item Hao Yu (2010). \pkg{Rmpi}: Interface (Wrapper) to MPI (Message-Passing Interface). + \proglang{R} package version 0.5-8, \url{http://www.stats.uwo.ca/faculty/yu/Rmpi}. +\end{enumerate} + + +%\end{raggedright} + +\end{document} From 6535cc9ac19c47d7819808212f3018e659c9071a Mon Sep 17 00:00:00 2001 From: Charles Determan Date: Tue, 21 Jul 2015 10:38:39 -0500 Subject: [PATCH 2/5] fix documentation problems, removed all R CMD check warnings --- R/RcppExports.R | 3 + R/bigmemory.R | 131 ++++++++++++++++++++++++++--- man-roxygen/flush_template.R | 2 + man/GetMatrixSize.Rd | 15 ++++ man/as.matrix-big.matrix-method.Rd | 17 ++++ man/big.matrix.Rd | 25 ++++++ man/big.matrix.descriptor-class.Rd | 19 +++++ man/bigmemory-package.Rd | 1 - man/dim-big.matrix-method.Rd | 16 ++++ man/dimnames-methods.Rd | 21 +++++ man/extract-methods.Rd | 64 ++++++++++++++ man/{flush.Rd => flush-methods.Rd} | 4 + man/head-methods.Rd | 22 +++++ man/is.float-numeric-method.Rd | 16 ++++ man/is.float.Rd | 15 ++++ man/length-big.matrix-method.Rd | 16 ++++ man/ncol-methods.Rd | 23 +++++ man/print-big.matrix-method.Rd | 22 +++++ man/sub.big.matrix.Rd | 8 ++ man/typeof-big.matrix-method.Rd | 17 ++++ man/write.big.matrix.Rd | 12 +++ src/bigmemory.cpp | 3 + 22 files changed, 458 insertions(+), 14 deletions(-) create mode 100644 man/GetMatrixSize.Rd create mode 100644 man/as.matrix-big.matrix-method.Rd create mode 100644 man/dim-big.matrix-method.Rd create mode 100644 man/dimnames-methods.Rd create mode 100644 man/extract-methods.Rd rename man/{flush.Rd => flush-methods.Rd} (92%) create mode 100644 man/head-methods.Rd create mode 100644 man/is.float-numeric-method.Rd create mode 100644 man/is.float.Rd create mode 100644 man/length-big.matrix-method.Rd create mode 100644 man/ncol-methods.Rd create mode 100644 man/print-big.matrix-method.Rd create mode 100644 man/typeof-big.matrix-method.Rd diff --git a/R/RcppExports.R b/R/RcppExports.R index 1505a88..549a9de 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -117,6 +117,9 @@ GetTypeString <- function(bigMatAddr) { .Call('bigmemory_GetTypeString', PACKAGE = 'bigmemory', bigMatAddr) } +#' @title big.matrix size +#' @description Returns the size of the created matrix in bytes +#' @param bigMat a \code{big.matrix} object #' @export GetMatrixSize <- function(bigMat) { .Call('bigmemory_GetMatrixSize', PACKAGE = 'bigmemory', bigMat) diff --git a/R/bigmemory.R b/R/bigmemory.R index 290ce35..b895f0f 100644 --- a/R/bigmemory.R +++ b/R/bigmemory.R @@ -199,6 +199,10 @@ setGeneric('as.big.matrix', descriptorfile=NULL, binarydescriptor=FALSE, shared=TRUE) standardGeneric('as.big.matrix')) +#' @title Convert to base R matrix +#' @description Extract values from a \code{big.matrix} object +#' and convert to a base R matrix object +#' @param x A big.matrix object #' @export setMethod('as.matrix', signature(x='big.matrix'), function(x) return(x[,])) @@ -283,9 +287,11 @@ setMethod('as.big.matrix', signature(x='vector'), #' @export setGeneric('is.big.matrix', function(x) standardGeneric('is.big.matrix')) +#' @rdname big.matrix setMethod('is.big.matrix', signature(x='big.matrix'), function(x) return(TRUE)) +#' @rdname big.matrix setMethod('is.big.matrix', definition=function(x) return(FALSE)) @@ -341,18 +347,32 @@ assign('rownames.bm<-', return(x) }) +#' @title The Number of Rows/Columns of a big.matrix +#' @description \code{nrow} and \code{ncol} return the number of +#' rows or columns present in a \code{big.matrix} object. +#' @param x A big.matrix object +#' @return An integer of length 1 +#' @docType methods +#' @rdname ncol-methods #' @export setMethod('ncol', signature(x="big.matrix"), function(x) return(CGetNcol(x@address))) +#' @rdname ncol-methods #' @export setMethod('nrow', signature(x="big.matrix"), function(x) return(CGetNrow(x@address))) +#' @title Dimensions of a big.matrix object +#' @description Retrieve the dimensions of a \code{big.matrix} object +#' @param x A \code{big.matrix} object #' @export setMethod('dim', signature(x="big.matrix"), function(x) return(c(nrow(x), ncol(x)))) +#' @title Length of a big.matrix object +#' @description Get the length of a \code{big.matrix} object +#' @param x A \code{big.matrix} object #' @export setMethod('length', signature(x="big.matrix"), function(x) return(prod(dim(x)))) @@ -470,51 +490,76 @@ GetAll.bm <- function(x, drop=TRUE) return(mat) } +#' @title Extract or Replace big.matrix elements +#' @name Extract,big.matrix +#' @param x A \code{big.matrix object} +#' @param i Indices specifying the rows +#' @param j Indices specifying the columns +#' @param drop Logical indication if reduce to minimum dimensions +#' @param value typically an array-like R object of similar class +#' @docType methods +#' @rdname extract-methods +#' @aliases [,big.matrix,ANY,ANY,missing-method #' @export setMethod("[", signature(x = "big.matrix", drop = "missing"), - function(x, i, j) return(GetElements.bm(x, i, j))) + function(x, i, j, drop) return(GetElements.bm(x, i, j))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", drop = "logical"), function(x, i, j, drop) return(GetElements.bm(x, i, j, drop))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", i="missing", drop = "missing"), - function(x, j) return(GetCols.bm(x, j))) + function(x, i, j, drop) return(GetCols.bm(x, j))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", i="missing", drop = "logical"), - function(x, j, drop) return(GetCols.bm(x, j, drop))) + function(x, i, j, drop) return(GetCols.bm(x, j, drop))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", j="missing", drop = "missing"), - function(x, i) return(GetRows.bm(x, i))) + function(x, i, j, drop) return(GetRows.bm(x, i))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", j="missing", drop = "logical"), - function(x, i, drop) return(GetRows.bm(x, i, drop))) + function(x, i, j, drop) return(GetRows.bm(x, i, drop))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", i="missing", j="missing", drop = "missing"), - function(x) return(GetAll.bm(x))) + function(x, i, j, drop) return(GetAll.bm(x))) + +#' @rdname extract-methods #' @export setMethod("[", signature(x = "big.matrix", i="missing", j="missing", drop = "logical"), - function(x, drop) return(GetAll.bm(x, drop))) + function(x, i, j, drop) return(GetAll.bm(x, drop))) # Function contributed by Peter Haverty at Genentech. +#' @rdname extract-methods #' @export setMethod('[', signature(x = "big.matrix",i="matrix",j="missing",drop="missing"), - function(x, i) return(GetIndivElements.bm(x, i))) + function(x, i, j, drop) return(GetIndivElements.bm(x, i))) SetElements.bm <- function(x, i, j, value) @@ -890,32 +935,41 @@ SetAll.bm <- function(x, value) return(x) } +#' @rdname extract-methods #' @export setMethod('[<-', signature(x = "big.matrix"), function(x, i, j, value) return(SetElements.bm(x, i, j, value))) +#' @rdname extract-methods #' @export setMethod('[<-', signature(x = "big.matrix", i="missing"), - function(x, j, value) return(SetCols.bm(x, j, value))) + function(x, i, j, value) return(SetCols.bm(x, j, value))) +#' @rdname extract-methods #' @export setMethod('[<-', signature(x = "big.matrix", j="missing"), - function(x, i, value) return(SetRows.bm(x, i, value))) + function(x, i, j, value) return(SetRows.bm(x, i, value))) +#' @rdname extract-methods #' @export setMethod('[<-', signature(x = "big.matrix", i="missing", j="missing"), - function(x, value) return(SetAll.bm(x, value))) + function(x, i, j, value) return(SetAll.bm(x, value))) # Function contributed by Peter Haverty at Genentech. +#' @rdname extract-methods #' @export setMethod('[<-', signature(x = "big.matrix",i="matrix",j="missing"), - function(x, i, value) return(SetIndivElements.bm(x, i, value))) + function(x, i, j, value) return(SetIndivElements.bm(x, i, value))) +#' @title The Type of a big.matrix Object +#' @description \code{typeof} returns the storage type of a +#' \code{big.matrix} object +#' @param x A \code{big.matrix} object #' @export setMethod('typeof', signature(x="big.matrix"), function(x) { @@ -926,11 +980,16 @@ setMethod('typeof', signature(x="big.matrix"), # Little function to test if a value is # the 'R' representation of float/single value +#' @title Check if Float +#' @param x An object to be evaluated if float #' @export setGeneric('is.float', function(x){ standardGeneric('is.float') }) +#' @title Is Float? +#' @description Check if R numeric value has float flag +#' @param x A numeric value setMethod('is.float', signature(x='numeric'), function(x){ if(is.null(attr(x, 'Csingle'))){ @@ -941,6 +1000,13 @@ setMethod('is.float', signature(x='numeric'), } }) +#' @title Return First or Last Part of a big.matrix Object +#' @description Returns the first or last parts of a \code{big.matrix} +#' object. +#' @param x A big.matrix object +#' @param n A single integer for the number of rows to return +#' @docType methods +#' @rdname head-methods #' @export setMethod('head', signature(x="big.matrix"), function(x, n = 6) { @@ -949,6 +1015,8 @@ setMethod('head', signature(x="big.matrix"), return(x[1:n,]) }) + +#' @rdname head-methods #' @export setMethod('tail', signature(x="big.matrix"), function(x, n = 6) { @@ -957,6 +1025,13 @@ setMethod('tail', signature(x="big.matrix"), return(x[(nrow(x)-n+1):nrow(x),]) }) +#' @title Print Values +#' @description \code{print} will print out the elements within +#' a \code{big.matrix} object. +#' @note By default, this will only return the \code{head} of a big.matrix +#' to prevent console overflow. If you trun off the bigmemory.print.warning +#' option then it will convert to a base R matrix and print all elements. +#' @param x A \code{big.matrix} object #' @export setMethod('print', signature(x='big.matrix'), function(x) { @@ -1143,10 +1218,19 @@ mwhich.internal <- function(x, cols, vals, comps, op, whichFuncName) return(ret) } + +#' @title Dimnames of a big.matrix Object +#' @description Retrieve or set the dimnames of an object +#' @param x A big.matrix object +#' @param value A possible value for \code{dimnames(x)} +#' @docType methods +#' @rdname dimnames-methods #' @export setMethod('dimnames', signature(x = "big.matrix"), function(x) return(list(rownames.bm(x), colnames.bm(x)))) + +#' @rdname dimnames-methods #' @export setMethod('dimnames<-', signature(x = "big.matrix", value='list'), function(x, value) { @@ -1167,6 +1251,7 @@ setGeneric('write.big.matrix', function(x, filename, row.names=FALSE, col.names=FALSE, sep=",") standardGeneric('write.big.matrix')) +#' @rdname write.big.matrix setMethod('write.big.matrix', signature(x='big.matrix',filename='character'), function(x, filename, row.names, col.names, sep) { @@ -1198,6 +1283,7 @@ setGeneric('read.big.matrix', shared=TRUE) standardGeneric('read.big.matrix')) +#' @rdname write.big.matrix setMethod('read.big.matrix', signature(filename='character'), function(filename, sep, header, col.names, row.names, has.row.names, ignore.row.names, type, skip, separated, backingfile, backingpath, @@ -1308,6 +1394,7 @@ setMethod('read.big.matrix', signature(filename='character'), #' @export setGeneric('is.separated', function(x) standardGeneric('is.separated')) +#' @rdname big.matrix setMethod('is.separated', signature(x='big.matrix'), function(x) return(IsSeparated(x@address))) @@ -1399,7 +1486,7 @@ deepcopy <- function(x, cols=NULL, rows=NULL, setGeneric('is.sub.big.matrix', function(x) standardGeneric('is.sub.big.matrix')) - +#' @rdname sub.big.matrix setMethod('is.sub.big.matrix', signature(x='big.matrix'), function(x) return(CIsSubMatrix(x@address)) ) @@ -1412,6 +1499,8 @@ setMethod('is.sub.big.matrix', signature(x='big.matrix'), setGeneric('sub.big.matrix', function(x, firstRow=1, lastRow=NULL, firstCol=1, lastCol=NULL, backingpath=NULL) standardGeneric('sub.big.matrix')) + +#' @rdname sub.big.matrix setMethod('sub.big.matrix', signature(x='big.matrix'), function(x, firstRow, lastRow, firstCol, lastCol, backingpath) { @@ -1420,6 +1509,12 @@ setMethod('sub.big.matrix', signature(x='big.matrix'), }) #' @rdname big.matrix.descriptor-class +#' @param x A descriptor object +#' @param firstRow the first row of the submatrix +#' @param lastRow the last row of the submatrix if not NULL +#' @param firstCol the first column of the submatrix +#' @param lastCol of the submatrix if not NULL +#' @param backingpath required path to the filebacked object, if applicable setMethod('sub.big.matrix', signature(x='big.matrix.descriptor'), function( x, firstRow, lastRow, firstCol, lastCol, backingpath) { @@ -1494,6 +1589,10 @@ attach.big.matrix = function(obj, ...) } #' @rdname big.matrix.descriptor-class +#' @param obj The filename of the descriptor for a filebacked matrix, +#' assumed ot be in the directory specified +#' @param ... possibly \code{path} which gives the path where the descriptor +#' and/or filebacking can be found. #' @export setMethod('attach.resource', signature(obj='character'), function(obj, ...) @@ -1613,6 +1712,7 @@ setMethod('attach.resource', signature(obj='big.matrix.descriptor'), #' @export setGeneric('is.filebacked', function(x) standardGeneric('is.filebacked')) +#' @rdname big.matrix setMethod('is.filebacked', signature(x='big.matrix'), function(x) return(IsFileBackedBigMatrix(x@address))) @@ -1620,6 +1720,7 @@ setMethod('is.filebacked', signature(x='big.matrix'), #' @export setGeneric('shared.name', function(x) standardGeneric('shared.name')) +#' @rdname big.matrix setMethod('shared.name', signature(x='big.matrix'), function(x) return(SharedName(x@address))) @@ -1627,6 +1728,7 @@ setMethod('shared.name', signature(x='big.matrix'), #' @export setGeneric('file.name', function(x) standardGeneric('file.name')) +#' @rdname big.matrix setMethod('file.name', signature(x='big.matrix'), function(x) { @@ -1658,6 +1760,7 @@ t.big.matrix <- function(x, backingfile=NULL, #' @export setGeneric('flush', function(con) standardGeneric('flush')) +#' @rdname flush-methods setMethod('flush', signature(con='big.matrix'), function(con) { @@ -1674,6 +1777,7 @@ setMethod('flush', signature(con='big.matrix'), #' @export setGeneric('is.shared', function(x) standardGeneric('is.shared')) +#' @rdname big.matrix setMethod('is.shared', signature(x='big.matrix'), function(x) return(IsShared(x@address))) @@ -1764,6 +1868,7 @@ mpermute <- function(x, order=NULL, cols=NULL, allow.duplicates=FALSE, ...) #' @export setGeneric('is.readonly', function(x) standardGeneric('is.readonly')) +#' @rdname big.matrix setMethod('is.readonly', signature(x='big.matrix'), function(x) IsReadOnly(x@address)) diff --git a/man-roxygen/flush_template.R b/man-roxygen/flush_template.R index 544b4d4..f7040bd 100644 --- a/man-roxygen/flush_template.R +++ b/man-roxygen/flush_template.R @@ -17,4 +17,6 @@ #' x[1,1] <- 0 #' flush(x) #' } +#' @docType methods +#' @rdname flush-methods #' @keywords methods diff --git a/man/GetMatrixSize.Rd b/man/GetMatrixSize.Rd new file mode 100644 index 0000000..2345151 --- /dev/null +++ b/man/GetMatrixSize.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/RcppExports.R +\name{GetMatrixSize} +\alias{GetMatrixSize} +\title{big.matrix size} +\usage{ +GetMatrixSize(bigMat) +} +\arguments{ +\item{bigMat}{a \code{big.matrix} object} +} +\description{ +Returns the size of the created matrix in bytes +} + diff --git a/man/as.matrix-big.matrix-method.Rd b/man/as.matrix-big.matrix-method.Rd new file mode 100644 index 0000000..b7ba0de --- /dev/null +++ b/man/as.matrix-big.matrix-method.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{as.matrix,big.matrix-method} +\alias{as.matrix,big.matrix-method} +\title{Convert to base R matrix} +\usage{ +\S4method{as.matrix}{big.matrix}(x) +} +\arguments{ +\item{x}{A big.matrix object} +} +\description{ +Extract values from a \code{big.matrix} object +and convert to a base R matrix object +} + diff --git a/man/big.matrix.Rd b/man/big.matrix.Rd index 4e3b8a3..aaaef6b 100644 --- a/man/big.matrix.Rd +++ b/man/big.matrix.Rd @@ -1,17 +1,26 @@ % Generated by roxygen2 (4.1.1): do not edit by hand % Please edit documentation in R/bigmemory.R +\docType{methods} \name{big.matrix} \alias{as.big.matrix} \alias{big.matrix} \alias{file.name} +\alias{file.name,big.matrix-method} \alias{filebacked.big.matrix} \alias{is.big.matrix} +\alias{is.big.matrix,ANY-method} +\alias{is.big.matrix,big.matrix-method} \alias{is.filebacked} +\alias{is.filebacked,big.matrix-method} \alias{is.nil} \alias{is.readonly} +\alias{is.readonly,big.matrix-method} \alias{is.separated} +\alias{is.separated,big.matrix-method} \alias{is.shared} +\alias{is.shared,big.matrix-method} \alias{shared.name} +\alias{shared.name,big.matrix-method} \title{The core "big.matrix" operations.} \usage{ big.matrix(nrow, ncol, type = options()$bigmemory.default.type, init = NULL, @@ -29,18 +38,34 @@ as.big.matrix(x, type = NULL, separated = FALSE, backingfile = NULL, is.big.matrix(x) +\S4method{is.big.matrix}{big.matrix}(x) + +\S4method{is.big.matrix}{ANY}(x) + is.separated(x) +\S4method{is.separated}{big.matrix}(x) + is.filebacked(x) +\S4method{is.filebacked}{big.matrix}(x) + shared.name(x) +\S4method{shared.name}{big.matrix}(x) + file.name(x) +\S4method{file.name}{big.matrix}(x) + is.shared(x) +\S4method{is.shared}{big.matrix}(x) + is.readonly(x) +\S4method{is.readonly}{big.matrix}(x) + is.nil(address) } \arguments{ diff --git a/man/big.matrix.descriptor-class.Rd b/man/big.matrix.descriptor-class.Rd index b06f900..c167aeb 100644 --- a/man/big.matrix.descriptor-class.Rd +++ b/man/big.matrix.descriptor-class.Rd @@ -16,6 +16,25 @@ \S4method{attach.resource}{big.matrix.descriptor}(obj, ...) } +\arguments{ +\item{x}{A descriptor object} + +\item{firstRow}{the first row of the submatrix} + +\item{lastRow}{the last row of the submatrix if not NULL} + +\item{firstCol}{the first column of the submatrix} + +\item{lastCol}{of the submatrix if not NULL} + +\item{backingpath}{required path to the filebacked object, if applicable} + +\item{obj}{The filename of the descriptor for a filebacked matrix, +assumed ot be in the directory specified} + +\item{...}{possibly \code{path} which gives the path where the descriptor +and/or filebacking can be found.} +} \description{ An object of this class contains necessary and sufficient information to ``attach'' a shared or filebacked \code{\link{big.matrix}}. diff --git a/man/bigmemory-package.Rd b/man/bigmemory-package.Rd index 11acaaa..9bf1c53 100644 --- a/man/bigmemory-package.Rd +++ b/man/bigmemory-package.Rd @@ -99,7 +99,6 @@ matrix. # Our examples are all trivial in size, rather than burning huge amounts # of memory. -gc() x <- big.matrix(5, 2, type="integer", init=0, dimnames=list(NULL, c("alpha", "beta"))) x diff --git a/man/dim-big.matrix-method.Rd b/man/dim-big.matrix-method.Rd new file mode 100644 index 0000000..3c64ad1 --- /dev/null +++ b/man/dim-big.matrix-method.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{dim,big.matrix-method} +\alias{dim,big.matrix-method} +\title{Dimensions of a big.matrix object} +\usage{ +\S4method{dim}{big.matrix}(x) +} +\arguments{ +\item{x}{A \code{big.matrix} object} +} +\description{ +Retrieve the dimensions of a \code{big.matrix} object +} + diff --git a/man/dimnames-methods.Rd b/man/dimnames-methods.Rd new file mode 100644 index 0000000..78bb6c7 --- /dev/null +++ b/man/dimnames-methods.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{dimnames,big.matrix-method} +\alias{dimnames,big.matrix-method} +\alias{dimnames<-,big.matrix,list-method} +\title{Dimnames of a big.matrix Object} +\usage{ +\S4method{dimnames}{big.matrix}(x) + +\S4method{dimnames}{big.matrix,list}(x) <- value +} +\arguments{ +\item{x}{A big.matrix object} + +\item{value}{A possible value for \code{dimnames(x)}} +} +\description{ +Retrieve or set the dimnames of an object +} + diff --git a/man/extract-methods.Rd b/man/extract-methods.Rd new file mode 100644 index 0000000..3c8612e --- /dev/null +++ b/man/extract-methods.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{Extract,big.matrix} +\alias{Extract,big.matrix} +\alias{[,big.matrix,ANY,ANY,logical-method} +\alias{[,big.matrix,ANY,ANY,missing-method} +\alias{[,big.matrix,ANY,missing,logical-method} +\alias{[,big.matrix,ANY,missing,missing-method} +\alias{[,big.matrix,matrix,missing,missing-method} +\alias{[,big.matrix,missing,ANY,logical-method} +\alias{[,big.matrix,missing,ANY,missing-method} +\alias{[,big.matrix,missing,missing,logical-method} +\alias{[,big.matrix,missing,missing,missing-method} +\alias{[<-,big.matrix,ANY,ANY-method} +\alias{[<-,big.matrix,ANY,missing-method} +\alias{[<-,big.matrix,matrix,missing-method} +\alias{[<-,big.matrix,missing,ANY-method} +\alias{[<-,big.matrix,missing,missing-method} +\title{Extract or Replace big.matrix elements} +\usage{ +\S4method{[}{big.matrix,ANY,ANY,missing}(x, i, j, drop) + +\S4method{[}{big.matrix,ANY,ANY,logical}(x, i, j, drop) + +\S4method{[}{big.matrix,missing,ANY,missing}(x, i, j, drop) + +\S4method{[}{big.matrix,missing,ANY,logical}(x, i, j, drop) + +\S4method{[}{big.matrix,ANY,missing,missing}(x, i, j, drop) + +\S4method{[}{big.matrix,ANY,missing,logical}(x, i, j, drop) + +\S4method{[}{big.matrix,missing,missing,missing}(x, i, j, drop) + +\S4method{[}{big.matrix,missing,missing,logical}(x, i, j, drop) + +\S4method{[}{big.matrix,matrix,missing,missing}(x, i, j, drop) + +\S4method{[}{big.matrix,ANY,ANY}(x, i, j) <- value + +\S4method{[}{big.matrix,missing,ANY}(x, i, j) <- value + +\S4method{[}{big.matrix,ANY,missing}(x, i, j) <- value + +\S4method{[}{big.matrix,missing,missing}(x, i, j) <- value + +\S4method{[}{big.matrix,matrix,missing}(x, i, j) <- value +} +\arguments{ +\item{x}{A \code{big.matrix object}} + +\item{i}{Indices specifying the rows} + +\item{j}{Indices specifying the columns} + +\item{drop}{Logical indication if reduce to minimum dimensions} + +\item{value}{typically an array-like R object of similar class} +} +\description{ +Extract or Replace big.matrix elements +} + diff --git a/man/flush.Rd b/man/flush-methods.Rd similarity index 92% rename from man/flush.Rd rename to man/flush-methods.Rd index 03ab834..405bcd7 100644 --- a/man/flush.Rd +++ b/man/flush-methods.Rd @@ -1,10 +1,14 @@ % Generated by roxygen2 (4.1.1): do not edit by hand % Please edit documentation in R/bigmemory.R +\docType{methods} \name{flush} \alias{flush} +\alias{flush,big.matrix-method} \title{Updating a big.matrix filebacking.} \usage{ flush(con) + +\S4method{flush}{big.matrix}(con) } \arguments{ \item{con}{filebacked \code{\link{big.matrix}}.} diff --git a/man/head-methods.Rd b/man/head-methods.Rd new file mode 100644 index 0000000..a7de2fd --- /dev/null +++ b/man/head-methods.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{head,big.matrix-method} +\alias{head,big.matrix-method} +\alias{tail,big.matrix-method} +\title{Return First or Last Part of a big.matrix Object} +\usage{ +\S4method{head}{big.matrix}(x, n = 6) + +\S4method{tail}{big.matrix}(x, n = 6) +} +\arguments{ +\item{x}{A big.matrix object} + +\item{n}{A single integer for the number of rows to return} +} +\description{ +Returns the first or last parts of a \code{big.matrix} +object. +} + diff --git a/man/is.float-numeric-method.Rd b/man/is.float-numeric-method.Rd new file mode 100644 index 0000000..9f6d016 --- /dev/null +++ b/man/is.float-numeric-method.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{is.float,numeric-method} +\alias{is.float,numeric-method} +\title{Is Float?} +\usage{ +\S4method{is.float}{numeric}(x) +} +\arguments{ +\item{x}{A numeric value} +} +\description{ +Check if R numeric value has float flag +} + diff --git a/man/is.float.Rd b/man/is.float.Rd new file mode 100644 index 0000000..5fa0eff --- /dev/null +++ b/man/is.float.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\name{is.float} +\alias{is.float} +\title{Check if Float} +\usage{ +is.float(x) +} +\arguments{ +\item{x}{An object to be evaluated if float} +} +\description{ +Check if Float +} + diff --git a/man/length-big.matrix-method.Rd b/man/length-big.matrix-method.Rd new file mode 100644 index 0000000..87bda17 --- /dev/null +++ b/man/length-big.matrix-method.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{length,big.matrix-method} +\alias{length,big.matrix-method} +\title{Length of a big.matrix object} +\usage{ +\S4method{length}{big.matrix}(x) +} +\arguments{ +\item{x}{A \code{big.matrix} object} +} +\description{ +Get the length of a \code{big.matrix} object +} + diff --git a/man/ncol-methods.Rd b/man/ncol-methods.Rd new file mode 100644 index 0000000..e63195f --- /dev/null +++ b/man/ncol-methods.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{ncol,big.matrix-method} +\alias{ncol,big.matrix-method} +\alias{nrow,big.matrix-method} +\title{The Number of Rows/Columns of a big.matrix} +\usage{ +\S4method{ncol}{big.matrix}(x) + +\S4method{nrow}{big.matrix}(x) +} +\arguments{ +\item{x}{A big.matrix object} +} +\value{ +An integer of length 1 +} +\description{ +\code{nrow} and \code{ncol} return the number of +rows or columns present in a \code{big.matrix} object. +} + diff --git a/man/print-big.matrix-method.Rd b/man/print-big.matrix-method.Rd new file mode 100644 index 0000000..ff2005c --- /dev/null +++ b/man/print-big.matrix-method.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{print,big.matrix-method} +\alias{print,big.matrix-method} +\title{Print Values} +\usage{ +\S4method{print}{big.matrix}(x) +} +\arguments{ +\item{x}{A \code{big.matrix} object} +} +\description{ +\code{print} will print out the elements within +a \code{big.matrix} object. +} +\note{ +By default, this will only return the \code{head} of a big.matrix +to prevent console overflow. If you trun off the bigmemory.print.warning +option then it will convert to a base R matrix and print all elements. +} + diff --git a/man/sub.big.matrix.Rd b/man/sub.big.matrix.Rd index 04d3a28..126c37c 100644 --- a/man/sub.big.matrix.Rd +++ b/man/sub.big.matrix.Rd @@ -1,14 +1,22 @@ % Generated by roxygen2 (4.1.1): do not edit by hand % Please edit documentation in R/bigmemory.R +\docType{methods} \name{is.sub.big.matrix} \alias{is.sub.big.matrix} +\alias{is.sub.big.matrix,big.matrix-method} \alias{sub.big.matrix} +\alias{sub.big.matrix,big.matrix-method} \title{Submatrix support} \usage{ is.sub.big.matrix(x) +\S4method{is.sub.big.matrix}{big.matrix}(x) + sub.big.matrix(x, firstRow = 1, lastRow = NULL, firstCol = 1, lastCol = NULL, backingpath = NULL) + +\S4method{sub.big.matrix}{big.matrix}(x, firstRow = 1, lastRow = NULL, + firstCol = 1, lastCol = NULL, backingpath = NULL) } \arguments{ \item{x}{either a \code{\link{big.matrix}} or a descriptor.} diff --git a/man/typeof-big.matrix-method.Rd b/man/typeof-big.matrix-method.Rd new file mode 100644 index 0000000..d6c3a54 --- /dev/null +++ b/man/typeof-big.matrix-method.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/bigmemory.R +\docType{methods} +\name{typeof,big.matrix-method} +\alias{typeof,big.matrix-method} +\title{The Type of a big.matrix Object} +\usage{ +\S4method{typeof}{big.matrix}(x) +} +\arguments{ +\item{x}{A \code{big.matrix} object} +} +\description{ +\code{typeof} returns the storage type of a +\code{big.matrix} object +} + diff --git a/man/write.big.matrix.Rd b/man/write.big.matrix.Rd index 08d4e98..2584c8f 100644 --- a/man/write.big.matrix.Rd +++ b/man/write.big.matrix.Rd @@ -1,18 +1,30 @@ % Generated by roxygen2 (4.1.1): do not edit by hand % Please edit documentation in R/bigmemory.R +\docType{methods} \name{write.big.matrix} \alias{read.big.matrix} +\alias{read.big.matrix,character-method} \alias{write.big.matrix} +\alias{write.big.matrix,big.matrix,character-method} \title{File interface for a ``big.matrix''} \usage{ write.big.matrix(x, filename, row.names = FALSE, col.names = FALSE, sep = ",") +\S4method{write.big.matrix}{big.matrix,character}(x, filename, + row.names = FALSE, col.names = FALSE, sep = ",") + read.big.matrix(filename, sep = ",", header = FALSE, col.names = NULL, row.names = NULL, has.row.names = FALSE, ignore.row.names = FALSE, type = NA, skip = 0, separated = FALSE, backingfile = NULL, backingpath = NULL, descriptorfile = NULL, binarydescriptor = FALSE, extraCols = NULL, shared = TRUE) + +\S4method{read.big.matrix}{character}(filename, sep = ",", header = FALSE, + col.names = NULL, row.names = NULL, has.row.names = FALSE, + ignore.row.names = FALSE, type = NA, skip = 0, separated = FALSE, + backingfile = NULL, backingpath = NULL, descriptorfile = NULL, + binarydescriptor = FALSE, extraCols = NULL, shared = TRUE) } \arguments{ \item{x}{a \code{\link{big.matrix}}.} diff --git a/src/bigmemory.cpp b/src/bigmemory.cpp index 65d87bf..8304f54 100644 --- a/src/bigmemory.cpp +++ b/src/bigmemory.cpp @@ -1768,6 +1768,9 @@ Rcpp::String GetTypeString( SEXP bigMatAddr ) * quick function to access big.matrix sizes * possibly convert in to a method for object.size??? */ +//' @title big.matrix size +//' @description Returns the size of the created matrix in bytes +//' @param bigMat a \code{big.matrix} object //' @export // [[Rcpp::export]] SEXP GetMatrixSize( SEXP bigMat ) From 2bfd4ec4e585483867656c80c9c04180e95c1783 Mon Sep 17 00:00:00 2001 From: Charles Determan Date: Thu, 23 Jul 2015 11:19:10 -0500 Subject: [PATCH 3/5] add check to test if backing file already exists when creating a filebacked.big.matrix --- R/bigmemory.R | 8 +++++++- tests/testthat/test_create.R | 7 ++++++- tests/testthat/test_float_type.R | 5 +++++ tests/testthat/test_matrix_manips.R | 5 +++++ tests/testthat/test_misc.R | 7 ++++++- tests/testthat/test_read.R | 2 +- tests/testthat/test_readonly.R | 20 +++++++++++++++++--- 7 files changed, 47 insertions(+), 7 deletions(-) diff --git a/R/bigmemory.R b/R/bigmemory.R index b895f0f..de20f06 100644 --- a/R/bigmemory.R +++ b/R/bigmemory.R @@ -112,7 +112,7 @@ filebacked.big.matrix <- function(nrow, ncol, init=NULL, dimnames=NULL, separated=FALSE, backingfile=NULL, backingpath=NULL, descriptorfile=NULL, binarydescriptor=FALSE) -{ +{ if (nrow < 1 | ncol < 1) stop('A big.matrix must have at least one row and one column') @@ -157,6 +157,12 @@ filebacked.big.matrix <- function(nrow, ncol, backingpath <- path.expand(backingpath) backingpath <- file.path(backingpath, '.') backingpath <- substr( backingpath, 1, nchar(backingpath)-1 ) + + if(file.exists(file.path(backingpath, backingfile))){ + stop("Backing file already exists! Either remove or specify + different backing file name") + } + address <- CreateFileBackedBigMatrix(as.character(backingfile), as.character(backingpath), as.double(nrow), as.double(ncol), as.character(colnames), as.character(rownames), as.integer(typeVal), diff --git a/tests/testthat/test_create.R b/tests/testthat/test_create.R index 7657aa1..596d88c 100644 --- a/tests/testthat/test_create.R +++ b/tests/testthat/test_create.R @@ -39,4 +39,9 @@ test_that("attach methods successful",{ x <- attach.big.matrix(bmdescription) expect_false(identical(z@address, y@address)) expect_identical(bm[,], x[,]) -}) \ No newline at end of file +}) + +rm(z) +gc() +file.remove('example.bin') +file.remove('example.desc') diff --git a/tests/testthat/test_float_type.R b/tests/testthat/test_float_type.R index ac75a1c..b9985c9 100644 --- a/tests/testthat/test_float_type.R +++ b/tests/testthat/test_float_type.R @@ -54,3 +54,8 @@ test_that("Proper warning returned", { float type downcast") }) +rm(z) +gc() +file.remove('example.bin') +file.remove('example.desc') + diff --git a/tests/testthat/test_matrix_manips.R b/tests/testthat/test_matrix_manips.R index 97edcc1..3738905 100644 --- a/tests/testthat/test_matrix_manips.R +++ b/tests/testthat/test_matrix_manips.R @@ -46,3 +46,8 @@ test_that("flush works correctly",{ expect_warning(flush(bm), info="You cannot call flush on a non-filebacked big.matrix") }) + +rm(z) +gc() +file.remove('example.bin') +file.remove('example.desc') diff --git a/tests/testthat/test_misc.R b/tests/testthat/test_misc.R index 65f74a3..f9124bd 100644 --- a/tests/testthat/test_misc.R +++ b/tests/testthat/test_misc.R @@ -37,4 +37,9 @@ test_that("dimnames returned are correct", { expect_identical(dimnames(mat), dimnames(z), info = "dimnames don't match between filebacked.big.matrix and matrix") -}) \ No newline at end of file +}) + +rm(z) +gc() +file.remove('example.bin') +file.remove('example.desc') diff --git a/tests/testthat/test_read.R b/tests/testthat/test_read.R index efca2ad..77b8a7c 100644 --- a/tests/testthat/test_read.R +++ b/tests/testthat/test_read.R @@ -58,4 +58,4 @@ test_that("test_read", { expect_identical(bmnull[, ], matnull[, ], info = "full matrix without names") } return(TRUE) -}) \ No newline at end of file +}) diff --git a/tests/testthat/test_readonly.R b/tests/testthat/test_readonly.R index 7367757..d0755b2 100644 --- a/tests/testthat/test_readonly.R +++ b/tests/testthat/test_readonly.R @@ -9,8 +9,8 @@ fbm.file = "fbm" fbm.desc.file = "fbm.desc" fbm.desc.path = file.path(back.dir,fbm.desc.file) fbm.data.path = file.path(back.dir,fbm.file) -fbm = filebacked.big.matrix(3,3,dimnames=list(rownames,colnames),backingpath=back.dir, backingfile=fbm.file, descriptorfile=paste(fbm.file,".desc",sep="")) -fbm[,] = 1:9 +# fbm = filebacked.big.matrix(3,3,dimnames=list(rownames,colnames),backingpath=back.dir, backingfile=fbm.file, descriptorfile=paste(fbm.file,".desc",sep="")) +# fbm[,] = 1:9 bm = big.matrix(3,3,dimnames=list(rownames,colnames)) @@ -39,6 +39,13 @@ test_that("test_readonly", { expect_error({ bm2[matrix(c(1, 2, 2, 2), ncol = 2), ] = 100 }, info = "Writing subset by matrix to a big.matrix made read-only by FS before attached gives error") + + # in order to reuse, must remove prior objects +# rm(fbm) +# gc() +# file.remove(file.path(back.dir, fbm.file)) +# file.remove(file.path(back.dir, fbm.desc.file)) + fbm = filebacked.big.matrix(3, 3, dimnames = list(rownames, colnames), backingpath = back.dir, backingfile = fbm.file, descriptorfile = fbm.desc.file) @@ -83,4 +90,11 @@ test_that("test_readonly", { fbm3[1, 1] = 100 }, info = "Should give error if you ask for a readonly matrix and try to write to it.") return(TRUE) -}) \ No newline at end of file + + rm(fbm, fbm2, fbm3) + gc() + file.remove(file.path(back.dir, fbm.file)) + file.remove(file.path(back.dir, fbm.desc.file)) +}) + + From 183f79718053cc9d09b395535354ca2b44f9b2e6 Mon Sep 17 00:00:00 2001 From: Charles Determan Date: Thu, 23 Jul 2015 11:37:28 -0500 Subject: [PATCH 4/5] make more badges available add appveyor and coveralls badges back to display --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 04deb1e..48e2866 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Build Status](https://travis-ci.org/kaneplusplus/bigmemory.png)](https://travis-ci.org/kaneplusplus/bigmemory) - From 627dac612b1eb5dd5e7e110688e705e1264edfb9 Mon Sep 17 00:00:00 2001 From: Charles Determan Date: Thu, 23 Jul 2015 11:48:38 -0500 Subject: [PATCH 5/5] removed examples directory because \dontrun doesn't work on example 'files'. May address this again if such functionality becomes available. --- examples/attach.big.matrix_examples.R | 22 ----------- examples/core_examples.R | 56 --------------------------- examples/morder_examples.R | 7 ---- examples/mwhich_examples.R | 39 ------------------- examples/test_example.R | 1 - examples/write.big.matrix_examples.R | 34 ---------------- 6 files changed, 159 deletions(-) delete mode 100644 examples/attach.big.matrix_examples.R delete mode 100644 examples/core_examples.R delete mode 100644 examples/morder_examples.R delete mode 100644 examples/mwhich_examples.R delete mode 100644 examples/test_example.R delete mode 100644 examples/write.big.matrix_examples.R diff --git a/examples/attach.big.matrix_examples.R b/examples/attach.big.matrix_examples.R deleted file mode 100644 index 5fd5a21..0000000 --- a/examples/attach.big.matrix_examples.R +++ /dev/null @@ -1,22 +0,0 @@ -# The example is quite silly, as you wouldn't likely do this in a -# single R session. But if zdescription were passed to another R session -# via SNOW, foreach, or even by a simple file read/write, -# then the attach of the second R process would give access to the -# same object in memory. Please see the package vignette for real examples. - -# Not run -z <- big.matrix(3, 3, type='integer', init=3) -z[,] -dim(z) -z[1,1] <- 2 -z[,] -zdescription <- describe(z) -zdescription -y <- attach.big.matrix(zdescription) -y[,] -y -z -zz <- attach.resource(zdescription) -zz[1,1] <- -100 -y[,] -z[,] diff --git a/examples/core_examples.R b/examples/core_examples.R deleted file mode 100644 index ed87cbc..0000000 --- a/examples/core_examples.R +++ /dev/null @@ -1,56 +0,0 @@ -# Not Run -library(bigmemory) -x <- big.matrix(10, 2, type='integer', init=-5) -options(bigmemory.allow.dimnames=TRUE) -colnames(x) <- c("alpha", "beta") -is.big.matrix(x) -dim(x) -colnames(x) -rownames(x) -x[,] -x[1:8,1] <- 11:18 -colnames(x) <- NULL -x[,] - -# The following shared memory example is quite silly, as you wouldn't -# likely do this in a single R session. But if zdescription were -# passed to another R session via SNOW, foreach, or even by a -# simple file read/write, then the attach.big.matrix() within the -# second R process would give access to the same object in memory. -# Please see the package vignette for real examples. - -# Not run -z <- big.matrix(3, 3, type='integer', init=3) -z[,] -dim(z) -z[1,1] <- 2 -z[,] -zdescription <- describe(z) -zdescription -y <- attach.big.matrix(zdescription) -y[,] -y -z -y[1,1] <- -100 -y[,] -z[,] - -# A short filebacked example, showing the creation of associated files: -# Not run -files <- dir() -files[grep("example.bin", files)] - -z <- filebacked.big.matrix(3, 3, type='integer', init=123, - backingfile="example.bin", - descriptorfile="example.desc", - dimnames=list(c('a','b','c'), c('d', 'e', 'f'))) -z[,] -files <- dir() -files[grep("example.bin", files)] -zz <- attach.big.matrix("example.desc") -zz[,] -zz[1,1] <- 0 -zzz <- attach.big.matrix(describe(z)) -zzz[,] - -is.nil(z@address) diff --git a/examples/morder_examples.R b/examples/morder_examples.R deleted file mode 100644 index 13166aa..0000000 --- a/examples/morder_examples.R +++ /dev/null @@ -1,7 +0,0 @@ -m = matrix(as.double(as.matrix(iris)), nrow=nrow(iris)) -morder(m, 1) -order(m[,1]) - -m[order(m[,1]), 2] -mpermute(m, cols=1) -m[,2] diff --git a/examples/mwhich_examples.R b/examples/mwhich_examples.R deleted file mode 100644 index 4e11c92..0000000 --- a/examples/mwhich_examples.R +++ /dev/null @@ -1,39 +0,0 @@ -x <- as.big.matrix(matrix(1:30, 10, 3)) -options(bigmemory.allow.dimnames=TRUE) -colnames(x) <- c("A", "B", "C") -x[,] -x[mwhich(x, 1:2, list(c(2,3), c(11,17)), - list(c('ge','le'), c('gt', 'lt')), 'OR'),] - -x[mwhich(x, c("A","B"), list(c(2,3), c(11,17)), - list(c('ge','le'), c('gt', 'lt')), 'AND'),] - -# These should produce the same answer with a regular matrix: -y <- matrix(1:30, 10, 3) -y[mwhich(y, 1:2, list(c(2,3), c(11,17)), - list(c('ge','le'), c('gt', 'lt')), 'OR'),] - -y[mwhich(y, -3, list(c(2,3), c(11,17)), - list(c('ge','le'), c('gt', 'lt')), 'AND'),] - - -x[1,1] <- NA -mwhich(x, 1:2, NA, 'eq', 'OR') -mwhich(x, 1:2, NA, 'neq', 'AND') - -# Column 1 equal to 4 and/or column 2 less than or equal to 16: -mwhich(x, 1:2, list(4, 16), list('eq', 'le'), 'OR') -mwhich(x, 1:2, list(4, 16), list('eq', 'le'), 'AND') - -# Column 2 less than or equal to 15: -mwhich(x, 2, 15, 'le') - -# No NAs in either column, and column 2 strictly less than 15: -mwhich(x, c(1:2,2), list(NA, NA, 15), list('neq', 'neq', 'lt'), 'AND') - -gc() -x <- big.matrix(4, 2, init=1, type="double") -x[1,1] <- Inf -mwhich(x, 1, Inf, 'eq') -mwhich(x, 1, 1, 'gt') -mwhich(x, 1, 1, 'le') diff --git a/examples/test_example.R b/examples/test_example.R deleted file mode 100644 index d08d7ff..0000000 --- a/examples/test_example.R +++ /dev/null @@ -1 +0,0 @@ -test() \ No newline at end of file diff --git a/examples/write.big.matrix_examples.R b/examples/write.big.matrix_examples.R deleted file mode 100644 index e0c65d7..0000000 --- a/examples/write.big.matrix_examples.R +++ /dev/null @@ -1,34 +0,0 @@ -# Without specifying the type, this big.matrix x will hold integers. - -x <- as.big.matrix(matrix(1:10, 5, 2)) -x[2,2] <- NA -x[,] -write.big.matrix(x, "foo.txt") - -# Just for fun, I'll read it back in as character (1-byte integers): -y <- read.big.matrix("foo.txt", type="char") -y[,] - -# Other examples: -w <- as.big.matrix(matrix(1:10, 5, 2), type='double') -w[1,2] <- NA -w[2,2] <- -Inf -w[3,2] <- Inf -w[4,2] <- NaN -w[,] -write.big.matrix(w, "bar.txt") -w <- read.big.matrix("bar.txt", type="double") -w[,] -w <- read.big.matrix("bar.txt", type="short") -w[,] - -# Another example using row names (which we don't like). -x <- as.big.matrix(as.matrix(iris), type='double') -rownames(x) <- as.character(1:nrow(x)) -head(x) -write.big.matrix(x, 'IrisData.txt', col.names=TRUE, row.names=TRUE) -y <- read.big.matrix("IrisData.txt", header=TRUE, has.row.names=TRUE) -head(y) - -# The following would fail with a dimension mismatch: -if (FALSE) y <- read.big.matrix("IrisData.txt", header=TRUE)