gower/0000755000176200001440000000000014730230732011376 5ustar liggesusersgower/tests/0000755000176200001440000000000013465343632012550 5ustar liggesusersgower/tests/tinytest.R0000644000176200001440000000010513452644704014552 0ustar liggesuserslibrary(gower) if ( require(tinytest) ){ test_package("gower") } gower/MD50000644000176200001440000000202014730230732011700 0ustar liggesusers0fd010acb615a297ad21e4592be58b5a *DESCRIPTION 83404f04f998736f089f40b74968e0a3 *NAMESPACE d69a7d073af4637ec27a2c0d93b560cb *NEWS b76763f073dfa84a596de62ce4b9cdbc *R/gower-pkg.R 4a16726ebf78bce164a0317a74aed380 *R/gower.R 5182d7e8c00a6aa828e3d422472f237f *build/vignette.rds b54853011026a0f34882fc97a62ac44b *inst/doc/intro.R b69562b9ebfbf47bbc317ec4ddc75bed *inst/doc/intro.Rnw a28e0bedc5ab593027de7b9654d91598 *inst/doc/intro.pdf a4cb8fda8f8f4c00ac14bb7c62f53fc7 *inst/tinytest/test_gh_issue_18.R e18ddf4bcf58a0d66741d97a2973a8f6 *inst/tinytest/test_gh_issue_8.R 16597acad91c4887f4d218357d94aa5f *inst/tinytest/test_gower.R 807415d767d8663322e7d84d276d7bf1 *man/gower-package.Rd b3113685003a6e17ee83b0a382c51f85 *man/gower_dist.Rd d23e7f8ba6fcb8599acd1f3aa61596ad *man/gower_topn.Rd 4e95da77024f1ca60e63ce4aabf063c1 *src/Makevars 0217cb9e5a7aaecd95136460dcbc8390 *src/R_register_native.c 7088b90d764f756fe200b8178074a3fc *src/gower.c 4dbc149411df0021bb5e262551d45e28 *tests/tinytest.R b69562b9ebfbf47bbc317ec4ddc75bed *vignettes/intro.Rnw gower/R/0000755000176200001440000000000014730044154011600 5ustar liggesusersgower/R/gower.R0000644000176200001440000001604714730042476013063 0ustar liggesusers #' Gower's distance #' #' Compute Gower's distance, pairwise between records in two data sets \code{x} #' and \code{y}. Records from the smallest data set are recycled over. #' #' @section Details: #' There are three ways to specify which columns of \code{x} should be compared #' with what columns of \code{y}. The first option is do give no specification. #' In that case columns with matching names will be used. The second option #' is to use only the \code{pairs_y} argument, specifying for each column in \code{x} #' in order, which column in \code{y} must be used to pair it with (use \code{0} #' to skip a column in \code{x}). The third option is to explicitly specify the #' columns to be matched using \code{pair_x} and \code{pair_y}. #' #' #' @section Note: #' Gower (1971) originally defined a similarity measure (\eqn{s}, say) #' with values ranging from 0 (completely dissimilar) to 1 (completely similar). #' The distance returned here equals \eqn{1-s}. #' #' #' @param x \code{[data.frame]} #' @param y \code{[data.frame]} #' @param pair_x \code{[numeric|character] (optional)} Columns in \code{x} used for comparison. #' See Details below. #' @param pair_y \code{[numeric|character] (optional)} Columns in \code{y} used for comparison. #' See Details below. #' @param eps \code{[numeric] (optional)} Computed numbers (variable ranges) #' smaller than \code{eps} are treated as zero. #' @param weights \code{[numeric] (optional)} A vector of weights of length \code{ncol(x)} #' that defines the weight applied to each component of the gower distance. #' @param ignore_case \code{[logical]} Toggle ignore case when neither \code{pair_x} #' nor \code{pair_y} are user-defined. #' @param nthread Number of threads to use for parallelization. By default, #' for a dual-core machine, 2 threads are used. For any other machine #' n-1 cores are used so your machine doesn't freeze during a big computation. #' The maximum nr of threads are determined using \code{omp_get_max_threads} at C level. #' #' #' @return #' A \code{numeric} vector of length \code{max(nrow(x),nrow(y))}. #' When there are no columns to compare, a message is printed and both #' \code{numeric(0)} is returned invisibly. #' #' @seealso \code{\link{gower_topn}} #' #' @references #' Gower, John C. "A general coefficient of similarity and some of its #' properties." Biometrics (1971): 857-871. #' #' @export gower_dist <- function(x, y, pair_x=NULL, pair_y=NULL, eps = 1e-8, weights=NULL, ignore_case=FALSE, nthread=getOption("gd_num_thread")){ check_recycling(nrow(x),nrow(y)) gower_work(x=x,y=y,pair_x=pair_x,pair_y=pair_y , n=NULL, eps=eps, weights=weights, ignore_case=ignore_case, nthread=nthread) } #' Find the top-n matches #' #' @description #' #' Find the top-n matches in \code{y} for each record in \code{x}. #' #' @inheritParams gower_dist #' @param n The top-n indices and distances to return. #' #' @seealso \code{\link{gower_dist}} #' #' @return #' A \code{list} with two array elements: \code{index} #' and \code{distance}. Both have size \code{n X nrow(x)}. Each ith column #' corresponds to the top-n best matches of \code{x} with rows in \code{y}. #' When there are no columns to compare, a message is printed and both #' \code{distance} and \code{index} will be empty matrices; the list is #' then returned invisibly. #' #' @examples #' # find the top 4 best matches in the iris data set with itself. #' x <- iris[1:3,] #' lookup <- iris[1:10,] #' gower_topn(x=x,y=lookup,n=4) #' #' #' @export gower_topn <- function(x, y, pair_x=NULL, pair_y = NULL, n=5, eps=1e-8, weights = NULL, ignore_case=FALSE, nthread=getOption("gd_num_thread")){ gower_work(x=x,y=y,pair_x=pair_x,pair_y=pair_y , n=n, eps=eps, weights=weights, ignore_case=ignore_case, nthread=nthread) } gower_work <- function(x, y, pair_x, pair_y, n, eps, weights, ignore_case, nthread){ stopifnot(is.numeric(eps), eps>0, nrow(x)>0, nrow(y)>0,ncol(x)>0,ncol(y)>0) if (max(nrow(x), nrow(y)) <= 1000) nthread <- 1L if (is.null(pair_x) & is.null(pair_y)){ xnames <- if(ignore_case) toupper(names(x)) else names(x) ynames <- if(ignore_case) toupper(names(y)) else names(y) pair <- match(xnames, ynames, nomatch = 0L) } else if (is.null(pair_x)){ pair <- pair_y } else { if (is.character(pair_x) & is.character(pair_y)){ m <- match(names(x),pair_x,nomatch=0) pair_x <- pair_x[m] pair_y <- pair_y[m] } pair <- numeric(ncol(x)) pair[pair_x] <- pair_y } if ( !any(pair > 0) ){ message("Nothing to compare") return( if (is.null(n)){ # gower_dist invisible(numeric(0)) } else { # gower_topn invisible(list(distance=matrix(0)[0,0],index=matrix(0L)[0,0])) } ) } if ( !is.null(weights) && ( any( weights < 0 ) || !all(is.finite(weights)) ) ){ stop("At least one element of 'weights' is not a finite nonnegative number" , call. = FALSE) } if ( !is.null(weights) && length(weights) < length(pair) ){ msg <- sprintf("%d weights specified, expected %d" , length(weights), length(pair)) stop(msg, call. = FALSE) } # If the user didn't pass any weights, then weight all components of the # distance equally. if (is.null(weights)) weights <- rep(1, ncol(x)) # check column classes nthread <- as.integer(nthread) ranges <- numeric(length(pair)) for ( i in seq_along(pair)){ if (pair[i] == 0 ) next ranges[i] <- .Call("R_get_xy_range",x[[i]],y[[pair[i]]],nthread,PACKAGE="gower") } factor_x <- sapply(x,is.factor) factor_y <- sapply(y,is.factor) for ( i in seq_along(pair) ){ if ( pair[i] == 0 ) next iy <- pair[i] if (!factor_x[i] & !factor_y[iy]) next if ( factor_x[i] && !factor_y[iy] ){ stop("Column ", i, " of x is of class factor while matching column " , pair[i]," of y is of class ", class(y[[iy]]) ) } if ( !factor_x[i] && factor_y[iy] ){ stop("Column ", i, " of x is of class ", class(x[[i]]), " while matching column " , pair[i]," of y is of class factor" ) } if (factor_x[i] && factor_y[iy]){ if ( !isTRUE( all.equal( levels(x[[i]]), levels(y[[iy]]) ) ) ){ stop("Levels in column ", i, " of x do not match those of column ", pair[i], " in y.") } } } factor_pair <- as.integer(factor_x) eps <- as.double(eps) # translate to C-indices (base-0). pair <- as.integer(pair-1L) if (is.null(n)){ .Call("R_gower", x, y , ranges, pair, factor_pair, eps, weights, nthread, PACKAGE="gower") } else { L <- .Call("R_gower_topn", x, y, ranges, pair, factor_pair, as.integer(n), eps, weights, nthread, PACKAGE="gower") names(L) <- c("index","distance") dim(L$index) <- c(n,nrow(x)) dim(L$distance) <- dim(L$index) dimnames(L$index) <- list(topn=NULL,row=NULL) dimnames(L$distance) <- dimnames(L$index) L } } RECYCLEWARNING <- tryCatch(1:3+1:2,warning=function(e) e$message) check_recycling <- function(nx,ny){ mx <- max(nx,ny) mn <- min(nx,ny) if ((mx %% mn) != 0) warning(RECYCLEWARNING, call.=FALSE) } gower/R/gower-pkg.R0000644000176200001440000000111514730044154013623 0ustar liggesusers#' Gower's distance/similarity measure. #' #' A C-based implementation of Gower's distance. #' #' @name gower-package #' @docType package #' @useDynLib gower, .registration=TRUE #' "_PACKAGE" .onLoad <- function(libname, pkgname){ max_threads <- 1L max_threads <- .Call("R_get_max_threads",PACKAGE="gower") thread_limit <- .Call("R_get_thread_limit",PACKAGE="gower") max_threads <- min(max_threads, thread_limit) # leave one core for the user to control the machine. if (max_threads > 2) max_threads <- max_threads - 1L options(gd_num_thread = as.integer(max_threads)) } gower/NEWS0000644000176200001440000000274314730044346012107 0ustar liggesusersversion 1.0.2 - Imporved sanity checking on input data frames (Thanks to Brian Ripley for pointing this out) version 1.0.1 - Updated compiled code to new compiler prototype warnings. version 1.0.0 - Fix: for integer vectors, the output would in some cases depend on the order of the input. (Thanks to Tobias Rockel for reporting). version 0.2.2 - Fix: for small numbers of records and high number of threads, the output would depend on 'nthreads'. (Thanks to Matt Austin for reporing). Gower now only paralellizes when more than 1000 records are presented. version 0.2.1 - moved test framework to 'tinytest' version 0.2.0 - gower_dist and gower_topn gain `weight` argument for weighted matching (thanks to David Turner) - gower_dist and gower_topn gain `ignore_case` argument for automatic column matching. - gower_dist now returns numeric(0) invisibly when there are no columns to compare. - gower_topn now returns a list with empty matrices when there are no columns to compare. - gower_topn now warns when n>nrow(y) and sets n=nrow(y) - bugfix: comparing factors with characters would cause a crash (thanks to Max Kuhn) version 0.1.2 - fixed valgrind warning - registered native routines, as now recommended by CRAN version 0.1.1 - gower_dist now issues warning when nr of rows on input do not divide (recycling) - Code now depends on gcc version for compatability with Windows + R<=3.2.x - Bugfix: bad range calculation caused faulty distance computation version 0.1.0 - First release gower/vignettes/0000755000176200001440000000000014730044355013412 5ustar liggesusersgower/vignettes/intro.Rnw0000644000176200001440000001144113452644704015242 0ustar liggesusers%\VignetteIndexEntry{Introduction to the gower package} \documentclass[11pt]{article} \usepackage{enumitem} \setlist{nosep} \usepackage{hyperref} \hypersetup{ pdfborder={0 0 0} , colorlinks=true , urlcolor=red , linkcolor=blue } \renewcommand{\familydefault}{\sfdefault} \setlength{\parindent}{0pt} \setlength{\parskip}{2ex} \title{Introduction to the gower package} \author{Mark van der Loo} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\pkg}[1]{\textbf{#1}} \begin{document} \maketitle{} \tableofcontents{} <>= options(prompt=" ") @ \newpage \section{Gower's distance measure} Gower's distance can be used to measure how different two records are. The records may contain combinations of logical, numerical, categorical or text data. The distance is always a number between 0 (identical) and 1 (maximally dissimilar). An easy to read specification of the measure is given in the original paper. Gower (1971) \href{http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.412.4155&rep=rep1&type=pdf}{A general coefficient of similarity and some of its properties}. \emph{Biometrics} **27** 857--874. In short, Gower's distance (or similarity) first computes distances between pairs of variables over two data sets and then combines those distances to a single value per record-pair. This package modifies Gower's original similarity measure in the following ways. \begin{itemize} \item{In stead of the original similarity $S$, the package returns the distance $1-S$.} \item{The original paper does not mention the concept of \code{NA}. Missing variables are skipped when computing the distance.} \item{The original paper does not mention character data. These are treated as categorical data.} \end{itemize} \section{Computing Gower's distance} The function \code{gower\_dist} computes pairwise-distances between records. <<>>= library(gower) dat1 <- iris[1:10,] dat2 <- iris[6:15,] gower_dist(dat1, dat2) @ If one data frame has less records than the other, the shortest one is recycled over (just like when you're adding two vectors of unequal length) <<>>= gower_dist(iris[1,], dat1) @ It is possible to control how columns from the two data sets are paired for comparison using the \code{pair\_x} and \code{pair\_y} arguments. This comes in handy when similar colums have different names accross datasets. By default, columns with matching names are paired. The behaviour is somewhat similar to that of base R's \code{merge} in that respect. <<>>= dat1 <- dat2 <- iris[1:10,] names(dat2) <- tolower(names(dat2)) gower_dist(dat1, dat2) # tell gower_dist to match columns 1..5 in dat1 with column 1..5 in dat2 gower_dist(dat1, dat2, pair_y=1:5) @ It is also possible to explicitly ignore case when matching columns by name. <<>>= gower_dist(dat1, dat2, ignore_case=TRUE) @ \section{Computing the top-n best matches} The function \code{gower\_topn} returns a list with two arrays. <<>>= dat1 <- iris[1:10,] L <- gower_topn(x=dat1, y=iris, n=3) L @ The first array is called \code{index}. Each column corresponds to one row of \code{x}. The entries of each column index the top $n$ best matches of that row in \code{x} with rows in \code{y}. In this example, the best match of the first row of \code{dat1} is record number \Sexpr{L$index[1,1]} from \code{iris} (this should be obvious, since they are the same record). The second best match is record number \Sexpr{L$index[2,1]} from \code{iris}. The second array is called \code{distance} and it contains the corresponding distances. \section{Using weights} Gower's distance is computed as an average over differences between variables. By setting \code{weights} you can compute the distance as a weighted average. <<>>= gower_dist(women[1,], women) gower_dist(women[1,], women, weights=c(2,3)) @ \section{Parallelization, memory usage} The underlying algorithm is implemented in C and parallelized using \href{http://www.openmp.org}{OpenMP}. OpenMP is available on most systems that can run R. Please see \href{https://cran.r-project.org/doc/manuals/r-release/R-exts.html#OpenMP-support}{this section} of the writing R extensions manual for up-to-details details on which systems are supported. At the time of writing (spring 2019), OSX is the only system not supporting OpenMP out of the box. You can still make it work by installing the gcc toolchain and compiling the package (and R). If OpenMP is not supported, the package will still work but the core algorithms will not be parallelized. This implementation makes no copies of the data in memory. When computing \code{gower\_dist}, two double precision arrays of size \code{max(nrow(x),nrow(y))} are kept in memory to store intermediate results. When computing the top-n matches, for $k$ cores, $k+2$ double precision arrays of length \code{nrow(y)} are created to store intermediate results at C level. \end{document} gower/src/0000755000176200001440000000000014730044355012171 5ustar liggesusersgower/src/gower.c0000644000176200001440000004532014351012272013454 0ustar liggesusers/* gower - a C/R implementation of Gower's similarity (or distance) measure. * Copyright (C) 2016 Mark van der Loo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * You can contact the author at: mark _dot_ vanderloo _at_ gmail _dot_ com * */ #ifdef _OPENMP #include #endif /* R-windows-oldrel (3.2.x) uses gcc 4.6.3 which we need to detect */ #ifdef __GNUC__ #if __GNUC__ <= 4 && __GNUC_MINOR__ <= 6 #else #define HAS_REDUCTION #endif #endif #include #include #include #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) #define RECYCLE(N, K) ((N) + 1L < (K) ? (N) + 1L : 0L ) // determine when something is numerically zero. static double EPS = 1e-8; // set max nr of threads to use static int NTHREAD = 1L; // recycling in parallel region. static inline int recycle(int i, int nthreads, int ni){ i += nthreads; if ( i >= ni ) i = (nthreads < ni) ? (i - ni) : (i % ni); return i; } SEXP R_get_max_threads(void){ SEXP out = allocVector(INTSXP, 1L); PROTECT(out); INTEGER(out)[0] = 1L; #ifdef _OPENMP INTEGER(out)[0] = omp_get_max_threads(); #endif UNPROTECT(1); return out; } SEXP R_get_num_procs(void){ SEXP out = allocVector(INTSXP, 1L); PROTECT(out); INTEGER(out)[0] = 1L; #ifdef _OPENMP INTEGER(out)[0] = omp_get_num_procs(); #endif UNPROTECT(1); return out; } SEXP R_get_thread_limit(void){ SEXP out = allocVector(INTSXP, 1L); PROTECT(out); INTEGER(out)[0] = 1L; #ifdef _OPENMP INTEGER(out)[0] = omp_get_thread_limit(); #endif UNPROTECT(1); return out; } // presence or absence of a character. x and y are 0 (FALSE) or 1 (TRUE) static inline void gower_logi(int *x, int nx, int *y, int ny , double *num, double *den, double weight) { #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx,ny); double dijk, sijk; int i = 0, j = 0; double *inum = num, *iden=den; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ dijk = (double) ((x[i] | y[j]) & !((x[i] == NA_INTEGER) | (y[j] == NA_INTEGER))); sijk = (dijk == 1.0) ? (double) (x[i] * y[j]) : 0.0; *inum += weight * dijk * sijk; *iden += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end parallel region. } // equality of categorical variables, encoded as x, y in {1,2,...,N}. static inline void gower_cat(int *x, int nx, int *y, int ny , double *num, double *den, double weight) { #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx,ny); double dijk, sijk; int i = 0, j = 0; double *inum = num, *iden=den; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ dijk = (double) !(x[i] == NA_INTEGER || y[j] == NA_INTEGER); sijk = (dijk==1.0) ? (double) (x[i] == y[j]) : 0.0; *inum += weight * dijk * sijk; *iden += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end parallel region. } // strings. Treated as categories. static inline void gower_str(SEXP x, int nx, SEXP y, int ny, double *num, double *den, double weight){ #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx, ny); double dijk, sijk; int i=0, j=0; double *inum = num, *iden=den; SEXP xi, yj; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ xi = STRING_ELT(x,i); yj = STRING_ELT(y,j); dijk = (double) !(xi == NA_STRING || yj == NA_STRING); sijk = (dijk==1.0) ? (double) (CHAR(xi) == CHAR(yj)) : 0.0; *inum += weight * dijk * sijk; *iden += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end of parallel region } // comparison of numerical variables, by absolute difference divided by range. static inline void gower_num(double *x, int nx, double *y, int ny,double R , double *num, double *den, double weight) { if ( !isfinite(R) || R < EPS ){ warning("skipping variable with zero or non-finite range."); return; } #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx,ny); double dijk, sijk; int i = 0, j = 0; double *inum = num, *iden=den; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ dijk = (double) (isfinite(x[i]) & isfinite(y[j])); sijk = (dijk==1.0) ? (1.0-fabs(x[i]-y[j])/R) : 0.0; (*inum) += weight * dijk * sijk; (*iden) += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end of parallel region } static inline void gower_dbl_int(double *x, int nx, int *y, int ny,double R , double *num, double *den, double weight) { if ( !isfinite(R) || R < EPS ){ warning("skipping variable with zero or non-finite range\n"); return; } #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx, ny); double dijk, sijk; int i=0, j=0; double *inum = num, *iden=den; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ dijk = (double) (isfinite(x[i]) & (y[j] != NA_INTEGER)); sijk = (dijk==1.0) ? (1.0-fabs(x[i] - ((double) y[j]) )/R) : 0.0; *inum += weight * dijk * sijk; *iden += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end of parallel region } static inline void gower_int(int *x, int nx, int *y, int ny, double R , double *num, double *den, double weight) { if ( !isfinite(R) || R == 0 ){ warning("skipping variable with zero or non-finite range\n"); return; } #pragma omp parallel num_threads(NTHREAD) { int nt = MAX(nx, ny); double dijk, sijk; int i=0, j=0; double *inum = num, *iden=den; int ID = 0, num_threads=1; #ifdef _OPENMP ID = omp_get_thread_num(); num_threads = omp_get_num_threads(); i = recycle(ID-num_threads, num_threads, nx); j = recycle(ID-num_threads, num_threads, ny); inum += ID; iden += ID; #endif for ( int k = ID; k < nt; k += num_threads, inum += num_threads, iden += num_threads){ dijk = (double) ( (x[i] !=NA_INTEGER) & (y[j] != NA_INTEGER)); sijk = (dijk==1.0) ? (1.0-fabs( ((double)x[i]) - ((double)y[j]) )/R) : 0.0; *inum += weight * dijk * sijk; *iden += weight * dijk; i = recycle(i, num_threads, nx); j = recycle(j, num_threads, ny); } } // end of parallel region } // range computations static void get_dbl_range(double *x, int nx, double *min, double *max){ double *ix = x; double imin=*ix, imax=*ix; for ( int i=0; i imax ) imax = x[i]; if ( x[i] < imin ) imin = x[i]; } } }// end parallel region *min = imin; *max = imax; } static void get_int_range(int *x, int nx, double *min, double *max){ int *ix = x; int imin = *ix , imax = *ix; for ( int i=0; i imax ) imax = x[i]; if ( x[i] < imin ) imin = x[i]; } } *min = (double) imin; *max = (double) imax; } static void get_range(SEXP x, double *min, double *max){ switch( TYPEOF(x) ){ case INTSXP : { get_int_range(INTEGER(x), length(x), min, max); break; } case REALSXP : { get_dbl_range(REAL(x), length(x), min, max); break; } } } static double get_xy_range(SEXP x, SEXP y){ double x_min = R_NegInf , x_max = R_PosInf , y_min = R_NegInf , y_max = R_PosInf , min, max; get_range(x, &x_min, &x_max); get_range(y, &y_min, &y_max); if ( isfinite(x_min) & isfinite(y_min) ){ min = MIN(x_min, y_min); } else if ( isfinite(x_min) & !(isfinite(y_min)) ){ min = x_min; } else if ( (!isfinite(x_min)) & isfinite(y_min) ) { min = y_min; } else { min = NA_REAL; } if ( isfinite(x_max) & isfinite(y_min) ){ max = MAX(x_max, y_max); } else if ( isfinite(x_max) & !isfinite(y_max) ){ max = x_max; } else if ( (!isfinite(x_max)) & isfinite(y_max) ){ max = y_max; } else { max = NA_REAL; } return max - min; } SEXP R_get_xy_range(SEXP x_, SEXP y_, SEXP nthread_){ NTHREAD = INTEGER(nthread_)[0]; SEXP out = allocVector(REALSXP,1L); PROTECT(out); REAL(out)[0] = get_xy_range(x_, y_); UNPROTECT(1); return out; } /* static void print_vec(double *x, int n){ for ( int i=0; ii; j-- ){ topn[j] = topn[j-1]; index[j] = index[j-1]; } topn[i] = x; index[i] = ind; break; // out of main loop } } } } /* For testing purposes SEXP R_pushdown(SEXP entry_, SEXP index_, SEXP values_, SEXP indices_){ double entry = REAL(entry_)[0]; int index = INTEGER(index_)[0]; double *values = REAL(values_); int *indices = INTEGER(indices_); int n = length(values_); push(entry, index, values, indices, n); return R_NilValue; } */ static inline void copyrec(SEXP into, SEXP from, int i){ int ncol = length(into); SEXP col_from, col_into; for ( int j = 0; j < ncol; j++){ col_from = VECTOR_ELT(from,j); col_into = VECTOR_ELT(into,j); switch(TYPEOF(col_from)){ case LGLSXP : { INTEGER(col_into)[0] = INTEGER(col_from)[i]; break;} case INTSXP : { INTEGER(col_into)[0] = INTEGER(col_from)[i]; break;} case REALSXP : { REAL(col_into)[0] = REAL(col_from)[i]; break;} case STRSXP : { SET_STRING_ELT(col_from, 0, STRING_ELT(col_from,i)); break;} } } } /* for testing purposes only void prvec(SEXP x){ for (int i=0; i #include #include // for NULL #include /* FIXME: Check these declarations against the C/Fortran source code. */ /* .Call calls */ extern SEXP R_get_max_threads(void); extern SEXP R_get_thread_limit(void); extern SEXP R_get_xy_range(SEXP, SEXP, SEXP); extern SEXP R_gower(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); extern SEXP R_gower_topn(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); static const R_CallMethodDef CallEntries[] = { {"R_get_max_threads", (DL_FUNC) &R_get_max_threads, 0}, {"R_get_thread_limit", (DL_FUNC) &R_get_thread_limit, 0}, {"R_get_xy_range", (DL_FUNC) &R_get_xy_range, 3}, {"R_gower", (DL_FUNC) &R_gower, 8}, {"R_gower_topn", (DL_FUNC) &R_gower_topn, 9}, {NULL, NULL, 0} }; void R_init_gower(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } gower/NAMESPACE0000644000176200001440000000017114176730663012630 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(gower_dist) export(gower_topn) useDynLib(gower, .registration=TRUE) gower/inst/0000755000176200001440000000000014730044355012357 5ustar liggesusersgower/inst/doc/0000755000176200001440000000000014730044355013124 5ustar liggesusersgower/inst/doc/intro.pdf0000644000176200001440000051454214730044355014765 0ustar liggesusers%PDF-1.5 % 30 0 obj << /Length 455 /Filter /FlateDecode >> stream xڍSM0W#vqe BMMmT _8v ˊؓx{3cA:"z%_5o%`Zwa1@ 4nmǡb 4McMXn0G^Tr=9}],g%$Lynǐӧ;#0`ɇ\cfCw*Nױ%` sURH]PJ  CXm̥eqHqHsFgq9F4F{!CsuACżt=V \b:~Nahm} q'r5䆁JP"wѶ,rpL곺8 Q,QqNvCjq~vuQ2}M!ՅS ynw}ŀ ym;,4 #o|rrnYw endstream endobj 43 0 obj << /Length 1520 /Filter /FlateDecode >> stream xڥn6-a)|hhovPZzWVڊ\;p-!^p837YXႅw7KqJ!"K ]FyS.e¹R ᕽLd)]c]Նy0n~~^gf#k%RLg"0S\,!TW-/ س5;\zz]sǤ4Ih8;vA 7^&y7T4S_T|Fu߹Fxtk.ktܝfXu̾ PZ;]tKM.Ǎ%lzK*mBh10:x2Ш-o.[[:70(PyPG4G3.D)Ѭ4[c~c뤔/s]JY4<+G[ECJWW1pcP DgDJ&)P`1G#)ȉV: Ogg^0$ӨiT OU3ح4ʊ1[䆨ѧ'aO[Xh)a&U;քޞ`;l}YlC 4N 5֫^ ֨?#uYG r_Е Tэ 52d|sL|$,GrD0 BmP5aa8 ~If2 >>¼>H71K ~,ƅnI<ϙ7zCK^e^@I7Տ8Ɩ0 tU0.,8Ktgn>Aixq 3ҫsu+٥Pu 5=S:3Bl>^R|j;n7 vJ|8w3e;LiE<)Y>U%O7B" endstream endobj 54 0 obj << /Length 984 /Filter /FlateDecode >> stream xVK6Ce`")Z8biK,\}g8m R]΋(laNFM tƔN$LYZO=e]7E$ª'b|p$ϫb|m1 3B,3x&M8}#)49Xi5S%-~gY_#X0KfbB&SR% f}E1KT:"ԄE$굶Z)fښeix$hîIlӵ; hd0@%r:r<,D6Uwm(I)H'#m.a*cY,GYYDO1гE)JWe*DKyZCS <3Ht6b%7scLX圖ڍ z,vSބS?Rb endstream endobj 58 0 obj << /Length 1358 /Filter /FlateDecode >> stream xڕWKo8 W̡:@zZ-vϳ(1ɴ~)IڹdI{رݗ+FՇR퀕9wUii%Wv?Pg'Di݀(tqaf=7+G7 4rܳ2HLLLLLL7j +siSVAUѪi5ZZ]Â52ĽpgB(H$p+I$#HQϖE--۬G p"K[%Qm(7%sdݡƪ,5f ȑ $eJ-P)`%K2d8dH,0\gJX<3^X|@s#X"fyt|:(cN^ uyfĢC/ovS _ *rPW:9לKU.xZ. p+2XyZ?f=,x g-Sf 34m ֤c%^SuwSKƺ8٢kC<5vDQw92&@,oSklGccQc j:^%:(. 1eX`% IBf#Cu!8Uq k9݀}j86sCakJCA:2RU&"do #:[ iʭt/Mhxe9WyũF%O/髆%a-}wdSSX#7=UYtZWE֋q}Ȃ.l6Ie>f$];VMKp6CKƆ2nR^42 s:v ]+a8nzE |$r IX"Wji}>^B*UEbQD 6NkcTPFCr*=!9Cԅ-Ý)wsjUd^QZ PXrj0 븗E,ݹx+fAܝ֏a,x> stream x}Vn6}WQF#7.E H EBt1DzwC*Whp.gGb>b;ןw򈳴b/We*UOEVF]dzݵ2Ix|{=pߐ4q}35g̲D ^|W+nIFvp /Ʃ׻^3is~eR_~xt|L5m#9< 0hV 17u 2J,_^&4PrQ@G(ǘ .tA5erAk=E)3[XKIT9q3?sܷdU%=Ҍp$C% PI3hv/4%Ukwӳ endstream endobj 80 0 obj << /Length1 1423 /Length2 6556 /Length3 0 /Length 7525 /Filter /FlateDecode >> stream xڍwT6ҤTNTI*]&!@(IH"wޛtAHtHrZ߷Vg3{?ϻpܾgįhԐ,?H(P@(Da :q8!e4 TXPh=r 1)%"R+B"`2e$ w{ r@|.04 FtX nG(`aXqbQR`m/pc0 vM`!`4 s8á0a Cp4u(7X7p пY B.(0a}5F1H\> wCp_j0n?ah8 ( UH!ٟ  S:!-;8P&# Eo= J K`Aƞ(د 77 ƀ`2o |3O ¡XfG: m q??ZYfD8{=TO *)!=B~!Q s j"쐀~;{vC? G]L/R4YewW7]Ξ8>dĉP3ol\;䠈Q$"c0{p,7m~M~ Cb?1, b8Ap C` Nr_ӆD>TPO h4ؓ w8K AKf!d?/ZB hN6qD2)[pm? }@Bk[dS X`{TG⍲2'K>wԬ\g?z/ղy𳩭ڳAb'.%x2ߙh{f*UEA*okcAWMקwN5qVL:fIo_ ͐~e=r< ZHK-vL^E97?MRgVZe:w,m#NaS6ǝ|TadžmqDh7c*4R*:7%v*;O.cڕx=[I+,Dsrkxv`.>xًobB[NZR^ ewΚ> 32Huh5+ nO%,| ZirCk^"ymmJUQhig' 7uд^. >U :}.B VTOR1-w*YcmJrN"[JO67zd:/{7MGz>]~kIqQ 7L4{ѵ,QKR--M\Wp姙zr=֠?h-it^sN k%$Ͽfn 31f`3of\"o(1̝&RCVy5C5~wpbǶЏfhr*;$SYq=nnֽ9> /A5gj}lb!;mC9;5=hRC8R.G& k&g/ӵU|;u L'9. .(9/-C)FӧN|Vѐ$`!"Jċ4DӧC'mI+kPL̲6'lƪ~KKtTg%񨚽,ۦ mE )>J-ޅj?噞z*jN[s=r`^2(FyH3Da0N6|ݮAfQ(S, %e"wP-'njǩ?0"r#gMzC_ ~̭ %8P4rU?''@3Tge> Eƚk&AѲIOyt787 2y?/厸Wl݉op"wu$[2:!$}օJkOMZBbs˫+ 疁CPSlz;ЉERG^rW)Q&Xm [+˓kzY`}{ThCVޜ#e xi޼=,|EC̞f2 .5z(,E/@}tt 5d&F9͔m YBKmw贗nSUV<ڟ_X}zNSϨ/S&+PZ(Yt:Zo,s!_ i5Sb~o#?{/g|xSKFI=N6W!+]wcͱ;ˉ|I@bX8movQ'~$̠E )WWM؂Qw G]x5N5s("!4^fjk^eU;}%9%3q1NUތ׏" x?a)lAAG:91{:tbřTd,tÜO5#03L"tf$2Dmǒ Pe0WəĘ>nRėּ^+䓠6>G;1\ROw<'S$/<+R"i?3ـZdb*[YxxB˯użb\-@\55+8JV]Q#5=./LH wy I_iܠfz;f Ta^hNyA!*#J硣]15y^CNf]NJ Wr "fr"s >S~y4z֘/'Yj]UoxJ^~$Xa/T*%*դDΔ=2z$%$pə+ZQ9rj}ٜݛTwR%jFaֺ@񯕏[F;I a.c*11(;;%\>$mӓGO<_҆k=HĠ^t?ACN9i-1Źñ>6G)Ar[xk_^q1Y|mPZYHX_͎"p]s†KfZcٍgcW&=ow0ZC|,^c5ׯn ,,^za݋eU1?y-s>>*|Lʻæ ;;%]4^M#{l0Q9vpp}&/zΰߪv[9|ZvhJ@F0V%|p:/xW wA+]w8Clhg_YL5|sq_hAB{?VYi7f9+q U-BVB. r1O}e]P` џϻ0M VAE` xe)[Q6+`VFvV&4UucۋDw.ڣ/bSsN*6 `,5*C^;@i.݆OcAO> 2 AdBϝN׆C4O,~+P砊@ m.5t85`]L2r;oIt~]bYr֫ewfW7>z]LhEj$TEbȻvWŔ?iN=~$Eq$+ɾ{={OXIbv)\z [C j)^h0^iZz-n,rվ@܄E4FeB>[SvɁqH ehGzycmNݶ}Aᅖhq|- ʻ .{IS㡏=M  bqo$LeC}Z5}õ5;I'g{:O% c<4il?#k]Hx;f EP\ӧ!);BDHrmmGk)$\*2ҵ's50,y su "Bcg-3OrViegб6?h3]+,g`LYګZo#(Pwr7hoR3d՞W=^fݍG[ @ m|y`5& x~H^`"׃Aa1_W-=L &O*_(yxc{6~-ۃTtX`ҡ.Izg`?>ޯNbhv@+!]oL݅̃˜!g~]>?HǨhElUۊݐ־%rg=`:5A垲Ȅyջ #Iw+hs_iX2%ȫpM޶,8/Jz_evMCUg^c1g^.OucY1^"|8u! Vx* 8)3 b}8/ BǏ$(ō(w $EQ`]ɷh|NS U_Xȯau$_S}ޏrϹ~XTK’&zEM^Td#{@yΛR5/;Ĥ|ӊO:̄ӎgb$aJ!_U^1?TI~Ŭn<$ |Mi3OQ}WZYƨ; + 6龌 w$#b=ȓvyx5[у0AWjESlcN5u2C/z.xg~мM۫z b:1UhfzHVE;'HW{b#fN&ϘŦ^REdqbK,f0b#kFK4RݪXN <C>d,$>$OᯆPRlySQg^20V>xb.}]s0XLqXԑvl7jz^59h6u2q9\Byd}L|Б uйqFƴ4xCЏc^HѠZrJ ]{ 4 f'lŒ e (qvklo<#"M o%i&{^EfA;oR}f?Sk[& ݿ>Ǹ9'$pJ=nM,ڗEGk_͸p*tOn*3+28?Ԅ]7^Oi@*0O+\onFKZݛфpeZV8dpy>B?\ԈgF~|0+MqRTKCvM`T7C#Zicq}qMG}JJ5*o'E,$awY[,OS\%5;ԧUh3gfs}1b-6u {l{$wc6ً'Yl$ DCMm{%"ىhw{'S|֝*J$_o="& ;a!t՚<ΓT=\v>J#d.W%Iv`i،wd&N@? ?rgƌ-+MWL56M SwYROr'WEx[{xAw="AD=5#̶0I7js@#,APq4G+쵡V5L97;yֲ\:( qٗLqRk,c%1:PL6TOZŸz}3bGQ,Hkkv*ag X͗̚vil\fex;4â3$* ZO3QQ2iR#[ R6Q7ZFe}JJK/zL+R F޷o묪ER=] u6c7o;khVm>;C~nbNÈ<ԦȉOcTN Tsʨہ}yYMci8v+}EGv2jT`I֥Z2B͐ViXfdћؗ67RY_SU V endstream endobj 82 0 obj << /Length1 1398 /Length2 6731 /Length3 0 /Length 7687 /Filter /FlateDecode >> stream xڍt46!0Dw D'!HD Ah]Q{ Eo$yy}kz}{_Ƭoħ"(>PI$CQ0_j)EA u`ԵA@H\JP($((/GR :u8pEB]Peur:pA⼿Á $ Q.`|Srz#β\@o(h _u?؀.P?z#0q w ŁF@=7^_wNWDP` NP͏Ap_`:;U  uCy{@aFUJWW՟2 qv_?}GxpG_C8z  \U!(08JomR_Op:] :A`/:BP@{3wk5||$h)x=P5pW@MEBٜ>@>A  dׇCj?b5Nn_{οg.]5j!@JPT?Cwῲo T=af v|r':k :G[5Pk"(a_#Cqԇ\`P8DW_kj9<~:Г=+ebZAXgV!l9#4,x(d;>$Cd^1i&7c-NFS#52a ܫgAN\^XEadѣ,!G ?]ktR?4mvzaBrpe#}(EqWUbsY\7[2zjR*hT&3 72tKÁ%3[ ~?{YStBCyp;dvWޭaA پMu`^!Gƌv>hrLSVf(d"[5c*=1Nпr.ZU4m4%@[2 .gNBHceF8(:?ħ 0Ir]+k|PD[BL[6FFGc U9{{=a ( A ${I&$Xv%S]Qu213>[_Y}\ܾxmOM>2"Q_ձ&HjZuW&JX7*Q%}iG/;0Yͺo[֮x1[iԾy윲}!Npnўksx/YQV kW,´pR2͵hwq5Ruk(Y(e5NrGkqD (geW%SY6l Czb;iz 9ؗEiЦz" ahf<ҲŸ_q%jk!*nVBEѼՎkT \bW38wCJ=kRuz^߄W|3!5 wfmEz%N?Os~'['Gl]3Bt,BN ZU:Œt!wIgJ,(ܦb—mdb2|e@_bǵ3 <2ES;fojʕ;e9 )6$oSA7g5h㾥{`cAvՁWX ͛v9A rI>NMf?&;Q өꃽhMz)m߿h(1r:bux:݂#=!%Tkc9OJ格Eaί[ݟgQ;R=6α?{h96gNN3WGRGX_E @{$M zI6x8ƥÉoI2hgZǑoa^ʍ1:j⒬Kd1gy8L;J ^UrOF`yC7O/NA+29hf}|[xDr{-%-+(t|Г>E сSPy- ߳YFa%2?|X_>p;?h҂OԨwRнɧMOy!wv6bҙ"qU{twZQ3;b̧)jl쳁[b$]ћ!O'{ҷh9nH-p5))-WK9i~##1GN,wzؒg J~ҽ'~ø-xrA!]7z 4Su&ß8w*Yk!]nZfɱpzjɜEPgI6jwx&/7c0ck/zMŶ搯RVx~_qGÚ>t?TKBci6[}lu G%qcq ͱb"Eg8aU]YDRLV[d'Gr>zQ:HݓYx~4nWQ%fQKH=Uf}\K<$S5jѴ-ܶ.Q`_r`ٹjUr鼀SljƗ,j%N:\VVUc*cm=`Vo܎Sc=#o/(qA+C=-4$\hLݺ/wKh2 ^+(#a3 νx<$VUIopsv^wKj94`As9C-ݛ)oT^nsl=±ˬv|zDw:#bz$i؄͵RnԋLrBB漢6^Q{aԤb²"-Mƚmh(/TOS`cNޕB3阊oH8.tTBװGՆ^dF-u=0s&d7F>W|*SUKu\9z{Fx6Lx9۳yZ*?=S tYqB;K=}׆m-sb7f3Xu(-ZݱQtVx':kN ,n^jk$3GY|p(;x0g"NZj]JZx^Hj%цb X?Y.wLxGTPĚ觼@n%ݼ {)&'.Y<&^br`=ֲUckK}csZK]S$ wN<3Yz}νॸ 4V7:DY$S&+~wmCKǷe7 Y7jߕ(+G.t:~x, >{$gSna׋3T6 Rtgnoe֜4'n0g,gXp.šm'k&,y}036'}zoTŕH_UtG'AԎjڣ1s[ҩ"{MyܖH$JNvN5B'/sRoF kK4ή"V=:Z8NƹKC(Fl %R2hɑi i/s:IxɨG ОtkxK@;GG]LH zY͕QD՜~U;8ȡV{ý?䌥TWuo=h,)s3 iqQUrh|c;n eϲ#BsXÛJA+1]vwMjhT .60C_I/$Y!n I2 |YPeasr\vG~4TWiRDNxilǜT[,n5 akVLӪv.9n,&!%Xdi1O)Ŷis2UsTH'(|X=Sec2sZ`F!NDbWL 7,}R^P=%46\T1a}<.(] %KҢ =jZq{G>4eh)9M~P:@`,m(v/T.+]XrE3;| ]K-73{^xA*ܙU>˞iXJE-Wy)]oX{z+[T3,&\&le٥[N?Iq,a)wpzOI.r~YGbzlqms ?ñ%^mLaLuЋNgM]uxݟpLs ?49\j>K9z5IlNH٧]c^weiHQdv墜d>*؎Ojz$ORc>$岢D᫼Ziq(LA 'Q ^O#7+*;tōʱRI[zR'IWxwl-p$ e D;)SI]$OZc? R鎅 D'b1xĞ}Mgwd+?0v$oJ tztb`b%K`hhbx4]jBl>AkLH(;︠)9HJ^GArP|a%}>OOOG|=w06K:(ƭ3uM0,IkF|k(-Y/TrK[QW";)P?G\RY7 x׻ܰ*|[BFW#R3/K+tokS7虰ޚZ)F/L92ۅrsT?$%~^M EewB*6I*w@0z{z $ɍ(͌Z-V1id+ endstream endobj 84 0 obj << /Length1 1379 /Length2 5902 /Length3 0 /Length 6848 /Filter /FlateDecode >> stream xڍxTT6"̀t "90 % H()] JZ߷f=繮=6;1#Re]cK! M(o;> EGm*(4PhyB"!1)!q)  J DxHT콠]F+#}=N(to\ n8p tQ`7tE= `A(qFܥݐ'9n>7 0#^`Gzn? Lȿ @`PDxtu@ gsBBJ'W"(w=psBN|P|{/= @{Cahj{C<( 54mV;*#pW*P0ツ@᎐_c8z ¡<*0hmN`@()&&*?}@΂ ;3#@(G{(Op:8BA( wv k> ;k4p῏XPLr*)!|’~I1 @HHH .. g{>#VA$jO\ g.=`׿( /BgWݑ' ۻAahz*Eo9/nD٣ՠwB3__v(R v4@//p AGC ~ 5Ϻp؄EFDBhU:}~ (G!nP'Ahߚ} 9H:exe"71յ$hQ3glGJv54#O *"y/} Y(@ao(};}frD9M? =J6d$¶L5z @r(='aɠG+wa>da[C [>$I 44|MPꈣa5܁"'Eڽb5~Z,#)ɹZ-H %s$VH,;3EEyT++Ŧb4t-ԝA_X`.5>1_Iӱhb鱸yZe ?n}1u`;dIMn=Gjƣ*מGtr''cR~ 0ɚh&B\hB:owR*B1xR3Vt`[*$w {ݶIr8Ƴ.zlWǩmKV9[)PadK^a${׭ ņ 磌2_Ovroh4]c; K Eە? PƘZ tyBϾY]H qn;r^HI@F̹!)Q!MmBU~)Tx. i߄k/QY=i%mRw?>e@^ 5* Ue [_EDw-kG*m8іWN#[I,gG, Tun7lִU 4}i)v9;ðһN%|qQ)=5 ,Kf+?ۇ) OS{ҘreGlUu=d֜M=etpH9};PhF/j$ӕ*RԼ4l^&/us]|Ob 765lkW!",k; $NX}_`ja/TL%Y1Lz><7lZ+ְ'3.E4O-l P'NU(K9I1 iFs7Vg>OE W'(J1{N~z 񏚴!Uq~&Y䟕>;xz`1) T>]Y|1B$ZFv}W}YU s0'+ԟ]1e=²Zbٿj_؞yxj3ĚTقl#nÝb/؞spqa*ӘP:q;8_Q$KLIt eWX?1uQAn-3=50P0!Jtd?Zh8_IWq̎Vsh_+ Tm9>m_m}-?Gyp*f:%ԏ-1mL2`_yD!vFAv+/iUF4 Յ@(wR(ܺC<+{hC7v}ƘXH66︇:T-l8rV~ok&x+!H`Mm$5]_xib:6GG]|̯yAcJ rn+4pn9r''+PCĎ-(ɹ,".\̛,_-l+6d6,p-N/1o_ač3o+~j /#HM\b&;}T\ԗJxr+Ew`o^朑juΎ\4Pn;bU $('<-ȷn*TNzUǵf6e5V& 7[(=Yy$BPMӛ^yD'yoZAx@[-րͱtZOעޮ.*nD5n 0LB|E1m5GeNôɧG ۳oI~$Zy%H=?3vd܀ĬBK9Ka>K^_z5s`*:GDB. ሳNNIU0%Q\xH轧Q_ ʕrl?9LFCmG z.=s/*^1c=w)j#b0_*aQRP񜯳)GMOHvFE(ܵXLVo03m7A3望ɡVQ~=#tHٺ!NccIբv$Y'<۵Ģ"%jN3 󔲶7s˫:8!f^}2u 7)8iPݝS9 <ˬ?HT=;Bg}x@`aѴr]jcYiPY7[<#8[8}1F\ OA znO?<`y20"2:m}'Εz6e'}nIyg@&J/&UQ:Z8ٸOˌEx]h<NV,G9M`25Hx暣e(@fuEAJ4QMpLc_N}LN;mfaMRƣۙrDc]"rZ~*z:,X%xt \"c/1Oc46zU. :(P>Y]"`4[rCY߫>AZ jI^)cg(~; 3}j9+aRV3G]jSض?fIS{pi'sIvㄸlXAG'r䡺ydlr ~s=ēv]ڨc_')c0dr W} [JUճOTWPSKN ٮ^R} ϕuTqXTe2bj0eK+;>_˼=I['DrSFJG @29/֕fscpȵe&-⮟j)iێNhvByFd2} /^ME铧j_M/ X_iGFVuL[vU\xPGzlFi'W\7d\Iq0_f)>+NiH5xf ڴJcп;lr*Z 3:y\ߩm+jB{p յ 5ZbkF+PLClݑHew*4q.q(R`u=aWH)SK\$/dkm,H{?WwfED~>1B94sRImuJ)wb, 4 XLw[TX֛/Rd,bܽIm|󕭍qPzlC؉W/q6__zxvP0ĠVh!Bc{Ik;_:gnfizo9r|Uq|V+5V1S:{mÙp -LՔ^ABzmeZL@`H(qHEo5iIKukFSdh߭O}&qʢN8}$lQO8cP\KXXi˅U 2Qrc=no9jNLF$đ΋%f$efo;NKjA9żO6,^*th3Ҿp9)x[CJͲFzv }a!V35],|ˋIpý[V9~)l`eYѧFv\ I}序7宒k|>l3]JWCzq, ^cIl?P(߱{ss!Fg̠ NJexގ6/hg[箄I{}n1Gy+9M&w߼a8Igj>Tfd7ݣUEGHz&w8e|񹏝1{[hreu%+p'~*8EoYk-h×tgu0s@--Jcvrmz[T|`3iRY]j97hc4TܐPTVnCga7_}oҪ,9W/,L'Yd5_=SkŦ _fZ#x^7$~5˚0M}dv[0U;zQyAշ̧Cc[޳?|-ӎwg\(\#mbf+i'0C/t7G1mvRa4ud'y3"\V{\,Tnƾ CFo}f0¸"k d#*j{oVUK5M,KR|3);"мYO0> stream xmwuTZ7 ݝݝ0 3t4 = ]RJ7HHw{>ַ?o^gD4sqqUxńXLLP0 };ˇws:;xXAlF.@[GWG(yqC$O0 1UR*k0qq4A` s\Q 7_`xA\JZEyyb P`u Wr++#qclA#/T!vn̶^qC6-O `wsuCn`(0u!:O ?Bg&aJ`[G?]0Ϙ4^Tπm .~{韮GS]AUE}ۭ:BBm5:L[ :y޿$Fɹp |BQ1! a-/$2Z"˃+P9' 9N8:ZR\PPOHml^58cqtі? 5?u _Pc.=V갏 ըyI(YCHZ(YfpTO;DټUsDnPTez-&ojXÄB;eR{5wӻ0Q4!T!rC^2Dk!O BZ~)gshx8=`ӷ–k)l˞yW)H1a '?q-PqC\g6ʖ We&SC[WH,/Ha<Lg[o&8pj[wWd\J}uDay_y%^ku\H `N"%|&V9_ܕ0GT,u&?ÿ*#(#aj1v0Q=Ho1`xKZ]\9K}`berGѳ_/2ׅ_!Wފ7(5хrH}')$怙0r蚼},z[N R_ 5B:3 \GB(PX3Gr?Jmj6RJ0ȆȊq? S֡U:b,O?&Q {&MRT=+/j?DH6I)8J8q[G5LO@WB\n_WaF#-U0cIXǛ :NXα2 Wc"=ۘ2W#_,u7Ӕ=Vk)zoćcwCj叁8c2 u &%כqlJ .i zh1³Umkt}LOlI  ‰hcg!1m#H}FdY{5=zLieVܽxg/sFj#LE^E>QU?_@-ɋj]^s.UY 'VJ' ) iW&-dbaB\vB n:2)rFD3&T;nB Uo 0ɭoqv1`AqGoc i֨4 $L&糇DJo\Ls)G]`"[캔b= 8&﯏+O`6Kmkp!_M;ڢ0UlMQNFifJ`Ab].5#<@5(`sȎNl#7j"LR8|e]' e#ҙyk_p m_ÿL/j^7 8'Q-amq(: ]&#'+~XQm5Ŏ ;RG CW`"~) g}V5 !5$FZ} )GĸfQT4jDZ-w* ~(7nϩzewV~Vֶso} W,+z|ʋK DwtI!#v_JJ͵߸>-~<mnםnD&&gum? @=^ʩڞA!ՀM`K5.K' h:AH6;ˮ ,i\t8~ .e~-2Yd嶛s MJg{f:(o ,&fXL T[g8dOY,q0/ _+6ZG NE!׾$ut)}gݖb~㲎dz Zkv1w4Y L޹hbؽ-2'vF"\~;$"őڽKd$){}g>Q ꨔrE $ibnAp4іq]2 QzUƂRrBG>fnJV)-|#H#B2Za;h4ߖep\NuN(Zp g%ЬKO.c(WQpdAEKEuϤjk+9X'8'zo;^IG')& ~pʋtII'kZg'G0^9se1<ڨaآTSF21c0[IM og#zk_{ QXFik j!j\gqmꯍ5`3~sb@3GrISwFPvOޒu&jB qI3lZ7?9[1bwʹIX8>\=s82|K B`iSV_ Fqf0޳hF6mǏؼLSh Jo<Dx!#"OX TaA 7 iP$$7Z>'V(&YջTUOs6~Ko6n֓NzRTbIG6.TʻrA_uZBg͒cmjjo5Fs3G%=\Kn34Lf2F&סg 93րK /]͊Ex,LT{PG1WHxb:Xۣp}ϫy#dځDLǞB+\jm=8OY)mtBh\6s-/( 2)h4φXLQ86 1js̀st ?rbC'vQ$3l\>5_gbYP]c^Pe&n bzM5EJ:I]IjɥN~{z Jmwp ]m|X |+'3YU@!ӜcDA._NnχC"{Q*]<ۧ~W)s y?rl C^43Id]Hf sI| 4QNctj$^bmߵUq 4*C5\gE55D1n+1.͉Ց)cKty`wSiX[^ip`[KЖ :$6sf{P5.o8QȡW#[{OI]Z|w8kzړ7L#"<8kF#ݑ Pe Ų WkT;1Cʕ0$܇uaLl d)@í;jpccyuge`N.!*+%:a;UOAHV=Wi- hģk*ǎ,k/͡Ďy,;OFIs[y_M+4i9eD70*\R&FVEjew#qKug26f?kŶ,vr6!*q%5!w_ySCe"HlE$JKG /#6rxe|W' *] ']9fi{bos$8I2n˷$@Czu|a@zҳpڎ"}Z1dhexILk3i7i'0-B6돍>HDeU/=mdF j:229<Ė; j!KPU,,+W_%ړoHfKRs<P< ,3g_^ P;؜Vfrv\ e/][c`CTPeo(&ƶۦ)"h,XfbRBUD(nH?>*~u>C ]Z|ы<*n%1H7iCխьO^1*}oLY7&m3.I׊W*!{ui@bDL]=ڱ0 ڮ',M~qQd`^IVCDpQe7ڵmQB; m*fusyXVDzsGoQ[BWk1Ӈti,aUkޓmcb0OoL+I ;8o^ѴlN@7$'L+Bg`*Y;sr*{ PVn~NuITTk-*C/CRnY⹬엧a 9\"6Iw z)WIHb~F.ﳕJ5q(E#NA *kC<%4] ۠|s:bј!p Jm#>_j&e ~K kjN\Ut-_!-ɨg<_> stream xmspѳ-Ll[ol;ض7mNlĚضm9sϹU}X]{]Ou&'sQt2330TUTL "N@#K{;Q# @h P:Y,LL̰{O'Ks  u#SK[K'৛++?ÿ" bY" ZR* y5ddPt54Z휁3{';{;Svn@'̜mrbB 1FU)@V_3?4ecZuo`ji0[2nRvf:O!T4]mll*{[W@dP1s@l-m<!bO !;1wYhhOo3#:'ˑZw=(("*#*JS🴘9@埠FNOZGH/gdaba,ggea0qr|?tM\v.Q_/g@ ڲ oUZKXXl%촡23Tϵ堅%*n;tN~d-#:( ,d|צeЀn;k!0dAPAd*@K}6wN*>1u~8'c"WUzkS ٍ%E &gįD?,n)5haw!/\nF1m*aTVaϷ&EiS},8JApB''ԯ6j1QІn%t6ˇ.c0_?Sވ7'} D!x$}GOp%s~|ۭuW l! H|lG$0˛X3nqE|i&9J msd{T{Uv^ԋy M_$<%IX$Z"B8)n6ߎM8l-E'cн$@,BNWUƲʟ=v7_F#"3nmLJMVaƓtowQJ`2SǗ͏_NYTdʵ(. paCq[͓uݺcXOҬSl ۋuJ/w%.-q{J#^pͻzĆ6F^{)V+d fȩ!ɪ}vM؈bkxDԹIrTq4)m<p}2??\'z0SHU舮~?j1 ]!D,)t7Qs ڡW18T8<i$ )4Py::ؙ3 bKVRYu%Vn, a80f>7xSM`tJy,XF|9d H8nLֽҧub.[#+" \ϡ16o=>* @Ge'Pޓv,y@Si'Rm2I5\BPK":ޱ(ЪcNȯ3NYȿ6YwtmQǒy"?vs Swd?Z%f!/q҆|X;06@?%'3/^a_tQ(i`C8^[E|B*9R2b;wFC=;YlZROcYtpPD(ב: T[~w'Bx.I-q(e#lorW80u HQw)J@8ᮅghI[3i >Vj˽ۏy瓘K\hPUQ.H3Iȓ*G#nLssDg#,w|w1S=+HSjX4T纂@ K&iQmiB2F]v2%SHcfX_>~1jvknyFGlYf)&t,]ahjDLU8c͖o'5XkK5D#^~ڏ % Aiނי9em+1H/z e&ոnZ/ؐe{'Ķ]v\(4X3$a^NwhD3I˶4)Mb st[M;0N dL/N)U'G=SG/g 3q( LPEFa5jƩ AvvZ.:",kld-֚P Mq#X^* 9"k0}l=NY7,ga 0vbM߬iEz*HSqL"dMֿ)gifcn)Ʀ0B_>,qHvBZψrՍaeEC}I'R_ٴcwohݥ$ ҝ뀦m1`|ToeEdK+x2 |*@5nɃӚVE1(-'u{~p$ynHT5stiT~F> lۉ\!}ni:%  \QEV%@EQyoE/4=3zzv`CDƥrvoe*6\/*CޙZwciW.ݖB}$ejz@Y#(;})hlpۦ5T)YŎ #뜅u/ۡf,L1bӜQce O02VD-2zyogđ.(Py[sz(WTDi[ź3zP(Q0L$GSnDfSoE3]k3ݢ> EptÏ~tWwBc_oߵ4WEGJY{>G]n$`Wt26# 8ۨe^!u&ŎTY;: K&#!*gbd.`.)[;KnO+[ZSo-Lh~dnF s{ ְQGu+Gm*&}Y̙ɹxo%w %V޾F$'`eRrp+RxۆOukcm5ߞ@%3Av(}DMt4=LQVׅLXO:!n:+MGWFu7'Dpea㌃Ws\[CI4=iVȴldje.eLEPwKa.nZPiGnW@ox-sj`DvE8*%m#`-kuX.Ʃ6fU_-rWF'GkP!w#yǷ!(_CTl5% 7AA8 MWFblyO3N $}xM$bx}N*+?Cz8H!MpKWVregF;w%DT d #fXH"8vV曠ol\ڜOOH55Q}aoR EÅ sx0JBGÖ-9ohӲSJW>*ToɛQMb,b2w }vMe@ebAh[ȄIGs VsodӓNlīUG5;Jl41ׂ>׎rK{3`74UB)N4\ Q[w~-rt̏i 8֧f.**92fttS ȶ<rjtaٮ{O~WHN~/!83٘`([(b`3MVa]W*P;N)Sk"Ig9@I9x4(6lu"Dkg(N+Wk-F?CE _oZpo<\_ßyԒr7f Ȑ2S/ݥ筞U]$-ĞyW|FCX8%=MӵkU|KWSSQe1D<؍I8e 9 v3ϲ%+-ti\;ym'S<'j't&\XPh[ӲW\I\K@>G=9'^}fEө5 Bt*?f?1KmsBaLeMhܬ tAzvy7@,5H]cl**|NჼA>ξO]e (X,yM)r$kEP auY9:tFrW3[grl/y{ dh_6C]~`ʹj؎q٩&VyKc,Gjpqiȓ@PǸe3-; I9ÇxK26JwF1gs S{AX6q@* 2T@sm6sI'm/LJ:v+Jcz w l(zr\#櫮OҵRw^e_")#6VCleOQ RW8N[ڗeB^ďK/D[n}] 3+#Prkfd&8]ohL|nU> De@=E0ÂqM k^KoILt c_]YG>)PiJ;Wp5^UGaJg"hԣ,*Ln"HUɸ`zFEFX?wr}B"HDa ZMjV#ev MzЬ.@1kIpl= NPzׇҮ ZҨf'10qF)Q=Yx1^:T>{v%> \C$;ZoO'9 |t 3~=YعN308K4=% h݅-1$@8 HX]MƃH+mu$i5G" jܚc]qc~7ásqYb[ܨ EvvI}YfD\]\a2?c- M!kKYZc4e#s>ޖ 7,7\P2 q-˴~Ї5;H9Y>S\Xfo-YبDJ23LnbfU9? vN6F3tg7g9J܌ ˏUݭС>Kmz}, 2vD}e~mf:x6%]/^7M*: n{d(oh"nٚj#TZ (SP hbv!5upC# (D| _E gئNhCI?j~oy#s{1%,* }sw2V<0/mY9la(+ ?hO~oYfg&Ju#vO7Jy EۅA[S0~Wj<NO;>l̳z% /:B=Zl c¾ P7'P¢qesDuZ ٍK'bs7=EG67p :`Q)RYw,`@Rb`{t{p Kl76^d<,[+2{-6U"[6)(ΫSw<΋[PkM^I}s23Jp4lgVGmv1Ib=gǯ ?YCĝS{o%]'depR g2O#?xT)\0ZY=Ү5#NnDz&G?XYH .z"I@8@tKSa e1߸\ 3`KdOٵSĝgZv lh6Ift;4+=]xF ,ϝo$[ o y(օ wk{(5)1bZɆ1rcn.)dB작bg;c+Q@V+Z3cfwcNvؘ[%tFjt*=kNG51f0ͷĨ[{p|z~?IÏBy:%4U [] ֡"ҽ!IE<\tИ>K)ܚ kWQi ϲbb{SHui%Cࠔ;tE{d&)8WCTKS>>dbt"iz|%*$/ֈ۩AK?F42Gy➿7" -+rfٷaw$s4 rt(\J|zlUDNu$,gjIpu_I:00?Ъ\9dO/UX8F[>#c_ &p]  PO[o <Wv9B+s[Gc 7r\3>I[k1BI(,&3YYٻU4CP6/xj'祰 kr )Ei6#d3}|i).\HAV)_Jʯe6-sي7g`.p>ySD^fd/*մ͇a䚣~rj}MCV4 |8 lcồr5ƃl a*GeۧtB]bM`&C!OhI( 0$S4Z]F "6kʤlᢉ7_Q<2ɯjXka( w4>K^qV akgx*G|=ˀhӸ˭ թc6NFiik֙C~*EZaaCM0WBa{% AluPW61^ ,kSn]}-{ WM5 >̄M_5ڕV֜mXZ 6N^[L)^[<#cKo^&5hq5T-k>-)R,VJ~@W$\ܗw0ߑ?t,tg4+\oYwY >Zt 6mZ yYcۚf(^/rfX}Q a܎ݬ\?Wh9ErGݾ[4AYI6H5v(*s`*bЮǮt2Bq$,m+Ǫjզ1=?=3dܜF7\m=L*xY<=RBi"L ̤9d1ݗzBC"5^B-dV+1Ġc8v2O5E Ӥn&?-҉!wŇw+`'Hw:}jρ Tv>}xf?A/jԢeG9I3/"gӗ,@CSƒ-.FzKS Qh ut)Aspv|{A n("I}dF<rM͇2?xe]گd3FNZt>>$Ch( 8nJz3> .٘V 3^7s*dL=]FDpJ"fO SV&5FwJQcC0Ab1*.zn W)*% t`nmzK~c9fv,k4"0RVN"4₋TUAzuį0Hܣж=.Sm"ƗDm6O:VSt]祝B԰6" L60_s+rvȵ 0fFnCN9S<;tTGO q sA[?ԍ$T@Eٽ{v=g P)mTlǡ•J !;OE%E{vnqvl5)'=řdžsjJ1k~SnTy6÷A( gqcqPMb5AõikQQ܋FUtr Ya FqfD~w%͋/gVҖ<`t%9`B (돏kIum-8֓Ϡ22ۢ% /؆\?bvE宖x밈p_m=wD|j5'fo:JG<۵Am1%s=wر0([V Z퐪`bo7v; 6_7#˞fgXZ.pvV$/%QU|~YS!c;Cu7 0s*+QЖDށ{ĬV?_;8bdb#CGߢ=tX бXǔ - R c~~M@V:kk#J̕قb)lr׻t;+1̑|7<X9K7kdTY$?ݗRj1 S..MPx{]^|lͣPÔe/y[{j쳌@@Ə84@8:=wB%؃@n=Jo䡊g('A(3N\G8AC/ҡ7TYs=J햘#.:GHX:&A:*tQL(-ohpf=b :,N=FWgd 3ioƥ$/7\BuyvQwJ㦣UG< EhnK"^u-rVJTo{/Q%Ox֑caOJtѷu*"3İ" '؇Iem)L2 Ä|xXH0p`'p +mq\aܘyqtq #6i'Гg z?_W;: ؞ʷR$3C>Z?h<`,VMUcesPT3it$!p:Dgb/r2/eI四&4}L@].{xhHwr$Vh-Ru.ɡy8+M~'!hrtnW1 ml`Jj?1z7 O~Jϳ1uT*! ^J%jFvqdCiglG"#4l6l&k2O#B@нnN:x/_'6ŷ;Ce1pp] /$FYٓ1Fq'%bĘt^V@Sk'8lvnVR{jfS6<)C{!0ӆ*{ Ui Q D yi]߯L>RċgcleA7/+\ inXGbtjVhjj֏/eCjnł,7vco3v8A[z^-F 1;VZ͇gE( oPד(%D]VQ7Cۮ9 pܝgg_T mûSGf JpP$heIl?X/̅AƍJq5ݚG.Yt6e*vJ{_/ޡA{]$tgDڨ2;!^ o@\ h!#>$ʧ$kD` 9fH홈i~|-cR{Jq`f)Leq* v~g((95GIiUHm|Y'uig6ÃOT6`|w}9k>xs^{fDeHL${&tp#:I]`Ny rZN;*cc aRjt(m%U9v}] OHSd_f$ cHYג2(l#~x yײgv+v w>iή0)qAgN'&'(Ur}$\>u"!lW QHbL(X%#5pn5RǮJ\h\ &?Y [UPJ'KIo#ԷŽ=BZ1z^=f2Wj5oܩgKk4<&\S;:/^3/Y7Р*Ld^7l{1Ϫn!Spx*~@iѿK5Tl/޴?Aw,SE!*dTO8E.bbZIx<̳Ue޹c>Mj =hBsc,9֣">.wN 뚡,mKeQػ5 endstream endobj 90 0 obj << /Length1 726 /Length2 8844 /Length3 0 /Length 9432 /Filter /FlateDecode >> stream xmweTL-.i݂!@#ݸKp'xp zg>B\4<@luiuuN.7 - H : DH@s:LsipvE83GD8Q=nЛuSvdiwHώn [@~uuw k2ەb|{huz\ Wc"►]|DGH2&X7}GE&Z Cj6vޫ=2bOlA㷷6bFaӰBoZpA?m>{^"Z[>hwvaIN>mKie+K_l`2 ~o.0p`31mGv7;x矞>9f-4h{v>e\7so@9rڝl  9K reEM 2nmml%{W .st$)Tцy_̂Rŝ6ޤ\d'utޱ1/k5wb74=zju c(lN{:vʺ_ll>ȍ'Ҍl (p5n|69ZsQG]iSl*JKȓB-U5:2 dBuTveE09q>Bԁ{:rrEɑNJv^v֠xBURȳK7aF@x$ccq A{f=j-YIH˒(W|HI1N&ѧ9 &%P-\fSuTTQsPTb)UȞW}"'ӹʝmJZ~A!Yj/6\X|^^ReaQ0Wh15c6kZrw(N8յ^XVe_5* ~by2SkNk*ܷnC߅0`qf6!yS N׻1 Z-\ʺ4d=0; "Q6FxmZCyD zߺ}0G^ee^ج4{e/MTKXW4$ؔ2Z쐸mmI HS*c5CWג,Cy֋vQ+תh^eMnP.uED@~%҆s=p{8,I$mo|1s2MIPdv}jʆ7CM6Ru v|B=lKRpn|RH=fa|ާ=%M ]5K&ݚ"BX'MC |ȼ&#MIJ5yh޼Vf ^Y! њewvG pb zܩ i{_\ {-\=Fވ߱0_dX^Ԣ8s`vʥJ{_u%\_q⤹2f., 8) ^kE/#g, , KK^?\tUb ~ƻ>~fWzBUC1ngr>X%ݪ_^\;@A*D!65t?@:[QM`26%Jee='~ F kWc;r. Cl+'TyԓZՒi dWvy Nn Hs8/߄f^>Kė4|ӸZ\U ǰGK-͙(M*|۝Ţa~d?C-2r.qϺ19N[" ^=]֯Rw͍-4J<P$&':]Q4Te$-;ENz9 LoM$F%T2GCZ #Y'/)"V ZAyKp?]^u8b~y25iJT D$s8̶(6L|3.B%EvUdؖBwtck sw>V晝)Cm?(Fʟ5>t5rAzSm+_dueJ4dK"rUPk7'`֖n^x! vC\S{<G UEt#AmPמscR<ܧ,`4l'Vur'}mUZXʈ .HdO0x zJdݣt:ιV8emMI W>s ~ 5δN}KC3bŚN^|LE|ƞyqR2dڸQUtF{ ,au#DB*u\RQ/#gǰA%1Rz i9=\}(YURJ@k8FC$!\U|9Jw-5:3`5-bO7SwϿeYf FyIͼ= 9`.^NFhPތ2> U~MI_E&8U==ROV&“jnVx-s(` 1-iK< !ǰ'y3}*q?8.9oB/znKٟVRvT/UsiYCVK/: bF*N >co# $zJ2%b~5Kr,Q~߈sUʨ٥,ПZ[eЈHdE5C^[jXIWq|Ň5LaJiƯ(7U~7d|v2Q+8k$6}yuS'JF#:#9^ٶpXzл2@DzWRwm5"jM]e=d"#s?"A&diC NB|,k 屷Az-+2D[1p_W^A<˜ c#к[fbAq;jr=M?at'~8,xaW}XNƩKNlcSjv"A|A|~+SуgdoZ񂙅=,G0X[qs꽔GY>hMSRڳM ?],|Vb,sndJ;Kjj[e_w_^_iV_USXN%4绥`n C#g:S}c:$ kHwX=#7A#hں]|p%UhVsJayFqrm0H؋t_85gCtjpdhiS8P`%Fdž4 $ePQ" ܉'[Иr%6q!נf2'O&H9y>{-\>oˠUJ p5:$L%RL:0P77ݮIݬΨ{@?\XkDɕ[)7ʿ)wv7dPH&8滔*9i{LRm'u2J~ Cɖ}#YzdBjBB<}cʉ].-說.pve/ M3gTN/Zno#13P '27L~_^^E&/k̕^W>km'Pp'^r![;kRiSɵ9>Stc[ۦ1c |.z>/*S!=& ]!of&i_bDlIpHۭ&_-Ӡ߲wa72*|V[td,E7L.g,5S`[ns\@?U?: Ż̮ZesRZ̊w`G.y{O}B!T&/lr\#A{vgsR Ԋ`(w3ܻNx0__UňwȺvat&Jck>B>R ۽vа)M~jͷ>B:*LmML1ө3_@%MDlV~+xP{ÊT D^]~Oiq݁R yd#`YW ahE- %oE1$1aUV}ҖQ ΃fE+/J;zx$8dxU-# E)g=BgA.N})Vweoz6lM+Zp&U dLp_S+,"~ԡkibb4JJt6 "%&~9qۋ!9g)/mn2#A@ ۵]HkᰑC@jDžx@ߞऒq?4kuH VD\Y!TU?TWjذ P^ojR2)uݘS~{MD{s4zwS,eE`،IïTѪrqLYBPHw/U$ iAeB̜Sړ8m9Ż3]"Vw0<\,8 1|̃ ؠkhmQ FxAWSAHg[I(oԔ5v_/wnwQ#SzwNAO-_$< }dF~MA4ۻ(ȱ̿E䎁~^zWkSC9{]9QxT,{7n9FxbY0@,EzN;ԩrR:b=^=(/&U)׼ gsg.ZV߇$1Y iVlײe\p1 ak-siDA8=Z»^q!?*⹩0w 7t%M)ϤTjn&f0JȊe3 ]ŏ#E&OVXQD-4|F.k{GT19:Tk62~MiڇOr#jSdAZ;N`s.VHw<>ҢAWA!{Bdny=(jQwqͽ+ XVqr.}w uWUGT۵%}Vh]P4!b_J)iN>?o90jҙ&4b'X :RayI̾A6?IM\RHpE_uMTt&S&vAyX"S ",8KD  . (-Zkec O뷎.ZγLP9>"0%u*pڠy"qЙ_rECBz. 텈 9/'\*+8r\`ǖY2)icPf@p|G&NM $V0J)K-=]0_i2)BO~1;W>kuSdޫHM_^UxZ$ǏpL\$rZ )&8&%KN:R0)4y?^X-;ԩhݾb9D8/Tq9ItA h9Ҁnq!;]8bHaeX5l,{L!M[cYEg1r3_FseHNҵp D{A߹e"}=i͟gSå QV E2{R "1>xNƙ*5ojH-_%Ty4YBP]N1bGE]bcjz!~Jv}R-E=3F>b$is4#Cr P860,D\ֽ^x (@[)sS՚.gӇ4@]TyL 5ϒY7Lj˃r􍁆XBn%2lO8l*6aMڎ01<wʚYkdQ"-ʢ=L ->0/r~s.]}-1mA.ƒ-!i2##{X`;YuwA %y DZߴsN(]q0N$=AFS\L0<wtE*VkZV┧sh~J\9XN7cXo+ʻ Ai00d}6}7#8IwZc#@A׏V$]d2A FأE8DE.[5WY|\Lw|轃8o04l,GDC0I~V8³ERHnnט=ž#yP7Ҍ SN7y%ESBRn`}5BGLg,_<*Hԉs7suPqߤ cMY {ی[CǧM:!++5&' Ʀt~qJՉ(1b)L5 φX ր8g{Gy]e|6wJT>DÚ6ouse3FڲL"y_a endstream endobj 92 0 obj << /Length1 726 /Length2 7165 /Length3 0 /Length 7754 /Filter /FlateDecode >> stream xmveP[-]C23 0   I x h=9sVt^]{]>&:B rttu|"^n~l&&Y8uY#bC0 v|@l&jgڲ  APg(` {zzJy{p=^si{0ud55E0 vhy8AmjP[0N$[&w86%ڃ,7 piBl$VVϚ譓[߇gnJ*E[P:jǜ"~·j dU} R[u.)3yqTGHG*[=f/,q݈2)^Ȫnܺym"NFJX$=|ŀ+F+~$cZ(cq.gPYf!_~\ONDΧrh͞!3 ijى"yɿnȥ*'@i٧!$wH^Zv}>% Uq 8kަnOVRCT[kӋzƷD9 DM:ҊjmWz iU˙ `we;)e[v9nR(J~- 42ӷ<ަ&k]!+# N@;\UWs N1; ,V;wԈk [15JTHky?טثEF./J#񊨊vDҎ#Xlv/)r?c s\UǦ(ؙK;\[aJ_l45Z8=Qrb g1,̗kn/\O8-<֘S/ZשƢj~XōѢ9'/$w{}]XWNވA$PL @s(yq^!PZBDWu&9mFB]>/7XJ˜xT7-ran`[6]F,YdԸ /) AFY|IA/䯢TŔCn]P\O>sM<\3,<:$r<ae +5ߢ+Q,VB[NzR&xZAH{쾷0T^SO΃p! =Uw3uv584'x۷yV]n}gٟm?tZz[a\8YYԣ'[HmQEO.][-;ЯR! |sY[C?Fz/kOʍG~Z]5<* %f{e|q$GV9Kǫt#byxHO- , $ľM@7(׍bq'Nߊȿ(o0 4ˎ<  pҏB-+尦{7Wc. 6tHXB,$c5(ߠƏWb.|5c7F+_tL`WL4z;I_}> Q'4K1 L*^Ԉ}ǭg@0?BpxRe~Z32aKpKzS\npj+^Zdp]) q=]i&'iMRj6kܳg_='ʫ` e;WUr\*C"+a5Y+-Be, P~vcZNٳbry~)H(:z/&ޅlϖ@c)<3o#J0 g%$%a @ĈZ^u? 77YyE`}U42ewz4c H X|~ޞm\57.>`G>[ƫ}r!jS7@O7Li!'0}.$9eZG9+QJM,n@2˳i(iW?=m,.T7i1-fp;Vt&&Z퇰6}25ޔJ7\Є]ZŁscn{ U)NuCyqWyݼ_[ɳ AH8X_9+ | 򲼍;-A%f0Wŝ_GgLF0=sp҂'ZXp@Q Ywut]W+yu[{?uTu?x*xUS&7f4̬Wd:wVJேcvKS j{Bm@QdbŽVP>pIX5bPQ44[EG%*jx+mN|J;d f#5엥_N{_N `Ŀ!e;Cl}=[gTTI:35 t`!ۡΛyƱ99=q$r{lyFU{,T#Jl5 L#y) Çܡ%7Lcڇ}㩛XeWXhHXy*O|Y͉h۳${Nc/ꅔn}6A)vphi56Q%-p죤v/Jc}*(g0c(njf G* c^.m5xτ0k7kw.Ya2ȼzwoh?۲0",0kuZq d$ j~kjS]P^/K;yDKOtb,6n~<=:QU>sM4@J>$ysB+'d0l 85Yf.Fl>m_ [uq@dv\O J奲<.2e/OTQ$is/dy|~%2`k&"O gnZݳE,4R T*Xt~ v_V;L$H)ؔ,u~2RWy.%= #c:8wKŊMޟK!A̓fۆH--XܳC:GVAvNtD#*bӅ_hT;5 ENJ$ ou~ꕼOr-4gi^>vJ%iVl yMXbMeuY>q1@x7+oY}TJpJpCvös4iH*?Ҳ:Qu}r`XjպhXD{S mo*os0AG2X]3۞j:͠>)TMop>2uxRGyV͠-GF,&Ky5x°LǓKWfoHnf74C#:ZQ&}<=i$5"-&S5A;DŽ[4z{_!ޟPl3#lWSJcL ,9C[Ϗ5oQf~J= ELkU*q:냸9Rz*G@<%Κ=K]} WoE,:JIQ j)߇p孠7t@Mu oUŚT_JC=M=uSh͎m0rsVp~0`<ll >潔246-7w=̍E|bn̈3to{i0m$VXYVa7i?P|)-z_QS}.QO˗ ۤN[>xcd9g kwMD7 lRz#Җv8P+7HߊFIxO^աͦpA1b~nܘRIɔ5ԁ*mALIqO2v:axDeqa%G,8`A"hROU˥d{ٹ}.߃W>r~Mv _b-ƈٝקkr9yyPEj:()7 eDh zu %ҳl}l;9|A 7|C7WK Kg9):Jo0.\TƎ"0SC.s""V'PJ。Ngb%vhJq0\ sӚwo~ rp5RI( ^PapC++jCw-s~62uӍ.K ޳d[J/ryr~0d+3RPLm} l*Z宜R审s kXkFBAS.Ulځs;ےd1Jgw}R,KݗɒZ0f"Z#lU&f*nwo@x #SA@HtIpm衆Z@Jc^R!/*106gWӺEtP<_󰚙v5+0 g}m΅47t!}KiTϒcԻOW;.Qt 9Oz#b-?.$%B5ߴ5+՛E $<{TPpt/>VcZ.X:/[3#v ]?׸hшGm0,MJl:_4G-IC$F|.,I(LD[B7m,L7$τ?o!If#ag<# -?ʙ>V="f%[r4BQBD.8kHI_$ߚ֯JbMU= :3Ϭ`BMHHh([A0cn8g JD})S|OB.ws~Hf}N5 +! ;t}]R!䁭G$Q(.9wvl=r_tbrz:)P9)ߎL'}3@fPN4c"8sZ5i5&?ٮ ײ˗ٺ&ke3K9~UNVaNtX̝l9| uZq oYdo bȣǟh )F˚%~MҞJě"m-F^Z> m:7v6B7bJˍmJ%1:33!{̭儻0MvAKzy?"-更M©6m8ȜkaT5omȬ{x`eO gSf0.% E_\$bY&NEvJQr6Mb>bv- uB ($G$3#P 3  j8Z8IЊbw9_xoDsN9P|cNSweo}ՕU_.U^<.w4@V!F/,bYI"UCTb}&Y3MBk?4(f|.mU΋Y=zrE3Y endstream endobj 94 0 obj << /Length1 737 /Length2 25284 /Length3 0 /Length 25853 /Filter /FlateDecode >> stream xlcpݮ5ڶm۶m۶m۶m۶mw}P[O2̙daV-RB1{;OSFZF:.e1eFNV:f(RRa'SCK{;CS.uSeSF&&F(Ra{O'Ks  cj6&Nj6n "n@0m@n#]277Y.kyc *:@v֗)uɑ~`Lk-Bn6 anI1-*õ 5%01Evvݪㆷ2Wu G@oyweqsyTwyY|#^fu\fuwEl6W\d'9&Ցp+-Oшۣo.>1ymH2\L؊@L`d ۥ`*?̓-nMgc8ZYSDž-ㆼY/UAH|i%a+"=.G<eojxbT 's 7򨗔A& OÞ Y|pvN B_)X3X儌+*U"Vq̓p]bڿ޺[e2{qoqU/ i/0fʭi?L-Upzgg"VtLmgaCujRvFs 0SC>XR%"j}Qolms-n[AA )55Шk mé (`fxGM놆ʌ!&Eq1uޗR檦6,q+{>85՟9ZɣK~daڒx_4f)s.p"F|% -@, |ᘯI Y"}A;/g؁S|GΔd_@wı_-)B'C_ȒtMphsnAޅ! -\Ugs""ʚuu T,ާmo"Y%hltdb2ݒ#j)م'ULupACJW_jK <[?^]ws%MQ~Z,k\QL\H$H_L2/?΀c3*kѧ(<^&|q8}@&͞iCI2)9&K L[{~8 >GZqo蚰FWk{b4G+zu?̩Yy|VU@ _(v9V T-%mٗh*!U)E$ / ^ S,2=K[KĮK1. ?izP+=28 nd{|8 >DDՐD(5GaOz@K f[^ǴŁg` u*R(yv喻/ЄF  c RfɿşJT}Z0ͅ3Zbw>`ju^x8"5TDZAoxv\]Hb2>"^4Je lq~0nFӄ{P)E~bԙ%*f ! 5W~FaN]4ѡ.: rM;V)?YJjO,,;Pd2A#4\ GY|ĭ35S]#1i# ({-)!y TUvc =;X*}7`2":<Ņ/Y u/ ھ,QKO:֠uc#{]N م`0ٓ} ox]gx.SX6X~U{ybqZHn7Ӣ֘ЌV(r;5&b{OjjM]s$V2{.l||ΩQX3D9"dy+K$d9Uv5_ ]}[xMc{Y^$ىDS^*{ Vy2j'.P7[O_&tԋBo@Y4bn:X9;o=)o>mvN 2s@ x&ysQK|0NVU<3_-z ?")Զ$dm+2(XpGSO`v{ߕ].*ybJC XCQ&wQ}`W1|ѵKhJRf <}᠇.dasin[>%Wm>𙡧p5.bD'Np(J揁l laz/@ AC3\N!)(WBn ŚyS34(g8P،|]֬|>z+o<~*V\LI7~;%oΰa@G}ƄSCY#,f/0U (/ YWӊ8( 8+Y'T}@IȝIw Zzn*mN _)-i]=Ynl4ڬeLYY~u 5[ثaA,. pj@wg0{<_ޢ:b D߯0OSG9PG"lJYW9u)\n,xPA2dLJEL.9Pi?8 :Wꂲq;omntc&7Wn]\* nje5b$[+Pz[ZZ]A0yl/ҍ!H*yi e7eXpscF+$_3[ 's@-(/ Ye6!`5_0ڎ'(`/C<{YdWd `og{θѴ_6v.mFRU^qv2p8O& 5X\5 Q 5H34M{ {6 Ϻ^B1"j7Y8[ N)6Nmh;-Ӣ21Y֖YU:yFbيA ]r.dS57w :Rɨ8Ktnlne'Ϙ&~p-+/jN6,Cc{&PTzɛH u,_rL jbOބDkJ%J $ PQGn<eFYmS>.:cH5k;7 J++<‘ot.5o]Ͼ"fXT?Lhļ߱= i5#W#WFk `V/wTč J$LHK:vW0e9{ ;rGU{S' $G*6 v =LZ{4+ _uo C"9qz3BavӓQ2b׌ ;$1ӟW

"ܠXIX_k8>&꬀uM|JBQ V&Ly2ռbkB?9zרхMluIΠgr,? r^S@x"Ue0h@G+H`{`H]>.Q[uؠ@"4'" ھ]\`λZ"OQwd+g(|c'!C5i/u 82VRg6.-rNҸLпXQB6oa8#Nu" KO4[gŦcu| T .(֡n0eϊy1ű/Z‟T73qGpߧOwBH&Waɮ%ڡ-$jmyVMJ9bLQJ/-Mn$@.@ÄP>i4uǚBvF[ /yR' ;}hds}ubSog\jUJ=KKOY%K{Sپp1$UsxXS̟ZՒ\%NGlA9Do8n^)y;ujA/_™@dթ;-g*ހ$?`c[qnSyl5w?'CyIw#6gMS$TZZ,Jwȑ:3!n9>+kvaeF㹲O-=< 䞬% ҩExkmsC]gRJF )a.@N~<Լ+o?S>7 `* j z4W}< 8&5 )t \~]:#"gDLY KDz)2,.Tge=;L&*!|25-y5i" rqے^9MH!+[2(LmZ`/a4$*Ҋ%QB!'3rٯqX,!nfV,>n?22URp-}GlO+9ULj :]D>Gsmj ϒKZ7YO=Yquыv(kGGOflRQ]( V. sF! -[1x}Y4.tuC/k3+T]1Wߥo* )P^l} YE?K%1 Moݕ=szٺ /$m9me;sq@bcS8h+8'?D ZV3w.ׂ .%uxQRkI'wU倞`R^K b+bh]Ej1-Y BTXbIƜׅdE5Cz{qCh`-۶`MM Vjvp,r4y 7hÕOӖ"H(!Q4hd07'!1̫*υ¿'t)#sS};IJEDHϮ=g8ݪ7+ޫ)ZhjVr cu'cܢsXߋԧV6sޛo<*b;~0r C޼~){JpDK\ b1f$g1V%f՟0{'4z%2?2:/g!T!r:-|®1ק/1 2#Εn|wT~Dc n0^+wkF~RW6SI+@Pxo q˔Z}oVyve1,u NBZUiA|l1f\$*?3 cX('VOѹc;f\04lw9'ݠi Ghe3.R<&}fB&[`ao;)YՉx0AWRkV5Oe{Yi0)F R͑âzL1ы$Z(pu23[L뇲z=.qj~m5hR-CntQL|x>F-]!''ˆAe֋}4/fzpp76GDFr:Kt3STp6ME9SkvVHb!fGx5$ڎL\-$LC;uS-Ŭ7[}rnHDӲBM-5m}Z{΅CloyNVw۵ E27<|5 :E,ݙi->F-yՁsb L%~([O gd#BVf';H1Rlmu5u=w8ѴRV'oK$ɸƑ+M_ \jHz]"e-&: s |I#`q{[A6uk?B *=$tX,@P<Ϥض4I zuWpG0u]E8/6/1 #.MGI3VB ѡAٕʬ`T83`pd; '}eЈɫ6)%[8:k{ęf/L}r pydLÖjyE^ehH UҎɝj} X޳p}z}z{x'pvVz{[x%=gz{[t]NA Q>Q{ Zsg<\=9PųgY$lJCܒSä 5O #t˗\ mv̝t}Ws/Xz]pI/ʤ;kJT@D~482%8 d*JʝB3Vpt/1_B►b8YkNJ֫Gc m`a'sHڷ2Ct/`ZCǯ__@N#=dO[.Xx]].9QCR?,`r,O GG6OчMbT\d:+pf!Yѹ';>V2D8OvRP 9K5b&NL`iy(А\ji'(P\1riS?䜇ecaRAʺѲ+e_(Kܪ8|G8qFmQIBKPhγ:7JB.9ǖGyӁ@jˣ]9(Cd_)R_.(u\HjZ(fZ!ysμ ݢ|rL 7݆J9XczKš~+Xz6"sy&.=ÆpK <(F~NZ%.#T̗~C`Z>m{AfU1 P%h3mLBe)2Ұ1WT,imnIJЧXys7 _@‹K'~5^(Ԏ>^ؗ8oYp$z]SbKT\sԓoR̲`N}RH@:‚16tO6.@ts o:ƟAT(=c&K*ے|1PtrɈnoVȤP.&Ł-܏Ud6nV[iX*(W.45ZY)s <`r1}3O!kaOG@sQK gX-c!zq7Kw%k,zq`3s>oDU$o/P㠌Ǡ]ـkH.dI F)GcQszNw~jnla^Z܈J*>;kI39;-Ub(݊÷v-'1U8Ag8Py8Kp񂀯k.8Y{*!GlLs]K|8*1i+ 6 9.5."Z] !5OUҵmeӝ 3zd=y_o&4) `'u`aP^'K>URCcz. j}BmH RK8V+OoX;/V5Լ@8ب̵F[(;3ⷂЈ^Tw P_c8! hҋ%-Y $6]kO$€&QҮfM>Z$Hq=oZa ⍎g C-)xi!)E$e6smPѤWW!yԵ_O[%4g+bN)=7d2!:oo[ dm6 :;xTa{ԾVfHZovh9Y9?GHىVyShm폨.'0{+ h8/rOMqS{21)yJ2TIsߡ۵pb&2Bҙ0MMJimwޕɴM}+%NGs5ba)^CBiKs[3y^h} +L s񳍣8yŸ%ߩDK UWAjHv6#|9~P?M2y#'055|ӭclߩ-3_XREei(AZh⯿θg!GQa&U WIS쭬\t!xۺN(jW`fN~-f1w`T1AIvyˠfy|1Gv%*#!#;3%cRCh70BHp`?|Hs!KpB*'g/&Wz[ս8K!iv9FDzx$3:T p!jB\O[q.B ]‘`O!hP'KBYE5p)fEֈXj2и 5Kml(},BK#؞B؂1'|{9F>cs+BrFZ=i$bӭt&lQ2Tnx6j$(rԐҗOE;cWSgToE2@ i,WgМ Rڈ+ ?/Pg$$udUE v& ށy_ǜ4)WR^@gx STl쉏b(Qmk[㐭s"0]//޶읮ϊA*vgWC}b6ˆ;K^6 <> [!ըUoNzAaɩ 6"ׇIdրj9 ^Ol: 7HG9l3bJ1\û͡5Q \MA[E_@ zG6FjPy# VbV yo 5g޲BG=븉3"hU 2i<=nN\o'hp䀆_Bk XWQ)m\'l~nL +, W,Av> -;.a >g>\v=|` _ŏ96F 7`}!)%*d ? }Eqro 'j]ʿ* >^{Hjެ<"'p@ΓF/^{ |Qڴ~GE'!m-nZeG8dFuèN-^1ӣO:絧Q.uv=ţ{K~u* c,LUwJcaX:xo , V{/2o{$Ǜx|1^X!vPv7}[`LJde n#qwJKxZ6t/y"#q)#l*\l sz3vM X9#1}btQi?ϡ4_Rxէ3WF:kt~RE6 ;Zօwk7ܩHg#M8B z ]qpQm9 [JɀW6q8nM_F5Z$ = U6m)и$jIzhQ Sti90ySd)P}P' K/ǖ|L C uք+^ZP R!^$(@SC9]:My6邴Myfǿ~eWbW2m]/vlepugQQԦ2[*({"F@l}1{{ݼ26P_FEO+>Y[8uWs>E}nf"$̣q}b\Y`#hdH )!UR1GJyWFi5RUx"Ed4HU0$㕶WAqul~,❉Xuܵ' HԪJ9kHTJwP],k[r$U(Ozj??irFΫs6NVďƉݳ)=ՁIT/5X{|A =,)nE%6ѠzO5DY_!{1$EسA;;j3T[dat R@+DPƊYykg!ui-_/C^7gBG; |*}F&]V=ObeloɗLe3`j9_/dN:6olT-TjKC* kP( + }JNm PCL/<FFK*뎅R&$K{Eyak Pöx @?Pq},\{2 l"ʦsRΑlȁR)3;PV4jǩEA rOH+w<(mq {!x+8_+{Emae:$C<, qqܑbvYuޘ;3kNoQpBOdm7Q~Ѷ־x3m~\++w^Jqu#,~R?'&A(;HSE}񧡚Ӕ5wr(v "^_FN۳$>:IdQ{nUC vWpg.w7 $.d\S?wZF[DMȑIq;T4DQu&[f84&saI'߽ޟ̆ 1+upegmP,!q8̐nKeIayDa^v{0YC80F1Ik8HD,iis._Z%t*#05bf рcu>u?#ƭ@ \ -S*7Ԉdsß0ns赣ޟ 〔|H]׋M<h8Z#_h뼤1t_ M9`Pthd䲘UB0)w#?IIw}.<cŃ]Hg"J-"yCU`UHW=s 1g=nM/5CEjFM6]4EB^B_pڕpn7ƽvzSo XSRESoAOF:fՊ{sk +XԴVwf?/h۩uO;nj}1v^bG}7K> p.9֎,t9$ڗutJ?_M6nY]1@ܾ  2{p\cG$_]S+$!=O$dʈUIl`&CTէ ŠuU|l[1#tRbZ7&~DA؀õy s1C47X E螉IAo$NjaŌf0Bz a mN_4t$NFoͦ%[M뤂 )o/9jpm2I v$Fb{~R@,>c*Tl"Dk'd6`R."DA۸a :U<5-AV2sђL h0 C/"zOo:PYl,>YND#}q:W7 _7I֮ )xHGzlUbrdcϮO1=}y@ WMY?yp42uXj?⧐Xl[}T hb0%~#U.f4:\!"ud!uJ 3(TvnEJ__45(փΏJYHK9$l_we`q-|iy0}ej$Am[B$O۱`&崩ipXmH=d*;qbe-LR߮,BD&Qzsva,tLEw%0%1AnN 5hi%j "_y`9U~Po*ʺ*rl$k&Ap*Vݘ y94|/-ڡJp|x}B#+C;!(M56-w [\l ?iG=)\5^Š~!vu;աe,Dvv۽*2& ֘z %,.eoH[R,[>a,Ŀgcꔐ1h{rmM9nc\TgԊ⭀V0\*2W1< I RC] Q]kU{KCP+&LGqdpn+IJ.BDH:Wї^kJ~+I]΋۾I=ˆdXa)K9 ܄ՖVaah_ qm5IEy(%m]4NB-c胁|Ubcjŏ&),1k#fͱ9?F~y*W?NR ͝+t4ÿ6#pk;m>} F ='vĖF4Q #ɖZԙg6V/nj QO&aiz,_YiEk=Ǎ9\w!m<J6SAa{FJ#0{^f {}C| 42}bA ^!%g8lґ,q"vķSܚ}ᤧP2sȰM䋯#pk٬!Cӟ%m.r``%]"6ܥidҗTrJZ ( P%{cN.1FL+nX0)r>GpvF)@}+g52B)W=Gx$Q&vow@4g}.ցS]o͏ڂ 8>&;ܗ^dH j 6ZX ]e  n>edPtPH](TkRhL:B([1>qn_t %B:Š[z)dkV;"0 Ay;R 7ԅ=K5"W;H#dx#ʤ qJ*&*,UFM=7hΜY ؇wܬaad; >&øYB3BY-Shr2 45 @:D3>Y~U|. ezEKݨ l3gE2xzM"Oqk>`|%:kt+k|m&$ D;uc/b=T#&-_ctcJQPasd} ՠXPvW=Wg*Z=a%@^3xIfBrĉ1oL}ekNH );УP"@7dhbET V?Pa6Ƴ(W|,<&nţ)aнeW2]/ǃ;Y:#& 7&g!P'|;!H,E'(^SbٟxCAAnHNhp8hC WR tv:zmyȩ],( Pʏӆg~-}D',aTv~ XErbMA(܏+`H^LnSm;0B:1igd=tI q2γUW۔ 'Md,rx4*[֨!ソpP)}v!{D/d*kjJf8B%" G XmrsA'q_`A2)klÕH8l#J)E^ۂ/:~gb)Tp(efAg M0jMPrw{pa,._sw$3qB2,5LlW;1N|Fwq?a׃5LC]fL y!:͡otc__x ͎y3 qCҠx6`sBOz ON$dzXAH>z=w-< -bs U~dx+Ӆ54 31ֿ BNknȂW{5:ڜ5b;z.54ig*!: f_%oWpGS(T'~O c"oB"@M$(Pl1u_- ;meNY$Ggd Ch؊|Hb]#7:$G:suas1UAaUd4c93=HFG?T sr[%9E}n;S;BSJ1ܳNnAO[8|:H7YGFG3pKRXҜzu8:2>;`403Bc3ۏ-fe9qH1/6͸Y l(XJ*|hƩX.Z MCךH #cȽ%m,Y{쿢((OL,d-~ڐ'պ׈n ,D&C3m@U`CMhipQi/Ubn#ב_ 7 5ިg sJ境 kM Z6Wr.`]/lƯ wHoF˨dK(PkhͅǏ@' kh. TɿQ:h wrEWҬc‡ Dm^I_B6@<!u_[QP?m::~kG8H ZN?[$-rN_ HIj;" kAmJ ~\0~CPNibtʿgRǿ]x`V46ѣP,i$Wwyw 3@,U#cr47,ނ, w[r3̞{ڝ8L]M(&TkdB!  B-Lےs@9|sj(ycLwHn}rk?#3ApyW1elܝn7<пe V+#P@찬X?2b< cɚ>RoAh!bq(6KՖOEkXvv1Lb L9 c*1f3%Y"Λw&cAPt0Ψ-;5~(/͚{@'DNս:$ȼPa69Rdߠ#յd~e0+:MBCg[-1oS2FUW:+ݢZ߸gk' JkznaӫT2(CqqM%*AiѳB$,JxR1ybUlOr5Un/D rHnJ>Qg~fz5"[okŹC/t𞮜}apB+q => ogA.}c=)T߯cbdNA3+lt#wuL"uV(p ,SLG얗- -ʂ^#( o yqؒ1(}}J/v5pb1>Z8]؍#$iz z;LS~̸?1Ց{O\:,>=N Cj~{69lhc /c#KeO5EGwcWEP"?j.3h'_)'emSrf0+^R]n4Og, [Ooxg%A[++4 vdMQzYⅤ^]c\<Ē{z@̤stm =~ь?k*Hg~)#oBR<L~HJ'.Q ťU :𺡡P׉Q!Dmt"gW'󾙗#; ܁{7Tta{pNu|}9Je4ӄˋ?($ Oяf3_Aq_aFH.3ORzlD|AU3h1hX;pΔAyCɉ:<Nev# sEK咆8dQPšڿw ϛgh4t6)\;XSnjD&`ɴh$tO5 .~ٜJ;n nn nc냟^:¨ZV1 1;rN*$Ws^_Sa!K~[Źw k$)SVo I_@3sU3 C{xێ$i١0CqJv"6 Sv\c9E\&$@: ]FF3tգ*7:"So] Yҷ7)$s'5jOimuQ6۞@f Q>YĘA68Y/Q%w~ɱ Q8:!jjV׋'\r?#PtU%bKWQtQxt }=0ڪشDIؠw_|v2|nr09֮8Hbk m8"^aBĉHo>&ymЯ1K3Q,eG-֝؈l+kjG0 f1K۫;Igfaغ }-37iR4 )FsIHaUADłg1fLar?,~)쨮F:4%NW*a :qiȹ`?"TV/};<(L,Gz8wrFZNIxln/ /FFz_fk#^80t,fngP ŷ qU':MOa#Ty`lx)V+4W2!5 oUnդGˠݣ{G]Mp y9V(&0!4la:9oڙv7Mqsor*wzeXK"Уi~Hdمb`:42N_d_FR^CA6u>R)LĚ }.B;`HؐQSֈ](A4K:1Ӯ/{^M}y*l<0l7GTGkaDgޏ] !D>aYL1m‚.J)-B3Q0 tԋ\Y}Vy$;}d"έ㙴rߚdY~V&v= uɶ|7;pCR׀zoV@ ؃f8sކ]űYڌ^6t%i BcT&f[vE=">|gDrN !0QoIB)lR(PB$nFRGt *l2>j[LYsP}]mkGS.R5)Y &Wrs• H8Ι5z֠m$dtļ؀%+?pvG)|57:8bJ1>BlE*Wo9VHO7e0diI 'gp;Ⱥ0P|$9l.v3X܌塘‰.&iQ[RUp|Aȷ %3k҃ŷh⿅wUo7"j\?"+wո3P/eW| uTɆy8Azgl l^;O$G،p*6 ̵Ysmޚ*ދ>%S7k endstream endobj 96 0 obj << /Length1 738 /Length2 18534 /Length3 0 /Length 19104 /Filter /FlateDecode >> stream xlsp&6vضm'wl۶m'gm6&6s|UXZ{w5/G  #3/@MRMGA! 4vr7v4f5#GsprtPа56rh8:[Z݅]IR@- -(RTHƶe7[+S)H0wpG:؛Y ػ]f`P!" !C `lo'ՅhVGpdk_ΞXXfV=ӿx7wpl?@43?nv@+`tۻÈ9@ 7Ooq5{dEhlƶo&?WdS OmorL:t%M̬-jkl_ÿV?`'@_$%*``ccpqrxX\S7gg;ZGd@SSP*jH#u]T!K3ãkxA&{W2- @ɩXH2j wH?v7QwYʴS9uNR,F(;kR4Th:Z9˰?&B`!{7UAG<W Ԕ#.,a;\90űӶinIt9S)P K*3#C9ɸQK zʊjRgjP͋m|~D:h,&aUOt81? .XIDލ.f9*&gm6٦CcNoVDDQPs6 #ep̸\Lsx3$;&jjg| YRnf(ٶ+ "wGhq\(AcGS,+ZK/P7}I̝3v밌:?0`OOKc>O7?|tXljYX%-q<+rt"ϩ]# cb݌:-P6x)S9@ ܻ(v\mS Ku<`G,_׹=>[JwwiޣX O)eNh鉓z)"^y_+c`L^abҹ o~EQ6nx G#Ͻ oWz(`˅bX͉IJYbdHJ5l'-a EU3Vn&t.b^ۙ^Z`8h1#^{܋&yܒ%V&A=R>#*M_ ѬKʼbP;eBa>UȐKnnJ۲da#ЫȦXZ%v瀂pbT}lf>T2>D|[c. ٛ4pL&h~wXaǝ~2'mCd)Z6 PeK${MYl*3 6jᰒ88OʜHZfK4DđDlQm 3Dq )UO<+WSwX%v:UIZ5n#'olQnP0d%CxWQBʥM#&BAl2;됡˃u^M}^V>*3GגwXXbթюL}C{qT/ tK)6$/b*o{"\Y&$7._>Cˡ8h%]:/D]3<%ڄ`~D s?TN]u ұ]!iQ+:Bz@~FU=Ô]#Ո@F:megPvD bYD+:N*x Wŧv8cDŐ7W9 ݧbRI#Bhz-SIԟmkYGFJ\ qtYw]қRng_ʨLM/Oc L"t?]6&"z1KotmXY&+kbI~o_<kKevl\ChJG-ر.@N!da%d$=%|sP329g4Is?AE2`uAx|S],~A H翅>UxL*VA2Mˣf)^qBE>Q^\]@='/Bo2HzZǡÿ]\}N:r؞Qη5ҎX78v&ߙm HFw1(mf KͲ\cVCmf H^S D3tC8UiFwڧGKz=HzP#5d) v&~i{."8<(R'HĦzFbIPfzʼni.HlkRnijJ9|]y|^2!ꑿGk8i_U> WyO: L" rjyb'j&q #7鮔vۨ]ݩٕoӊ Rrӆ9^IeRNԘƨ<8z ~9szjl ټ#&Slȥj; Z/O7^ 5Ŭ% Yf;9]R;%P(xcO3j}6]BGzZF(236 ]yZ2<7Mf  óNv zOKSzIט-1cMY|U#縓 wtyA:7۰9)-xzX {o6{dWWDe]^n3;fM,#iM^|׀QVį8&>~h(&їMFx%*Whᄆ(&,%;xv^=dWSpɜunԏ(Z;Jf|xko/Ă2C[-qP~Õ a{9/;^aށ ENLz!v|rf3c$J 5EWw?oqܗjMKZ怰2^H;=pʀz)=A3{M2RǢ[gv̼[I0ZصێLƇG@P@P I!Dd`d? {R>/*3ޞ,Է6f9(#^}?ˈ7U),C6TxM]lZn!%(gML~V@,(EzV+ XL>My!m4ۦ6lZ!SvY2=й ΊBt r|ք}?ŪvIц?~.F'VR}6,~S ml˓iZ^,'y_B僀:3@Qk8vUIB>=DH`ܓY|Jk^wC ΣnJԢa!\Z.%s,8rgXH|LFgRmW`).O#q9Ns~v259 g"$L( -%D o'a!},\ak$eљetMiL·.ERf7#T-z>w)N}Vz3MZ zQ:kDG{K:gy1"TPeJ1Z{Rd0J zLK_.(g>i~Hܛv;L.YUAEbuğk`ȶhY ICuO)B* vMTn@(_UTBY\%L()|<J}WN2{2A¿]֌Me0{ȥ@B3%7׫Nd[qxUF)f1c5o}XlZ6 kf'k^CS"bzbI-C qy(e(K%5e#D]uqY3ݕjezis+ yd+7E@w|BSEuɻ$?w Y.VH%t'qw>>۟L3S3^v1VEm w0,%9T̻Sat۳8OMlC=3r*$O-[XA:1bܬ%x_9xŀzw'S!&΄.Mʵʔ)Js嚃뤁MMNFz D6GJb }C+RV.3}@rd*%!@ś%)̼LQ4xj"CRcIV* l ^t1V[9 ddylLuy8~k xbݰV%RnQEKd*ᛣ}!@m+iXbE%YGlv.61(Vp%|=I{[֬f5E!sc]fLsA)1V'I,m} /xs Ў&dw^miogU8U8 E}t5mزC4ٟ!T _)#aJ$9 䭮. M=jݢ:?a bAw'dWg$:jCQ1YP"ePb~QE)F-k`$m1S$ı[ii7͜c/[?Aw&= ?A+V#" 5,xd*J//]pVe<̍֞%ՙ \ f!&FcTbƯ;5LȠSKcQP5_)>QI9jJIHۚSLS!S߷xY_ovty^[G:ga~ ζ߇,#Xzᮦ"q<zxaHuJoGl&p|LȼvPJ Մ椦 TEmd-ywQҚ-J*f!`Z k#ȷg%ܓ_Kj iHRUPb}=6w"㪣kӪձAK{3wÆS΋QZJ5.|"&[i÷5VT3u-9;A*XF&WcN ` LmmΦ6kv˹TNƲLeCNU=9Qջ*zvbJ C{Ð6QMqZ\Z[xkq[N8#7]YMfJdÞwPlI9%W3h2gԑ꧖|*t!Rlg?wDbZ5U ^X#{W?ԃ` 4[̑~!CVuAI.dcg9.jbmF??櫭%pz"4$.MLh37Ob|H(Dq y1< 8e0^pmVcNY# X0~1|!fFs &b0ॏZt`\XWyOTB/^f~sySiUJbkh*>Mĥ|{)S{l;PFuᔳq2]ύEuuBʠ1Yg,LZleE-5VAZ^F ~ @714Y1ZN lܽx^ :+mpUMѓji%X,Jql퉘{}7~2GAjʕSzRcLhVj[Χ{s+O!Py7on+z"[-*#^_ U,F:6[lqh4\k6-oc [1}+QDý քgA mDyD7'q0q2is/i>gy,J^KuؖN^̔Ɨ}*^F۔NU+X#wfQhiPlۇˏ j\(c)ĐjX@eYh FpT[ywkCkJHm,VY}.jL]{zfb$=8ka3AcW_11߅g#S2"DŽq+ ̇6]rMKK\AQ̠W +ӛ89-pp׈V-|뿲Ϛ[mM(&m;0m+n$@“B9g"MJp>(HhahRrA!YV9)]:=%c} q y'Z,gx]K0B{ Rm[34e#18lhC#\kydLS ww~/#0 ln sGind?Y ]UwgjK#+PH0TN%zF 8nT+(ExeSTA-ܨ;w<*Y;Mi~R,vW_\T\qN<{$o3.qf赺zQ呛~ >MWHpH_!OO]a%Kq-WJ8_*ư+kdTMЗ)cY,ρg܋7aN6Z( >y/c`C-7zؒr3O ׬?֒_e|Q~0Wͽ[Y} xZ8kIWT1rD_Ǯg-FKA}`;ekbųǢN!Dpq6?yLeiy#0Sb=S6˔v2H*Ax,i,MN0a 7,pOv䌚:NЃ$NvRLږٔ"B@rdN-ܗ'L V!j[!P!{?RAlPsdjZw qI}'Pëėز;5I0.yZ^m HO6 {cgÊb l#kSJkKƋ%J7er}P0#^DprIJo3#lڇҤ,N0}aKc(W o:+/x~(2ʓ(-[ |paXJ܌-Mj5=lWKդ:g_(5p!)qJ+FhQfhrQaY@ӃnhVCQ .QiO<`z]`9!B|8nJF {;T{N1$~qP<&>F@1_.\P^^Ddž[b=Vh 9:gfaEwFiq уW=믟V?CEPQwCx~uwl$Ն&5/2ԮB=S&U$OMn3Sj=y{3W!0αcuGAHHYԂSA#PIڥZTo¹ݷ+2pͿq<@]<撶'I $8W z=vJsy<\ wH3n&̵lt9q {g!,Lad6$om.Q$URcGhu9vINv#AH´sI.X^EvwF6O# $(}M`\o U6|93Vhi\nKa+,߼R|}gW#ڡɀFTl̩i g9dܗ*8/29{G-){{kl]w.uJR.kL:8LJWer0S=MI׬|橦\:8Ol+lCTbf'Iźٻd;X=+_iMdZ&/tPZDh9Ij&KS*O^`H/o,e`[" h)Lrb.?AHc?hu\4r7R71س5^yRՏS>OQZ;t!m;>1)>zI=y-kxY^Kl6Ѕ J1s#n Zz0̤8xfDc>Θ(jVҳ{ O)?:u J)(+KϽf|0%K=[0ɢkӨH!ƠJ?"\Ởq 2 Qj+.Qu&fug8?K$n;f@{=|p*OYld)c9\t[CIdU2\hۨk0m_V_>r+ 4Xb%-_g©6-.m9,{XAwja&Jo{;(u4p ]KUI;BlGilZ޹9? p)3΢ăWR1X"WeiĠ1*OC>ӠY|yBu+eI%+pݰ@$ H\bw[WD[g8 "\k9[tr\ڼQsYœ_M9EpUXny$-#7UՆxnt nJ8]tv;n^p މ*I3yIоu&\rcQێ046㵩n1]Z S99& R$wSyILC1>N@C!H U8F8zJ`QLz}Bd`+ OՉ?ޱdOC֠]s= ףEV *?hlJa5)48؎[1'CTR TNѻ`g.Nz#-̘SF+RNaeBrn܇!W\"]N~-2=[5bsM[0zL%K!L2Cv2brgg#U̘k&U-|߾M( NM@VwM_R'vhqp8#B3_<`<'T3`k1PlVu7 =%4md)WV+@R%I6}܎wf&ǫMbdi:O]ICz@(HM(Uz׌Wc*8O9i@\4Xi`9jɡ6Q!ovW[kI\#8&2I\[ !~NnJƪ _HbDV{:|T䭏RbϑPh5>> ;ǏV-z2}tD!0QSp]B>Ԉk}1!=?3ĵ" *S }-C7%9zh3q\`;0&<ӧǀB?2׫PJKUDnNe SНmx<~yi]K8BU>(nPA=}.-g眹o}`A-z[1 T<z$4 -Lgj?Q<lkqm+(nhqMB̕%m3.l B{R|2~ ۯbGG4Z`۬sܥf BIlNF+NtoJ]&a4XR :Zrev ^T?$Y H] i`PP/uXUgg {rT2=Y$;7PH SHX!耄2O_kOmc)܏ d']י+ʤ(!ydCC alǚ̏q"c5m÷CuWBʡ^ȕ HVxͅJ1D_ϧ]dK-~q666WnR }] ]IdMf8VgK //5]4Y[BH3D纲 mg[ZY "ܽ8^,Rs,dE(eq{?Ҳ3ÇWG#Ʃ. =z' osk˙snYGNlrcۙC.2PcaxU+r-HD?Ƙ@ܻ{5^%XQE(Ft3bæuaڤ;%sXEҲ$L[`o+ÑI"Aqƙ35MQi93Z!jY+Vo24ujyb$BX#Mċ|6_^ xvJj88%aW~7GI+OEg4CJ+zjOyr{cZ;qZa||ToO.$|ږ>yT^NzLD1گ4CnNTU/ ÍQ7#ONebpzŽs3Ghr2 Ɖ:$ǥJo#<Aqoj s?(_NX&/Q8 Z%8NofMZ}}L;ptq#&y$؊ f9r.'|Q9E:KbMrCY7~C/3Sh@Ov<ϖf!%Q+ ռWlhfiNvP$nϼ :q!-WOkăpb˳~ ^}\6,zS BTjsY.&g=d?ŵ6Ԃh/~j-T HThUЃz{[dL1;_GVOprZ0BѮbMٜWA;om e: p=3eFQL d UEaa3(]5>h" ,Ld P?Z0U)sd8~ʔD9je-87BcoZu,A#|imv:CVӊ qyf ]j_uA Z:iIbG# Pȧބəv C&I7/mZڎA [Q˟`&=/ēeq侓Q|㟅+>&͈Ajަ\YA깡R~\B3// fLا)@BSN ցP&8HZcEX4nTaAAfS. 1@-ᢟ(tfNN`O w 8FIDNVF#6n& =3f5MfK'uw"2lK ^&y܍kQX' ɃՄ2# w*'O9*¿n,ܝg@1U%tk}9<2MD\#t`7JPoK>$?%-oEMl=XzhOoO1#[W[ W{?5#ϛnlfad5s[,9ΜN!LhFЇk,ɋ-FȾ6E&jJjy5)Y Sg~լT|}JҜ&r0e\@rg4+t4i%ݯat:'toY_=:9,hf`3$L{Q K>3JFnb-c9A8gY/*AAwvKnFx<u18׷UaP ¢C3+سqcuHqz2ӝ4#o Y=H(rC/_TøZE3(M 9x+-o],GqTŕ;xr!: d!V`E΢6C?_tnCq>S0_1#^y=3+~Ufe,},)`@Do'k1͢dv@zzBT"vW;:~!ヵZ'=J17Oeш9rRKsh;!w/ ɔ(՗"mTiqs~A > c}ys20BK݅WNSB7:ciIКsEKDe_חz&y; !D"ucWs߱ اn#Iw f9Du/[*?4Ԓfm 3dWY=Rq _Iլ6xa{>VDF1}@mkW>52vfQG?#V['~:5ݑ?"HUےASbN"w|WTF:h!9T?8 Yq` ~#78,T"4gn5-6L+N03K޿B9d "D{v"8c~laNIV05ByBEw> lzm*N0(=~NE͞@6}{σ[bF\qHQ"S\0J9R4TDbC_:M2*/@yywS{Z EELX gFP\0+i: KB b뺽\ɛj2l?V֬:*g/?*@TpraD? #9JlcQ@{& ir])/JO =e,/'ُHs[G/Lr F K1>o\7h(*p>AhiV,S2C0&?\v27ҏ^56D5 #|gYKey͉IC >HW)D?J*AH;<1T@n- U8 Ŝܟ@IT[{ٞ#l Ԫi8uogC\[I3Eh(ףPZ $u-h2\C4|\]&252ZutLx6ӋiB&;֪⩗-k#/ᅝ#nOuō7u5Dt֙Not2|m Sٙ5fN qUJ.!@t^oINӎܻK5:gh!xW㌀U1L.\t1yn4*?rz^m^~oM7|f`C;P ts=۳=L;/\kycYsUmjHWGF*i/EƢԮJ ȞWeFUr,Ȯ3mxR$heIWj;ћCbжPR cDT뙖VpDw4dtoVG\^3]pV8`jlDt9@ r13"[lFzs 8brݬ΢MQp $8TTư4EbH=0۸b?Ĥ n1z[-$"_{j(5Α)9+WAL =kz1,&a*/]XsƂFt#cҊx tmfVˮ渆S#񽜄KF In'lH_.ulU{ow.LФXOY/'ن–f,izUޢflq!EqW-.F gzu{ MSZ8X`ԏ}$R2dsKc!9\1{hrЯkZBytNѸTA9!K#v PBηy- "!_W6iw /zE+6VDqoCR܈-R9G8h%;l he*D;Sݣ{=oeV/ÉK&aaĕ͕A9IG2EUr^^3oCl/_񽵮&K6 co4ȭ(Arp} g#s032QvxG |bWŨ''|*bӛo,r7qZ7ǻ d\rhAjO]*TMcnCA?:#$Zlr-Nݝ4_xPCrM'+f-=ZrC?8oֹd%w~ĝh@n"G6jg̈́ Hfr9P`B UMU {e0q5 yH1LQj F`Ъ X ap&=|*үZxs2Mx-!եwtl]&*&(X 5yw06bʻDrA:Cxs&O P%RA>~(D}S7}$ىj0Mԉ GkI3z7{ke!]~T*T_uB/XRf]-ca>kߧN(BGSH"!V㾓 墋%i@:Ŕ&:vz1 N`xB΀dϠt{%k݅i -2"h)YÝ*XK 9Kk = n Sڔ?w's_#|?ƧG-4D)CњVK/Pz!,Xێc>@9So4h"p7VW[]C֝L]RuWr)2%$dw=3Qar-TQ+.\ϒU+?xfۆxqKwFD@1c7u$8Ή XΖ (rN BXG)1ȀBB쫛 DwVm*ֈcoc NryR|8=.M6BM\..3J>Pwi>>חcw> ;@lU|"pdiՍVP<;,Q$dmȬ!.G";P-xkI&Hi9LR^l_ }7kV^OΉ+n*cJAxn:Iu[ɴ}G%B.\f嵔}9Fshx`\$T>M> stream xlzcpfnLl=m۶m'OlۓLl۞ضm{bLλ>;UZnT_}uתujrb GW5/'sfzf&3\hnj fj47;Y,LLpQG'/+ʔJ5hnmjswwrwqc 0jnp2XXۙD$T Iss@ gmjbN ps::Y ÿ8]ftȋ K(*EDf9\]x67uWutG2@H p3kSWxvppGm_?\Cj?nvv *QG{'7Ws @P5vp@ j`fn@c{k;ov5adEL-azM_O*?-6st 555%ig"mw0u4vC16+[g `gycW'@_習qgaгpL~ hS,ssOsSGSP JHڹ#uf[]!+3ãk5| ]sɩXHJKw傷H {Sۨ{׌`%)܋Z2~IX~HĵGIj}JL5sVa7&`!{8VANG:!JDQ]~3DR3L{r^YPKɰI oQS^G˥&t@[} ggT.QZ0$~-t[6Bvci9]BIg͍9#;A0p;ً(ɒp|Ŵh4ܒql{pt8߆$o{ڦ *W[6jLɡQ^Fl đWO ?.RWx3jwX~ά#2Ɔ@I{TRa] }ϳ7aq@K׼<_*CN?IamHU ~_B: y h&]>Gf\eS3alC$ֶq?a`rB>eߦSxH̡bZ@ (zf1_=H)x3R)Է<{T5G^OOs *I p~]71o*r~? -k^gވAeyWP}kJw(sբ\RmRr1Mxx=+a,.3Ϊ#Qx*KyyFcS"Pp'yf5 8wƱgDG]E^n "2[$p2 Zg= g␤o D@frAy\hѾ<5_"vj^ tpGdT 1@̿Ǹ;ȡg-.d̲5h>Eu ZE9x]^uHt1!WgʾXYbT K}cdt#~m n[-|tt˪8 ֒jO)fؽHvWC>voFFҁ_‚Q:^?qޑhrd/5>rڇ_#U~KM{XIb D2~)}A{|,2V{%(;R tMITxǁd vLt$$;r/ *OmXP0Aڍ \T^b sIe[KQ(+Ntyh x ܜEWc;ghZ-{pԸca(,JE^.Su9 Guu~%Ў"fS(PXu[ D09}c{bD,H?2s?i[3K>;.|Nwj$M~f6sVK{}*Bh&fd\4.tnNCxY $FV7TaC@2?ʔ(Z"'IqmjM|0g(Dw4, Kh t֬5ZAfmi)ٚՎfS)̨`9c B 1Mڃ`CC~蘮7߼E*׃)gcgw߯gxt͝&-:^gM:kj8_~vߕM8|^pP3g]y( "NB9e^egi`ʑ±Z@RgYN0qkGGdnn1,ւ+6 b}f5y:MPX]OP!Oth. t34Cs*_,Q_W=RPF5XX7`aqy*)`I(L̘%Wә<FO?76_+ -}aUixbD 1и bjE-O]*٣K,q>2喂&sN=.h,b6 :FYư8W`@mm7~^-?y @3bTĺ! h@rAN5ug 3@N).5B apx6g"IBs^+jf()iVޱX!G, =m?A_#IS s`~T F2dM,Ol8MQ;ۊ=xl+.X;j6wsʴ͜MdrtSɊÐQ֎N}jI]<y8|lќ{IuGSvxPόt~a2\.P"ttWOy@1ԭI,ڝD'UһR͋V<MK0H=߷ .?$%_2fILq`-wK^Q^D 쭁Ǵy!ṹ'>ۄ7i14 RC$pC.1bY(Onޙ (0 R 7О2})e rax9 ^$9ŃUND,(jmoht޶Vq<5>K %:>W0.F^n+ Mk1ma#EH~ т QSQN||p@|'U7'PDP3'UV+Υ8nԣ@J7.vo_<ge[#Ru򑾗,%mƓG^ɋ q}M?&^)4gj\/uٟJA r 漢6 Y )g >BƲbqC?0Sm|tnl-LbXzon/vV2!2Zr&צ] ;-`/`ڕ4M@M$p+ fU-,nh YzroEaǗ<<$a-34vgy&E~[z'Œ$zL/lplNr;TʡPB{;6HosesU&Z6T]4֗o*hi*۩vȦm~*,|P0,$37MGAޤmǯ*su%:wJVKf"8>i/CkezU3 Ds(jEy !j1}]/S}}KˏNfjB @Ԯrϼi[Uufj=o+L,~3P;sT,7K[N"wHcC !I^xIFF |dR\Q~`ߚ䱓Rf92 }4*_iK^v DKA0U9]#1nV ہ&@%lr,zkё'>p6lyaAquYYh6V.$B+/7ػEvΩYM'6LߛjV<82!9Ԑ(/fjӇϬ?)yeG :U㛡O݌&0`"Ss'^5*/<F9ZO酐D틮2con&3z9Gfs+.KRvcb_y-}s#*2@X6PX*Mcveq-'Y3vzՙ0M Y8!e/ կjo>K0|n\ eH̏(J^=UO;yu1: -[ ~ckڪ'(&ls I]~z˷B)M=T~Ce/oS=7 Kރos+,1S -=Τ0q=jOIk@u!6d}a5F 'Gu+UIbc-Kr;zczVh39Ʋ _Xɪ+-OQAq-cnt8cR_8?J=X% {vuOP )i@~ڔWީg&ԕ1{cVlDj71nr#ZjWkQC .a AP/=|F}菹O}\v:ˢ p]m ! "Ϣi "`uKY`3_ĵ wW$>Js֋ҭ_SSWm#ς<Rb5M!+0L4ߎQ.sŒD3Ց1-"( "lYkBE*FRㄝ9(˯}qw!tBQt)ے4k& o .dY/#%^׀L 2&tXD+YA^R/,b^b=nh~dbOܧ<[sq 8ꍡ,3BEzݪI$7|_Y4`h7  A``mh}uT]oAȍ:'7&ކ>>/ǯ5S;NNvB(r*j+H: [^5Lf狗KWExW4pR.M퉑I8ɓJ5Q46XR90ʬODFgy:VݗyːBˣ*"ţh__q8ڌ/N*HЯ'KʕM3%_-^}<63`2.^EXv;r}i.c=8gFZSд?+VveEo` u VjW|GCv$p՚Ey?iEO{Oб*_W@Ҏ&>~F?L#-Q ׍ʎ&{|9i;تQVkh~QzZ\0l 8l2;e9+~jE w1{B50qu15J8/χ%^(*yv͹ROc8ƅ Io*^.VBE`DY:0W 7F#ͅ, o%q \]d"`}ū - 1 a5+v<Uu=򂜘#.>&nZ4IunĄX2훜,yoQ|ޮb7`XHNh%x9npq z}iLJH("&JC-gh\ˈ7H8kF0/T,4NgP4_{!,%^d:osРޙ0@H;X{;c|vr(O \E ƍ4_EU"_o +Q.3}TN>ncWk1|gi'uكǁFQ$`Y3 n2wxw.d̀2/1H/Ȯr[v }P2=HQԨ ݑG ͏?r8(ouv Rb}VB-\{F%79nV :R֩[럼v`6&|'#_yGQ~;o)@C3eF"o-: Ff%q/9fuKI|]Uݐ:d ?jqd8ḞW~v z{ѵ'; j~PBQE6n 9q#-ߋfE'4B9F_P A~k-0}a;? kha&?$dxS=om3ErQ.KP~}&gb2ۑL XQlD'Sb}#ܖp฀W\Tg^Hf9` U ӮIyRݲR"UO1H`ޙ3DzgI<<{R%>4+IC}sRhOBwI =u>`±T,)B }e34~$*vgN\еh}mf^**Um5ώ@eDy67_!Uӻ+K2$jYoS4X>yV yͪt42`ա[mW! #[e9BCM4 wm 2#7`Ts}5 =uIiWdOoydsj9@0/y^bK>#C.WYb\eU*j/5h$s5ZYlgmarL-x==5Pov߄w>ole2՚۰7 b)R).̩doCbP`sya(\n.bz"9ڞŠ%Mrlgč2*^7|9"yKȮȰwʳ5RŇ,c&z& oNzF&4>jCnM{ߞFgmnΑ.[ja9qhύ"Q3)c="Cߑry Mu*k;[3ߐp?ޔO`FX\9Cnc}b#:FVf1dUn7(m~n4Dv_Ɏ+|\eqب1|}x/DO1M=Wޓc/Iޒڼp/:RǑp\PNXc6p"Eנ~ӥ (NΜZơp.3th<ӋiZi;I59+Q'A/rh#d4!mN4F dP`3qs=~u3x @Gb';&tʯfq $z&mHR\Y +b[ݪz'R%IaJAGNGame:k(7IHd N,>&Qj ]l2Յ|R󕗍Z*2rf_ ZE{>77dL`a /7ϕ_hQs{@#Z "oKFKlmtgMF~ē-DMK ۺ] p+=mw7>8 ?b@p5XcIxн5s3776ʲ ?}Zb?yLGR {b]yܪ dO_ [UvVj!GLYeMiYBH`X)68Ct-'81rjhN%n--XZbM6]o|Bi`JAj"YzAkx7aa l̳C t) BDߙ[@Qr ݃ 5W=}%c9OףH f&_7TFeF0WJ|p%ՈNy0uM(륜(&$uui.H: SE鞎2 dTZ4 "}a6{s~Ư#俴H TX`,H%Bkk,oj'>f.Wv؄VDFWЫ!<QKrٸ^LD4t[;^"롽Czp9* Yͱ)zLH̴Ov/^;JGQz!W^let NHK%W}?+ʈU9ʥ~qy ]t GѴaE创g` WǤhwRS7=Fc! kE+4QR; DDϭrڦ+{98& 51:քOڐճGn2Ǚ&&RTL `8Ƹ.|f_6TK fo07Hb(3χ&v!NW3T7j`%‰GO? ;.O6g|\p+Jq5Kq{ά(V:/p:Bj4U?/E\ѿ$omv(oQR#I,%:21P_ZbJ]板b{pRh ؉|UB#{]`:ap' y$OH&g\>>,Dt3Yo]y>@TA}Y(dN_J,p (䡄p.9]nˬ0wWvNYv,r.No՘Ö>UZ攌#da^X#~qܓ$p[[}1}ov!mlwC 1FnMS"fcV[e+f,hSʅr5RBj _ h:Uz[ NUiS(+E&j$v xŘUy֠DdUS'+Qi M)AdQAUaSؕH:b;Yɐ9>A7Vv/tJH.pIoUǫўQǿsgYkb]oCb{ȃ1[/IޅػJh! dkYH4'{Hp2qioT&bni1~7u&N-OCȆ K 6|f B0yb>.f:, bj:Xe%FXy{j߇R'1ڲ*FyJf?F|F _A$ċO$[4DE ~s x` SUSۇ<ax8a?jh1y\&Ĕ9,+0;t[ ,3Gѭ9ř+ABv<<j[lphǀ;Տd6?/%KP?`H,q.0bK.0Kk7ÛJ ?=2 epi逫"yk& 6&HGaJ% ,Ch-1M'OAfzF(q ȁ(V[{ӡ`:, [գ<<`*- GjՌro'b5opd該Lݫ0|w 5qۛF+S]a5>d{!US=2^(_"2S1`A'Gh$f 607MM ]d"qdrHJ7+~ga'7伨4GY-􅎓|Q /K.ZƌJ:ۿlGtSR[}“al>WؙD.~.>`FuG6XW[QL?AM! vЩ'A~:ĵr .IL| 5RjfUTؔo }uZZ6u>&a8MT| b;itۖ7Qbsߒ,nL::ixK69o8ஹ\&EFn-2 "5e||"?eM[Zxxq-13rw~c <}T>S#~lny$[^D];H.T6KPi31Kl={& s@B DvXO\+w5c_8d2RGehrU▢7kI yBj!OI֦%:l…Mڋ=Sc_;=X[VbT0 V! j"|ip+]=;Rsax3>Ų|˓G瓯Z`! *fʃdG ӝZ܆w3?W.0o }H:O7ō|gJv+3VC_ .S sJJ| b`s:*>O(BCb"C +`-bG6iyjAClˤ 'n`&~.̝ÅFOŭ@?OGs)S( q0C59ں *WHKx/d멫8cĢP@"\"VM V_ sبU6-n ~ w:_ʋRB\RBy}/$z]v"i{R571Z.AeBV.g P}\q'ӟ4Pn3<FZTѐPc.RO;#UKp~.YD>۶Cg#ycGQ8&&FhoSo 쥆\;_WB0ќ#!˜Of\\ZQb:zap! VM%PビT5د4/Vd(o6c5q\F)mۧtAչ:,v ߬(nb m]>g^dQTsz%VDS79O<^p\]!iV WABYiYYoi.<3-SВdBaaHvRl=ZjG0Xmj+> u]CIXS}Hh:iIW߷!~EFpsAz% dFuYג_r )siB`{med㌚rNSD+Ih͜b 6I,e=cɯW+N$AIYA2Z{ Շ*8] $;+d_bcv6"I茠DGD==6zm}ȁqBj 7?Ա/oե^µMCGQK&]Q !jb;Jϣ7~,P,A_F;`8, 5NjKu7 VJ%~@Kui;iNjJ Dbjc!\G<%wW4-pl#b FF^c8x%8;xHZ,eͰ8mN(+>J 3ʂ2椮^1vݛ͓lBO 4J ا'm HSǺ,ejۣ`߂n2nuHbpk:1P>tyjFn:HQXZ%z7L5(> gy-X@"ıhʼnfa[Ӌ0C}v)CnF+ 4枕lTDUP.V#X5'T«6p;78ʴ t* \òhlaHM'@X=ǝe^;s3~3n5N b2k0~2E0OǫS[h۰8g';Fyۣa?կ`>d"Փ þfSxzҗjA0_-",0/}sXrR?[_ႹX$2]Z|FC@XڪxkY^D\B 8{I/#Z K`!Z'O3Y/`k9B'V:2H97fydt7ʈ%zG ^Ejo'$^.^Kr/T ֶ8Gzvެ}hgfYlbx Foda=+\~9]0]CX.#Ip{N`7".s9k?3.|6wepMS{FH L^P/cƳnh(]泀mRUؽ@hq 鞨Ua9DY%'-b<>,xt!DKRi;RNXN"1&Eŝ.؜xi#(KMF!,qA01tH d+>9Ut 'υ9f{ #Ns6Mi篖.@dSh8 4pxDU] "BRżӞsu4qZe;GE=a„#&fTҬ͞l=s;^plQȶ:+T]0]_:j-zrfd= ƦɚT>a]*ARk`*ZᤸXk|F&{@Mer9y/4id!@tw˭e A:zk=kӅOV:!&$K-L弾h2km9C*mek6 G-;>Ԡjצ`iSB庡s{#7~aģ4傓<ͣILUUY/&s[ |Q|c[?YAjʥDgfxtt[mrKDFQڭq4ZbFOn4Rzl>x-{ _!0ZMC lڌHsdVaF4R*HA>qL<xUŠAQq<RݼP1G]] 1 @ ̪/5JEגS2j%1=a .TJ)T+=ƨo3-}Dk\Aڀ6JϺ:BYG6,GqiѿZNV4K֫3>Owa&˗h,aO1%hFE?6gq=GFK+-Xzɬ~(nA;~߁'KJ$ 5y@gUjNdjy4魯ƙGbu endstream endobj 100 0 obj << /Length1 725 /Length2 30186 /Length3 0 /Length 30711 /Filter /FlateDecode >> stream xlc&ݶ-\e|ʶm]mm۶m۶y߽=3ḵf\IB jkng@@K PUVf`2A9;;sԌJvF#==4 @ @nHo#@Jjkebnhvqqwqtup'Idf 012ɫKȊdUb6Vyg+sC1``hkcd/L`b0[k2@DNYoc'ɑhcC'UG pd_nhFNcSsh&acb `\r)F&D;[Y[ȅl휝2F6q`Bͭo?dؘCL探nFNlF?pϮX)ѩHS 1521(9ç vt2NnMz_' #=3`g_p mM?f26v36^[5 Hi))-SZf^D243=ºWuŝ7ٽܑo"ԏ1="^z-"*7zW{ ӹUŴ6 sJ[_ d>/Ac+mC܎]]x&CN5ާB5 ο6{[ {Ck_owWwe!.?)y)BR= pŴ*|K7<v-'+w )U\~;3Ef4M-9/Bs9bǙ.$m9α1L[f~<FX0pcC" a${baos+-t5z*[O70jCccpc<ȲD&6*dΔ=)'ºlRJBwM$~!GUvV~8\uISM(IZҗ[>%ӰϭVX ۝81q w,ceRwyBȒ"3hPX ,(ڙ6ˍEMG WvKbh0k.t^=ps0)6n&Oͳ, NdfFƙ_LE^!XGA{{\HbOwgbdN8ϰk Uf6zRߎD ̣.m 84d+&]Rf1y{x$t; diVplnvV!Z(| ˎ|hCSuKl\*/VWela 4g7 ܵz{b! C|n# 6<:T_@C O])= 0݈56aV:0ϵü^ۤUG j4o:uDsqR l&+3UvŨ[ڬXw6B-8^Ir;ybaS($kʆ9Q=ӟmW=繫Q=[Aͺ!v]]2qsIG]1I{O Ҽvgz5h.ywa1/bgzoB+HR/iЫNGnss&셋zڮ7[29 u⊟0=3tWtzeyIEd≞GUkf'yɹZ,UfTLh0W~G!ZMw.}i %Igz jZ؁N|-(d!DZs;ږ7(kLj=ĢdE͜k4Jfxn&.H)bҢiv?c굣-dي$gUUi/ʎf傣#c`c? V?7a2d㞥(>H\)"V-rn]IԾ!ח B@4\bF  t_vލ $;V!o|t2{ KDgvMؘ7;YTض6uG7a*{XibRZal]ϯ"y Lm'ePn_;oiLP#RZqGd&B|7핡DA|9d&`~ˍd^_ .;(B~Vpכ%.(PRc.BP|(w:N2끢mJv&{P۷4m٥M C |aڎa ) Haժ{<ޱr)+}0@\}:ʩ'rz[zC\7^SfH/3~)-q8krRك Iuj:c<4\(uz~#sure+_i?k+|]pul5 mEeF |V\Vނ2'M&^^K57~Db8H&~S!9oF֮%+>׉*U?A~9cf-+{X B+\l X `~Vu88r|{]ɻT$epHwj:'^bOtTLrr$u@. nXG Oe0^GkO+01}U~ GGs{iܘ-~>ʎ/z󧛧[C.'swD&-,ۓ0xTwqw8u1o], DZ"póBJE s93)s <(j[@µ}xMr9_VFPhp0@@R:˝@;==S8//* "+&/^QoثkQ>?K$֔4mꃪq"Ui2FTmlg/(̩[A9,/I<T|Iqrߗ"'Dݖ,(Q5ίTdH n:ޞP"ShoR1YU7 O*M9LV*^Ml0x9x_8X!F׺aN5b`3m8vI;OKLOM_,7DQY4:Iouvv^4)(ʊ<ƷPĐqJ օm86%|_\S<7J yOpB_慹Ǖ%i.pk]5r>X SZLn2݊6`peV \_M}u 1@w ,6pw^Xg7NZ)}b?F?,MU֧¾eޗ'1 8@]*JO6 }vu 0^NĄ=wvC>ys0bk]؛a-%R i*T{l4?a+5#ڧ B#%FEi*0q$1HmgPY^72`< >fq fJmV/ԣl qy}ܧ)q`nOt#Tč:7`zg^Z5IZ\@:cӌu *[;Q ^sL􍵠wgu~|BYfc2r,$)j;٢7{p11@3wLa#SK^ӣ^7&Q%dpdEkv=Eo{=FBܻї>\*G+`{gO!"iۢan!ؠSmMeMvb2}!*kN ~FhP0ۖ\AwalTE LLH[Q`:eHk `X1~[Zd"]il"\4 TZ4\j`'d_^@Ì!APegP `RZZx(AI9#F h &fsy셷og^Q[m/!7\\:ꇿPHo{OafA P: WBWO..X|"Dx@"-n{%R它f4|HnnIWj+l yAjR{&g&*'#aHt̾Aتf "җgfs=x֐AS#dI[%f:)cfb)?pg"hin<#O_ u 1G|~\!TfC6Ӥlbӌ!pÇ.“EʞS-ĥnP|sۂUEQ iqsk<3qnjh/lc: xV/<*7Na`g9/JOZd z4 O'g&x }܊QW/<>XHF2|PP'vGٽLt6",mܸvڲ]zFּތWz wPo+%2RR;t:Ce."1M4a04l 2`/.@骥LobI=O fN^w@+cڝiDT*P;废!b@MLЃ> wVODc0UnD.؃KrTH*6sQKTo+x6W>JܿǴP݆^gswPz&)iOH]eᖓ͊޷Dl Xc?RlB6\-ItʨyͥW-OI^>Ips4-ѽݡ8P,$&樥P8}hx?8M~)Vퟺ<%pj>a#v\CSbg Z ڞqHR򛂣\/: Hk|$ = y+I-ř jz3a$!b|LvMz.#cA~Y:yKֽiKL5k4jϥ5h#u|KF4?Y{PcKi\H:9||>5rLlg1^'6/(rm"-9ɗ?sH~d"(泈^xB\F}.A 鶈JQ}tPi dY6Zڜo{}x ?@P4]>[.w0'<+1S3'bRAvlm+g͕P'Ut@O*VBqlMAjqH/%?5%σhL 8bɛ |?#>!T*1J J߲gb8Ԍ o^,"j_`F̲ p柂EKx3Tgw `:s; GQm@u;%LIIIoH uwKUW]>W}5ҺƧ5~ͺiGEiga8("ӢFk7$Rqon.|%?snGZD'D $=" L&r)0F9S/ԋ-?cjr)y*'aS87ˇ7y}ڧ&WřơlI'Jp2`PܻQ9=/sKl傧UsÁ_FP5aߥjM㟄rǰ3iOK3p-49+IHw(Tf"n³ N-k۔ D4yx&Msz",~ip}G~&y"#I6Jy:U#B8sɪ' Zt',1`& aOVv;o:XC =Xrr4rƔÇĹ^/*>Vq(N:?Ttw_6^oѿS4UP;B΍P.L{'͞ctֱrbC& qv&+T _?\M="ۦ\EXϫgQ_0a4Z4rLfa/÷pA˻nTx6+7_my2H%`.o}XgKLɑɩs2s&1vLf^ JZYTA u ))ZRaTa'eW4 \6>ֈ2`BH?Pc6NjvTL _?(cie`-NфSK j}yey\&J(>p.|*ֶۼg2I<yECh :)O%|YSHoe|EQt zfg:wgxA\|˭yRqS7̺C@Vߥ%"룪ʌ5w6ٞ4 ళZ 1* Jsx f;\?|B0}) qMsӠ-AFNwZ}w\x nY:x H e9yOYQwDبWWu4֕UaVqg$TٯBptOʤĎ}zqN@C[eQP҃C ̓ fɇ&,?kT2ª7"F*f Gkنjbw'`T"egh4F" 5`ohO~Jy{O"eGJ 6z{kTn O饖̝8[Mwh`Ҁ<|Kd?OeJM׋A&6QVZr"*77&BtN%˫2ZoNfuע9{٩cA!]X - I+&xG@Tf,XW=K|\q_OMֺ<\&k$-g˟#7Nn\'`}3ЙBlч^;z_LnLj f]]թ{afᦀRLLGe07e烂>26X%iӃNEi6-y]YP9'6EX)C dy\+*oq<۟H l0c$#,t'Кٲ+;bF~s(gk:is*J0QEozaKpł .L3`$$ eڟhUi&J|P&kh|w p6(C<+5 {!FUUnm̊0oB櫸aZᶖYv6r-qxvkN/tU '6ƛT\Cp4j^.(ȪicFy 9QaVBgʊT g:Jl?V-iyp@>Rs?86$'\39f&H[Y5]sp)ҨJDֳxR޸iLMzthvyG<WWJmN>BFErŬ-KR^[+uWClNf7M,Â~@`mBq9VKC(OJoeEV='⨣ GsEרN7<<$BbK.G[k4%C $5EjSD p뻎1dԏ4!OY$cQoA / Df]z]>޴os,?kil caWVίIԼa{)#`@9=/9{7݁h`oMj z2cj7"[qh3Yj0xe 6:Ss딕\((Pi\mh'3;V=]v5C|o/=SaS-sʵ~ ]3֦ ƈBrB l߉==kÊ | d@>s#&gryI{0|oPf'} |e}<{nS3.Kq*Y5# JA|"Ì>VUfXgb 96vuVȉD}Erw ߚSa2DC5a5f6P+Ϊ=k%P^ƺDD Ee.c{K Wa`WAѻUE݂nOW!4CȽ 1h+3 S/.x;׉$5'CԽNBZ_8&_DxScYs4; fL5TTNw~ %HaB,%-0lף4J=IYedjl?\| ^ vG(~GYWDvd]z6ᱤ*[Ir%S-kU(Ç0A&>ElϝPs39c!rgiMmVf<ė% o?Ρ%gi; 4MfS@8gJWz_GԆ1Sn>%z.7 S{n, -.U`GT&*_҉nj蘒*E+|uL٠|̰짔, J[[c7Ix:Z\] KZk˜Y`bHdb^Hhǭ=zh4遈^rrq"J$[KfG;[ACWnT=t;cӛl LFΉ r>}],t;AW*iq#WWӃc+Qa,K["qY+-f./4xݮ{M`ߍ^$ }0̠[VB-E8S6.R0'z.V[-ͻS ̵7>0f*5U$hbx˔i (<u"fа2'G1`$]W N ΢ǣuEDp,GuΟb~ΫBK+=ՐaWh0 04Xu1eKRb߆Um[|~ɪIf ], H8K㡻^w`  BoX46kİɃI0#RŭCIU)??ÓQ9g/ Mn.=ϩ kl;pWTw$ nO_#-ܔIXG_?Zܶ:։\`CL]FZ>HWjٛ) @Rߠ! :hg?b,RVݢ!(=$׍}Ig՚taq[1~h[WxpXk": \ q [ `WDedZI]QE-{z}S(lb'_뢝z"{W5VfE1`%.0VZmSL0}Ewwuٜ;ljLR$U4.9"Tо+Jx#P:w)'E,Q Q/ߖ#R.W4 R(i`MiSԴL)e'.n1,S~r~Zt3^E*/n{Rk'FimF :`‡yAY(^>K8 A#p~ rjLWgk4M.*-avY?2#+^㬃g%PnX``j*F9э'IP^"/; yv1f[NZ] \q1ڀ|qxS5nmH{Р!74vRcU9橾omh[,\T5p6Č]w.ܩMwb9} ?|\,;k7ПODwۂC xa$=U6$Xr:7E>Pg['@TE=yvtS^ /!zkSvGO ☴s% bcS Txռʸ؈1WQQԍ.[`.$4> @`;|r O,#=E$A x$coԛ,TtdxjGHl?`oWC yrb.Ej_L8]QI7CTŎ,Iոnc ӧ+7|ICl[ nu?ܴ5lg^d κnWPJ\+۶FoS]<;cqtI_z r^OX)_(u /lwvB={Dc׸)i6\iRDw$rG{NQ2eL[U/> -%%6!8B0ZQogseȉ6X?<F GHSRW?,!YVAG%o* =wmih{94q(Sw>;ʲxƓ6P]8Du._ѡ8# }<`y9 K)qݡ|jjݿt*a9xF`h fЉ#i'JnOȵ(vJ$nA~)4x|]Vvp0^n/BD Rju E6@$Χ}cNKJvwsFYYbK*3ffu=- ;:P={",˩p\&AG ࠨF u0j7[2n@"A!mW@ JEQq9Ftc](_(g !2T:|tC h̯ EU*eyzdJL?KO+~H[2$sA/4EŬ6̈^ IJ")N3a֩ONG;ܝ%Mf"󦅜v,9raj~ @;'e.LkYd\Ś#*~0KRMe,WMXbqJO%϶*I~+ûFXճ^Jq oH(՚ljb(iyOOS?l^~!r>X]Ka^`1䙐 V_oX mWɖAݶ;~zc,"Bh4It Z55^>+УeitLR"W IigW*'>248̚4ګ;ub'*z ƃnfGC||$ۊ#PE!i0K? uBmX/TDN`"žFAV~k2s]֣"#-TI 8mbuK. ^qˑ=tCɞ,~G4ݏHO.5m>"+qzch$ѡ}]JŴF14ZYSEg0߭q#.֎V;/j|#Ue)ٚOmz)Cj皨sϚ.p)0 7C9gSosnJ+=kS7 Hfxu}6uYlJy *,'vQ\=cԜ.'Bqܺ)hs%-SHbaddB!(d[< ΌC4M._?&+/Sq"[[+6jW5,4m&#)!"a(;]W2IrcͭΔ]gj\Ɖ`H,KH²bѬ-TR&:A1mLD):D9_;_K69!#Sגvܐ {c,{6¤ |'V|[qg”c",9Q~qU=bv.=, #clg*݇=uaA#s@5S}Vm$wk*391p:$`j'50]V 4tuݵJNl'mضmĶm۶m۶}?sUsi0x9>9"ښ7ll z'[_^dNˀ[ :Rq.:Eԅpb펕옻@L𝈊i0 I|82)񌿘7i;NEɌO`yaB5/x Y<Ed1@$;47}Az` 6npx۸E!lr(H(aO1 'qyFuX~rܸ5"ZY/%- /וDvu&g{? kE׃wZn,o{N*mtѨ 7I$bL 1XLpI+U:wG*zBU~e/N~2M?VuK)J1D(+/{;bߡͧK׀8L:` _'[/ҷ䦼s4܇mtP9M%cƲ=nà-(ϋ9>TtyV75˞խPw'ߦ/34m$:ޫc==EGTa8WY,|+ O5tTYy] *\ _`RFܔK/pIjRM]n>F5p ;!Ҫyeh^"ũKRf(W<500w1#f<9Ki|։>vyi¢L=\׷P]DJ_HM3G)CO:)SAŠxp^ w]CM,P~OOG&3l2/~B::Q/5}REF:5L|LKV&7ϰl>§獄WI3y0ќ?kIPBEE7yF7_͇f!zc~IyVlܖdXBzN~\:`d;VgnW{ѳsϏ] q>I3}ҝ[r9t <%9&'9_=f-Tpϩd,(p\(f@M ܡx}\薝$c`y"vi`x. 2MW$b -@Lm&b|Go>s !}xY(rݠ0* Oe9}%jAb66W\Gu%u1dиM ?gtZǞL=IYOUm6d$BAzS]Zں}|'Na#NtlvcDqY~C$Ci}dD<6p؈ghRZT"%Vj .OWg.|! CiߪRqL 皈 {qYp?29WT&XR VlՓGW4TO>.ՀQĩ\$ԝ 1Fj:67@iZu 07L^(u%K$P3#TrA@` pP[z (}6fg]큡'Īk[ e2gOAFs0 >t RZQ"(g߳10 :B}Ya |7$j=ܥ~JYC  r%8fHTaoAsͩΥѩ%WÞzA30+SЬ u㇀6Adgsf?m2ɇEi$4_rg]ۃ&bs>i>m^8R"% RP GYJ²W-ۃU%6@DǪxgdizL"54)1_Spil5RZ N Ċ6r@XK*3*uRdgъzݥ -TėzChR:#R;/L됺H,vo hc˔Ulnԋ1-wZA{ZV¼ATuP2pvZ_>Hde.+.̄TC9;"Ut ź)=th6nI28p!Â3OunȓQ*rJJS/TbͿp .,qg<7=:C٢ XE;6A%VC|A%7 OVѧ@nPrrA&N:|ۻ1=*P]}Il{`E2-$4<*T*u 7jAF^y2@wq9ZͻN-nzoA@ W=`CgRֈ*ΊC_|#z䪋sȱ]fo4d%{69ac4V!y 5$}~YUYg,~bqb1{=pʥ=nҢ}#F%pE/k8`hHãf Y7]cۿPĮϞ xĈPy0jRm$X(TubaKcڮY$mA2ei9 6Q lz#1/f!jBy^qYM`Uz:Pf ϭ{f\: fKAg1/B;xiE~)ɪ{"Q݄s@U5S\^,2d'pb"+H, Kc$y%H/j-\z  8Z6Blb(eGpt8^cʌ?kVhOUщ2{HVpƛBA6;8o(=L3xZ%q׷p|S ||x\OXڤ[ƣ?g?u.Zey0J Vt p3W@7BQ !Dpȸck 5jW-T@xEoe kQNhPxE !Zn5P۶;bW;f}TݤOf]As&<x$[o~ ۬Zy NUq#7IeT|~2̴Ⰸ~pDW12(EO|Uȱ0W3&#YvRDfY`"۽AjJ؎YkyoO<^ʒTehDv"˝ɽߦJgM41t6?\M< +ֿMMI 7,0Vp\~N HYp%P[^-J|x܎c4*vV[{PdI oZRQ!tozAB]pI7e 4?Ma|>{.cP~s] 5`V vi+6:S/+|z yySf! ɂ&% qQǬ)|8||c_bC|~$*KUoF8 МWkG0 Z\)I'$B$wX {dkxމYf~K,JtgNpOmYU1:7\Oa!$íd=M xAoHgn0NqF͝ ufX lXc$ło̩jYE؏,YM>~D: ?chd..xDx*igz)pd5`= }ھ7> h$4vGdb]yŮCvl[YiDKMxisfЪ'˹#nNS -Ϝ#]|̢B`J.yn)*H=WY`y*e]0,RPUbޕ~OsSL|e^(-k LʊV"&}B2<AGkuV`)sQ&Na|*T/˃uSK=h12׆$9}+褋l _%琉$y k\vxTKpLg]z?NfwBDRЌPW*>;( rMA~֖`wSĴ.)HfӨ_q}̃}#{+蠼@Yט5rf%F]/`C0=WFƦ_s109ԥ+{\WK"bzDn1KEތYdN6IO!{A!^g|3|=/QX]WrA(LLX?EpvCir ,6"6p/tK3,v^ޏYe#Y_BHɦN6hVʕcf:u.z]:N"H\\jl`p.Moo"H;|:4#E( eヅ==PpX@ -j._+DU>1ٝ+5?3`P'G~Fuѕg25$U;[D㑃}eЏ E6.sCs}VV;CO*U%$_|;_v!y2pJ{[Clz;-XKWK&H / ᬹ5W]3Yp4igގ΋sޝVl{)ED3fpW`8܎F?Hca$>]g[,pTs/[1sAUTj׃˴(7<4+:zSn}.[^[[tcf#ߙҼ>"]*izeޔOd.AlAoN;h:a.dfA?-‚ߝY:PP=ڃ iS;#;~e+.gnP^R.lgB*[)!.P#̏qb9%@晔2៎ֹ3e"3V_NAq6c>,2T <敺oc$S,<6["M{4 Z)4׆ 睯&R`ʾ4!$Hɢr;QR^L}im@|HRZ}s͸D:ۏ][;wwc; F*ԥNJUeC. ]);owY1%EOg ~t^ugR3+(3B@gOeFej)eid2\1-V;AR%^ᶝ%6{*v"?\]YOLԌF|4,xYV%>D~дl&B%kOCٖ ҾȆYd(u ޫ47Ɨb9~ :!aTkض=⫷Zh"b IRp {=Β8B A[OfGZV.^s;ɞkN&|!έx4-^Pg%oxZ7c*|ăR7W3B> 7>zii0D'"t4}O*L(v$ X%oQ. &|+B+?j ܟa\n[9%c_[M9OƇ@5ao?Ut4`E2-Z1.c, R[3S8jz>D ͤbQ V t\@:ͅ߄fa?˖w1^r'Wn/IFKH؄ڬJK@(; [΃r;Tk9#U]'%B-%!ytҝ15.*SLM7X0]"vX%.BA0Jy+7?tU!ڹC̵z6H>5$i0ve#]ZisȒ XLj \}p$:kRz;[苪{AVg̕jٚX ߕȭŶXObfRc=vYʅ@S}mxbFKQ^~*b,cCC^ZL %~\aI@a:ו|SʵGzlH?VE;b+rwxGz)HM"tU}R9_м`'[6/3ֱDM`ۆb;25Hkб*DM|rN7ȂHLQ39J}-Jŋ+ӡor4ThH6$=9!R_{՘+'cc"Qv?>ǙyNh p:,Q58dύg%"|l>> TjG:?"+v59:(S{A!'A62`i|p{0\n2B/3RRpE\{O>}m+%QՅhp/xR% UjE s鷺R*Iª gtx+Bz% ڤ xfVͻj~SJ0CŬ j12 !aj qP8 Oi);̀Pb94b2WmB,;0G\DEoQev+f:f7>m&zrT4+ű}ZĀ -b7Eqro٫93Yo9tƽg`J&4in|j7HGiVy("'`p8{Wrv) vnF{=lu&Lj Y J&Vov%#J+ǕU-|MzRj\/zN5B;k,(pIޜޓkQeO0cQ>X8_?m&7zAaUG<Dr{[oɉݷ-T)i9 gvQT]bDTmB&ME E{ɼ s"vU}#Hϟc^O~c'>`'F/bU!zDvm}%M=IRyD!>{juP;`wԵyCsJVSڂPu1oAt?( 4.(e9 'KT f%Kg46"ՙO^l |3صYH^|X^y(P"B )LW7!Fw5>ւV/i: r]?S PoXF*ΎY4\hpw"/J!9ʛFD!$0nEFLPE6Ƚor r99179*P#U $X{Mf RQ](] !cnN{`.([f?KDܔ$*@/!y C\y [޳gy;jQEAz>n7vZϒ_e :r9P&e 9DPLoy v`]H>$ƦZ MwT,*Z-!IAHq7d87RHkC7`^ `R-ߵ wpJ]NekݔK<:[CY!)UH++!s]_qƩ$0ZJx,V,|pwG#rVm\ȆӬQck/n|  dFtx Hk'&_zwA(еa[RpHD# mvV?+FosğԆJ OBQ"w'%Ò%.8m~n[ !D-964˧TP ^,&GL:UٻpBKQA6`XygE7NH~˥iДwJ|JmO^1:t¥r:Ă.^.JoY>]KWe?Ϟ/M{ԗfLyGrϐV >;uj^Jth|ck7pHIps)pz6ݯ2 !9M^[W(.SR>1 $ EU3ďZl~Ol mPIɃdr EMʭ2R3bۭuu0S9vT9^/Ett?&18y&#>)CyE蕛v7e/|Zٍ̓XR3JDXؼZO?6 ca۹*[b ¹` vƚ8Qnބ H#Zh'R6*㽄%dp;8%\싛}[a{31auW`IxPi Gy6 O:"RHO)6;Gˢge vX%ĺ?J0{U)>݀Qׇ^UjRQA0VǍdfBe2ґ,\#n>a {XŤ*7ZAG%VSlD90XWL·j$sD5$'cQ q0ğ#vhQSHRp3 ԤI:8*vzUXMXpk|Q7DmQ JR|Fչj5H:,[2CgDt!I6=ZOu* +l0J\oLuȡ2Vw&UV/Ӿ~K )|vה8v1S;kC'o6էfyY眧6ȉ}q endstream endobj 108 0 obj << /Producer (pdfTeX-1.40.20) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20241216163613+01'00') /ModDate (D:20241216163613+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian) kpathsea version 6.3.1) >> endobj 2 0 obj << /Type /ObjStm /N 90 /First 723 /Length 3872 /Filter /FlateDecode >> stream x[ks۸_mMwLǎ\֍MPdV#ZEJj3I HHrfq,0ș ńE3IgRRIzR2)L I˜3Ǽc!xPsL&= i W1 L 9)Nim0 "=0$%4D" )7bU Tp]= $ W{V=aJ#Aq>'p|@A B`{C=0n X i%1;b=H `:۸G7"`^P7=HG*GX9T s,%ȁDn "5;=:ZPA XNL K A-P.L!=ZMr E(D@=ֱ[X"* 45M@Av& %葅`L:_Q@*=9 6AO {Ɵ%QU a9_{7*v1xP_ͦډ2M/'z8dKW},]UQ_@*|S / &AѨ _u9ͪ*9{>鯓c~9q]Q`)r6ȫbR~eB0b&@KbVŦK/)qj>pǟӋb9?D!*5;<٧t"Gyg6[%#wYd+Z,j#S$53QF / C AD &FdFT9T",CPrӛ-ôhл?SdbX#ƏgZXaDh& HCh^ WRmȯaa)~<-'?8dZ/RTj9*hmQA<."0P͑ߕ͐ VėXD XzEu+" YCT=#!` fzmxARJ`tO#jis(lT;:TG&aҠv\F!Ҵh"ixeqЇjjClPnZGv7D ENGDdUѭlre%0Rͽ3[ЩULrn)7kG7УjZm aa3GTmj[!!b H% _)5&'+0BLYzCڸ"$(:g ImN΄ta4WHZ^[Y%O>q-݃9ZzO QIeG 3JE%Q`2DF;fBџrV0Tp'I,H&-)lK}é5.(T!̈́>m֌mn&)8KA98.GH=9؈6F! aъh}+H"4!yO>A~Hp1V&"Q %74ږ醾 K}J2һisFL0gSUk-8 !z&~U]X~Pdy+OFF6yO V_FKK+qTG2rwN/fS`ΐuTV J)y|N#^PlTddSmnDD;:.}Ԓ\#3ӸKiF)1TB4+u͈Cy;ZD9}30$[/ChPTpRӴݿF??yw^Fˊ$#UJkks^57E6r?yTz+Q {Q O0X?7 ;!鋟ރ7APkCذr\hV$ݻHG'1% )͂)pm:ZYGoϫG|rxrDHإC 2Hh,XsL%,=^_'WŘ5/Co.6\89xqp@\Rᒶ>3O3~_1?;o;y?Ѩ!Ay}J\~u?O/TΦ_-dx_&/z<*>թ7N_f%@c$j^_M~ÿ_obu'b޿zxz#5E(*%wKo=Jsd!3eEa(?>}D_#O(<@ں|K : M4$'ๆo:n<_t})XJSYAt+)anoYE^ 6>΢?NE='? ['2돒u ] /Length 267 /Filter /FlateDecode >> stream xҹ2QۂH%}-vA 3Z0i=4E=gs3ffY` >JHBJʠ * p P@jAfQK`v`eAa `6`aڡEk p:`zdOS 0ÐXQqIiYed׌,5+o*yOkA%%kYA$'p W\+x|yij endstream endobj startxref 169815 %%EOF gower/inst/doc/intro.Rnw0000644000176200001440000001144113452644704014754 0ustar liggesusers%\VignetteIndexEntry{Introduction to the gower package} \documentclass[11pt]{article} \usepackage{enumitem} \setlist{nosep} \usepackage{hyperref} \hypersetup{ pdfborder={0 0 0} , colorlinks=true , urlcolor=red , linkcolor=blue } \renewcommand{\familydefault}{\sfdefault} \setlength{\parindent}{0pt} \setlength{\parskip}{2ex} \title{Introduction to the gower package} \author{Mark van der Loo} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\pkg}[1]{\textbf{#1}} \begin{document} \maketitle{} \tableofcontents{} <>= options(prompt=" ") @ \newpage \section{Gower's distance measure} Gower's distance can be used to measure how different two records are. The records may contain combinations of logical, numerical, categorical or text data. The distance is always a number between 0 (identical) and 1 (maximally dissimilar). An easy to read specification of the measure is given in the original paper. Gower (1971) \href{http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.412.4155&rep=rep1&type=pdf}{A general coefficient of similarity and some of its properties}. \emph{Biometrics} **27** 857--874. In short, Gower's distance (or similarity) first computes distances between pairs of variables over two data sets and then combines those distances to a single value per record-pair. This package modifies Gower's original similarity measure in the following ways. \begin{itemize} \item{In stead of the original similarity $S$, the package returns the distance $1-S$.} \item{The original paper does not mention the concept of \code{NA}. Missing variables are skipped when computing the distance.} \item{The original paper does not mention character data. These are treated as categorical data.} \end{itemize} \section{Computing Gower's distance} The function \code{gower\_dist} computes pairwise-distances between records. <<>>= library(gower) dat1 <- iris[1:10,] dat2 <- iris[6:15,] gower_dist(dat1, dat2) @ If one data frame has less records than the other, the shortest one is recycled over (just like when you're adding two vectors of unequal length) <<>>= gower_dist(iris[1,], dat1) @ It is possible to control how columns from the two data sets are paired for comparison using the \code{pair\_x} and \code{pair\_y} arguments. This comes in handy when similar colums have different names accross datasets. By default, columns with matching names are paired. The behaviour is somewhat similar to that of base R's \code{merge} in that respect. <<>>= dat1 <- dat2 <- iris[1:10,] names(dat2) <- tolower(names(dat2)) gower_dist(dat1, dat2) # tell gower_dist to match columns 1..5 in dat1 with column 1..5 in dat2 gower_dist(dat1, dat2, pair_y=1:5) @ It is also possible to explicitly ignore case when matching columns by name. <<>>= gower_dist(dat1, dat2, ignore_case=TRUE) @ \section{Computing the top-n best matches} The function \code{gower\_topn} returns a list with two arrays. <<>>= dat1 <- iris[1:10,] L <- gower_topn(x=dat1, y=iris, n=3) L @ The first array is called \code{index}. Each column corresponds to one row of \code{x}. The entries of each column index the top $n$ best matches of that row in \code{x} with rows in \code{y}. In this example, the best match of the first row of \code{dat1} is record number \Sexpr{L$index[1,1]} from \code{iris} (this should be obvious, since they are the same record). The second best match is record number \Sexpr{L$index[2,1]} from \code{iris}. The second array is called \code{distance} and it contains the corresponding distances. \section{Using weights} Gower's distance is computed as an average over differences between variables. By setting \code{weights} you can compute the distance as a weighted average. <<>>= gower_dist(women[1,], women) gower_dist(women[1,], women, weights=c(2,3)) @ \section{Parallelization, memory usage} The underlying algorithm is implemented in C and parallelized using \href{http://www.openmp.org}{OpenMP}. OpenMP is available on most systems that can run R. Please see \href{https://cran.r-project.org/doc/manuals/r-release/R-exts.html#OpenMP-support}{this section} of the writing R extensions manual for up-to-details details on which systems are supported. At the time of writing (spring 2019), OSX is the only system not supporting OpenMP out of the box. You can still make it work by installing the gcc toolchain and compiling the package (and R). If OpenMP is not supported, the package will still work but the core algorithms will not be parallelized. This implementation makes no copies of the data in memory. When computing \code{gower\_dist}, two double precision arrays of size \code{max(nrow(x),nrow(y))} are kept in memory to store intermediate results. When computing the top-n matches, for $k$ cores, $k+2$ double precision arrays of length \code{nrow(y)} are created to store intermediate results at C level. \end{document} gower/inst/doc/intro.R0000644000176200001440000000304714730044355014406 0ustar liggesusers### R code from vignette source 'intro.Rnw' ################################################### ### code chunk number 1: intro.Rnw:34-35 ################################################### options(prompt=" ") ################################################### ### code chunk number 2: intro.Rnw:68-72 ################################################### library(gower) dat1 <- iris[1:10,] dat2 <- iris[6:15,] gower_dist(dat1, dat2) ################################################### ### code chunk number 3: intro.Rnw:77-78 ################################################### gower_dist(iris[1,], dat1) ################################################### ### code chunk number 4: intro.Rnw:87-92 ################################################### dat1 <- dat2 <- iris[1:10,] names(dat2) <- tolower(names(dat2)) gower_dist(dat1, dat2) # tell gower_dist to match columns 1..5 in dat1 with column 1..5 in dat2 gower_dist(dat1, dat2, pair_y=1:5) ################################################### ### code chunk number 5: intro.Rnw:97-98 ################################################### gower_dist(dat1, dat2, ignore_case=TRUE) ################################################### ### code chunk number 6: intro.Rnw:106-109 ################################################### dat1 <- iris[1:10,] L <- gower_topn(x=dat1, y=iris, n=3) L ################################################### ### code chunk number 7: intro.Rnw:125-127 ################################################### gower_dist(women[1,], women) gower_dist(women[1,], women, weights=c(2,3)) gower/inst/tinytest/0000755000176200001440000000000014730042737014244 5ustar liggesusersgower/inst/tinytest/test_gh_issue_18.R0000644000176200001440000000026714176713717017560 0ustar liggesusersdf <- data.frame(X = c(4L, 0L, 10L)) obj <- data.frame(X = 5L) d1 <- gower_dist(obj, df) df2 <- df[c(2,3,1),,drop=FALSE] d2 <- gower_dist(obj, df2) expect_equal(d1,d2[c(3,1,2)]) gower/inst/tinytest/test_gh_issue_8.R0000644000176200001440000000141513671163420017460 0ustar liggesusers if (at_home()){ dat1 <- iris[1:10,1:5,drop=FALSE] dat2 <- iris[6:15,1:5,drop=FALSE] nthrd1 <- gower_dist(dat1, dat2, nthread=1) nthrd2 <- gower_dist(dat1, dat2, nthread=2) nthrd4 <- gower_dist(dat1, dat2, nthread=4) nthrd7 <- gower_dist(dat1, dat2, nthread=7) expect_equal(nthrd1, nthrd2) expect_equal(nthrd1, nthrd4) expect_equal(nthrd1, nthrd7) # now with large numbers of records dat1 <- iris[rep(1:10,200),1:5,drop=FALSE] dat2 <- iris[rep(6:15,200),1:5,drop=FALSE] nthrd1 <- gower_dist(dat1, dat2, nthread=1) nthrd2 <- gower_dist(dat1, dat2, nthread=2) nthrd4 <- gower_dist(dat1, dat2, nthread=4) nthrd7 <- gower_dist(dat1, dat2, nthread=7) expect_equal(nthrd1, nthrd2) expect_equal(nthrd1, nthrd4) expect_equal(nthrd1, nthrd7) } gower/inst/tinytest/test_gower.R0000644000176200001440000001047214730042737016555 0ustar liggesusers expect_error(gower_topn(iris[0,], iris)) expect_error(gower_topn(iris,iris[0,])) expect_error(gower_topn(iris[,0], iris)) expect_error(gower_topn(iris,iris[,0])) ## distance between logicals dL <- expand.grid(c(TRUE,FALSE),c(TRUE,FALSE)) x = data.frame(x=dL[,1]) y = data.frame(x=dL[,2]) expect_equal(c(0,1,1,NaN), gower_dist(x = x,y = y)) ## distance between factor variables bands <- c("Grand Magus","Skull Fist") dF <- expand.grid(bands,bands) expect_equal(gower_dist(data.frame(x=dF[,1]),data.frame(x=dF[,2])),c(0,1,1,0)) ## distance between numerical variables dN <- data.frame(x = as.numeric(1:4),y=as.numeric(c(1,1,2,3))) expect_equal(gower_dist(data.frame(x=dN[,1]),data.frame(x=dN[,2])),c(0,1/3,1/3,1/3)) ## distance between character variables dC <- data.frame(x=letters[1:3],y=letters[3:1],stringsAsFactors=FALSE) expect_equal(gower_dist( data.frame(x=dC[,1],stringsAsFactors=FALSE) , data.frame(x=dC[,2],stringsAsFactors=FALSE)),c(1,0,1)) ## multivariate dataset bands <- c("Grand Magus","Skull Fist") dL <- expand.grid(c(TRUE,FALSE),c(TRUE,FALSE)) dN <- data.frame(x = as.numeric(1:4),y=as.numeric(c(1,1,2,3))) dF <- expand.grid(bands,bands) dM1 <- data.frame(x=dL[,1],y=dF[,1],z=dN[,1]) dM2 <- data.frame(x=dL[,2],y=dF[,2],z=dN[,2]) expect_equal(gower_dist(x=dM1,y=dM2), c(0,7/9,7/9,1/6)) # check symmetry expect_equal(gower_dist(dM1,dM2),gower_dist(dM2,dM1)) # not counting NA's in the denominator dM1[array(c(2,3,4,1,2,3),dim=c(3,2))] <- NA expect_equal(gower_dist(dM1,dM2), c(0,3/4,3/4,0)) #auto-matching columns expect_equivalent(gower_dist(women, women[1]),rep(0,nrow(women))) ## ignoring column name cases",{ dat1 <- iris[1:6,] dat2 <- iris[1:6,] names(dat2) <- tolower(names(dat2)) expect_equal(gower_dist(dat1, dat2, ignore_case=TRUE),rep(0,6)) ## recycling expect_equal(length(gower_dist(x=iris[1,],y=iris)), nrow(iris)) expect_equal(length(gower_dist(x=iris,y=iris[1,])), nrow(iris)) expect_equal(length(gower_dist(x=iris[1:3,],y=iris)), nrow(iris)) expect_equal(length(gower_dist(x=iris,y=iris[1:3,])), nrow(iris)) ## weights expect_error(gower_topn(women, women, weights=-(1:4))) expect_error(gower_dist(women, women, weights=c(NA,1:3))) d1 <- women[1,] d2 <- women[2,] w <- c(1,2) r <- sapply(women, function(x) abs(diff(range(x)))) d12 <- (w[1]*abs(d1[1,1]-d2[1,1])/r[1] + w[2]*abs(d1[1,2]-d2[1,2])/r[2])/sum(w) wom2 <- women wom2[1:2,] <- wom2[2:1,] expect_equivalent(gower_dist(women,wom2, weights=w)[1], d12) ## edge cases and exceptions expect_warning(gower_dist( x = data.frame(x=c(1.2,1.2,1.2)) , y = data.frame(x=c(1.2,1.2,1.2)) )) expect_warning(gower_dist( x = data.frame(x=c(1.2,1.2,1.2)) , y = data.frame(x=c(1.2,1.2,1.3)) , eps=0.2 )) expect_warning(gower_dist(data.frame(x=rep(1,100)), data.frame(x=1,100))) expect_error(gower_dist( data.frame(a = letters[1:3], stringsAsFactors = TRUE), data.frame(a = letters[2:4], stringsAsFactors = TRUE) )) expect_error(gower_dist( data.frame(a = letters[1:3], stringsAsFactors = FALSE), data.frame(a = letters[2:4], stringsAsFactors = TRUE) )) suppressMessages(out <- gower_dist(data.frame(x=1:3), data.frame(y=1:3) )) expect_true(identical(out,numeric(0))) suppressMessages(out <- gower_topn(data.frame(x=1:3),data.frame(y=1:3)) ) expect_true( identical(out$distance, matrix(0)[0,0]) ) expect_true( identical(out$index, matrix(0L)[0,0]) ) ## Top-n ## gower_topn d1 <- iris[1:3,] d2 <- iris[1:7,] L <- gower_topn(d1,d2,n=4) expect_equal(length(L),2) expect_equal(dim(L[[1]]),c(4,3)) expect_equal(dim(L[[1]]),dim(L[[2]])) expect_equal(L[[1]][1,],1:3) expect_equal(L[[2]][1,],rep(0,3)) # case where n exceeds nr of records in the lookup table. L <- gower_topn(d1,d2,n=8) expect_equal(L[[1]][8,],rep(0,3)) expect_equal(L[[2]][8,],rep(Inf,3)) ## just to get code-coverage right dat1 <- data.frame( x = as.factor(sample(letters,2000,replace=TRUE)) ,y = sample(LETTERS,2000,replace=TRUE) ,z = as.integer(1:2000) ,w = sample(c(TRUE,FALSE),2000,replace=TRUE) , stringsAsFactors=FALSE ) i <- sample(2000) dat2 <- dat1[i,] gower_dist(dat1,dat2) ## warning on recycling expect_warning(gower_dist(iris[1:3,],iris[1:2,])) expect_warning(gower_dist(iris[1:2,],iris[1:3,])) ## regression tests ## topn w/n=1" dat <- data.frame(x = c(NA,2,4,5), y = c(6,7,NA,10)) L <- gower_topn(dat[c(1,3),],dat[c(2,4),],n=1) expect_equivalent(as.vector(L$index),c(1,2)) gower/build/0000755000176200001440000000000014730044355012501 5ustar liggesusersgower/build/vignette.rds0000644000176200001440000000033014730044355015034 0ustar liggesusersmP0 QHLL_ ׅ\č_. &tb׵`< E\s3vk.Ee4;լ00ń~e AИj~Πpo9oqS^8tHW?0thyEsрQMB!wgower/man/0000755000176200001440000000000013452644704012161 5ustar liggesusersgower/man/gower_dist.Rd0000644000176200001440000000504713671157664014633 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gower.R \name{gower_dist} \alias{gower_dist} \title{Gower's distance} \usage{ gower_dist( x, y, pair_x = NULL, pair_y = NULL, eps = 1e-08, weights = NULL, ignore_case = FALSE, nthread = getOption("gd_num_thread") ) } \arguments{ \item{x}{\code{[data.frame]}} \item{y}{\code{[data.frame]}} \item{pair_x}{\code{[numeric|character] (optional)} Columns in \code{x} used for comparison. See Details below.} \item{pair_y}{\code{[numeric|character] (optional)} Columns in \code{y} used for comparison. See Details below.} \item{eps}{\code{[numeric] (optional)} Computed numbers (variable ranges) smaller than \code{eps} are treated as zero.} \item{weights}{\code{[numeric] (optional)} A vector of weights of length \code{ncol(x)} that defines the weight applied to each component of the gower distance.} \item{ignore_case}{\code{[logical]} Toggle ignore case when neither \code{pair_x} nor \code{pair_y} are user-defined.} \item{nthread}{Number of threads to use for parallelization. By default, for a dual-core machine, 2 threads are used. For any other machine n-1 cores are used so your machine doesn't freeze during a big computation. The maximum nr of threads are determined using \code{omp_get_max_threads} at C level.} } \value{ A \code{numeric} vector of length \code{max(nrow(x),nrow(y))}. When there are no columns to compare, a message is printed and both \code{numeric(0)} is returned invisibly. } \description{ Compute Gower's distance, pairwise between records in two data sets \code{x} and \code{y}. Records from the smallest data set are recycled over. } \section{Details}{ There are three ways to specify which columns of \code{x} should be compared with what columns of \code{y}. The first option is do give no specification. In that case columns with matching names will be used. The second option is to use only the \code{pairs_y} argument, specifying for each column in \code{x} in order, which column in \code{y} must be used to pair it with (use \code{0} to skip a column in \code{x}). The third option is to explicitly specify the columns to be matched using \code{pair_x} and \code{pair_y}. } \section{Note}{ Gower (1971) originally defined a similarity measure (\eqn{s}, say) with values ranging from 0 (completely dissimilar) to 1 (completely similar). The distance returned here equals \eqn{1-s}. } \references{ Gower, John C. "A general coefficient of similarity and some of its properties." Biometrics (1971): 857-871. } \seealso{ \code{\link{gower_topn}} } gower/man/gower-package.Rd0000644000176200001440000000111614730044160015151 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gower-pkg.R \docType{package} \name{gower-package} \alias{gower} \alias{gower-package} \title{Gower's distance/similarity measure.} \description{ A C-based implementation of Gower's distance. } \seealso{ Useful links: \itemize{ \item \url{https://github.com/markvanderloo/gower} \item Report bugs at \url{https://github.com/markvanderloo/gower/issues} } } \author{ \strong{Maintainer}: Mark van der Loo \email{mark.vanderloo@gmail.com} Other contributors: \itemize{ \item David Turner [contributor] } } gower/man/gower_topn.Rd0000644000176200001440000000376213671157664014652 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gower.R \name{gower_topn} \alias{gower_topn} \title{Find the top-n matches} \usage{ gower_topn( x, y, pair_x = NULL, pair_y = NULL, n = 5, eps = 1e-08, weights = NULL, ignore_case = FALSE, nthread = getOption("gd_num_thread") ) } \arguments{ \item{x}{\code{[data.frame]}} \item{y}{\code{[data.frame]}} \item{pair_x}{\code{[numeric|character] (optional)} Columns in \code{x} used for comparison. See Details below.} \item{pair_y}{\code{[numeric|character] (optional)} Columns in \code{y} used for comparison. See Details below.} \item{n}{The top-n indices and distances to return.} \item{eps}{\code{[numeric] (optional)} Computed numbers (variable ranges) smaller than \code{eps} are treated as zero.} \item{weights}{\code{[numeric] (optional)} A vector of weights of length \code{ncol(x)} that defines the weight applied to each component of the gower distance.} \item{ignore_case}{\code{[logical]} Toggle ignore case when neither \code{pair_x} nor \code{pair_y} are user-defined.} \item{nthread}{Number of threads to use for parallelization. By default, for a dual-core machine, 2 threads are used. For any other machine n-1 cores are used so your machine doesn't freeze during a big computation. The maximum nr of threads are determined using \code{omp_get_max_threads} at C level.} } \value{ A \code{list} with two array elements: \code{index} and \code{distance}. Both have size \code{n X nrow(x)}. Each ith column corresponds to the top-n best matches of \code{x} with rows in \code{y}. When there are no columns to compare, a message is printed and both \code{distance} and \code{index} will be empty matrices; the list is then returned invisibly. } \description{ Find the top-n matches in \code{y} for each record in \code{x}. } \examples{ # find the top 4 best matches in the iris data set with itself. x <- iris[1:3,] lookup <- iris[1:10,] gower_topn(x=x,y=lookup,n=4) } \seealso{ \code{\link{gower_dist}} } gower/DESCRIPTION0000644000176200001440000000150114730230732013101 0ustar liggesusersPackage: gower Maintainer: Mark van der Loo License: GPL-3 Title: Gower's Distance Type: Package LazyLoad: yes Authors@R: c( person("Mark", "van der Loo", role=c("aut","cre"),email="mark.vanderloo@gmail.com") , person("David", "Turner", role="ctb")) Description: Compute Gower's distance (or similarity) coefficient between records. Compute the top-n matches between records. Core algorithms are executed in parallel on systems supporting OpenMP. Version: 1.0.2 URL: https://github.com/markvanderloo/gower BugReports: https://github.com/markvanderloo/gower/issues Suggests: tinytest (>= 0.9.3), RoxygenNote: 7.3.2 NeedsCompilation: yes Packaged: 2024-12-16 15:36:14 UTC; mark Author: Mark van der Loo [aut, cre], David Turner [ctb] Repository: CRAN Date/Publication: 2024-12-17 08:10:02 UTC