e1071/0000755000175100001440000000000012560437400011026 5ustar hornikuserse1071/inst/0000755000175100001440000000000012560362404012004 5ustar hornikuserse1071/inst/NEWS.Rd0000644000175100001440000003531712560362343013062 0ustar hornikusers\name{NEWS} \title{News for Package \pkg{e1071}} \newcommand{\cpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}} \section{Changes in version 1.6-7}{ \itemize{ \item fix some bug in handling weights in svm.default} } \section{Changes in version 1.6-6}{ \itemize{ \item fix numeric issue in \code{classAgreement()} \item add functions from recommended packages to NAMESPACE \item fix bug in svm.default (incorrect handling of subset= argument) \item fix bug in predict.svm (new data with NA in response got removed) \item residuals are now correctly computed for regression in case of scaled data } } \section{Changes in version 1.6-5}{ \itemize{ \item \code{hamming.distance()} no longer converts input to binary \item \code{tune()} now uses \code{mean()} to aggregate error measures from cross-fold replications } } \section{Changes in version 1.6-4}{ \itemize{ \item remove library("SparseM") statements in code, use namespace semantics instead \item Fix memory leak and uninitialized read error in \code{write.svm()} \item add warning in \code{predict.svm()} if probabilities should be predicted, but the model was not trained with \code{probability = TRUE} \item add \code{eps} to laplace smoothing in \code{predict.naiveBayes()} to account for close-zero probabilities also. \item use R's random number generator for cross-validation and probability computation instead of the system one. } } \section{Changes in version 1.6-3}{ \itemize{ \item remove require() statements and dependency on stats } } \section{Changes in version 1.6-2}{ \itemize{ \item vignettes moved to \code{vignettes} folder. \item libsvm upgrade to version 3.17, getting rid of stdout and stderr } } \section{Changes in version 1.6-1}{ \itemize{ \item \code{write.matrix.csr()} now accepts a \code{fac} argument similar to \code{read.matrix.csr()}, writing factor levels instead of the numeric codes. \item \code{naiveBayes()} uses a numerically more stable formula for calculating the a-posterior probabilities. \item \code{predict.naiveBayes()} now accepts data with predictors in an order different from the training data, and also ignores variables not in the model (especially the response variable). \item \code{svm()} checks whether parameters which are passed to the C-code are set to NULL to avoid segfaults. } } \section{Changes in version 1.6}{ \itemize{ \item bug fix in tune with sparse matrices \item version bump of libsvm to 3.1 \item Fixed partial argument matching in several places \item NEWS file changed to .Rd format and moved to \file{inst/} } } \section{Changes in version 1.5-28}{ \itemize{ \item bug fix in svm cross validation } } \section{Changes in version 1.5-27}{ \itemize{ \item \code{svm()} now accepts to set the random seed for libsvm. } } \section{Changes in version 1.5-26}{ \itemize{ \item \code{tune()} now allows user-specified error functionals. } } \section{Changes in version 1.5-25}{ \itemize{ \item add auto-coercion from Matrix and simple_triplet_matrix objects to \code{predict.svm()} \item Bug fix in \code{tune.svm()}: when a data frame was provided as validation sample, the response variable was not correctly extracted } } \section{Changes in version 1.5-24}{ \itemize{ \item Cosmetics: use \code{sQuote()} instead of hard-coded quotes in warnings and error messages in several places \item Bug fix in labeling of decision values \item add \code{decision.values} of fitted values to a svm object } } \section{Changes in version 1.5-23}{ \itemize{ \item Bug fix in \code{svm()}: Error messages returned by the C function have not been correctly handled, causing segfaults. } } \section{Changes in version 1.5-22}{ \itemize{ \item minor fix } } \section{Changes in version 1.5-21}{ \itemize{ \item Allow sparse_triplet_matrix objects for \code{svm()} } } \section{Changes in version 1.5-20}{ \itemize{ \item More flexible interface to \code{naiveBayes()} \item Fix bugs in docs for \code{kurtosis()} } } \section{Changes in version 1.5-19}{ \itemize{ \item Fix bugs in \code{read.matrix.csr()} and \code{write.matrix.csr()} \item Allow Matrix objects for \code{svm()} \item Version bump of libsvm to 2.88 } } \section{Changes in version 1.5-18}{ \itemize{ \item Improve \file{DESCRIPTION} install metadata } } \section{Changes in version 1.5-17}{ \itemize{ \item \code{tune()} now also returns a dispersion measure of all training samples. \item Bootstrap is done \emph{with} replacement. \item \code{tune.svm()} now also accepts the \code{epsilon} parameter. } } \section{Changes in version 1.5-16}{ \itemize{ \item \code{write.svm()} now also stores the scaling information for the dependent variable. \item data sets Glass, HouseVotes84, and Ozone removed (are in package \cpkg{mlbench}) \item merged help pages for \code{naiveBayes()} and \code{predict.naiveBayes()} } } \section{Changes in version 1.5-15}{ \itemize{ \item Bug in \file{NAMESPACE} file fixed (conditional import from \pkg{utils} failed in R 2.3.1) } } \section{Changes in version 1.5-14}{ \itemize{ \item \code{predict.naiveBayes()} sped up \item Bug fix in \code{plot.svm()} (error in case of training categories without predictions) \item \pkg{methods} now added to \samp{Suggests}, and \pkg{grDevices} to \samp{Imports} } } \section{Changes in version 1.5-13}{ \itemize{ \item Bug fix: sparse handling was broken since 1.5-9 } } \section{Changes in version 1.5-12}{ \itemize{ \item update to libsvm 2.81 \item laplace smoothing added to \code{naiveBayes()} } } \section{Changes in version 1.5-11}{ \itemize{ \item \code{tune()}: allow list of vectors as tune parameter range so that class.weights in svm-models can be tuned \item better default color palette for \code{plot.tune()} \item New function \code{probplot()} for probability plots } } \section{Changes in version 1.5-10}{ \itemize{ \item Bug fix: class probability prediction was broken since 1.5-9 } } \section{Changes in version 1.5-9}{ \itemize{ \item \code{tune()} now returns the split indices into training/validation set. Information added about cross validation \item \code{plot.svm()}: wrong labeling order in levels fixed \item \code{predict.svm()} now adds row numbers to predictions, and correctly handles the \code{na.action} argument using \code{napredict()}. } } \section{Changes in version 1.5-8}{ \itemize{ \item Update to libsvm 2.8 (uses a faster optimization algorithm) } } \section{Changes in version 1.5-7}{ \itemize{ \item \code{read.matrix.csr()} did not work correctly with matrix-only objects. \item \code{svm()}: Fixed wrong labeling for predicted decision values and probabilities in case of a Class factor created from a non-ordered character vector } } \section{Changes in version 1.5-6}{ \itemize{ \item \code{cmeans()} is substantially enhanced, with a complete rewrite of the underlying C code. It is now possible to specify case weights and the relative convergence tolerance. For Manhattan distances, centers are correctly computed as suitably weighted medians (rather than means) of the observations. The print method for fclust objects is now more in parallel with related methods, and registered in the name space. } } \section{Changes in version 1.5-5}{ \itemize{ \item \code{read.octave()} is now deprecated in favor of a substantially enhanced version in package \pkg{foreign} for reading in files in Octave text data format. } } \section{Changes in version 1.5-4}{ \itemize{ \item Use lazy loading } } \section{Changes in version 1.5-3}{ \itemize{ \item New arguments in \code{plot.svm()} for customizing plot symbols and colors \item Fix of broken code in \code{plot.svm()} for the \code{fill = FALSE} (non-default) case } } \section{Changes in version 1.5-2}{ \itemize{ \item Fixed memory leak in \code{svm()} } } \section{Changes in version 1.5-1}{ \itemize{ \item Fixed C++ style comments } } \section{Changes in version 1.5-0}{ \itemize{ \item Example for weighting added in \code{svm()} help page \item upgrade to libsvm 2.6: support for probabilities added } } \section{Changes in version 1.4-1}{ \itemize{ \item \code{NaiveBayes()} is more accurate for small probabilities \item call is more sensible in \code{tune()}, \code{tune.foo()}, and \code{best.foo()} objects. \item \code{control} parameter of \code{tune()} changed to \code{tunecontrol} to solve name space conflict with training methods using \code{control} themselves \item new function \code{matchControls()} \item fixed a bug in \code{bclust()} triggered when a cluster had only one center } } \section{Changes in version 1.4-0}{ \itemize{ \item adjusted to restructering of R base packages \item added a \file{NAMESPACE} file \item Function \code{write.svm()} now also creates a file with scaling information } } \section{Changes in version 1.3.16}{ \itemize{ \item Small bug fixes in \code{predict.svm()} and \code{plot.svm()} \item Function \code{write.svm()} added which saves models created with \code{svm()} in the format libsvm can read. } } \section{Changes in version 1.3.15}{ \itemize{ \item Bug fix in \code{plot.svm()}: non-SVs had wrong colors \item data sets Ozone and Glass added } } \section{Changes in version 1.3.14}{ \itemize{ \item Several Docu bug fixes (for functions \code{plot.bclust()}, \code{impute()}, \code{stft()}, \code{svm.formula()}, \code{svm.default()}) \item upgrade to libsvm 2.5. New feature: \code{predict.svm()} optionally returns decision values for multi-class classification \item svm-vignette gave warnings due to rank deficiency in Ozone data \item \code{naiveBayes()} now also supports metric predictors, and the standard interface. } } \section{Changes in version 1.3.13}{ \itemize{ \item Bug fixes in svm: \itemize{ \item Prediction of 1 single observation gave an error \item Only \eqn{k} instead of \eqn{k*(k-1)/2} \eqn{\rho} coefficients have been returned by svm (\eqn{k} number of classes), having caused nonsensical results for \eqn{k > 3}. } \item The \file{svmdoc} file in \file{inst/doc} now is a vignette. } } \section{Changes in version 1.3-12}{ \itemize{ \item The \code{x} argument of \code{cmeans()} and \code{bclust()} is now automatically coerced to a matrix. \item Started \file{tests} directory \item New method: \code{naiveBayes()} classifier for categorical predictors \item optimization of \code{read.matrix.csr()} which used to be rather slow \item Bug fixes for the \code{svm()} interface: when the data included categorical predictors, the scaling procedure did not only affect the metric variables, but also the binary variables in the model matrix. \item Function \code{scaclust()} removed. Bug has to be fixed. } } \section{Changes in version 1.3-10}{ \itemize{ \item Now supports libsvm 2.4 } } \section{Changes in version 1.3-9}{ \itemize{ \item \code{rdiscrete()} is now simply a wrapper for \code{sample()} and provided for backwards compatibility only. \item Minor bug fixes in \code{svm()} and \code{tune()} (mostly interface issues). New plot function for objects of class \code{svm} working for the 2d-classification case. } } \section{Changes in version 1.3-7}{ \itemize{ \item \code{svm()} now supports the matrix.csr format, as handled by the \cpkg{SparseM} package. Predictors and response variable (if numeric) are scaled per default. \item A new \code{plot()} function for \code{svm()} objects visualizes classification models by plotting data and support vectors in the data input space, along with the class borders. \item A new generic \code{tune()} function allows parameter tuning of arbitrary functions using, e.g., boot strapping, or cross validation. Several convenience wrappers (e.g., for \code{svm()}, \code{nnet()}, and \code{rpart()}) do exist. } } \section{Changes in version 1.3-3}{ \itemize{ \item Bug fixes in various bclust routines: \code{stop()} if required packages are not found \item \code{svm()} now interfaces LIBSVM 2.35 which is a bug fix release. A call with invalid parameters now no longer causes R to be terminated, and the C(++) code became completely silent. \item Bugs fixed in \code{fclustIndex()} function and \code{print.fclust()}. } } \section{Changes in version 1.3-1}{ \itemize{ \item Functions \code{rmvnorm()} and \code{dmvnorm()} for multivariate normal distributions have been moved to package \cpkg{mvtnorm}. \item Bug fixes in \code{print.fclust()} and \code{fclustIndex()}. \item fixed \file{floyd.c} (ANSI C pedantic warnings) } } \section{Changes in version 1.2-1}{ \itemize{ \item Bug fixes in \file{cmeans.c}, \file{cshell.c} and \file{scaclust.c} (R header files included and unused variables removed) \item Bug fixes in \file{Rsvm.c} and \file{svm.R} (incomplete list of returned Support Vectors). \item Encapsulate kmeans call in \code{bclust()} in a \code{try()} construct, because kmeans gives an error when a cluster becomes empty (which can happen for almost every data set from time to time). } } \section{Changes in version 1.2-0}{ \itemize{ \item Added functions for bagged clustering, see help(bclust). \item \code{read.pnm()} and \code{write.pgm()} have been removed from \cpkg{e1071}, much improved versions can now be found in the new packagepixmap. \item Lots of documentation updates and bugfixes. \item Support Vector Machine interface now upgraded to libsvm V. 2.31 featuring: \itemize{ \item Multi-Class Classification \item weighting of classes for C-classification (for asymmetric sample sizes) \item \eqn{\nu}-regression \item Formula Interface \item \eqn{k}-fold cross-validation } In addition, an introductory article is provided in directory \file{docs/} (\file{svmdoc.pdf}). \item \code{classAgreement()} now features an option to match factor levels \item updated API design for the fuzzy clustering functions (\code{cmeans()}, \code{cshell()}, \code{scaclust()}). Documentation updates and function name changes (\code{cmeanscl()} to \code{cmeans()}, \code{validity.measures()} to \code{fclustIndex()}) } } e1071/inst/doc/0000755000175100001440000000000012560362404012551 5ustar hornikuserse1071/inst/doc/svmdoc.R0000644000175100001440000001043112560362404014166 0ustar hornikusers### R code from vignette source 'svmdoc.Rnw' ################################################### ### code chunk number 1: svmdoc.Rnw:140-149 ################################################### library(e1071) library(rpart) data(Glass, package="mlbench") ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- Glass[testindex,] trainset <- Glass[-testindex,] ################################################### ### code chunk number 2: svmdoc.Rnw:154-157 ################################################### ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) ################################################### ### code chunk number 3: svmdoc.Rnw:162-165 ################################################### ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") ################################################### ### code chunk number 4: svmdoc.Rnw:168-173 ################################################### ## compute svm confusion matrix table(pred = svm.pred, true = testset[,10]) ## compute rpart confusion matrix table(pred = rpart.pred, true = testset[,10]) ################################################### ### code chunk number 5: svmdoc.Rnw:178-213 ################################################### library(xtable) rp.acc <- c() sv.acc <- c() rp.kap <- c() sv.kap <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Glass[testindex,]) trainset <- na.omit(Glass[-testindex,]) ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) tab <- classAgreement(table(svm.pred, testset[,10])) sv.acc[i] <- tab$diag sv.kap[i] <- tab$kappa ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") tab <- classAgreement(table(rpart.pred, testset[,10])) rp.acc[i] <- tab$diag rp.kap[i] <- tab$kappa } x <- rbind(summary(sv.acc), summary(sv.kap), summary(rp.acc), summary(rp.kap)) rownames <- c() tab <- cbind(rep(c("svm","rpart"),2), round(x,2)) colnames(tab)[1] <- "method" rownames(tab) <- c("Accuracy","","Kappa"," ") xtable(tab, label = "tab:class", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for classification (10 replications)") ################################################### ### code chunk number 6: svmdoc.Rnw:226-245 ################################################### library(e1071) library(rpart) data(Ozone, package="mlbench") ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) crossprod(rpart.pred - testset[,3]) / length(testindex) ################################################### ### code chunk number 7: svmdoc.Rnw:248-271 ################################################### rp.res <- c() sv.res <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) sv.res[i] <- crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) rp.res[i] <- crossprod(rpart.pred - testset[,3]) / length(testindex) } xtable(rbind(svm = summary(sv.res), rpart = summary(rp.res)), label = "tab:reg", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for regression (Mean Squared Error, 10 replications)") e1071/inst/doc/svmdoc.Rnw0000644000175100001440000004336512560362404014547 0ustar hornikusers\documentclass[a4paper]{article} \usepackage{hyperref, graphicx, color, alltt} \usepackage{Sweave} \usepackage[round]{natbib} \definecolor{Red}{rgb}{0.7,0,0} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{hellgrau}{rgb}{0.55,0.55,0.55} \newcommand{\pkg}[1]{\texttt{#1}} \newenvironment{smallexample}{\begin{alltt}\small}{\end{alltt}} \begin{document} %\VignetteIndexEntry{Support Vector Machines---the Interface to libsvm in package e1071} %\VignetteDepends{e1071,rpart,xtable} %\VignetteKeywords{classification, regression, machine learning, benchmarking, support vector machines} %\VignettePackage{e1071} \SweaveOpts{engine=R,eps=FALSE} \setkeys{Gin}{width=0.8\textwidth} \title{Support Vector Machines \footnote{A smaller version of this article appeared in R-News, Vol.1/3, 9.2001}\\ \large The Interface to \texttt{libsvm} in package \pkg{e1071}} \author{by David Meyer\\ FH Technikum Wien, Austria\\ \url{David.Meyer@R-Project.org} } \maketitle \sloppy ``Hype or Hallelujah?'' is the provocative title used by \cite{svm:bennett+campbell:2000} in an overview of Support Vector Machines (SVM). SVMs are currently a hot topic in the machine learning community, creating a similar enthusiasm at the moment as Artificial Neural Networks used to do before. Far from being a panacea, SVMs yet represent a powerful technique for general (nonlinear) classification, regression and outlier detection with an intuitive model representation. The package \pkg{e1071} offers an interface to the award-winning\footnote{The library won the IJCNN 2001 Challenge by solving two of three problems: the Generalization Ability Challenge (GAC) and the Text Decoding Challenge (TDC). For more information, see: \url{http://www.csie.ntu.edu.tw/~cjlin/papers/ijcnn.ps.gz}.} C++-implementation by Chih-Chung Chang and Chih-Jen Lin, \texttt{libsvm} (current version: 2.6), featuring: \begin{itemize} \item $C$- and $\nu$-classification \item one-class-classification (novelty detection) \item $\epsilon$- and $\nu$-regression \end{itemize} and includes: \begin{itemize} \item linear, polynomial, radial basis function, and sigmoidal kernels \item formula interface \item $k$-fold cross validation \end{itemize} For further implementation details on \texttt{libsvm}, see \cite{svm:chang+lin:2001}. \section*{Basic concept} SVMs were developed by \cite{svm:cortes+vapnik:1995} for binary classification. Their approach may be roughly sketched as follows: \begin{description} \item[Class separation:] basically, we are looking for the optimal separating hyperplane between the two classes by maximizing the \textit{margin} between the classes' closest points (see Figure \ref{fig:svm1})---the points lying on the boundaries are called \textit{support vectors}, and the middle of the margin is our optimal separating hyperplane; \item[Overlapping classes:] data points on the ``wrong'' side of the discriminant margin are weighted down to reduce their influence (\textit{``soft margin''}); \item[Nonlinearity:] when we cannot find a \textit{linear} separator, data points are projected into an (usually) higher-dimensional space where the data points effectively become linearly separable (this projection is realised via \textit{kernel techniques}); \item[Problem solution:] the whole task can be formulated as a quadratic optimization problem which can be solved by known techniques. \end{description} \noindent A program able to perform all these tasks is called a \textit{Support Vector Machine}. \begin{figure}[htbp] \begin{center} \includegraphics[width=8cm]{svm} \caption{Classification (linear separable case)} \label{fig:svm1} \end{center} \end{figure} Several extensions have been developed; the ones currently included in \texttt{libsvm} are: \begin{description} \item[$\nu$-classification:] this model allows for more control over the number of support vectors \cite[see][]{svm:scholkopf+smola+williamson:2000} by specifying an additional parameter $\nu$ which approximates the fraction of support vectors; \item[One-class-classification:] this model tries to find the support of a distribution and thus allows for outlier/novelty detection; \item[Multi-class classification:] basically, SVMs can only solve binary classification problems. To allow for multi-class classification, \texttt{libsvm} uses the \textit{one-against-one} technique by fitting all binary subclassifiers and finding the correct class by a voting mechanism; \item[$\epsilon$-regression:] here, the data points lie \textit{in between} the two borders of the margin which is maximized under suitable conditions to avoid outlier inclusion; \item[$\nu$-regression:] with analogue modifications of the regression model as in the classification case. \end{description} \section*{Usage in R} The R interface to \texttt{libsvm} in package \pkg{e1071}, \texttt{svm()}, was designed to be as intuitive as possible. Models are fitted and new data are predicted as usual, and both the vector/matrix and the formula interface are implemented. As expected for R's statistical functions, the engine tries to be smart about the mode to be chosen, using the dependent variable's type ($y$): if $y$ is a factor, the engine switches to classification mode, otherwise, it behaves as a regression machine; if $y$ is omitted, the engine assumes a novelty detection task. \section*{Examples} In the following two examples, we demonstrate the practical use of \texttt{svm()} along with a comparison to classification and regression trees as implemented in \texttt{rpart()}. \subsection*{Classification} In this example, we use the glass data from the \href{http://www.ics.uci.edu/mlearn/MLRepository.html}{UCI Repository of Machine Learning Databases} for classification. The task is to predict the type of a glass on basis of its chemical analysis. We start by splitting the data into a train and test set: <<>>= library(e1071) library(rpart) data(Glass, package="mlbench") ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- Glass[testindex,] trainset <- Glass[-testindex,] @ Both for the SVM and the partitioning tree (via \texttt{rpart()}), we fit the model and try to predict the test set values: <<>>= ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) @ (The dependent variable, \texttt{Type}, has column number 10. \texttt{cost} is a general penalizing parameter for $C$-classification and \texttt{gamma} is the radial basis function-specific kernel parameter.) <<>>= ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") @ A cross-tabulation of the true versus the predicted values yields: <<>>= ## compute svm confusion matrix table(pred = svm.pred, true = testset[,10]) ## compute rpart confusion matrix table(pred = rpart.pred, true = testset[,10]) @ %% results table <>= library(xtable) rp.acc <- c() sv.acc <- c() rp.kap <- c() sv.kap <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Glass[testindex,]) trainset <- na.omit(Glass[-testindex,]) ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) tab <- classAgreement(table(svm.pred, testset[,10])) sv.acc[i] <- tab$diag sv.kap[i] <- tab$kappa ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") tab <- classAgreement(table(rpart.pred, testset[,10])) rp.acc[i] <- tab$diag rp.kap[i] <- tab$kappa } x <- rbind(summary(sv.acc), summary(sv.kap), summary(rp.acc), summary(rp.kap)) rownames <- c() tab <- cbind(rep(c("svm","rpart"),2), round(x,2)) colnames(tab)[1] <- "method" rownames(tab) <- c("Accuracy","","Kappa"," ") xtable(tab, label = "tab:class", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for classification (10 replications)") @ \noindent Finally, we compare the performance of the two methods by computing the respective accuracy rates and the kappa indices (as computed by \texttt{classAgreement()} also contained in package \pkg{e1071}). In Table \ref{tab:class}, we summarize the results of \Sexpr{reps} replications---Support Vector Machines show better results. \subsection*{Non-linear $\epsilon$-Regression} The regression capabilities of SVMs are demonstrated on the ozone data. Again, we split the data into a train and test set. <<>>= library(e1071) library(rpart) data(Ozone, package="mlbench") ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) crossprod(rpart.pred - testset[,3]) / length(testindex) @ <>= rp.res <- c() sv.res <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) sv.res[i] <- crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) rp.res[i] <- crossprod(rpart.pred - testset[,3]) / length(testindex) } xtable(rbind(svm = summary(sv.res), rpart = summary(rp.res)), label = "tab:reg", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for regression (Mean Squared Error, 10 replications)") @ \noindent We compare the two methods by the mean squared error (MSE)---see Table \ref{tab:reg} for a summary of \Sexpr{reps} replications. Again, as for classification, \texttt{svm()} does a better job than \texttt{rpart()}---in fact, much better. \section*{Elements of the \texttt{svm} object} The function \texttt{svm()} returns an object of class ``\texttt{svm}'', which partly includes the following components: \begin{description} \item[\textbf{\texttt{SV}:}] matrix of support vectors found; \item[\textbf{\texttt{labels}:}] their labels in classification mode; \item[\textbf{\texttt{index}:}] index of the support vectors in the input data (could be used e.g., for their visualization as part of the data set). \end{description} If the cross-classification feature is enabled, the \texttt{svm} object will contain some additional information described below. \section*{Other main features} \begin{description} \item[Class Weighting:] if one wishes to weight the classes differently (e.g., in case of asymmetric class sizes to avoid possibly overproportional influence of bigger classes on the margin), weights may be specified in a vector with named components. In case of two classes A and B, we could use something like: \texttt{m <- svm(x, y, class.weights = c(A = 0.3, B = 0.7))} \item[Cross-classification:] to assess the quality of the training result, we can perform a $k$-fold cross-classification on the training data by setting the parameter \texttt{cross} to $k$ (default: 0). The \texttt{svm} object will then contain some additional values, depending on whether classification or regression is performed. Values for classification: \begin{description} \item[\texttt{accuracies}:] vector of accuracy values for each of the $k$ predictions \item[\texttt{tot.accuracy}:] total accuracy \end{description} Values for regression: \begin{description} \item[\texttt{MSE}:] vector of mean squared errors for each of the $k$ predictions \item[\texttt{tot.MSE}:] total mean squared error \item[\texttt{scorrcoef}:] Squared correlation coefficient (of the predicted and the true values of the dependent variable) \end{description} \end{description} \section*{Tips on practical use} \begin{itemize} \item Note that SVMs may be very sensible to the proper choice of parameters, so allways check a range of parameter combinations, at least on a reasonable subset of your data. \item For classification tasks, you will most likely use $C$-classification with the RBF kernel (default), because of its good general performance and the few number of parameters (only two: $C$ and $\gamma$). The authors of \pkg{libsvm} suggest to try small and large values for $C$---like 1 to 1000---first, then to decide which are better for the data by cross validation, and finally to try several $\gamma$'s for the better $C$'s. \item However, better results are obtained by using a grid search over all parameters. For this, we recommend to use the \texttt{tune.svm()} function in \pkg{e1071}. \item Be careful with large datasets as training times may increase rather fast. \item Scaling of the data usually drastically improves the results. Therefore, \texttt{svm()} scales the data by default. \end{itemize} \section*{Model Formulations and Kernels} Dual representation of models implemented: \begin{itemize} \item $C$-classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha-e^\top\alpha \nonumber\\ \mbox{s.t.} &&0\le\alpha_i\le C,~i=1,\ldots,l,\\ &&\mathbf{y}^\top\alpha=0~, \nonumber \end{eqnarray} where $\mathbf{e}$ is the unity vector, $C$ is the upper bound, $\mathbf{Q}$ is an $l$ by $l$ positive semidefinite matrix, $Q_{ij} \equiv y_i y_j K(x_i, x_j)$, and $K(x_i, x_j) \equiv \phi(x_i)^\top\phi(x_j)$ is the kernel. \item $\nu$-classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha \nonumber\\ \mbox{s.t.}&&0\le\alpha_i\le 1/l,~i=1,\ldots,l,\\ &&\mathbf{e}^\top \alpha \ge \nu, \nonumber\\ &&\mathbf{y}^\top\alpha=0~. \nonumber \end{eqnarray} where $\nu \in (0,1]$. \item one-class classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha \nonumber\\ \mbox{s.t.} &&0\le\alpha_i\le 1/(\nu l),~i=1,\ldots,l,\\ &&\mathbf{e}^\top\alpha=1~,\nonumber \end{eqnarray} \item $\epsilon$-regression:\\ \begin{eqnarray} \min_{\alpha, \alpha^*}&&\frac{1}{2}(\alpha-\alpha^*)^\top \mathbf{Q} (\alpha-\alpha^*) + \nonumber\\ &&\epsilon\sum_{i=1}^{l}(\alpha_i+\alpha_i^*) + \sum_{i=1}^{l}y_i(\alpha_i-\alpha_i^*) \nonumber\\ \mbox{s.t.} &&0\le\alpha_i, \alpha_i^*\le C,~i=1,\ldots,l,\\ &&\sum_{i=1}^{l}(\alpha_i-\alpha_i^*)=0~.\nonumber \end{eqnarray} \item $\nu$-regression:\\ \begin{eqnarray} \min_{\alpha, \alpha^*}&&\frac{1}{2}(\alpha-\alpha^*)^\top \mathbf{Q} (\alpha-\alpha^*) + \mathbf{z}^\top(\alpha_i-\alpha_i^*) \nonumber\\ \mbox{s.t.} &&0\le\alpha_i, \alpha_i^*\le C,~i=1,\ldots,l,\\ &&\mathbf{e}^\top(\alpha-\alpha^*)=0\nonumber\\ &&\mathbf{e}^\top(\alpha+\alpha^*)=C\nu~.\nonumber \end{eqnarray} \end{itemize} \noindent Available kernels:\\ \\ \noindent \begin{table}[h] \centering \begin{tabular}{|l|l|l|} \hline kernel & formula & parameters \\ \hline \hline linear & $\bf u^\top v$& (none) \\ polynomial & $\gamma (\mathbf{u^\top v}+c_0)^d$ & $\gamma, d, c_0$\\ radial basis fct. & $\exp\{-\gamma|\mathbf{u-v}|^2\}$&$\gamma$\\ sigmoid & $\tanh\{\gamma \mathbf{u^\top v}+c_0\}$ &$\gamma, c_0$\\ \hline \end{tabular} \end{table} \section*{Conclusion} We hope that \texttt{svm} provides an easy-to-use interface to the world of SVMs, which nowadays have become a popular technique in flexible modelling. There are some drawbacks, though: SVMs scale rather badly with the data size due to the quadratic optimization algorithm and the kernel transformation. Furthermore, the correct choice of kernel parameters is crucial for obtaining good results, which practically means that an extensive search must be conducted on the parameter space before results can be trusted, and this often complicates the task (the authors of \texttt{libsvm} currently conduct some work on methods of efficient automatic parameter selection). Finally, the current implementation is optimized for the radial basis function kernel only, which clearly might be suboptimal for your data. \begin{thebibliography}{5} \bibitem[Bennett \& Campbell(2000)]{svm:bennett+campbell:2000} Bennett, K.~P. \& Campbell, C. (2000). \newblock Support vector machines: Hype or hallelujah? \newblock \emph{SIGKDD Explorations}, \textbf{2}(2). \newblock \url{http://www.acm.org/sigs/sigkdd/explorations/issue2-2/bennett.pdf}. \bibitem[Chang \& Lin(2001)]{svm:chang+lin:2001} Chang, C.-C. \& Lin, C.-J. (2001). \newblock {LIBSVM}: a library for support vector machines. \newblock Software available at \url{http://www.csie.ntu.edu.tw/~cjlin/libsvm}, detailed documentation (algorithms, formulae, \dots) can be found in \url{http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.ps.gz} \bibitem[Cortes \& Vapnik(1995)]{svm:cortes+vapnik:1995} Cortes, C. \& Vapnik, V. (1995). \newblock Support-vector network. \newblock \emph{Machine Learning}, \textbf{20}, 1--25. \bibitem[Sch\"olkopf et~al.(2000)Sch\"olkopf, Smola, Williamson, \& Bartlett]{svm:scholkopf+smola+williamson:2000} Sch\"olkopf, B., Smola, A., Williamson, R.~C., \& Bartlett, P. (2000). \newblock New support vector algorithms. \newblock \emph{Neural Computation}, \textbf{12}, 1207--1245. \bibitem[Vapnik(1998)]{svm:vapnik:1998} Vapnik, V. (1998). \newblock \emph{Statistical learning theory}. \newblock New York: Wiley. \end{thebibliography} \end{document} e1071/inst/doc/svmdoc.pdf0000644000175100001440000103745612560362404014557 0ustar hornikusers%PDF-1.5 % 15 0 obj << /Length 2807 /Filter /FlateDecode >> stream xڵKo_AXkpazhoY=-+D-)Eo)NҢ0L LyDNG~_^_jBfM&*yRGWCT[_$qmN'&Ӣ),lڎT6=M _ݟzej"UimtQ*WQҬ``V]NtYh&Jw_!TM Ք,`wMS ?cy ,QE^LݏڸfGBi.A\uB'S@N|g?dY=7=;5uF՗5i#]w[]ċg< [NT%Q&÷N1Nq"r<A[xLN'-F8=g4Dj$5&RBg seHTytGmb/i)c2}]O Y#Y^u-|hY LH&axp{y)oWT^ 3k ]7bYuF,avtv$LYDLuvC?K2X: ,2$q!ͧ M1 dX%:9L<'!rIP23+-^h! 39jGSCPSJTG)vL2X6Me,8 R[I&B5l!&A{HO8U#|T}  cH!nCb*|߮KU'f'WH2 fkx暲E7\KCn͗-?VgUy 7sJ:?QwG,aյPL!Kuv@ tB \цYf=ST,^0c B!2i0KQ+ZU#f5 =,jƽj dMJS*S"**DkZ79oKܾ &P솥ls$P6\"d{O0h}T gCep!G7pdF*lXA*yXhՖ&/Q[_ N,+㢌ՉnaI%['bĕpz<˟½Q4m]+tU'%Hnѕ*gtM:u΂LW8Ι2ni9 ݑNa* Dŗɪlr09_j۔gh!1 IJ1 zGQNI YLm)v_*:{ʬj O ڝfY_?O8m5 'm?.Hɕ eFr0m6۷nWl[t|]=s⌴ Wu<^2eհh,jV]D3X9)Î.#m 94&zwdeHʢҐoHB,J*Y0崑?j4x%馡f I $k5FC\ʋ-7ӦwN.%bb%F]KdK>7gFŸ|@$Ɓ*/`څY[Yka'E\>$_8 ȑkN)ѥ/;DQwy-N.Zw-^X!!xC3 endstream endobj 46 0 obj << /Length 2160 /Filter /FlateDecode >> stream xڥXIF r"\ 4Y$̤=bDE_۪l)FKZ_}o)lp}s{uVۻB5&mrNަd&9Gh=t>6Y >:O᠗!Tv0Bۯq ?:[J-3[84M=~:}g\#N|=eط S f9%JrcT[,ݡvlppsO (8'1'{b(-&}MyƩR`bwkE7(fW܈eL7ӥٯY}ܶ l\?2VCGF9e`Ϡ֪n /=+#/A+4DlnOSފ=G+B6mGȐMq}dɄF;.#^w|`Nb hGi*+`?pr%|3Ӹp oO)0&͹~Tn1b,a& ǟs%"H|`Џ;)؂a48Jdjʋe`7$R4A/fsI `F>H5֪ pz/H`:4F?̲t ܢTcs^ף4806t·sz,Hu%jٺnzϣ=;qXd֝guP6# N&ޣ㟤n-*۞g~Dž KkQbAWtD{>|e.?&|g'=yf"]PNj5j J=nH;zsHlg߉y ; ihKDi 渚5/J.74~h{V>&i 1m\ ݆Ͽ1ЉIL.6qD ?oTQUO5i/?LxO):{S-p!Y as>F;9N}ˉw7@%;p*:2gjڋ!9kZLRVC圪aoD u:|S>P PBZc&سBqC~{pk:fxw<}1 Q|L qiYLyyz& čjuˆl"ǂPk@܂-ZG2ϚE(Ź?zG42 Xɼ~F<;{:K D&+Kzi1>.$~!aA4I7dyKs=~OT`6fӪ5!jE=>ߤ̥Kb.YI:I0qt2>q{ |4Kٰt>:r;sE`7Ivi^1sG.^f5stQw![cچץs(QZ"31EG((N$~ endstream endobj 41 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./svm.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 48 0 R /BBox [0 0 486 481] /Resources << /ProcSet [ /PDF /Text ] /Font << /R6 49 0 R>> >> /Length 25267 /Filter /FlateDecode >> stream xKv˒4߿f@5EBb܂elctvC7Fzۻ긏XoF░~Oo(~?n{]ןҿ{@&߭~: BV>ZEѴߜ2R(=hߥPv 9>]m TϷޱ!} = S%|oB$/dh,&dʌ)ۜM&{>BZSȝiu#I]x}!s d}?K G2}W@FxAo{}ݰF3k.Z5?kuXK{U_ccl8ri-^p=/ y^DJ_v٘/ۆlD{j/˔iʸ>_q|P6+c+f{z|qrO{qd6_Jg$̏T ,aVP،Ih0 fRܖ弯W{R|]8jrJqd 5+I[WNۦk];v6rf߹эX7 p73e[*.?>ﯕO_튲;LA0hB?}r^g^mOʿZ1y7~'wx^:^+jz i-/OW!XUZZҊFuidUӾ鈬W\LǿnUMJ?39 GL?Ls$iRit#r!KinEEsu@ewǛ+As5x4/T JjM]Fo'.4ا SڸSGB88`(B̀8*qr(/.,ѹ5sDx]Y<,PbVѹ[ߎ@L4nVp Qbm Dl46~]M/3dᆌynh'/ƾ`{Y0_}6}_:#m;TwV޽}U`]yUce*Ф+S^wG"}&FğD{" ޗ΋yc.Slcp_缝UiOfaorC$0F>6WŸ8,fVRl5Cي] h*6ԬmbFEэ*Laņ`D~X!n)cm,f oƮR1R\M]?.҉gE36\ jU`s<«U&QyMry)9r]n%3emutge'o^|ԼV3C*_;LJdrV"~yWld!G&U: ٛY3ɬչcen:uck@)++YIB̏W1ME&c*=c&`c&c1LPǂ0E5 oJ7o+dW@NX\9Assud*IժQk^W"\;`rlar'DC2]D~|Z7?[~uxgv:r4|ի_//< _iIĸ}-qU8˥m8ul_p_Z;I,w\" Kt eL@>F+ VA\I0!w8g ݋\r y \6]+!V_g\  z#sOPTᮃC1X9D K83Euu@Tbk@X"y` /8ĆlyT\5vbJ\S]e ͡+e-<$FƹGiҙj?9x")x6U}!j Qt'(s.w>B> >Q.}\wM75ok'LN&\9tt=Tk ۵hdcDٍB3` V1uXِ6v^}:<\}C\s]ų_|C/Pj+*1׾zK/f{V!\:6eNs&zzmxzzBmʅY7y|;%Dt8?Aȩ/HCO}CW__= pIsaAiqP*O8D(״$Z"yd]Lt['oAu'hU3{BuLlHYq̍[Ub$&g@</ 064 Ew[^g.(-,שXk?`u5Gt'k,s-ܤK?'d)e!FnkYZ`dW_俦  ">,\b5+;i ƲK625gͬ8t@3D&d~ ʳ@l"/63s04kab:DyXwS 75bT "Ptb+hT\ЛISALMJ1ld=XԿsfBO|ɆUL~|3?xwkݿm/D1[!O5@1_Vgk]/{A$0>A*{\7sSaW[=͜%aV  By w-呐98gϻ :䍏SI $ {rkG!\* t9;Ms|sO9ћd.vNq̀9>'KĚ%G@/!Ž█ޏ4.g}zt-#k H,*#ueVoMy<*'p[zd4ёF%m)3!^rLmtچ؇ AE Lʕ9M7jĈ4fmMr6򀬞 }f*^~e HԹ 4@i*W~5"x {E\6æW|hU4 ~C#7wv=iw˕[;2%<9(VP0ڛc.W\gGH@q!ϡP=: :Qa@LxTO\ 6MWÑWquYIE`EtpFZUD, e:_곾z!]\*g8FC%dوpKղQ[lBL0& xWrrWr[ `+R233pY1#cj D&>.O53Ef !Sn\vϟO<=X7n^=]ȃ/5,xM˸^ pMj =b5jV?5 BpChyw[1f:b i 1#cfY\# `A k3s̈pά22)33.R̝fYԑkzpIGMZ_1TuXt5k])y} _[)(2~]/*)f,8!0cyaD{T7>^9Ǣۍ?ΣqBbf6;`=sy49I]dd b+|"R*CD%"R*UfI\MKa9VwXu3+|L ptiɵӛk@ISNG]:>vqldjήb=8?ya,KR\r|X2?x ȴ@$öt_kKݰ/%O|9{Gi#1>rqx89.cyoM!lFff==]CgO|tOS#W}|BA8|+gC:p*ir⼧ &~#˩V5 n*\ w17H)~^G w=>ˁ83+Di(4_Mj Y~ .D/7Xr6feCZrkpDd!] Ae/O i<2fR"(~q|^sX=\R"Vb-; Z)^18>'"RLAe,Y@'ė(ggr+Ɏ;I"r 2JHi? oBp͍W3vf ^πy;{g"Bvdh2_O3~:$2s[-żPk.w(E]. eYݶtR5m純O#9ݽd469l6Z%9MaQϩqNs5昰P{fL p/* :s9eoJ@Թcp "**Vtgit*0 DIM 9JwZNiU Ķ3]k&HtS $SmAl MEњu6Md8u0i`0΄n8[!.Rr~Y3_w ˻-"q/;G_OU|r!xЀm;4a˃ )ކQc/&V6>bYYd :b6 6%=A˹6U*q:N#7YYp F#ö\m0!^@ҷpM[DmH6*;itrݠR!%P٩*D xh$D74 ;@LAC]LdGY'FC)!O(m=R"Qz=!_41#΃㱌U* TADcnL p%*nx&q]@8"5Rϸ\ytU" ۭeiU:bA9k "Z/4}a]DXZO5=O&Aw:PDkUb[==@wEU}2]WI,UBm! |/z/jX׺ < H$dݫH%d<{ZC3cc0m#.mK{Fߟ+֭j3[є;~^oy$4<ŎNKqb4zSdZt1kzȺ( 8S'p|M%92"rŦצ]9tJvz9uss,}n8\s . NqahwZx:yd|(zȨ}zki~UoVjd@hO^Gh@K(O0Ӭ\Ģk=Gˆ3T#yVX$RwW`x|D,Y*dgiW| XHU4bVSS ʃc爬5Y&Eu!V s6a]?=Čx99T F8Z4D7Vqs8|1xcp@h"a^npXNI\a'f&z@j x9%@_љyp3z2@Xge@/"I$eJi>xPc݃slc bD-XFđ-{D%Dm_D7GADID$RD[EDdDmFdvDGEqZĢ7F1lSG؛1~ƙp9 agBG =ŬB/1Peg4Si5TNSY>j741,WN"QKA%L 4TZ4m)`SCԃL;+ijC0[n`pKŅLJ5m-R<"G˪G/^VY|s'=I4޼qzhhWo2 =JlVQEhQ9L+ppCBxCf< aQhKǵ?5NnɅ9I E_1S k fSFά9S"Wl&lͮކ1K]S@2+p\7˽h8sZC5N ~`\N␵(dk0_MQS3_,_ Y ƘG }D(b7~6*^`őzqqF7xg$NȫzRk9Y@ږ[uAy{]&Kd*G,&Bjq&HۋhEؕK&~~dU/&V6>hcO100 4b?ԓ`,鏂(9yiq'9cH#Kl蘕t$7R? Ya/  Z ӹ*:w16_-=,2}AW 2-aVzјƧ3`6iB8uXRbkLmj-6d`**HXj8SA0rMu 0Lb;T|0ZΎn&8Ǻ)\sY$.Š1a:*,|:,Kȿ:~z| vF:-%/[6@6R/6iec647i$n 6_H &߃vopRAuj2>47[Uђ 8>`3Ho}C1xHj mD5b+Dw6y8SGfuu 18=x3w 7TŗBzZ<ٴ%\C8=ᖐ=@#U2 &i}Jhn$)kHD}Zбt|чǾ%֍BKD(d"2)!ȭ9&, CLp ҇gKpD@8qgچ34 3<8 `}p^BKІDoS~ivs J4 ̌jOW p[llgޤUEyLSݼFGh)豄\i[ɺlw{K>E:_LƃE?ڤK522v/ 7P QeG &w1B1 1S%dkCh&YHY̢`vYdҹ,42ށ!Qsձspq sP/:8IuP Ŵ- յZ8-nQEVE~-8i9~ {ʞZ?|bVʫJ PAΕn);EQ/aս|iTau:b7QGU(/kϜ<\P32kF^ͨ;DA7(fټvcT3 tQx?*٩xZw&@ɘ!*2dЪK=tyg71<]ج nf[\YB'YVN2lvZU;ﴕV#>=qԒ)_Em_{}7 F{;J)gX(fT%Fν]{[@I𒔜{[[i9!rm_ir%nVS.A.౼_I,}ܣ д(MOJ44KN$<{O/  PIK$L gZ2-R.dYޣ$}]E2hb؅hܪ%"h$r R *1dz-T_PiǠZUAئcMvr}|:ygWݺpw ECX)&>>,'w(ȻEtd2'ݎ}R8˲d 3h skn/&V6>hcOW0glbH4ήJ("a$׋x4յ"Twj<⒁53OC%x==Q@OO-ŀhZӡX"-pU7]ƋzC~!53"*SƒnA%-{6j=5@[Dy|1YE~E>3\MtY@Uo>yxe1bmHD4.߭@{A{I[r$)ߕkP\^ qɼpAJсDkx;#/G,Q */'>H܁%/dqՃiOC}n!* 53ٙd,pg~Xc}6@\U$1bZa, 6GtڻV$oXrNx}h# JOǛ#&9Y"EhjOn$ $(;3bļ7fC`>&WγԕH\Oc\ ihYemR1g3`57VDtXQ bgLcV 64`)Ӓ87׃N*l]:iuw,tsF7c͈pv;mai~{9 qwv/[lƿiDdܿ Z (nKZ?E;_h~8䛍E8!Om*+<܃̓Tf 4:KɈ94A^潴g 63 [ %!1!2wbS]_p\=KR^/-K!"D%U U)Ʀ2_iPnZiTpT?ꈴiFƪWmC5V"!jT%JT혨U5hhղUcN#"?{]"~%NˏLGfWZXSy=*Gs~|@_E~kaZrqQyU1/G ސ%",Mpx~\I*dJ=x\K\/DU5 k8nbZm \kQQy-<-_;ǬvB4tVJp*txmVpJEa-~{V7L1,* .KU< _**`Ixpy qi7yht' ayk(Đg 'JJٔ6ww83!C$+z@6GYnAƘ]!g5%bHڠopL^#įk[.{!WcI}X0TZyMk;;_{yos4_$yԶTL i^:SAk(;=yeIxY&4˥~5\|p \ho08@Y $Dݭp@ b1ʤW6MsV }-=U,i-}:|#4 NPa #8XIOFP|EбzWhc"hoTFb@4~Y3WddSXD@4MEU",czWTə5S%/X-㱢&cMΨSZ'J)(ĴVPk64~N!bM:QuwM5k}C UtpvvYM ad~;8IݦV5fٵG.GW[9z˺xS$BCҋEhqna7 8XJ3C? *[eHB'ŕ&jrWSQBFjጌuo^Ejdб;/ÀWx/[ɵývxoEg9oū$u+TZ(V|錶O3ڊKgt4Vf/ouw++ͤK~XA5Vr3#JG2؊'YNjG "@7"/QO^}m&&sr˳DV{-xXᝯ;k~ٲ׶)[7lfl// vW/hK{"#} HM˧%rkd'kԙ)aA=8)gX GLs6GU@cf-5\L@xWCn$J5YI|\ 6@Y<ލl]u^,|^ |5/ikΘ(v>V-vjhPA]QJ2FMUoقઆ5QV+ ht[4>h_4-XhhQ"Hj_4Pf,Z7~Ҍ`hBHR0?ALR% l;73s04Ka":x,IXv51bL Pd⺫F:oNn$]O:ٚ*uvm 9ĕ3+vg4WΌf8o foj=kVa8x崿^]8q䛍E8!O-5y2҇?3D }BяR͙+OE. !dk[@ Sxs.LpɍQ+S+ނYS9noT^y$#w5[! ;P Zq 켘-z<S3C 2bԠL5'4oAf"E#>R9ffM0-4M4ՓfȣeVƫU_jLe,?A {#Wq]!_asD F^yIzKVS6}A\yMJ˼'?r2|ʩ} J7Cvj[X@5Ns )dխs3[?0Y E&(;œ_gɊ_i#s4ǝc:c}[Hr sղ"*CU%]WaJ4~1EiT8J4!mZ CEljU5戴2L_N 3Th1(Ugi xm\;kw39ԭb,0iI+g+T`=u1UPNYfc9/|W|{$N=q'8+_?Vy4 Dod'l,I>4?6H826A+: PX1W)՘#YHۻ@*n^{ڴ=T:-gnTUar)o}k!6&vԒ"Io,%aR,0?,WWߛU5Hᘎ]}!jB3akGBP2bJOyo`S*3nn;DYIUGmIzgq;Fx%q#hG&n`n="BC̚R6C+}J_Bu肆 7 u+B<˪A OY 1?fT m~rR#_J%fV 3ijI$ejWzpJ(LPKMX\b?TZz^t24o{>.<$\*7|y1e[kr,@CD5>^Nq,^F0oKVϫG+;Ł ^u~uk kEl4i ,x7D>qM$@/ŋ,iAdW||?3*ڷuyJEAJLuLKO4zSͺB8Ws)^~dK~Z'⅋ wtb+}{ DJcLXb.n2#ᇈ`2]/X@Cԓ7D$O=f!/qW3' 5qŚֈ%zxs}!IǪXT <t,;%1Z =q&jH< OCpӦȹwtTS(T.cA=Y,62n jg_'tTo> VJ/;0]яPːXh%o9)SaU]#y1^Po#,o4$w’S|h$j\/XULz_#Fjge+'4ʒ8SD`2HQ>,xKm- I8gL[N6<1KFl.xr EXL1Ha%c뮭+,\|`̇U䨁~54"+Zpp5 S| E&\M0jp(H#8FP.0 <`_q#Z7(>'1$I$G <ymb>=4H1IhM̌z Eژ7A-ɹCRƟ"G4bIBI;`Er,Fb8JzEwRbv4{(\P],ATx7\h#ϻK9e/Kx+@C̣(Lk%(:\K |IkYLo4yN7el0-S9v&'߸ ~a!b(z%](4M]:j8 L!Ed( -yx"J`>Bg넹ʅ7iImu !_"PbNg ܫNFb!Ƽ}\\4>)>B+*s,qAFn.C W+G4_ 1xJK?h `U Jj3R;_I}CJALVMo,l3C=(u00gF(bC'v" !F㿉v-ρI|Bu6>K aԧpL?7eۏl;m*^=ko| z>^14OPCb\Z5 )8U_k$a0j&KGʼnÆ/ňYYװ:BԿo|'e] B \,//=wդįl Sk4^A"]aCCҶU'[op­z>iVIЀfG%0qEԂh6Jp%H݁K S /tB?;o 4Lfl^IAkΑ?Gvg^_Hg= xWE2hP/ӌ9ƛhΒ.If\]:@o*|D+xu.yJ:T}rwIg G:rQ cSdƐphoF☵/JliנhIUQc:J~/$._t3V"hD ~yv;\JiiĴOY⤯x6!w"i:4OMb>BCiEG:z超|?ԫA#%^4ԋ)XB" _ܣ|SH̎Hm  6o|Ȏǧe}:*|V3'랏$` nb\(%8?kDԒX4g.+E\e|UW\ҲCMՓؼ_OCC:WQxU<Պ>6PPn7qL3hY+^xJPsK)tQ7p1^xcc nGb70vԴPa>{}~!",J*\|&ݠjMѯ_W%*Mʟܗ.B@zƔhDڞԣ|HK`y9 pe2@'_ZbAfл(d/V5t'ۊ19/Y  ne~Ŵzǂ=rOBbT ~6<>%)2 5~^򰶷$k -՗=(įzd-۴wψًakSqav,XixFmgKHTB04_8E&kI!ڵܾc y1Ir*"^'V5 cm8ѫQ_H?Al o|Ďg]?7A\k{W*oVE.-Z|E(tҲXeim(^>gNv4hO#:><,U%SCý=Qfd2t63+7F<'n83`#q|,nug҉ih71`C&]ż_+ A=."7!I',%lmi5{G{[Py;D?;ԯ>"iVGORTF:C:Zo!p!_`g{\W-|/4jRYi fNo3 Nv@21MYyi_iAചBȑa ZU)RᎭkn߫.ֺic؋Z>ֻHo9Ѷ<}vonc:rYYV:oʋKm#AOWGKGMB\/;[-yoV:$)f fߣi9;${-F=1{_ ;y<yY_1_MzϞ vkP5>iL쩶ߊu=NKE֏| UjP*nNQxULDS$R%w$-cvf^H|'PP?Mo^[$T~Dw#d;P~zižUpLXW(_}_?̊JX kRoxM~-o>kZ1@ { 7G&)XѯfhK3tAګŽZlԎ/VD>嫏Hhf>NN.UTn=g&~bޛ@cʼ@>)DWRWzHKʺ,uHs?"G-1=3rHs~545%PD;} CZ)_}Dv/f>qHFsuH WWI2>i}|<1uHKUXIii44]^xi0y$F#'x%w=M{k?[` ]8*}+ʉ,pˁ->6m?fYYA=ڐ&q|ppzqDpKk~jD7E+^8*f %@`丏<Y,ٕ@2bv OotSB' m~h{X]N&i>4WSpEj*%$wX y,{ü;ԏ>vx)ovOI&RG0vԉḄOʻ7JBIf"Fai]tLuJs)%Ѷ3NWjcҶ>^Is5wCuc|G]e$)_HFΞzR"(:"25?(GSuU h$Co{Exn)R;.rMx7>dӲbտ F6F|e sv#H-)jhbjiGt[h[3DƤmmgk8 IGj´\ ٶp P[I 4-YVY\w̍9VF0-soA $@}4j`1XIi_y(bc\,V/Y GNB XH x٩V}[h_:Z[1;Okޫ~1i[b K~?|ĵXÿ~-w_pA?_GA ls{?':hX2~rn|k9wcvO]ѿFR'Ck\I[!էAA A+̢\K}!3Nԯ[VM|˭Cm kU䀘o M:xC!NTgTL{d(D$T9K(,4;3'Wm1\Il)Yʋ/#^1j>ZiM-A;B[~o`;@`#"/i%Z}^,|5_HV_wgSPv? r5w |.&?~ȭ9",s1['o{JIC'mWZkz“+SEץ`5ڙRƫњ|`+^RZI٥jtP l^5giS)&*dI)GԕZO΢SJzwH(qp>ж>x\*ռ({J/R2hBߌrͯE){.:㫫9+RG ӟ _ug\(5dDZnB~?䉖.Cs<W磔Ec [Ϧ㕀[}ϫlzBL jC5Bt|y 8u|R]ǒD4(/+ oTK‘6RAjb&K胄(kE*\޴>Ј$4+zS endstream endobj 54 0 obj << /Length 2342 /Filter /FlateDecode >> stream xڵYKsW*a8;$JX*C'Y%P,, >䷧_I{g҃珷W7odV*7v=KLJmfUbj~6ۿ߼uD,A,ɼtݶ?!_MIUVe '}^6^ܾ^b~I e<"CDŽƛHMfF ҶXljH|HUebCQv\g"%9Mvbw*t1[X`_XPl^ ºdy `~>QPl+ ƞRVJrn;Y?~TUYV%QOY>7ĒYla7Oïh9N , /'D=AP,@" jOYw7 -/9yRtbeצDeMfDw;</t.M(!#K8jA/Lr]{,JYgT\.`CS+2ہ- 4rT7+y؛ QXs|/I!%x \OS2<#S&AqQj]OILU>!Reŀڱ5?i9(8ҪڈL>I*dt"w'(.b*'`X+ro%J N%:8 ?RѤvO~A\s{^q< 0H>2q)FDA+^?T (~uIxKQ-W8x~ith A"}=,2n |:{BkWE/'D%rdJ,m2FGnh%5t pL7w^aDI7}dU:3oQxرiip  endstream endobj 64 0 obj << /Length 1694 /Filter /FlateDecode >> stream xnF  MMhH$B.L+BpE9~|gvfɥDC!kY$H~>)+W&U^Yie"B&U2HN&*n"` +W0a`4'zq="і_M^3!ʘ?;?EWa i[b5"}2[5O= q$Pg-,eIK$א( X=DPhɭCC=d36%4&$fk- 2-0yh,Cگ,XOZmqp @Bʛ812WF 竚 SDɵj52&j ]N!P+ʓ,w/41&o{Jtb|<Nzcď]C(ATf Bw#e-z zakrEKHTiW*$ZN _\bjs9R9DQT7\"kt.#2; X^nۅ?-4JZBC&8. ZBwdD&<2wOʂxzŧ9}p,L:j_V^߲ɐq.6[o6[ʬg¢~o4nBmKvsΈ{-UzCfpO䂠jCn![ذuKOg \^x\3^;u;<6 nֹc8^z{*>=PҊarr $PB-Mi\Ջ]#u<7C0P}ތš&j+8\{<羢jP/kba?Q//< ӷ>0S!^¯eˮ}6NڡM0x0 vh"@DCWo (v$twҝqC]ŇQxk ] $$D@HJ( \~Lg^uC">iT1jj {gs,vx(sUrndyJژA G7Zscx*_Su 4 .x;dM"7g&`]&}:;(rѻJ =rZ/w/քϒ|gl{m@e<;лr{CG%ƉX5˙G_>aLߧGJ_2:!0}]۰wQpŰЖ+W IXs endstream endobj 72 0 obj << /Length 2185 /Filter /FlateDecode >> stream xYY6~_!d_@!J7 `/l~t>&'Sutk&x!h$E27Z///}]TenrmR\[&*j2֥x賁l'.ƨyGcR%=46B.IӵDU}kozXrU,ZP)X C젞+!Dl[xrz=N+>c34=$ʧJߡUt=Q UN=<2!k\d0*m^|uy˅Ox`FlfN0vR n[8!{dkV[XwQ! ҔejHFG%ny;V~֩;Yiri}N{TI9.*3V`5,]1~ :-Q%k~Fc3P)]Z4 ΀!-6 L/Wyi'E.h5-[i})Z*}}.@aMf!S>|" \,c.'յءLؐ(cݬ#/FeWe@9p-ⴊ<|P6L1 vɒu%}o b>xu@qɔZ$okTpEmOi* FJ^i+I$YܒJUaS(hջ- F%:jP s&A:z |*Ǥ5uة/BrX&'V@_v+ֶ] 2^bx{C/XV1@fU39ڧ3\jp6x ^14@ykҺz gtVP@ Y\F?㟳}_f|fX+j YڢR-+@IB!V} {\ J4;Ix]efC/[*9l% W6_=aU<$|YVeY NW)@Ms[œК*dMǶ:HJr2n{'@DŽB1 E ׽N3"3P' Gրkģ%Ll:;~Yȯ7\~q-BcYO5:Fwܛކp=c-K.4cUgXSk\ݝ`,w?>1vz9JPt"B:XB!QKmI endstream endobj 79 0 obj << /Length 3004 /Filter /FlateDecode >> stream xZKsW 3uRrA->dRU3M{7H1~Prr;\ȃ//^urRi7(mE%K''ד_7SUl ECs(GǬj./VYxCk?tf-- z,7}؇7h\9v^n:e_ ZM/WTBWa:Ӯpj7y/OfJ,67f Shp˷J 7F(a<(][}MV||$#h sdJYmxsMps@׾vl!zdt}l S g D.i #]FhYcZTVulyEY|-hxtV$Pp+l{J%ERΪW->#bOh"A!}Yp:i@zx]/tj> vjQX+𯙮 ZY?s8cOѕ%'BD&</̸Iu5-]k=EzzgJΈALhlx`Xӆ?BbF/D]>B9jqnq{ }ӀF$qp&m~!FmՔGxV̙vR!Ӡ(YtMyC!^@e0 \a(Ar'f40Q<8a5'mCQ^ˬgZ1V>j%O6]:{f ppS~~Lo xs|60oۭbZi)+S@phf4>a<$x[krZPazE5RzJ̿%Cy ,qSfFY227&;Q~a4Rāwlz,FG;Ǎ8YK^vq8Hq$턮}\\oբ>< Bi@Nq2@g.b +s,bǧoi"ua J $Fnyfų󙔿{ G[`ToBպijbBm$+>a U.q0剳q9RU:^AR%PE{or5N~TPya+=>ێi:{Y܀!KB"!ł'd+/d="dw 3_ePq %N*Ubin(i{J6< ݺԦԿvA '}JܰwIنܤ;Q{PB掋@M!ܥ cC6IyZw% 1l<䙗w1Snbbѽ`v]  ommr:""iret XwҠf2A06}&4'"ݜE!C}`\ ːi9f𩛰 )z+zNF@N<` d,22'jo#8XxS.a倕3W<0y 2DMk9ػ]^\K^䉆.'` -&.އZG+UxCIFApWg=a˵aG8+Fhӏ2^1]Fd+32(sf5l]8H>Su]2pRWF\A!EܱUFXs-@ؚeg ?`z##<)uJ'_`l ;·wi 7~TSi}0kG8*MԌς[Kg!&*_!cB|bxŸ9^|8>]oTs oc8~nE ի}BjRwei{WUٻY:jFxw*VJ,SyȕLaZLynX踁}:x(֦RjJ!hSߞ9~sh A@.?a!*'A@B*OBUg‘~rԧRf~QN[6upwhƔ[iXR{0|UriMMF˯CZujgƪN٪lnF8U~5F=;ˁvJW? /\Ţf\Cybah $@х endstream endobj 88 0 obj << /Length 1992 /Filter /FlateDecode >> stream xZn7+8iwJp$D6X^|}{ݳ|`!/0V2U~ˋ3|LoB1?c؃p66Iշ֮i",JS=d.+tQFȬvJ#T(1%z',{~8"Dę&34!a"Ĕzq, Z-֮HxV^\/KGRaW;ThӒi ax3mߎەӤKBL(#(UR3 `AyjH9Z}DBHj'w!lnvل[&<T-`qI,2!(1nEG?̤1&^vL<31dx28mVXL--ҀNtgɵtֱmGLRJf4$bQ&1C$I1H4 <"LfiE&,fXDaOew"9$sV(@~0ꂈjZ33ϼbVi: Lb)$VJF$h٭7ظ8z}Vi& QNYyBT%hGgv&XjTBt)Jf;v&(Қ+s5~P&nKfXPj{ B<[m,hƽ7A~ v|&Hf&HzUjǰ짓MN܆|0 \#"8 m>g|7 mmʵ#΀Zv--MRv/7'cUf;KFCl HqK -V}zUb]S$d}0K:#;೑2fO"Vrǵָ87D-Nˑ .` #::/I)RePdwWg#0}Onp*SVOЧڞ Bd v<Y)2A74b̧I@>䟀$)<-o-gt" endstream endobj 102 0 obj << /Length 2115 /Filter /FlateDecode >> stream xXI6WTX#Z\4I&ALP4=ȲĖx Zf [[?>*-Fœ@WO.GH c=}Qľv6û+ <}u܎R?uhZy?W':N%lqf0فE#)|k,$A{ ~-hvX'DZWyì§a 'C=9EdP.!n,CGGz3ڔ9/&U>&IĎ&J)h+K³Y Cþc[5ESp^>e@' *p^L%^tl!4> ,I<{#~X?$IݢŮ@,%N{$qLR0pFOCTQ)l R ɵ.s\͐lns <,yg" tp2lGߵXb yĄ!&)/: Dٵ[ d?)iv\ YCDT9I,)9ϱ;mI,Ő 8r"%SYX^ySXDHX_\Ree!z9V0Ǎ07r̄=0l%`Kn"n$ {^.s3y A9'^*q&Q Td3"mOrvv/qLpG47% ~)3C/Qum62^ҠhՖ5cH|w( `T /$U+˭- ,CC $ >p%~'٦8L+S~z"6$#E9Pܠ.Ee91'rЌDICRW xA}'latgid$7|n 8e%(eyu McxtD$ɎHgu+% :|d},!17=o*W-}]q*8d1t8\t,( 4E/TӶhgխs'Y2V_כ~%srpWQt6BJ:̯L8 &qQZGXVPAANh;9"?7J P2s_NM_eI9u70r3̄qU4t^[~@ O통4sqďI.nӏ%D~Rxb'vz @@*R~O-ڥׂ K/dpn-<5⢢>(b |}6}nK6}V2KXQ$).P)ޗQy\'r @V-wMLJI-V jdlDה=WR֕j*+x{>ޡ#|;z0& ۺ. fl} DT|@vgWkw\I೩s\i J_<$m!sp-2>vJ6gRMַ**ئ}7+gάi]/ӶsIZ ^&݌\7Ma*d P`@_tuD[vwa|>1yHضiZN2^PS5:I4qu 2BiB(5^uuKx'2*M#247GX>&|Is] mp9: qɥ }x=еxS(7Gibau$8処SԆ::w<@liQLZZA,?Cv E\>%w%"7yJfb'_%~{];A뎸x*sR䫦Y9Pڻ+oŽA~?yiFӐ݁ovRt;@MG[wvRqlž=}/ endstream endobj 123 0 obj << /Length 149 /Filter /FlateDecode >> stream x3135R0P0Bc3csCB.c46K$r9yr+p{E=}JJS ]  b<]00 @0?`d=0s@f d'n.WO@.sud endstream endobj 134 0 obj << /Length1 1836 /Length2 13325 /Length3 0 /Length 14479 /Filter /FlateDecode >> stream xڍP\ c!6.wwwKpii\$Xpww #sz{s1׮P`3f6V~.+FbFb v3*4*v67??++?`g~9@ v H=- y7c09[8L V ׌f&v 5?! G~ ݝޅl)pXA. g79&[cAhZY[@MAW xАS82Vˀ pl,l t613;8xZ;X,@iE `` MbjbmG?¼Y\lor Q3uda`nG殎@-k'W6"d r<̬$tdCڃ#`b@]AV/Bbc[A KkAw豾ҏ O 3;ycuduU`737 y}8&/_9 0r_ XW]3t?V$jg/unuۙ_u,;Fkik5/%c@`?3+ѽn?UߔRf`?MM<^q^'@0ڜ/ljrDş?tX U\~0j ?sfcG;.OYew!тW7= Azh?.YT;:<F"L}aIuh4>B"5`$ߠE/A>oR7q3?no(GK]фKj]?m4ƭb!Ii/1tIڐxGUٳXgt)ik,~%SUN&lj7 s@gjNQqrbADw|&oVh%d[ Dl @YH|:>Z d*W(y )&0JdxgE)22!GIۡv\Ҩ:[lAdϽ0uG#1vZeDo?^蹗m !~5."(j_Bq1I&52NhMc-E R'Y~gky@uD}>Qj}ay'eBXmBwn=g/L;vE[v˥ZKSNLdoE6Q"T1v️H-av1VN '4Զ [r;7P mcێЁՔ/ޠP\H]J9*GcY$+7J Eo8 i ?'/y>*;3{?L-=@\Tm c%j}FKjqh:q(\}Sfw׼7*F]F1>"Ҫ1p ܥ D 3 aNߙWRQ#eM c{%z`UhdTD S⥅ͻأ!߇Y7VTez {󔳟b6;;n,]&8[v!, yݚkķ K6$Qm*(=qtCQ$}ni[sB\ Ygva@`{TE6vOTRO\2:P?ʐM4+y:VO!!`[Y 4 $ׇY2l3x0 <YxuG6+'mGzLgɨ,J\~HZ,pR-Yo|g__I=ERر($rF(:C񚄅;@YEjit%YQT:VPb ,W!GdyԏV_pݳ>zi\r؟K3Q<0*<)6m4+xBo5M4q7+Pt]nN R1|ޤŚ/UG+Go4XU$iij0FJ>=;uho~͸mqMFr!s9x})xӄ.lRIU[mD9֯ ,k$Ǩp>le4贷͙* -2T;G}*l[yyȄCCAÎ5_3'sID[2+ĥCWiHa׊[ Kmv\ -Bj6Mqkb[[&WP)hHp:[ JZ3{MsY5՟rkm*zqF"Q:! @S$J:IrwEV:Ct(}~68pB86l<3vˀ1y{|+^Nى ɬzG>qtF vь-NЁ[$Ϳ@P%-'LC{wm {`Kյkwy@k1iǪLt~L"[ )D+}c5,NA]ǰɳ9vŹ_kF=3ң=_Blг1`+2qi2ab ALņЙk]B;Ȯ.֔A1L u% 62?P~z7M6U ?ܧRGsSMJl:euj|΃xF)E$1GZ }gH>4kޕW*Jl$+&]䅉I" g񐘜EءU;/ML1x?/oIѹο()B@T2{K~AŒtDb \o+~g\ѳ %I8c42-;`Mc;YGfVvSE\b(ս^*sR:X*gso[ Ӫ̶ÍST~64>Nhyqn(̙b}SH}gY.cupM'? A*!)#TcDC`m/0[voY0~=38 ^FS0yTB؉L#te }W1{n"nDXB(ɑK.,Ԋq uLfv8-+6W;62 GAB;O.ryrLg.9[FÎ6iOjChM6w]ɀiT3Nz{ȅ_Վ"4>Cw(=$iJ6 t$$ӡXKg^R<5| \o8Ȫpw B~_ɒrܨݲL…]I!# }&Saet!{'1sm \Ԁ+Gkz/ `reX;M:`CR` 1A5{>EfMa&]#v o ي$.>ۈ~S!3O(ŗQ/BK3G~1])y6M!4|<ʣg^~1]_`(*oxt!@Lȵ$YDFffZ3*-8FM65 "S{#|vepZ_cFF8ZMU]ÔgE:AMގQ3 [Z 9}mk)&Ia}FAx`Ҭ~[0W/%c|\v C/*D>V6.j,Z]z:4}&y"Mm'ųF8BoiSL5 _vNrג#F:)CEM8zyyjxJgjVG04.d"4x]:JU%#w#C{%LfO/=G"q౓2F+ُg񤿫[(3N%gZ3 CoT/-9uIk/ =rAs zN|ZR2-ֆG*f2~m`@_ 5-|-"1Aƽt*"PԨ2%X9.\P䗮_g-awR?sj(8tG۰noR f?IJR8}o.K]p yR<- = <4(8z6 f=O:n ?`Aoƽ͒oQWz^4KkKD-]ʆx,]M>~ʛK;UB9"^qTP/:uL 'A*]P^eXQ  7ANhզgU o}*0(Ljtiy ,ɚTJʢUSsSsB[0*MZN$f:ՙ(b2,GDKD˴GX?O`n~GZ)Cgˆ pO|?LbstB [m!^ٻ?x} W .?wH?]#Z֖(Q}as1*FH>aq(#ֵwc1S҉)g;2պ |d=Vը"{P.!` )Yʺ 6e&_QOy@5QAB)6*&ȮmS2* :YU*9{"疥IٟUaDGkf45D#OLZ<j"ܨ/:vSWi7 2*^gTuftz◶!5D?NTԑ5cT=tg/37+9o‰d(ers?R+fM0 \?.Px)5t*1tU{[!^ˡz 91^Ra4j2x(LWfq\K`*ivϯL ,@m =N(?^VOeg _M8՟XbMl)WHHu7@ȼϵ% lhil~W MvZ3 "~>{P a|x:'Oy[`,HΩ5mc+70REd_O2鋭,|O3O*bDu=~s59ې~npy"Jٿ:JAXNM"͂Ubk'g|Ѹe=zʕSS ($}|BvwPLr0r/("X#&&0OXV'2Fj/x3L5h^+eIou4UrBPj^B|nT"*o&FѫG]4%ZN3kqEj6n*Q3%VKE5uX}i$u4DiF{-R\VGdFC!z7K"0A72&_ aɞjv1fͳ8O4zR:Tw qRa1ѻ44_3,Alm6^X 1 Lp7#O&uҿY5u^Y_3f;ab_ٜo.Q g|1C Z,(lz{&@!^NyFxr:rz4C!{z]MrІ.!GR额h(LutĽr 9DpaY0.;6L5A(o' yS2YQ&ᰅG H9CECɳ+Ɠbؘ6rKd)vnPCf)\ݳXI^L .$aZj$Q^R/wͪzW??y @U,s*SMp'fe")v߅|2| cUg*Y+$:ln%BtJKTMZQG$ifL=Uiild5eh I+,1^eS7/:v+H&m<9w^Ȫ SPa ?"kD "sJnK3`&֞KOB[KnT"VKZW{熍}Th]5QY5H` otZM\Qѝt{3c;ZJ޺ y:d[+OW=}W3FB^.jyt6T煍N'䔍qWo Bv 4i7:2DSu$uܾ NΈ`T2 ;MAF빇[ZX!3`^I`63K~> Cd/ON2%eFPUc ZUXyoFΞezusu WxVWLQ[94}s-d}!HCoLhnA=ܥJ8?1ay\F&3TΘ͆![럐Im@lI̙C/ސcڬĢ7}2\`Ԋ G磋j&x$r&\8A1{aՍ>慁6p)[#,}]ȹIxUf y+Ͷi7C~Ac'1/}@#Ւ[j~N;-|/nslIGpxs t[y9"uySRRZΫ|B,>=LRo=|sE9x#,-ywm/kG#6qoNkў Se{'LRyK-/~ v5hO=e[bUsqG몖>GM 0WsXdsh` }fED6@P4m𼳛jN,2î ?M iflrOpG* _Uڮ|;Avt+;:kGߊcq/[6n}nDRCh׿r&Q/|m;ڸ:=H'zGRz_ #]DXRfOb=Ԛ`'|%7c=Nkt0P0F/9gP-kVz\;0sM$Z-3^9˝H1+=:?/)J]Z,H0Ҧ,-HL[ݩ3 \3ҷkɳԤL6ɬy@v*OPçu E Ik(>xf<~ л }2Wią"uω7ЂC+/ ".s}nJ4,pGD\1VXoT`:\ȝe(U'H1.Hcqi䏹Q~Af Qگm{ls٧;/Xj<1\W m&@DZH]: Dqmtwp9G/,}Wr~w@,KX׈ç"]NŘMEIT"e$FD)mN᠋ѭ9oJqiD9(M5eMaVo.[@BB~ tc:/1giAXJ [^^-F *AP ˒g&pj|Sm$@,@Vxl~iHmrp@Wf k]^G{N #Ñ9\Mҧ{jQu>壻6SQKylA?`p 73;gBejQ_Oُ`)SςZisW]0_a,IN3(9<~\"84Fb'!n*٤,؆¡yQ+=O/䆣<eu`6&O=n831KNm?/ f&@!]3$֟gnstJzѯ{ړGS=όlFzaϬ4O:$jiGn;[<ᠾ[wdb4˛rk1]H/X_┟D։v"G++;7FPWLҸϧ[[<*(A"#x"/Tf!)73PS 3{fF10 ŧ ci_d}]*E"m֥L WD~"Jv O4)yr=pśJaqB"7OwYn4q\!>#db =$H[h ˶J;ax7*˨ 5:'t[L:9JAG*5'/ ՝IQ'lJ}!ڭɗ)gEG?3 z9-'mqn&Dž w0JCo{z!jx' cX{k9Icg݋lLZj4_r C:m#Sƃț'̼1;3&# PZ&lOѝ>ϥWCQܣ"ݩ݁0IqN%yF;+Bu Yh4MR]\y|deLƹ|lϬ(נLsãp\J@Z:`cGv[VOK}mg}*)aY2 X4}چmݕwwSۇ %%YI2nn"W'%{'QNUqP5PMW1}+3 &#.yrwoJ;avTwژ,M,t~|A G3c=F3LǛKϩ!8A݃LGp4QٖrˮVKȳ2?u&%.'QAB&$֭73cޓ=[N,ӅbFxO$X$_s.;wSd}`1Ü  U]רS]\E>ݙJ|shԗ $U'Rj%4 *|*$%6/ ;^/ .c0z'ՑZ>;-[ jnvmER>f6ZOo_+2{fÄqOn|w[gdiشARIΐpbϰ!pvt%V\}Oef8nW qvH}s;o|`r2*H[.o==0_ :JB:n^T4k j?-% n1W{-IO,0X_hwPt)BVr ?>.VR+#gu_\2V9|XQqfsƻ彿8UuؕTSZC?/nUi!@tj-X_h>)X$W@)#߸0`0ۊ#W*פ> stream x[[s[~=oLԵg4&F4u,1H Iq$AJiIM̈888bwB +N6h""i%}ZO% h+CAhjF<N Y)00. c8t9 g 4^"N{vD*jʬ2OC< '< 0?8L&/c0@p*!q2H|@S#{DtS=OYA b"HS*)TL&+@,b,Y;b0 ұIEߔo,3RׄPߴ\5@lД SjSI0dzi T0{o02E4?^Əq AD`hàhRHDIJlRW$Ė~ǼmI#Aw_-[!<~&sqdb<>.z!l6]M]GVOç_đBϾ3xrKxk@>-dz|+<~tOo7l~t]GZ+~J՚RCGK[21!wj밦DhŇi\> /WF)PmP.3$<Ъ\i f0g]&hCga󵴽|?-1\cuS ? Lu:|L &)qw,(;2U5]Ʉ+ȻYՇa٠3D~b:+Gjե`6P]:nr,|*^G%_%r~xN" c7gWR~-}7]^ve(5 %/|!?bѝՍBφF#Κ^N&@] &!E .mp,tޖ\U=Z@VQ*ܗ+, +pDH{j$Tj$ ĮLHJ !Yzᝠݠ1h(d:X [p{"$vx,PTE+_r<ޓ%Ts_ SLl|L_fg-gᣏd<<_̦MRT!rTb9&#"}+%,Yn=]͊kJ6ˌďyGQczuN]Vwś;_NEA)|:ͭlx.Gc2|S7l1^柺D6Q3hV]p9߂b;!nיEEuX{TF,ֻl9&.}qeBh˗9kMrnpA,nѶ`҉go]E/p#̶eG܈MBqTwqO-F3mP  "6;"ſ)uE6N|H'Uh#ՍZ+joKl-X X,_'#6Xb|`d+oDc+PЪnEW[)]9%rʻrJu  cAzoEI.@\蒃5* rMD;]#})Z+=ja+_4"Qn^xKju6fKwcs{eֹj^ƻpsp>oRr/b8:\.D\LfsN/rX\汑u 8y@V&B'8kJ,OIY0a(;$ -! S꠭N{8n`P|eJ3FBA;Rm~;a`zll 7gt۝AH950X \7R{ֳlw( QD@;,RmRkۗv>u}Ҏev[5s>HA2.JBJwB.NZO|6O2$*#G*6ڻa[tאam rbl[g1pˡVJ&M/%ھqaSXdI fSCWXy*<ꁥLq8*sBj3>W/H$FlfIGHNpfֵ+N4e@W_c49MrvW]g9ҝ|)ptM+'Ų)A19;[mJI) |9v]_MuʮnW|.c:b6JS?.POBxܞX׫iTvb<_, B0 ۷'˳_烌?MGThSo,_ zԠF^y?%0X |QFVu[e>/\AO))߲,Ϫ5Kdp7a(eb90j,a6kW5֎ִdl,-lKVktBܣXU{̓ lqߊē5dS+h6ݭ5,`dUMnlpTQma9ʵ%JcIe0[],$ŭ^S6L9ԕr2A{*{rg<a!\[9GEƱkmKTP:O[0oig]Zb4쳹oahC\UUWu7+xޗKx_r^>zZdxM ň! gËlI'xdz:п]}vJOLʿ_r(ɑ&> stream xڍeT\-w wwkp)B ww5[ ~UkTd07C\X98Rʒz\n6.ZZ--?rZ3"/ )'E& ty1T\mN>!N~! 흄@79@ `9J;x:-\^`g ar!e%ioxWa+!vvwww63(# b9@-TvZcChYTh[@- q~qq/JUOc? X wCp9!`%l *x߆@[gl 4}1t @VB|͜.l`=2f>ie d[nՁ]vtKe"BGf rrpp @Z?/=z;;,^-@/og  ''l0Y!(D,/pЏ !qZ*zojo r|;WC,2ZFRa. 9x9^~8G+uCGze\W-P\]I{[ɻ_vAbiβ`O)h`Hjrrpel^N,ٛ2.^> B%.^^7:<`1 bxi`aD쒿E"~?H.7x?]Eo$`So$zizi7=7vAN;_%?7K `|oR-ŋ/|_P K r /RӿK^./rW/<3W';}~42C7{b]~[-Aκ5*2I= 1*#hZ"i ÕţAK=bxkz۽σIVu_ɐIYķ}}tm`[hs]0pn<꾖R߮SD}(``X4Ek9MHJĄ}9uu==Lό{]୿s7TMDCOH{=? t))wv"Mn.rj;ۿ6-ybɹ7SmuR92zcY ba|0mr+M7sәNrEInxov75 I -z,t@~sOKI.؁sc]]}EH<ތ"#PmĠt$bp+S\-A4֧K1CBMoh0[?l9@iNB s2p}2UWZzppQA_~$ڲxGƻ{nWf\zMf3%D[-!rQb*QxL*c% )"1|X&ʜEu}+ tN<v'OCʺ;w;|m,t UJg%2f4j[η@ h>m!7MX&v"g>5.`9`Q]YU+JY!eHWO7"}`rg%WQ|D9'dՇ4,k{dUaLa˸F%GjO+8nlsԧeiQ8ۼL+ktBZ,Xٹ^_'T ٳh^$*H6C$8Xuj Vgk͠y1ѥҬ ]Zu<_*?[w g͑ͯ.j*i2T3eC%Ahj$2 EWc4*m! yTzmzΰNs2UJTLcaXĸ7_yzI1QO4UAhvOBI52;9:F!:w,Tq@Ce 9rEԆe#VBӜ)qҐY^Mð33h_& Yd,@bO0tS m,7у%VAvr]o6߬Ef;HtG˚\OER@rśfJKIC}w7tP^h(v}K`{Bo`Y?ujW-:H`lc+U{ٺHKDҨ;-Y?;wqT@ )̖Jg.jt_xIΆvOOց2ۊ ԙ_PO jg?Ӳ(hXTkOG"iEX("{ m ׭Y?9]]P& xmܴ)6ez&W_bk{[KF6{7TGY=wB-߾(Ky٘%τ {xNӑBsk3u~^JގPV4QB^* JKY}I'~Pԇ 'N[ֳnL ǻC"b2T-_qC\t |s@tѠrcCV܁;i%%W|n]݀YBBc3 s˚8ɆeZ"c!fZ!GV WQJKڭJ(Aqs"{!ϒ_ TޟJ]t{ }Il4oL>0l N q++bQD+s? YŘU.y U:Μ@ _*?ُ^~qP\WWAѽl!hGC=#&@ZKst68Ӎ]Eݩs뼨*ay,c0hNŚF~X7<3dθ.W vj |.YSHb_tX i^jit* H7Pv~)]O̓z, ,1~D)2M?2(L$^4zE9c(#CU(l?X O;ך`%hI_Qk*<,}3zsmZmK:/l7fJY)ˠWdpc,/ò8OB)o g w6.rQ}η;殺`O>J&r,ͭ"ʔAGiP7M)NJM(HK1ltjPmJ^6GﬧDXg t]uiIPRMrPvV}uv#8%7bm=:9Ν_S\5 q^rUGJh㣧E3ռ=kbI>oIpbZd|j2BCAm&ٶ%8|`Y8b}اuZeucQ¥^t:By6"=4R&y$l* G ثǮ:kE#iéḾsBƒ~Vy)SA0e#0' ^b+^_E'oڒYv /Sw[e@M`M`XyaEA#c)H])IP֯o)+֡J4 ]uWʪ. Ei~OlRD^pkyLA .|<m/O v eJY9_o:b=MEoBD"X''  kcGyF>$XjS7#I60) RmУlstޙlQ]hizhWu:S_ú {9+%">ZZrex C>4ws]9ZOND2\D=xEZciV'|,x*D<6 Bk6?XiiE M=.)B%}OIfW;Jy٘fn*k'eVs!A/. V+$ҩ*:#J7k5^q${ -vX?UɸP/?^2G:'GAc2*)5$7;(|ٷ nSIFV£2|ltsN:j#aW ܢ<1jae5R ;s+`kdCX^U0@H*oIpS;llN!& bw|Nj04>)<ğ}棋oC,kOxܮti_m08Vw l9 ~~/~` ofN?ZӇ6FAjBr$|r+<<:ȶ(rȎCwVX'-59ِo°vvfAE{!6hmuͼ?dg; #$/bhG[)l,E}N lfRQzR2T@kzıQ=AŤK%hY7k Q2ph8a2P 7ʾHpoؚЎ9h>~yoxې1Vw6Ŝ)$f U,ߵ4 RPDuT ר\ a}x&"obwiC} + w5,?bG}2f q L o:YEht|F_JG_!/ w^EWbo~g#ݏkt7,q @ 5<,PU)s·Xރ>h@Ke}w]sWJ5/#,]Fr4yS;+8ʇ|L][uoUe.qkzj%Eaشp]4͆$&s!S^D71tKD>  ^[ѐPO{Ͳ|#^WU#Veb ;V['VFje>Bߐ @zƦ浛FWbۦ՘D譝_$iCܜ!oأ8yO+9Qx^g_O8!`ΐnG%ɻvX"̱eiP>N/by4S&I9CyzRjnkX)^M\ɘyXĒf&` Wk뢦yp`VVjA==og)qB|rTj^H45D !XӸOd.wxwWTS2΄A߈ k"~b+ <=,0VW,PR،^0A|CӚ\¢ 7b9-` nu<0k!j=&Msc 2? X6J^mK!J ;:PcKѺW8X7AD,zJrj%b斷ph7+zW6Ny4YsLBOdxf<`)m}/Sr;Zm]62z^$|ݣ@Dtp'Vx[{+&0+(bbc'E/>arE!`./4,<1ql&i6/<>ީѺw2sP ~<[wO0}Y4}7)8R2@Lt{m`qx}#/.]\*{cʼ;lە6DY1 B+iTN"dI:`W4vpRv)uEHY fTq"as[!g@mP(Pg훩El[mi Gʷh CVIח(*!;e_ֻ9c($jѫ?I Tu 3EXێaXst@{Y׆?UW`es*H=lgs5(*htˣ#f'q% L,L= M] q`FTe25JmdU OwP'.xMQ&5;N]Ԕ|ZyR\Zbva$DmZP 9cy;R*[oOnVBUebD Uʇ<%YLmUJ{d ڿu_/9M(ݕgڲ:>Y e*qh,^⍳<#S0]Gf! :+GzGH|ȗM3B|*.x޲؈tUzδi[Weq;7zބa]}Iz#u})RjWqȾuj_' ZOTkX9]8|I%,awyc -%JCщ1NaR3T₾Cu"]wYq1o; !O|>ȣ[ !CNvC sٲg1[r7ߛ0I}Pfӵ9dPGd.ܽ9p[9s+i6#¿@6zB]&W _xPCY9$L:B!}Y_Uը2z*'.6?N:H&yd$j5] XtuFd9XA;Ug\㳆C,J@_R i2J[1t,'=>y"c(.s2m5gWmX!ۯq>w;pƸy7.ܐj,JGY .`:F|PxyA8w:[O?(uh/D5S3^R˶$w|n6*m9L+bG,8Kw|X+C-7uvהѕiX}{oGdjdoiY`I<u ^ RM!ȝG#gQt~=zo,^X4L|;cSѲcSk1Gb5⫱E=RmcžUIE'9*8t0`/2aK<"m K] X7,{o606"jp4`T>]0y}uS\X.XE8C}A1"(tV*Nsl{p!rHJY0*Y|.n=EEA#\nqS1Uu+B dQ&U󒁸ջa0J^{||Tq1A6MY;f$  ,2>ˏ՟àXd(†XQ̧ő0]SRXQC?qxb?'Η#J̈́G4V kp#`qڀ>^e+(VWY+Y)*Z00b gNfma72Ai@,GQBIOsCji 8!Fl~،ي%|x̠/qh%+ۑ.Xv17{. rd :hyR)| +$پܐFӞϪ1.~B~ Vҙ*3M .cl+k8}c\l/W1dȈD: |JpR넥ߺgNneȂ>qyY]\2ͤd )19HZ"xH?ƪ [qFp$L`t G4Qi֞C-^6a\`6[Eծ(?FlDƇ';;y 'sC ĉs%8¡t~Ő̡pȂ\XJw+ eiI]'}5agc\g;ܲ&ȈA=I5P:pأSWOz\ {%P;?_r,+6) endstream endobj 139 0 obj << /Length1 1387 /Length2 5975 /Length3 0 /Length 6929 /Filter /FlateDecode >> stream xڍtT6]ҡ" 3twJw+C0 *]4J  -(H}{y}Yy}]{_02R"aHZ$ kX PL%6aɸ-`(o8!5 W@}$p$eAR@ @Dp(@_pyq!=PpgU>HFFJw8@C>L8 .h0[rV.7 ~ 0{&L 0s{0E:(W!>( 0zl$ W?ѿ#NpwPSO_@7* [4U A=p_3Js@{OA=@!~+'8k 9Q2 C$2RqU, e!8] ;>do/ F1 @4 G;Qp-~ ?+AS;FSUDe$8@JJDF`F#XFݳQ Wԅxt;r;G_YWwG>?qE] Wb@7vaP{u+9 poM? jGC\b_v_Zs#`FHo w%0 }E.ؕ~YRAB MTBFdW|`@W "@BW(_g*- }Aޞ_TPWr̈́^6 L!!rQϢ:~ԫŽ(|Z>̠:}~RgF,U2Pͯj)ϲc[cݻo2m'ex_J"dtdߊuGҨ_cܻ)zqd$ "ǼI&N"+ ?;4/ I+,L.TzblĊDn6Fu#GLEbG祖Y8'G:l+\F5sG xg$ג /W}ZMK̂s [MA!!զTD.!f_X*I?AAґ ^OqxRwpt(5 El𞸅?z/Uf"|&j=:K奉F]ֵI<n{Tr2.eJuqfr.6moasT&L{[ip"Լ}ѷCqA f^=?9ni%}.9qysCy* 0ǀ(9+!Oytv3~v<o[t)V#vFp!\gL|zFu q/0g#,'~~et~6h(]6l:>Q>_)so5"*@pKru!vWEJ;M÷:ߵ."$o9#,:,-CE|4xcw\_ٯ%|gff%:z-^,*?*~?f L);n?ɶh )ySVƃ\mݬq"ױ&rL62(9$y6TRVsv{9InB*0~ʾJ>Bq}?&]~7.9f@ _X:OlY^%UJg-XcΩPi#k y;b L=)7YX{ڳmkthC>~ȀKgNfioQ-g 6Nx[Bf@uI*Cm ]g~2Bޭ;o{} 0b̩vͷ k(*).oOjel5x'Ns߷=g3U登NmQtע^.8noL?)<>1hN w д۩bP-|kIܺvGzֹ#H14:̘#+ b5_(o. d#yTwSu…y5get/Gb׷8qhnn~>Jq(䀃0gl׃TGY I{ Z妛Qg9k;*2G)ɸ5\=$I}HY)F?JK66;5LW"S]8C= ^҆ٷq 7OX=3 LÒ26 CqAulCѾ~#(QQVx)5U|C ~nЧ26K܏cO`pp- |#osLF;:7nY)6 #WplRVavwBɳ"n;=l,(K@v=E!jr;Lx.Vߨl ]{LeG 9mk ih"̱ȌѠD#2e磴oBk+o 3co1j6M$ȤM24WShE93,G;K hL󆤙-ucCw#gYPD{K~tu>v + 8-بC[ڀ>%yPFN|{ʱxZGdakZIMg L:\h^q9}g~5>0fqÁ9{9dG;Idy}hm~JZ*^5(l+ě׊~u{7Е̃qUK4H}OژBl8/mw;AF O{]ŭ5~{7v^ yqCCwO Vc{k)ܔ)TxCw/3@K%M60*ce+hU ~(\T?*o4fgynӈ`^-tPA2DY~jqmNufۮ O*Z%"sY0z߯'oP,G|$JĩԿEfp Xڈ nsa._8K L!5hdURpLj;(N6(ۼ.g7FaϘ=v5EkY&X9n(ZGg6;jZKkQ\jRoB<zGGLEWkD /"GͯgvϾH(+5s 0LVhy~YGY:=Oi2$HIMvxZmʒV kbEW+I藸/m)(aXKf?~z7Qh}Q7)5\P2Oɨ -O{)(TRܣZU/A>`1\3Ij9V~HtZkuHz>2^9#KD=Na(!}x9ښ>|}N,xI@LŜͬdrwO(9ފ̓M>w1|Oj]O"5X?39T`G+-) Qyc ֟CP2.J[,Q2:kIцITs?!4G^_Jdgٵm `H=r6>^y5،olK8ڄRS6GjDưw˕nϺjp'o( x%9hb"D-J:8z?sW:>rB)GL*wc13[.\"W[-=kxEhj_f'ܘbmcE8l\_H91_559xJuvG۱u"K=i LF<%p]mxg׭xKsUіbJh ׊B};bUH% ,Y62f ;\=WXO39zPzOC^ 9<~O F,sZggLq=\r3~29yP|0a2/R ˢ畞X?1MyZ$bi`JYkߍpM#{w/3(`c3Ea[M"q[ԅ5^Tir"j'WzTwҶWEf m ,,AP7M])fÑȪxWdLY.WW \\t5ndgG QC5riӻOȔTҮܘ+lMT ʳIԐeo(P.U^w]OSODYت8..|4T~,Ԗ}N{T!<ێ)UW›󋖱=ɽS'i/[.qߋo$ljsKSQ y,ugSGظٕ%wCuɒET\!le'ŏFv`P좔xޅef"VD6^.Jy&wsk͛&Hu%iNK3sL(,{vp7Iqyf(e?0/s'8Q?\OV_[q?V |Ux:𡢮<è$/OFgA\ģe9*ҋ]E/vZ{Fgy~y\DUI3e}hU-+Y e<۝QZR [YU-̙䭡ryݖA H&HވڂR᫃ͩm 8nUC q L&DƱHmΕPykjʧV\j(>U^`d/q՛ 4?8p@}tL|Ƚ+Q?/8}qc'ɒь%<)]؊Jϙ(4G we%LRyB 3cqK՗nxtݤt+ĝ:z?)g+tvRѵKSBvO}yk&ڑ3gbh 8{7oCLu vx:Q.hr1 ͋RIrVMEYNk~l0` =\ endstream endobj 141 0 obj << /Length1 1683 /Length2 9326 /Length3 0 /Length 10429 /Filter /FlateDecode >> stream xڍT6LR܋K@"݋C%@kqw)EKq+PSRK9s}+k%3왽 #Kmv)+Xg dԔ ddԁc2]\!P'1d\ 8& #jP'k_K@pB!B] 7@ ub2@a.<-Y\BBl.K@ ;"V90R00aNNwww+F `7wu#80:?Pk; @ `'WDk'+ :@[I;IVks\\+w" KK# qXC yU rM9B 7d Q: / !:?WK q#4ms::஘듅-;Aݝ!NVֿ۰z u8+A0ـ>  {Xr^@یm}!`+ z `,6'#`?1] # B~\O&YA~DM WRr#(6 dĩq`K̹H]]HU;+nBStx܄ZvVJ\/]UF=O vZmZؙGS ޗT3xHy4.}H/;1$l||Kpg".PmSo)T%o;#{]zqDz:h5f{5"A/uWT[1C@NdJIb>btBo "=:ۍ=:N[Dh}kj"tKnVBv8-JӀx¥^OD{;rxT*)JF_C+6}?ŸY!>I&ؐ{Aɲkx:m$jۦ#~Q(5 ZcIᅷ}i{4ӼsuS ajOzai2^k>k&"J6GYPamvnGdH Gk}zs X+@/6$L==t:&㲗OE&:l~h(:JGxgZX_䓴n B^o~UKАije'Z`~D9.Mj%'erD,CG %i.Q4^M}zrƬUFKHb!I{IEsYc􅬸>$ܶ\vmJp:,[2@>1,]GFL@:$+LT[r|{]Sv ҁKotIt,,Y]ϊhay;!vŕwl^- P^3i]DŽ7\G/ &7q(Cֳ7F&:r]vZ~/n66HvK^񰺳,E:@F+"9>a7g*XgD^x}} @Z9'rQiUg M_Ɖٵni=Svb̑?Mh78w:Ox%X Snlyo O#mhar+#T'tvbd _&Nn9g #܉( xXz#|9ʊޓ> w}cQK}Ufz5$,pw GO;/~W4Gp#D!ΐAaALe/eݱ+lͲP'ଡ଼DN;[_|b0,`~Cd8FG6DfERGI$o+:(Y RAj[YU k t1˸{*js% 0kWT ^Yd_ؑMuƶ7^ \dnt&=3z\CP3#<>&j-J%*$Di].Ɇ0N!dqG_޷~TAFqp^ͥĬs RTgeYHOeX k:L(bD*њHNsvkD8bZ@2kĺddM.FH3 ?Qq1+hr=LE*͋jM2 U_NQ>{}K1M|{_oQ 'Ͳ뚑k"UVM̋'|u~OvɤI6]|Hd=μj?fCckr 72G-me#x?|!rf\7~{Tl%IcHMx:0>j KrKxI^(9JrC, ׂ\a><W")У{usNL҄=8 ֩MSW 8]O9o?) ԙQk2ko1s˽9be\p 2doTq{eM )B s58.HߊDiER#6czv:eƗՆZY x~JlSO=P:ȴeNqʭ\,Ɣ}/vk ~᲌^Bs*gTʎRq״\)yKc "2,Ud$瀙YQ@W@$Zޜbc;v-EkgUh$ ovj$Dgcc8NTt# dZoǗV.R6( HP˩yۻ#Pyrȏ)r95`nn'̉L]ý{F~Jo[k qC/`(v;=eHUrTvӯ)'ݢcm,P|Lnk4NLٵM! ow; B4}O7weMmby_^5L?AxcXVH yWW6! @F{;4f}T%Tt +~eh`ZL]I^y(%nq&S|vg@T?x;[-0-~Ŋ&u:zZf)ZmL Xԩ=Z~T.->,>bi`FR1O1S/>@r/a˃eఽv$'cdbWOo+IjkQbږx ( Z4OZKK&tRLXx^)X.uE)6Cu,/umT7uĝ.^S ^L];3?X0"%'YݚqmR_$L(^ޞ9T?%R}m`6/Q?sgښԨolv]k$Yk'rJ#xw-Z(7/a!>m/r>1x-:z}zۣgn$V;Be&Zff,.n|,_r}F}tPGEJ#*u-#-lTvAq*;,Kȯ&bNܩNb :󞬨H]MPʜ5+1u~ʭ0/SZg]9–eޚHEm-Ď'g:8W2s,u)T0˟X1'O _i?Њ,=H]oPfd0տ8(p1f`0#}7ͫp~l(ªLƲ\q.-$4_hE;eGp{~ & kMEO'Y ZtvLN}(+{DΒ+!GL|'XysrN,J8Ǽm3VYEݜ9 e_W rzXQ`3*I҇{yQÇ_~=>'M+SDg:.wiz-v >n8T0:xA~?d_ʨ7.lI=4qDfl),^R;GLؗ-qMWBV%`8Ȥ00q|HM: JjkQH$j>5Mr)#? @D-2sZa琽yA#"%/c c?">5 ;P6̢;M6\5\p2n ˊ&|#Y#@̣q<ηf[}b w/R'46ä|G|qkuGḤe}'O|^ҳPM ,Z,@Ob!_\x!>>m.$ I/$)(‚uM5p} 0c^ x?^4V (gg^G!hm/NPST:~蠺(uuשh w=QM`7mK۔6ZGG#<6>V+ yn~]WbecJ˂qv-ɏ;ǒY^:`~x>LI\ޮռ@3pޕMT;>0l>be/b({c۶}\eLḾ_O.yȒMCVoX%hɫOج݅uZϯ ;#sYUbz6;c|ld|NfNos4FicRۭNCxg\a#deA6ۄ́ia%OgI_p`$:p RR(# bzGjʍU!p DyURՍ:uBmfQ iE8}Z6n^59?a؏\ShlQڼM gn6h)'E+9ٵ[,_ӗgO6["8)k+N)PǑB}}%:gA3~!}ND K.*!Z@_ A@fHЋ+pTM&򹶱mvy⩓**UTb `dǯR}!ה|dmSRnS'_!jh_^r0/|efxM^0+/yv~DŽm X(gbMbSm1ߚynzB(+Z|\FBɟ .c=Ct~ɿ<1"줤~w8Ք~IJ)6MtFޭ$Q=KM{_ygwi&"-*5+ qhQ~d,q5/]8< 㷫O knj2kM ap~a>fcfj1&:Fq\LL<*tX.>6nrF`RlO{y4S Q䘔YbU\A}8uGgf՝=$[ŊV fvxDȏ)l{(/9lS`w /l\5]& c{jS+ͻkX᧨sZWD{gjT}:g9re'XUC}҆Үf2٤WcEm O/x6ÓKzHLw:Q :OU:'欌QT`Z}QP ĜcqyKMsپ}VB bͶнHgN)]0| &+xS,9O]?^&3Y9/fPj?N+ȶ$$lRxƸZ|>:I>hRht}'[ehrg]>X6H 5Y'a?T# wӎP( oP}=XO\ð۱xǠOR"l$ͨ%Ra elȪdRd*.O]kSX;ml &T+}aWFasCEӋ9Ԗ\W La!S5z8 yeRᤇ(1/ >|2?XM3+Ud*ƴ-8ѓ>Ÿh5(;91* 5/{PdbZR;:~s{*V؛ cŢ1p }%̎o? aۻv6]a|ӳ2HIGk4qP./Pdu+̢YY^Y-lUI\{.HяҠerP|))Ct cߚw<8AwH?mo{B eJDH$;]-.̈޻")GN%g<z 4<_Oފ[ &=JJ]9X97Y@E۶soqz=gk1@2rYPiBR١(uσy 4^/-]^rkfdz+)E}E<<ѹ!>Hrf c@ teXTy\kADa*aH RvvwBwJ eؠdc3,ݮeuZ` @*f)rULxmaŚXfЗׯ (y&};~|Z,0׍uv2m3įq.݆ƀso撚e-jG3'@ĤTmjSd&+v.RǝnZDvu5jq& W?3R =Jpf@(U,Q"VbٔO}L +G(MQ:kb#틓)>uDHU1ﲁi3$kPűfWf'}/cnz j(. J46[[yxs)KP#\82Tيn c=)ZrFa- F],QN Z [bYF/+r{L 鸊.\TS۲$L)YE0;0zX4!I5:Wf11͂C)qn:cniѧG؟3jԖJvLv7 5hZFh i|V!&E^ meU߮aGD?TAQ=-ݶpS$2[Y!Ü>x4>++AaN!y1!ܢ5A2)6}h;$d!vY.YY-_O4 3WU"wV Z 9̦i_Wk"3>}y}m!Ւ#xMNnc|DqRgrͮJ/0_v䘊*3f`ӏ sw#Ks܌~aW{U U/SbE3b2miȤ7Ks'^ۄ<نgox+KT`Q?1K&)Kߎxev0^c0b2fhwŤ.8պXՔzdD^ j1r-];5} 3:=c+.QH"XۜJ7 endstream endobj 143 0 obj << /Length1 1400 /Length2 5965 /Length3 0 /Length 6918 /Filter /FlateDecode >> stream xڍUXE$QJF6!lin$i$DAB:DΌ;ιv]y8Y!([  Iut4!!!!aNNc>A 8 ꠐMPJH +hP 2>=߯t#uuF(0G .Y8$-(&r09n> B1P+2@ 'n 4s8 P$₄@\w6@ 9PrB %`@v(@OM[@ [ ~0`?wYw̪H2bH~Χ@Css(7_ Ipvj\$`P,@LHRBDRu@p =n>^N('n !€\,H@l0874`) 'k (_W,hej~Ϙ *)^"@($,=>gs5v(\yq̮HG!܀E pt+!1!0 ?LDj.\#rD8xA@PSo@!G5 0B G`ߴ7)8 ~bpYBBT~{`papȟ6'Ρ ?',& ,1'SHCI~^4P u©:ƵE \_BBݡ`X&Ⱦ*{"bf}y6D_c&l*9ϘZfy!Embl8#Fux٦J҅<}VbyÈ87$4t[Z+Ҵobmhd9F? O}Φ%rLVN>=EmkGBUQEjB^TF:٬$9۴VgWq$7s/Q~I"bmIBaO j~-=4GWf{7r{K|P4O~ 0͂Peq ];W&ɺgt%K d8Z_W3,45Wo>gt70`JiDF2DrhL;.驩*o)R@%)8Y ]f>H:B9ݺ>zb }ڤ?0<*IR@WNJTē\BePŏ> >"mo kꔌe,h8v+n[Q>ײ=g]xa'-֊7d/}g!U}"qT4*D3od;bNx!23[-u`3Nu "}$XNמ67{yT1P?ic龻;e}˘H[- 3ɫH݇t& 6t-Ui}gؼ%VlYw"ϴ.8NUaSfyzacS1Yu2UsŔ4ɾxBfn\:zlMT{|/'hEogaLMt~+H݄#"vxW 4xd,n烐ZWJཅj8x* uQ9H7(*\Zyquc"7n=͏< ?de gnh1Pl 㯴z耟+[AEY5=#syxc? ?j Э Q&<$}Ѧ8|RxW[KJ{߽e>dڶ7X,B. RڬZ+ñDb{.ʖUMpoƺ2dͬ Ĕ=Yݵڼ>Lj#\cQF&#D7DW[{nBf`4F)~`׆Dފ'a)Ԃ{'o9 &R]/ytw>}D8ooӪ<6l(ohGJҞcք4LAtUqyPb&U=1T,j_ )HF4pZzW]<٠wܭuTx]jW*8m(P&f7CKڡynz nuߝL3VSDII\}ȯ[| w2x3DPn^Zeߝ<9Y!ץ[0۝Gӯpꃷ*N5g ܏nn")o=*$ȟ(q|s!M"{Q|Q@L{* xXCoQ͹hڠWknYʞ?~S/OVRi"&GRجW^TmB9q#U}ɌmBpz%1Ɖd6?07 ԗҒK lM?Ѥ@B0d0ۗ/z)veߛg;r]pPLMVڜ3w+$pF^FQ9z/ *|G۴@@ Ba&*yuE4gɛȰsRFؚ$x¾Vٕ`ʰUb @0ͻB8]VTD-HXoj]|ݦlgUïphc71scL[&\fVuL\s1ik&In 6+Zet%ąWw\ ;}%Q~NzbҲ+miTƆȋy'9o|VGpgmNుPq!DQ{均no? O= 20Ȏ[< 5[50xC-vW,lb QRC(=VW CD,lX a`rՎ@ p 1'`xnGZJ9eD LK7S[i,V:RRj׼OH9mhv$OD TO鸬 )7/ /Kص-[Ew&P]pRg|:}E}lfpOpdFW5olam$Y?^[ʔ*Mϥb^6} ̈́n>c&mT1DPzOt B+F}73y -ѧxwbZrL_,_|6Hw@Qx׶G-TFLY*Bu("|֊_RLp+Nf7}LO\}Un1/-3g@֯$iN|blHa}@L$6bA9{a`1t 4Hn"ߕgQ@ggT ӝntd|S12mt%ďJv%6aC6&TGlU 6MM_M6LBOzBx\_`΄NP^xeN7l*>z2sa[u2}nOɑv8WW\g'vNku>G+RKx"Gg.-39{6[p鉇] +OhjWJ$[n˳1̬6-&x1^/x:?Բ@D &,8z^v /ͨ랾}K&k4Zv, $Qe/$Vg6G U Cj\Ѳ!WA]r8t(w^녗/6=7ꙡbܟGrG$,$vzI{;GUVTm}RV#=ޜi>ڑƱ,}T+c#dqmȬZyO3ٚ[;VOgxjޗe-N@BWTu2Fhi7 n΢`ٳc);pW+\t~z%l'N9E'BKW%ej;[ C.)^]ytEom뼼/Ұq&cl80X x#{W_M$xyށwV8ORc1"T|Иdӄk:Ah/-u*n>uyv +]y"gi1e).^zHZL({SgT],lqEI0r?H`[V+mbG|2 ^UX"|F%rYCӔ\9Fv<}ytYgGfՄOh-A)5H뭒v-?Ho u&';@)Ӣ#xDT\7Ҫ`G:xi^wIO׶j䫄! iza.ezǛK D5Q[8/ endstream endobj 145 0 obj << /Length1 1466 /Length2 6967 /Length3 0 /Length 7963 /Filter /FlateDecode >> stream xڍtT>)Jt0tIt0 0 14HRJwJ4HHH#)H"-"7{{}kώ9s :VKqdԔ<<|\<<@. C]\aȺ@H&Fp Dyx<<" D0+@eN^.0[$j-,VHDDw:@50v 0(%XmH'Qnn.+FCPwu#d\@-Fz]@ᮨ 7 p u6U @N` n9@ \HO$ vpE`s0@AZ F xҕkD_eP,E8:BHW_\Ա{qY{8a [Y͉[sv*plH0/ zBlrv~ |NkP?5 v.nP?tV0` ql<<(<~^e;x~䵔ULo  p @ !@gM0.xNU[# ?ݢ_E g1uP$7>3FnHᷛqa^HD @ C D9W F An"3'sUyB4aH~Ij"\aTPأW/(!_/?CVt+ pQW> @ #jf?55 vp#"nF~m ?LaoB\\Pjٿ_ ( B@Ăj[Ϊi<8FıS y9G"{͗t23TJfA fv2gY_}VkO9[LݞOe"jD1Hy(Z҃Iy=I+ 㚮xfb!U";&~5ˎ/V^'1yT7п@Mv%X^VR!*};큏SEVq☵m,nybvۥW_2,zjOo(1DWHe=?Rlᡭt.#->ѹDOM{F1]jC/!\g5dJ0.}ej "fٍde̕~D $d3L:WMm9_k&nMLzMC&$Pp-t>K4@ߘ|`OUB${5/"$͌xo$E\7=/+$uVܣAWތWώE*bj#fƸYu=6 (qEB8tn ҃R#9,Qe˪.GΙٮТl|q 7:2] 'YqTR+&l#hOE(y?ϝAЄ=li,/Kc:̬Er'> Ê &MTؚa˹Ǟޗ8'ZkL*vEQL|Q{nOM5px.%g\eUɄG}Z)/x]t>TZc̝`!,,m{tHKAI)KLNfm[Ӝs!k1ɤguEȧkIF,կ 1A#;'sx!a_]8dDfқQ-KBH~N _.Nedp EVAͬGU~XȄKYWAGaӂ~'2a=CoW=-]#93w3)w)^w9 _&?w!,1`‚ 3&˗֩)B@0[]n(狟 S៸KԚ[&V>RI-Q]$赚KH>7~DMO`Oي?* 0 ^-khPQo NkR9Ke[<DŽ+f9(RFR ? udU  ]6Q7 RK5]9omiTk`~t|IY2|-K[vB/^z䳮Ҥ\eȺZUT1s괧Mrslхiy4*ŗ1)b2AO MK|%SzG9y&tsKh@EkFhkͷG[e뢥n#VvH,d,9յ0n/*k-3tg5N4k30-n:6&XWAeS;7'=*LH*}1¢Gѿ& A%[YfՋS65LA%0O7-aE=G A!YGzxJ+*⼒6-zN{Sg/H*L4u L7 nf{gFCY}u8ĩa>$ K^O_n܎޵uڨ,1\&$m:ဟ\^RĦ?Hվ`.] '/r1zIonaѶQrh{B,ݻЏo`c*w0 i-iaհM# 3/>?vJ]&xޛVeɱTja)ِ"VTF߀cR=qf ҟVKak>e¶{1ȦfО0ϮG~i~vBQxwGmQ^FlYvSA=u|4WӻGk~m΄>RfAA%:5FyRtu;z2T^*XwVx|6rTR~)dRu?]At=Ǎ^hy$|4WtF 7Nkrm~L ドOMG搐/~ThoWp7My']wATS 'Tm*2P\±)ɰ [U(OOEIUb/?oxTR'mZ%N]a2EIn7|zQIڊX~ Xƹyu5]~X#xt]_\ {$+K3ʏ녱Vdydz|La }nd0Z`|ԃAs?qحh d ^ηO> b23+}E/j3,Yx+Ӯw3Üӌ~gmtެb9&(Rbu /JvʺL+EyS]s"QCȘ+ wq}=#ݍ(ڤaRq FЮDJ>/cHL:/b+wR1 U贔2vľrnum*s4T;OЅٹ(7smIaA |,|uyNLGI_&_c~BsoT<'Ýeid3r.׿),6 ;Cܹ=z^8ٶ}>=^erO8R&| Ϊw@/f6ۣ ۫YN|Θcͱ!Fl$ctvrWF/Z |ɄTWve~-Hk{/jŎa5QOy"a?{J> jWߋ/oȏ89ßhu޾-C˘G5t%1;^Wh+`ß Vf8M`UWj钻w{Lx\="g'%%}پtEd&'S8;J4.n(hySHI􈖐H ">J;#C&7U "R(.ݰ?af{+ƈ a"fV8o^:<)6wnw~m`GӜ;vh[r-i7]kԫ:@zvDR8 zԭ>3f(#Z,ԏCX@;>5FтϹ#+onﱹ1R ٞ p^҄ |-В>&.A۱S4GXG2sו.c,/ps'*QzJ=p!y<:^2Ņ%C0xRp(T?"#SB'C9e0 s-z0[|Fza{s}P-ßN喜=nH8MV ̀pC0qnTu>l$0^74.G&ݰ2fVݔjsԭ])eOh 0y ,#$b3hE;2uR^#hLll-FJ3S+FNmft%N'=0m"$U*ܯՃ>7v_3Ro6B?}d}0mzJ5)`Sbts1RfCGúxSUٹh ;N{ l{t_jəRw=~ΒxlZ/L#M}\@NFA@ߐRSv%P8! {ٛxx\vU{#*F[*㞨D߻hQ@K^W}$#GAeYLSPCe1$y-#ޒI8Z/;;aOU镏$Im [|>עŚjr75gJged:1)Q'hrˮvFs}p dDG'ɝt||o91 O#o/\3Jff 1cT8n}GK ߃w&<^.s-U= pIn% -\Ĭ[|ڢ$ϑo<+L4C_d羯!dX{Idӈ;4]TtͶ.ش}|oQ\Xi ~tHxhs;]8<${p)^-ڒلx%ج j}urc}=3ig> -kfâp8æ1 %??Sm8_ gLJύ\r҃yTʂx]}%j6*ʥ)#nA_6w^j&lc4na7/WƟ$?KvįV0IuM*b2-JO+Lݫ!/c줦1 I/V/9,'K~2Vh3~>OA0!d> ~z*"7?×&W=(oU4YA:RA%:9;?P3 c/keJ Lb -7e-J`U^KyHPi2)c[-QGXZf#oPEkѡM܋xA=sɉL;#,^Lڊk3S/> stream xڌP\ -$<\Ƃ;'xpw N̝dUUM9MN"D'hdmrcgQdb02322#+9X#ͬ>a lwD@v2VIG  FF3##Z};dV@{rakW;3SP 20qqqڙ[dL%kC3BP:8|``pvv׷3ᣦ89@;'WY}Kߝ#M+Y;8 !he$r6@63=ӿ/g}CCkK}+W3+ '*M@ з2eoao w77U>@TPj l,~+ h--V1f?[Y;[ͬ5ahàbef$B-3:9X@[ДWxeW_J_bP66cP@O3c `tS_023tM̬~Gc\ 1MD/#k+ AE]RYNvӱ2LH0f񇯄5jAc!?A o,Ykk$bdc4}0?S/?#.H/5_Zi@ c :mheFf[+:A+hf/j47s04-U~]Pc@ZҁN3a_* r򣕡ѯcfc" Blw&-]"1 0CQv6/߈ q#No`/`0F߈ $#Pv]7e@eE|A7eW@ٕ~#Pv]7eW@~#P".N_Ltkڀ ;}@_(Ὲ dhmHXYI,-EyA'o#HZ'/3(0HJc:ߡA5 A@_쏘 N+c%헹@&@Pձhjc $#?#u? hZhl W+MnԠfl~Al@Z+ =2#/-XAUef{ѬAX8__hף_z1Z; ,⿩YWk 4ߵ쁖f%//am 4S{ ﴠ.l(R? 2?v»Ar](Ty:ځVkt0  ̫Z ;N}s_ku|@H[zZ`KSBǓnn3Vx`u/!<dzgFvIL[GNl;1呠] v)ħ)p-߂,YR:B8sԙiWb,y̑nd8h#B y+} .۠ĦNO^~g&+RF!:Ԁoh9y~ =1m22jpBwez,=mۘy;oጦ.jОx~kQ/5*+cgHZwvƿ| ^ȕX:fmg?YX|`=WjJW0уZ!!֪eBY!m>rIba۳NH,PՔyG;i%D)ez~|X^#r]\*wGf5;VF cq@net{׹t-4r{5k^upu`C'),P tIif0JWy$Ɓ ކmRb TE%TDgE@-ۍ AI zŞ*a10Ib0nw|U'':fgc/PDMIE⢜*yTZ+%""Ny11y%4<_H]4=_ X/W[{ %GH&f|%<+,%8*27{Rc#da0hdqiW/C"ru3=V9V'[gO}{ax%22ꌥ#QN8qsZw dR\[ȸ4)u))ANZl!)w`a !V"Be*P)ʠnf9irv y22 t8G3~<8\y fr8 /#I^2=8nk1I_fii{K&_ {r qo7M2(#{`[cZ2dRrǖnԘ]8mIʷ񭏼vTx*NHc:ճN'n}{'176èYB0jP\o:ȅ8VlJEtG+ qx(cvF[$Lejw(ߘ g-1j;(He-{fpr,W A<%dŮ2_wYd@*H$$ͰSuʆ^,.~f]>܁Hi(L )\7Nw똷=T;j/R2sӉjo_[]wd^}J2+uZo҉䘎DձK6Dx^Մ,}mrG(/!+B- E xRZQX6å:]+8SDjkm,nO?hqJ!YY?8Dcomk@{ w<[W]clv*0apm٪5bu>dEXEw~#NwՎ|{^l]$+&#E&!mB+`ie E>JTG ~H~4W.RPg)({m"bN}wrq Lmibן#W `o8o%&(7JҸ$XVd#8NɚlP{* 1%ZE%M"!)~a삋%|t  Cw1Av E=) #E҇K>sZoIrLo~opԘD]Og&/.׵Ko'H߹y$8]t"E', qaZ5 3=8 -,e&L;x4wNL Beh>8fKi xLٛuP^bH|.Z(dz?M7Z{1bD[{&{m%dai:ֈN]F|lvA6.x~?X)UPm5 qlY y5X5gT.?}hTFM{!_ϵ8\>x0NK! _xLgā,H7GF?7H\ZI#bܱ]^Ӏu/-гr)/vA˜(˗i)YTpʪZ>p 1T ׄBjL14J3]u?)?yϬ'1XZCJJga!Q% TgO$#K֮/|N1X::ѓц[Uou Fs:^_ifbFng)zjwyaI[t;d}na :G",LmGQw|FLjma`hb/͈nRbl&BǦ ɣ+~'Xk?n[З+f~8˖/ݟsH8qgs-8/"q« *i{ ̀H*Q ODxP*燴pZq]_3NޅG<0V{Yh::)ݦt&SX҉!W 3de=ih U -fh}obE2.mv KrjZP]7ja=B:BG.պid *N1Ba#Pk s7zH5죎8H䖵{/X,Kx{ul& ( M'llS땎G}PJ9;s"/]&:${#.6!V IÎd!KIG*F!&e[Ȣʔoy[-8:XH 3~%"FNM1 + ȑg"B(1"H&, [P%#j*2XȲIq=C=C64+X#T<{{ a0T$ LJ`$3p3껅Ry+SxG$}`n.ޚh*Iy)ٽdŊf'"&|bV'RӺEͿdٶǴsYI@أ[XdMPg)+䎨[^}=!8E+tK) 7Mԏ@k[RLյe$9. ~2/s! ƞ, )GۤbE o)e'ag?<{>7F ̓ɉ Fׅq|ޒlpB^y@[L)l˖L|2@lN|~iFah k5(;wzVz,NzM$5OY]Cq0+ .}K?Mٶ{@*tt]!HXwD04~E=qB[IgA"M.g\(PTv`NC7q -(0" maWrY孆:^OG-1wXt,f+_}?7(\?;Q[ңQ*mw4,Z>pbe#_ WZթsdK]dDu`A|و:G` d* }yg\leJFP -p&s3(&uV #ag{&Xb,跮̱ԧkuux MBQKFDyXAHGt_i1sLƹ4g _qbp(K"q6܂p ÷qJxm1&]P,aXaJA&2չY=}sƇTZ E`~?T11JAMr;)C䣞yZrfX9]xDHYn{fhCsBw={]PavG~cAqG(r B kzNۅ`) ilmo4&DRRjU*tJ\ό^Mw+8X=ޗ}EUԹXSJl6j(*RoLP A=IGhL!sBQ1BX5ss2Ppɦ-꥛F)Kv D-⤀|\4XӵZ pg,*Kn}?wDS!Gs ?~ D{RK}p.?7Aƴad.b3ֶ1/Q A R#jCa ^.@#3GzF =4qeKA Yܹ"s/nfQBdJ5Q=̰C9d_K(fyd S8EMxׯߞRj4WxT:?} [Z7|CQ "ۼ"tY QN=דZmreuGǠHf  Szw@!KbW֭ǓDm-h$!@ggw@yMbţÝ_USڕ-,YyxƼ0!.щ]At6HW%:Q&z^;y@(d+ L'39Bޖ&9ݍm'bGUܭ܆=ٕ/yuO|Cj- 6 yrֹjrF}ex$:xR++#s {J:5гGHąL3"{#~,&HMm17YpgQE١A1@3xyqXyJsS}au !~F٢Z-[*z_e0k6l+6LHS}DΪ͹}Q;xZL-oso1&7{T!=& 'GkD1Kd^)9rY*F)-^DbĐ<[o0nVvuppʋz`kxkO>܊C-սi>0O}r:!BAXY;\p9',jX٠hu*O[j^+Rr̀Lh{𮣑E{_!qGٹ ,"ܰQX`\x%E'dR ,3 xby!q0J1E޴`Q5cay'Tjkh}ƍ=P@8fXSOVNa Gkу،8V籸6FTbK"%P!.'uU *OLQhލ4N]zo3,<{ηEJVA&Բzq!XBᱨ_(3>aQ6Fͣ.&r%z 0 JPaךGJ}/-F%h aEp=h6驘YXݾ$$wFݻ?|9.#~si^I!H~` n' Vî%vRqtJ\u#ޞkvPXi.e|2\Y}vWS;!IdP'.ѩ*ƨSaҁԤgR YW|!IX'~p5a&ȰC5p>ҧ+zBoÒGӊu˚kPNUPkˀDd^).j;leuY?l6VՎbp#w";"ѣozDN pj7&!c; Jú~˩F [4u64ecL LșIj}ѓ4ص5]V8, J=",qkS߮8Ow+a9>°\oJ?ƴBkKq+`x 5*+uh,]NﶆHK!{b,_|pvF3TS;12wKk#?B9~%` ,4M SӬ)^Vh7@#IY|b(8 ojdo7gᙄg~rOLӶ`*C&ec1qMc?wH޴zIx R B6?vVyN xwE=J' 7:kt dC{)N!W]q4G tj$ݭ-ϑ7"v<oب }%<NMs&ZG7vIvntŦh8&W7LlaX0 "lR<8(oGXɥߒ[lLg5⦌s #-̉)4H‹j K'>-Fc+1F=yAdh`3}k\"B8ש6l8OWph"֨2eSsBP◨>IA'> 4;"pglx5ɮ7X{'t4i!h+dxb:#:e[lkU;Z⇍bpBnGuv%fK~׈&9b5N2e}Mu=Lf[0ja5pbHt֯sS@Z Q˹[ծ搖FV~Gwi;\|_値]%p83c.Pېʹc-+񪳀:9A@-&z!Znƃ𷾊uVj7G>LuJ8jos!{wuSI,d,[%x `M ^C,Y/ xm6꟩ƃ XXr$SI̸臲`#_m] +'OЎ̂/}w\П^ERò*B#ifxVxl|Fʵ1dm)?q -|.0gק?V!Y0}a]ɮL,-53My7?/d =jS$O%ދ(4ɲUa 7wfgJgKrؤǑ:Ԗgbg6y,b1$$)}7JzM!k}C.F5O$̂Bzɣ̛D'G>m[e%B`WNtk8;)vrw~$y1᪵aPg⫐ތPj#+p8>PY ͵,sRٵ'ˏM %&xh/i(_4G҂p ' Ɠ顇aZm261FMzpl㱽(#i;G9;&kYɳ` *ƞ1wQS"ߎv+c^&HDƑ0g]!w}P{& ӈ΍B Ite5Ͻ 96k~yNh͂lqbl ^v9*p@i)>x>Et%K!*a*Vm/D6S8H-W }WMEɾ;¢cȟZ]d9l:FEܤ{G-.PVqDfAq{M4Hv{ŋ݅r)gu#c?&ߣFp\xa\>}w*I?DC(^Ec(;>Չ!èHso^#[P͇W2ez&|AIٿ޾hZVyr FsXM(6Û|2N,C)q)>e$Z 4q"DCd9l[u誻5FБR)Q A\9hdKBWA{u-君Xi \zHGt?;bk^Wi*,oGg%hf: Ht\6$# :wV0E[o0@j dzytwZ%vݟ o^ǣ*I@㣋6Yؘ^3ڹMf|ǀc _ꯎyw֟1@kSW:GZ6dś/[E/j_KBP&pOB*f %b .qY`"Gt%:E̝]zPmm}. BZ$Be{TȬƀsrsm?&)I_U>5+L{zh?+kOE('E _z2I?6Eb,~~eTM-i]UJb DyKVŔ;B(l-8q w ۸ zoD;jJlqly}Z#W$<{%vLS|4lDI,o7m *LL\bgZ:y`69 g^.Ȏ~wxX H,Y\w1d vU:z(Ɲ\!MväM`OS`ˆ>)YӃ8{+Z+5hMÞCwC)Hp}yeYNa+2zQDS\8ƾJzu\g"02J >̗p{ቤVo}JCB= B'9\?y Gr~t!ZqcᄳơB[KTN@cmQ˝i-^1 yX2:W=wc궷Ae$A5lӳ'Wb3jszv p=-n8XW.}II=gLu1< Fk,*KI1¥ ;oUu%k\j퀓 " ٠Tǰ`0P>"IQ&: V HxJMXmpSWW(8jy5HaB@-EQ/h?*N~XhPuo#yeFZIܿ9j:弦+,1@r4ODYIAoSyb@M~Fٻvc9ϱq +[LZX*D_@-}Kb? ZmhWlK 0$wZ [Q̶wʳa`f),J ̪e,TS˸3^ܵ5\Ҩֽ!P9;'"fBәƾ6qUkjy$#Zk4JP-+ެ>y*7!dYxhW޾K[Z*y}Hw)fjf_@<,s6 *K jBʏ==\)`l!*& sj/t\?kJF%">ZӞ`2yܟf=NyQF( 9>2|߫#4],˓{w v=O]VKMtMT }wHAD/JLITlR@%7ҽң}[xig%hHw's? ɍOoc?%RU.D/݋}&ݡRؙtHuY`':7)0y DPG9Ydaܫa^w`|CXG؝?S2Õo|bXMQf15_ȑ&Dܻ9P3f;}22N 04G0ae.{Y{uiRwt U~? -ǹ񄝉;כR-|s5rdɫۗxdp BbSD4fB+v5y۹bLKs<.OL)qNY>Vϯ 'ࡊusrb;H(ΘxfjY5Z<}BYeO0+T,-Ff W(¾$ M-uD3880VaչڏQ?x*T09֩<3mlHxa^"Y4!~F{%bR~igA(\Q5T ҧZIs ߜBX#+J>f rbo(Isu7Ϛ]>ji#: ,zp.܈3=?bG v=Y1Φa7ɷ\1HGnl{1dd^O SC5 08꠱@3cϭ*^=2}GDzJ!@i6~NSRpĨ%( T+j `_x q8lw"ܵ6,w9\bI l k=\u` <ˎ_wa!7mHoD]e>SZ2 nk"r9+ \QVܶ[ŵd31رJ`.lǵICĶ"Zԅ\҃^qg xooژv^-S/ 2Q С1o1YčՊT4*@/а18>_-aY?01thҽ7M8AMjxxti83gqvfS@iZ:Ċ_ZUPOjF'\ʿb8#EM= VPXSG֐VvʺtZLi;7--{6V";[f&֌Oӭn+pʲv*") 1_t8㕰Fb˃5E#>F2EuZ8"{`q.3謪 Q )%K(y%]deEnZb&%)H/|hߢD4! Q7@IoyxO1UfMUozqQF> ߤK@Y<{\rضSkFG!Nrvn!G]xV7 w`)ZւH_pjS%awce8CX&|8<`s8z $j^.~EpF}F/qQ1@\oڵ7Fl-fZRŜ5bdbu)-%zlxvs[Q :o)̕CIf0/`ܙwڿ^aԗYn-S8??U,7{|+pFM,ay^s0>Un-pjrmY6=ɏOi@M6 nQhQ[ƾ 'TDFE}҉Њ¦Mg#BN"mf幥LWמTxHV| |R?X}.v(E9Nk /qji @: uG9`*i&ْB&O!e<ɴOT"A'Dђ{szS1Q|S,z! ,cJ|&مJ)&&j`7Zٌ83q?uV %Sޘ<3ZnUΡ1)nsS{ev?7.Wxч)yC6)j2K ي`#$WrMH@wJvpTDRC~{@lXk&1&4ʪ@JYN¼~icl_yM٥-uIXe=zHf߫UխdԙPBq"pXl^1=|%2wJVSkt%4xh^h/fHG@^yՋ*Xyf||A3tHf(!6"WDf⯱6"'sqüv[e5W,0-njԳ<=ZL6}*fN-0i]ݩBzvP?N Dz[6PhEj! >7OIY;x s󚄱`ç/3ꄚ3b&L]ZU-bIDk>+z3lMtی^9JU*1[]BTj.yRy NxoD3BGu+O߰3Ho|쮮/alT<+GOvQ"JS#|7'%+%HNZ{Rrjyp;j&sa7uUeLs =۲ S!FS{VIrNdV?Bfz(9ojܫo6bY9Q4e8I(+Uob܈5BBDo]U}(q%cvAPP`cR#BeRۃ-x|.::ħbH*vkҜ1Sfp{ *̤+zy'o,'Ӈ/8\ΛF&Ѿ9P;Eŭ8`an}RwS~MѤL b|Mu$ļ͗e3 TaDq5a>&LGE#{qQx9U8=hRMqXMRN?.Y,Ng ղbbW\}\`=?F0ʘ[eT"ʊ-]B-MsTt!SpH6,6#9t;y(]˧q(_]?; 9"[qx_Y6` ]rsܹ*Tv%'3vnwrE9'*B.efH~Zʒ3PFDδmsHvC_dYE5!AZ!V2JyA o 4:Z7d0~{MP=:,0E#@4~BrDudY[LFfmEPYm*\I:yIBhL98;nDMG sG3\b>ÀGP*3~{ G>oѥ'<ZKe<)oH㙙""tdnk?!9YU*bd䰁`y8n]Hi7T-lFVv3HGy$r&ONʚD1=h$G?xdt/g+PWprj*/4JLJ:j)q>_l}j3C;6ȐUjnN)jZH_nܕ>yuY落N/UG;!7{1=.EJl<3O ,q{鯜McE&%}zh(b}F'!"yL}2C /Hի.}3r)}nF+c0 L+?cIa\&D-s]`ear} \N}rdN.?U|׻۠$f C:}-,TyxBHFW_˟ 9qo}'*Qucw0*XVɖzYpl/a¿QvE%'zd()5~3f~GКЭ~C J-f,Fƞ E9Sqj>aM=mY"27m,K^pkˑE_Ƚ3ײ˿d4>184|pp5 G[<52xJz}d }fbg럿[xr ½yh(RUW陵S4qbj{*\2 Xmfs Sd[(0א?4wY|ֻIk & w_v'DR-'P'C\"b6J8{ 5}tP_h8!srO Smdl{D6›@µ0FƖ\-Eaꖿ O>?.44Lqm܉ML!8 "ýtcF>}r 'o7)/t&XH}mLQSl*T|&MzΗyf;pw>Zjk',ˀg`{8J_NXO睈4.K"n67Z̈́Gͮ< EAo`}1P,@=:jlaW%A|zC`Fp@&XX{yEϭ 6מҙRWwHIJf_"bDct#BLoM87Yy]^!D_ 5 zL;J[90ƓVB6<ʾФx'<_yS-&]2' oJMդ;5J`э>ִy+˸zfZWAU}X [lj"/1~5K~ /QwE`r`j ׆FC; Cʦ.0OM"{f55\9y؛8,q{6N.EQĤ>4LU0$s#mG/8tV _^'PsH"z!4P-ʶ$@j)ucW z+ێAIlcDN_0ʧpׇͥE "̓Ee`A%Ѷ>◢].h螭SҺ-@4`7pnl$p90{=Cc[3Ѿja(B9 xJrJ*3,+%.r:#dI-df`9IʳʍOǩ0ݯ"&wr[u1h-&Uo?a\^${ KNCdC8bBdm:\"6 $ ʛ>XsllqJ]c>Xg ٷm]3Ʌ3 ԍjxݥ9˧?"M ;@fQ=pb%Z9toE/^bqmkDJbn Ť )T7|ZC{Ic8A[WB f z\8&*ԳX)#^悵)"Ht@XP*n!z{솄6onaV+%F"5c;fVrzޖ}`Cu@Yz<WY^ϰ^rr8 ;XWUvht5")q{l ;+ٴ*iݕߪ9˕1C&!-.3ژssC{I<\O!~V&}-Tԟ @(k_mdVixTNRaW߹$\ .G-}RԇU=6C=^4Es?uKseJb,2c36YRg =^:L_xuw@N)!U#[ӼkuDk 6(s E`jB>^O$3̪:;?Bb*J5nMGwth-'HI1}H\}Y ӧzjP,A#Zb*ʍX] 6%=WheW-"Zbƚ~cHH>\!Epٝ]ُ~}Md-]N3˗'jAs$ފ [m"t:^ źj}9~ƎGfK76JQj/D5` p|MH!,$"yD9j-DmSԖW2|.gD& sRmbG9Ԩa>C;}{:6I"..I"tMJ]߈);8:'+#@(#!=T ay&Y"/d\][f-IJ(R@RbZR)äͤI!xl9k,t֖`J!Sժ^;t;yN5(|j' G~:j(0wW|ZKF*)^ .Fȅ ~rTb؊,фg:nT(Ι-DB? n<ŤqiWtW l|͙V~d0EDrk٨UOn!YU4UKA5c@*ՍOQjIq';DZLִѼqhf2v9rk*R{NB:@]}#Inr*yZmtE8Ts:1Pk66^ɖ٭so b#Pg4$y g,^{xV2O.TBcǝɿwZPa~kNTKr͂/0 dC41$:ɐM~cTςu[T׶Ċ$* MP*/ Ie誜FzEiHxSۢ)0c9i7@m4U1ݎ?VcW^d̂<-PLF nw$cBp\5،c`N3ulnKq}̮EÂAE+۽;O#:؄fot*(8 -d`=+鿎_S 6PL}&,˂02U]!i*: Bxuu6n4à' (QE哞lau-in M0'_0SKy-(нz 4$NhjR#S?$ᐷ|I!+xSO:^uo}ݖvŕuC8 yE3w7fLm{o~R3*Z;*n-P}'fƐPI"4؀-k?fن2M ikO旁,?Q.#V^ڼ7D#* 7 xQ } cVx߁Xξt+ev)"Pa1ϱ>Gu[98ԛA/nhϱ1xBN*i1$;MBv5 }ܮ{񕳈NMۜ_͚̓ ܗCvHja&Xe8͘j`x ;4rRt1{|)W_6/خV@Q畔)!CÅ`=|iR j噪ي#zowR'KEƓ4ֹ Dl`Έ /$;eaZK70E$1ݬ⌢ Ao: L՟fтmu8"?Ԝ":Aim'XiUqi ^FƞGɯvλl鸪**X}[gxcж @$aw1]"yX-$ϕH~XY(Q_)63MÊ(NT}0mN0?$Vr>nn.B@Ȕ7㩬}"6\kdx-=2֊ c3FPWb 6Hq;xj<_v[׹#@0Km Sx =&| uP{M.@G5fS,"dX_nHl%+e*g7J: dO"VKdyQD{7-!K9oNBW\mWPWZbN!RR2d9?4KVI _qH@v9E<*W̋@MUXuN|qy:FJNҊ-\ΖӊϾ\vZ!L-+IŎT߽o&$U| NKmWg"\G(\ zTp%Ƽѿna#) c[ZL* e^`4.۱Y{g5B$\Y~KElʋ 8똫!}]&iRl_hE+3°6J<'u+Oઞ/ EQ*v*QCt̹~zfq~Si6V};ԧo_Q3]/x)+T]"ף)m.C"В$.0CY;#lxJNpC ,UtmwM6M_(7)rǵN),}Ż}Ŀ~xzwPEShodqAֿwmk(@+7Uk\ZHa#Б|WzE:}!i^7V&S 9l*&T?\)S7J]MDX0zćGcR FɢdbбHUS4y0ߡ߸}NLZEJ*&xԾxe$ΟeL$19Xcqa6l?>?!nLmHݸޚ/#t\C=N*+4yx$j̺Id=Az`=9`tC~K$$O4pٹ*-O?zdA7g I6Tb7OBo|œB``H+K#0Dz1!q佋#p7 x@;?b\IkljM*Pn endstream endobj 149 0 obj << /Length1 1841 /Length2 12014 /Length3 0 /Length 13161 /Filter /FlateDecode >> stream xڍPڶ-wwwwqkqw !h]-}UUWu:Zc.ZJ mVI+g 3!Vpppqpp!؁inv H6sk3p q qp88'M cigPe(9ȴ.nv66`g3 t4T@׎mgK; J0؂.B^^^lNln6b,/;-@ tZfk26dZ_vmgkjp_3<@V@7ks @+XgdO(d3mX9r*l``#55O9IMnfvgsscD?ʼ,J #O hzݬ 7YY1 .(wȫ   ]@-u]:90N~og |Au7n@;!sr, f_ p?WyY9 ~u?>))g r,8IUY;"zJCg{7]KU@?a?SG7!9G? ?ns';G^5~տw>UZy8o"u$A69F;w9;JliXdv  ^7pU.wKY0ws3Fx//u?5 `g9_SݐQ>^]?UR .? uA> Wdzg[Vy}@|ح9W< ַ|=WԜD@D!J_ۿkcA>;)^~/z@W"yu/XzH%򂳥p}cXm$,~#[=:b*c]NȦ۵dϘk W+O͈)]~IZ]KJ%ȐHYu$\`;h \=5pn!MC u|(3qh -r doC0殮g^(OK}}֫u?^aOJ),nLl;}t.n&Kc|Ce 28w3y2y`ʉ:%D35_=~S.ǵ` )w2C {DU.Ȳl=vsC5 ~Gw~&6qn-{iXZsNW0"Fo`<pؐS(PRA۠؀s"ӄhV}U0JP *LhIwE9 ܃/Ld<[c0sA_%>lST/)#VE|Ҙ TV7w_/oe F}II.QM5s^ň&zD{9#SzץX}~F U>C6$q8ڟqοY\3?fhp18IsGo{I\`^&f€l=ǔպQ HMwiJ3+A,^#T^%xHPԩ)}oG#G{<JcH7q&k[i"K> .T,Cv!JPƮR^ld>cdFUA$j,2'x8B+<۵uoqF8;qCX+pR/bm5 -XB m(*a~=[A'┎TlpWpuS[R;`KlY8dU\) W[!}t'Ocֲ_vynɋDf!rǹ,>H\˛-)rS(k3"S 3۵Q-$aR[|MG"I%rJqKMuݗb[8Kto\+9c6ɬ>[3GW@s(fDzi_ϦuIxHW)?0+%i|ʄ.H gDi2%kh0KKN E =q5g*u)%ɑ̬n12lADo&DzE'plizHYs-Hee =!+d {Jp-/0iCA-mPFE ~h{ ˱""9%BM 5 iL]'>kCRKQ&RO9q"[kP*h)քf^SeW:vre!6u)!j}i sOCcSEV aLByqVfQEEaȣ:0\1uKi ݗY`yz a4,o"Z=Ѻg`)#8tv1&8Cj<|ƃdu±Y|Gv`cPo$QrR #*q·Y1K|+VQ̻_Myz [L,7 cs YFpqau|^G;)gtG_FFEHxzbZdbX)w[X@U%222 n'[Di rk-}BMeI87f^jMꉑ^aqh)ŒPԿ#I\Vĩ"U_5MY; j \ +IHEʼ8@T|<@E@!V1O0j/f(2M$p[*X%ط3K q (g"ƃnl!lMǪ"=zv|) 7Nȇ=$Ogt0⭖ ҫ#f#4pu5?~5ӹNPP"ߦxa¬ӝ)nLO>8swU"D5cGBTL{.kX0ZCl ISg.+e >$蓸5Lْedsku-|5I=PjdP4~J V&WfW$og70/e>$gDUeRQ'~ـ2n,5e'9>%N!|Wv>T-ª Z%`Y {z%r0>gow@ ;j^n]rYypH.&?18A|{+i@@9o-HO&ګ\jQ i5S9+\a#a`EpB"/[J>11!5k|Y^}٪4i禪qG;W`^^ tW;P2Wj,&{qc]7~ʵQ_n>3=S׶aA EB=2^.TUgp5HfZZ fԶq6<Ч(6‡)ľKrdH)q^ ǗW{%A9lZRЛS~d4nӢˑщ$ħf,[sM܄yʼnǖ~ci-!Vo$٤GF̚bfr)L1|m-oSTݭf,8nvD$=Gw“իi_c)!"3D#]^QuxQ1GD;=f[pnd^օ= 'ل:9:(9a5 !f.sQf>9QSsy;4gQPR?nO0_Ki72`wɰ/ӞrF |%zby4w%JPtTiIv I?w.(V).Uฺƺ +vzAađ{ h6MP&t:ZwK: b}Yno2jk}ǥ^O}7T\H@%4B*ԌXhؒ0(x:3)t쮥v_;p30ESrK S!IQ#i }+ܘfy]i PHu}Xc[˧CI.Į+Ef~VۓGİ4?/fTXbIP+Tl΃n o_m3e1NR˜b].V qd <(pQ:-Ta5hLM;U@a,H;^!Bw6Fpgϡ$S:)enu˗:~>[1ES`/@$ġ3wσqosq,q rKv=ojbo`_B4xpuO+k2 O7Шgըh""<-5zR]]$t flH}; T*y ԡʻ/qSg0|HcәRHqWC+vb2VZ8Wo 1;G:3U_Y\c \C`!@KcY_NqoN-jG3%@0ҰCRd>iI!ϴ5VQ㭍z =$BJJnd&ecs~i E2I]f3긠U-{I.fPcO(9>$٫䷧lFjj!2$dSQ`V.;󞍗AyoV1"{^o>7XbS?$M$QU\i驺!Y`Ty;k~2в]? F^7'8m UVV5iwCy9볗-2&7Ex_Zᳫ@=ח),ˢP`,Q :wƟr-7 )6J]~q$['t;&feeP]݄/ȰN41Dqws[H`|ɓuڄ4$okc6+쇳 a5y(FESKei˳p%˯{c)PO= tVu^aE%>v 9bo B)? $gNE nj(F˳9Vb>&Mv{l1>1LSXR=F5&+8,j&\<UUd?8D<.+&}B!joak3_H = Og䥅ǀ\v.O;4{a ;X~[ыV'Odyuр--\+HE?4J(7ԬokZs>gZ 2F[ mk ¶t=_vroш Bqm9pV!'ӽF$)wFfNVRUڠ6]@:XJOS+1m~_Yg9 [ldRآzuGR+H߭1`*߃ia[qp$k ]hy|Wroo{hI+6}"ZDS+Nlng_[fJ$MVQ]`[ \PO5mZ ART`Аҙΰ{SyMUOސ`rslv:G͋n x3ŷ[lxSoZ!t =_ [C&/c7@ddu ť<%,AvYxS:kξ&V> fjP9-x[-d,GA8b\HHu0f+~'eC!b?a47ն|R;YǖayN?G` w|4`YƖ t!b4G> /U- fN7dcG7/2@SVyF_70 HD4fPwz'~fy/F* ʑBڥRc~C뽀1a0e)+ +wPp>?9b>\2ߵDAPk#ŋt*g֜)(0F;4:>^˾4j0`ܔ5٨`ɔ 5c Mvgrb GнVP$}Я#*! *<,Nݙ9×WJbE3db.?5cX͖^mpr֨β>eFN=zOdtk>x'sŊCD#%9k&}rɻǝ~GAHjh#b7jFjk;;˝N<vFO`Fh}xnJYPD'd->\47 V -6#<7 Q;)Ur;v}Ǐ62Ys h*ħM q  R1^LFĤ:*zf+o)K;{vȃ} /'Vy}-o65p)aJ,wDq%*sh? !Z?ExOueob=1V؀ԧ__{:LU)3>RoEa:dh)i} X|5rR+oZ5P9.O.f[r(Y+5jAk&1 iqL+LPW=qtCb'Ol"(c0rit ez4bpaxhV5UYя[?i֐Q&"߸Fn%;fz qğ8ВuQN*a$gU96KЮ:wa0*,ed֤+^8Tq;%#owZ;o) 5 syCsmum=.#'~ %t%UQu  @?cQqG2G2+km6 S e>8# @ţ(ʃ5 BR;j]ە*[ǴCNV&ǫ +b}Mck^$NmYm2N %\Qfp2%Ut ~)ca"Rݞ8!Nإ5Z{d54w;VLlff1hJTaR}}WYQSׯ{ mFyH'j\.ѱHI-ڲc]/b[_Tݖi.Ĕan;VxCP]GOR|EjtܝXNf1vIxzjM!~P5 ]Y›rh(C葎N_I DcՄ/2#t?wv|0W*{I F;4# YϑNYgdd- , +40H3|/V-1- 1XK Wb_ ̤N4HOnȦ3jb&hו7Sgg j5qG)sme'8]~ѦE+ l;;*v[~{2TuS8su;5shV風85xK atƽ#}  : azAk;) u'Եhc}|LϿ~:.G]ayo]WH<odlđpw}ajdQLCt\!~< ahz7{x.e)B7!@4A!;9u򓼹r[PPjm%/ߘlcb RyRys%Q /w 2d!a`u ­N3"?ӯrԓ@;?h/\s:SOr1*&K>X+Gދ8O%F#Ɍz:GP ;O;`3l !||H(%PQj< }kbtdT uL8S5hIL|+\wd @;)xF&l^;A&%uEX# &FFQ9D*{C 8ەsm*?WR:}RLe[ϝ4. I}ľUW$YpۋI-}_Ye1wE4! *]vs֎a(: 5W==p⫡kQRz~T:F$u*l Iolط‚ŗϗv]0Kq $KstD8kۃC7ǐ-LwJFZTG+"0ΰ{T£*i)*T&-J2@[BArPjz` z|-t2!GE/H~ucs[ǘPd[CVP;t R.+^?O}R-[Ө %V݂(Ny٧٨5- "][r #ӧr2^ҩ>;@;Sprϋ$ 2z4/e q92j6BE#)[IM zlP*q#5"DQ>dl14PT"}"qY UyOtBR(z!2 D@)Koe6ޗ=ɲd0e*~;!knൗ[._}d7NA-5&bіjZSc>tؔ$:$cNch ePID{MBy 4|ҝQ $,{C]A ȁzYB) ڕ}|ǰ~1^|Jw-Ik8n@D>dBT"Ho]gy!05x.у+Mev/Y^ _(V6q/4nɃUMckBd[e]l$6i)X'QX1yIe  Iݓw3 u],jq]S0qvS3nE=ڥV,C.4 #XiE}.D..X.j==KZ2'eGi"0okF;ň1[\KNq{ɯ,ŧI2joe͹taηM$fXL>,7\cI4?s2Ɣc NOB ~V*I<+ ǜM[e  32sP9a -g͋YW@τE'bj`Z[%UQ|pFvU'@g:ILXfV9+EXƙQ+㘽13$ ..x\@ y3F0ns-W&L~DbmzO1ToZQH08̇/jן<"2ŵR"̮.x JEl'G$lDt*@9NT nj5C8%N-ܱ|o(In'>9ԋ_-*ٕ__fa$AdozTCt+F+Kh1Լ8N+{b&z?_.TB4 Tos"aMkQ)rmNXet ? 4DOw*h&U Y^IܟpP ޴A?l0XZ$eg4k|̋oRŧfTc5 gB "ޅ&z e՗8В?/]͡uensbz GLyPZcnd f->!>a:E8v,>N#˗+@o-um6 I ~Ku/lUnK\uyPSO,r[Ͻ_(qD9tNRHWY{A[V2&z!arlN}MG(9~`5 z% #L)TD=v +u =>( m"5bVk$77"0yHם<^ac_>AE8YJb!nvp0*_=޲ת[f;Me ۦ0w6`\Ot+4'4h<8̙ٺ> stream xڍPk. A`Cpww ` $Hpw Krj{~LEI (;11ظ̬HTT 'b$*-#E&abmlw|l|vVVB&. 3"3@:"QC@N/@kJ`f:LME'Kˉ&6u)_!h,XX\]]Ml!BtW%@ tp~ P2U3@\bjl@@㋇3 x9.P2Vˀwoll@ gSS le)f'7'F 췡#dcO&)QUKhsrdv.w.K!@#$@@ӗu`+o`.َE wJm"Bbee@7SK5l/x{A/EA$OG O#$66 h#'h~|= ?~2xl?"+W։AL&v.V/'QTL@gWY9W/]W.?߳AXJ>+3w7!)g?j?d g^yjYEN&/s wAR 7 /%=d6 0PULl{,S?*`S cz0qp0qGb}!;èn8 `aC^\/y!Ho[pXXx_,Mx,Fl/drX,,@6V `| %Ej˚C I@iabdUv[%Jʴ3*8EJ|LWp-}yKJd!%Q(^mbi~@5Ȯד5L3tU3J>֭k[m_pn;yIh(}iY3NLĈnhWS9cϤr HއyDobb28 G#5i5*ߍ qxA iڽGUl!FW 9!n.\FVsuऽXb7#bXjv+FkW ^i_f"GN'Ul;Hq6"yXt5pՂXQ\ouo|"-7N`&-QOXlgUZ`Aj'| ax)hKQF常T[xp[H˔,L=,33 Jȭ.}vSn= ާۿ%8'e(e.XpD Un=|}#񙖵SDGoyfnњBj6գ9Y>~J Js!J3l6F~ȳLlt0/N ҉h(i~ XLf`+SIYx_`!hSG?uq͵-S77FU{ڝ HȀb=e()=C|ĭ-V|Z2'mfT.Da1D PP|D]XSi, Xrm҂S"$Haaq;m[γxzNqyPIJ hxAѕHw"0lEmu87 ~)FBP[a:{ ud/x}ǩ \H}jDZ|ʹBWl{KbNZ^2rY1l7v2öTgwU=@g S*;UY}%.NJD4Y4L|]tm*eIgtxQ„wXtR'.E}P"lF=RGLO$wRܑ +ŁFBީ˼%/;'"l[1n:;5/ MAw"U=bH# GNwf^ swdeI3T3h/;N+iZ3oي`6Hr0=Yf(EccYzT ׿ ٴ\ g-t(>b0m-V?M2"7 iD|~O5"OW _wH[: )a!dUE]eD(l+T{+LeaJ V}e'㯕ldj\q2֮|sEdPߴԚ#ogf;6ٓO1fel_` j2%S6:٥kL$MX&6U&QRN!H8&tCY@4F0 g\ܙjxX5,qIq-aTr:FRo$JF岴ixA &1̋r0f,DU%S~s!QSTd [Q (Z';3"ުUr7huNN;{`B୴&Yy[w } PwM<W_Jjm?m!: x ׼lJz>5xy pvpj.of 4.я%](W5iXmK}ͳ23 Eqh@ny솅~]* Ҏ@fzBEM]|*OVx.v97袗( bZ'y {C !k5i&?n7axJJ>(đfR{W^m΃#L#"ߨ41' NTH$q63ڰ*j>" a?c;@lv*\ ÙI4Uܖ^ak"s@bPRhg^Zd/).g"Y>"Y3ԟ"}͈u[tm6juTE8nY_Iro3л(`07X*}TFUH+(2t-rx誝4qkQ`ߦtK.@?OKٴ&PөU!~FST냍Iv`KO U:|B1><ښ|PR-k&\~ݬoXĮk2om7] MҶI"ׂoZr(u"|(?`DJ0߮DQ PdE, W_\0{ I'm?*`N}@M0ȘGje~>\ե*ja;V@7f$0]OdgM p{xWރAW@^U_SԶ}Z"(L咻Dgtţy*vR-gj٥j5͵ `YC:,7/*7(3m+R ^Vv7π'ҞLɞ'@ Jn}d2av8\r2Z:%.x0!+`&̣ ]=rFi l\Hq ֜NOGQ^ 5Xl鷗JBGfl3|7R-'Ah'_RA lV*FVF8:z3FAk1@% ѠCDLS"NؼS97xܬTE'u9,{s$L_z*آ!9; u&#*>g1v.E$9hCI5"s2#GNXOK$d'HgqHC~!&|Ai )qITvZdQńzNew/D\eyL&kD+|$CiLz_Jb>yq&sxWkBɆ/{ճ0e7%7{{#Um]ۊ)#CVj'DwUi2jO`O}t`p8LNm8΂eˣI!}\^ш{VĶgDÛ/Jbxa֔NNՓ^T )~O_yKzlusZZS3?H]JTd&q鍗+厔D'ι f$wģ<|/eM>=\RL̑,_}~J㆙4>&bE.9g6A(-ft ѕ_!g1֑KEjgaY: VBPQWjqwkwZׂљgW?*W7fb&8Vk̆AjNY puHC}㛭+n^!GfR I\Q]X~ ~Q jXNc.V MJs5ekZ*V`|\BOn2_lƠ٘agPUЅH&HzK-~ +~& bO +h[!Khc08Ơ _ֻ{SucV4^vw~G#s>cZ97F^H%D r cLLV8[땠~`'xƮȍc" ;Mo*$d2r:wFidD_R7I:[>>KL-gN`'K)l,۴I84׷7My0h% u0Gaq 경!~Ay-#kKsL۳;RFh3,n;h-1NCxfudlpׄuI/T +ajuqLtxľg:KTPtĆ\+12~xQV^k4Rf -__M$:@Tl9ط( kH!0AocIr[tvQFF |y#dUٶoORARH&< YzwGvF_{i댘_ ym #Įb.CO9aSÊm Z᧜E $jMä\oƫɋWWoH-D}#Z7P)#>t}]0[j{gmpjO2oEsb/KR#D,JD> CjY%sq~E s=V3p%K^i.2kF/Dn" j E>C2ǚ .uU mfۯjU/<* +S(ҳ?f ݹpKn2E) ^yoz\>܏0PXD&h/EaUuv e]ju(&IjA v=`r=>S829N>=2oN})|DVm9{M)"Z'844d`!L~Ho|څE#K< bdܝ :4-*SB300v+l{R34qnk:pVF +[VJJg8P\0N?bd*dNޞuZcb ;a"ؙo0D 檣SodC2m-HgkJujhY.m kD7vKO>V,U~9f;D͗kdo׬& HyGKm2E@2?"ߗgV&3OI)krABXpBuh$Z-*H[z^լT*Ngr/o^E귐GG6T9*-S/JH{΂q\]na2]˪_8#7ȷF"Q9dCjrD9@ (]S ?M?g ~ ѓг`dbAEƁL[OqZ޾G uЇ^,cvUɻvtX:]/q}X40Fe66͘H8d"&]mGajGr1\aK4k籖 ݦ|M=Yo[O:\۲/7)X2MHvp 8"N|eP+K0hP3Ii8ƦjfEA&T :^-I3-MW/_P{&! tHSP>-酔fq.4QABEKGOңߌvTf7㐵( Z\֖I{|XvTk Ȅŭ JAE}hŁvf?1}.RK'jɘG!rOo1'Nټ^j}:aZTSFfoQdvj-~Pu endstream endobj 153 0 obj << /Length1 1357 /Length2 5945 /Length3 0 /Length 6875 /Filter /FlateDecode >> stream xڍWTlS@$T1:6QBc66CB@B 4P@N}w9=Ͽ{LHD"B`a,@T @@9#ZP^p$BP0'SqfH@ %eR @!% P]$ETCz`Qpg4.˿^(,##%Cv2B!n3$CcW{ #QΊ|_8` |`_ !ߍ S.p?b3p789x#a(.7LG`C1c k40 Bp8`#M}a4- Bܼ8q.T1@p՝@{ {~u(+ nG5; U:⦎VWG8:jCeQ-s HJZ0P_ͱJ/1@ ,P{A|`4QG8 p9GljaNͣ <0[Ho1UWUH _H`1(_UA8!2M_}޿g,C$0I/]7t?vsZ; Wo4HijCW#?:h*g h["3Fz=(!0:G *4L"KTBA X ܊q7 ?GCG7"$pB(~S\ {~ )Bh{0 A)f&Pmǵ*7|ƀVgPOIjQU^_{4˟gɦ#/)6UE~S\y%32ԕC-Mm\HwV ]쇨eI=ʳQxq`C Z= kyCl[ bK'~^\L}W]K׽>x!c'T߲1j]n,/3!N\bv{){ xޜ"FTQ Mr}ŁŕA EjRi۾b#ȴ-|Z8w6rS"gɱ/$u=٬J]*R쏦YX\ژ}ВJTEO^Nkn'UH~Y?]-V+H?<5+*ɐEɖ I+j"y X~%]y6Amo^^gHxF`^UH!5}R@AUxvV#kR%+HDᆩ(L۾ZHې_X^=Qy5\gBSV{x:zQU+^4Fa VV1a%?OiMv\u3@`%J;x\ZNu^W? KJTwBZ\Π]=s B)E;K3VR&,7S*EW׭<_!\ȥ'{12{{Nq~U;{/ˈ هI1u}.T. ]5͔H9vz/[h"/I:]H";mvX=L^hf\ .\p:V+zmLR1N9Ujp;[),x,w5!stjh\󺘹|mktI:5J;o^"-cJ5yZmߨn>$IOxLRz\G"nr$4B0$o5 !,*h2U\;"p:v17H`duu%K`Pv "sޛ] 6|g @"tQ:糙X  CgL` *n1L)& Iv%[w"֮`vrxL=1#J}fFG3oK4ǠkZyw}|mؘHhcwNE=Ԗq9aA}e#l-}DH1t{fE1SZN6_f9} dzD.HGKͰseQˢ"6f|.˨Kҕ*cWwؗV:y {) jZ\ʎ3]uMA}*`0X=xْ3k۫=ݲ+A_{:29^8l\3fffrzAW]&6*$ V>g]p_tO/*uu0V~jeʷVן!+%e NλpfSI#;TTp6p#uRaގ NbUjx @O?eHiƶܤWM<)(ِJ!|rї#U\}Bfuy#i!X}yv7ъntHtu:_Z__'_ȖfoF%o`I'sS}wJ0&[ 6m--5^?XLJiar@^ R-4,2f;Ӿ;@ʩ8,}Uڒux\n T:>Oms< m.wlrlH)biK k U{^t{jec%QAu+ f0Dտ,&K 0XR滏L߱l,8ڜbpVgWrS8T m I35UX6?*'QPByΔ;[E:W1(Tԗr]^@/ݰ6qV'tk'LYY>+ۓ$ ԕK]vccg J9 Ɋeh&W'4To㍩a}Eeq7P: 3,9Z-RUr&x348uxTk\+ife#^6Y0FVr%" ;aýqם"15KR*o#m1T(d Rtv~ȉPu1WC)͊7LLdFh.b:mwuj$".㒉ğvM(GeŔggcIޡ6o^9|H)M GCS+Ff*dUvV@Ny셼2GKEѮwl '_|"2')*W6XNWÚd1nzn CXK~)vWܸTlOH9{ g'/ۏ)ƅXӍp iNh wWxž{Ծ$bv[3zۤSݟTxE?,z&?hepD촎2ҋu%'}L> T'T98c7SQ`+ħn0vy}7'4!,} S4%=IũS} _j@{p㐋fvkpCِȠ8o[/ Ր=N0Y9;q=MJ$|.{١>5^}l G7c.ۓ}A Cjb6a9}Ssi* KToOŎJp*Vː{kG>(1[cgws7#ԷK/\XbXއZ oj֎ r6(TTT!+s\rzv<pZiRrг|P<:ewm [/`#(=/Ŗo=4cx۞z :dLdNqNqp85zSM!R-Ya\6Ƚ)KM7fA8p(3zgKk޹d̷g5">& rlZ @SZn۲=Mo/Vzcps s{wdL,g.֤G6x~-ܹ&zXav|ՒQ+{C9HD*a{VDMA#CO"-%&X6oLWWPGJf3*Tk@JpN5ϲt;_T,'J5T>|ޛԞn矇 ~#S~ۀv-ѼnۛwD6a:oU So¶D4Ts&}B+<%و1x@Pl@gF!tⶳEk5Q_4+)>#9SLyGXf$q¯ګ,h06#u5JXCf4Dtf[\G&Nsw`7;Mʫ33S!V #7P[u</-LҞuU\Aji_!6td_p:aܞmxV59/yi cLVUMx]ndk1&7A {3aOy`@`7EB\Qܓ9|5jړU)X"W4Ͱ/C9 endstream endobj 155 0 obj << /Length1 1408 /Length2 6330 /Length3 0 /Length 7292 /Filter /FlateDecode >> stream xڍvTZ-RB/JHQz{B$B TAAH"]:H"ET~Z9{̙]34QrB;(D, T3`uA|p7_ 1U(oF}܁q DJ"- `1@U/ ' F>gş%&H v*y1Hԃb]aPw c ) B=Egya4{1p'rPD|@SA1p pG(o h =&а[]_{T'2(7ʷb& 4P& *%~ZV?P:mԿ!jH2j< :O4YiL_}7|C]Tq5+Qm/Ԇy G~U]3+Ft(J?ě+u|6M ;8NoƋξ0neef :S^Of+.)J`2D.};xRڪ>Ftts᲻垄kg잻۸ R-gϥU<$sUN]̃i_.i.}k *.#*uj7!]'`.5dI[6@'TA+)IXۮ:Xxw6.A|Z(ͥdo&!uU{Ч?{aI(q$\ Dn)[/ktSQ($W܅~~bnNN<g}_ڱ y}\aD< !x[0=Ԑ|{dB'-ug|CkFuZlk.>ALk]ai$IC=ڗT>NSYM>Y #ǷfA&>,Z.%K3je󱝭LޘY1}z!PrWokᱡO}к uצ۱Lym)НKr.J$-< h ߆9F0k&wR{n8wr 5A 7T:~ت4`iNV-7N(VJ$gW3ockf}CWg-D ezvb`fZS]}ХF ug ԙ(,=$R7TVU˾eYDMsҞqyiҖ ';rG$Q3NvL>'{;ژO2YLUxZjKi{_NV%SL毶 =5!OPv<-jL=9!s[KRDU䈅Aq'rjgӮctB5(6OʛHbR[7J )?U{ogNv>yQ!NrNǝk0Qj7i4hrW>wv6+G6Q0IsHaH?*vY0Tq}2AX8|NNۡqF!$WJsqןi$'Saib;=2kE}Ӝ-i.r:{۬x2.4>z1j?X(uRuS9|$K:F&H*iܯ9SGfL96# H],â V$q y[)x6lU@OXt?2YT ?&<'L⪨I~LDY/7T7ӝ&~%av/,ŇNEkDtc=5ʟDJ{%^Խ_jnvI(|^@(2*r 7>D27E'=%XW 2zǴD-36j,U:y[حYry1'>Uak[)2єm]h>{񈮓5IesP{honjȽ+C5vGԙ;5_%S$Vh|yQ9[W.KGr{A t.Zq7(y/7+NzFRJ=݁ʡ 6*ėmgjNn˓x_['[kܘږ[67w$}BWr iV֧ ݈N`IU* me{Uw2hX/xz<s749I|lfcn,Zmz93^Po1]4h ѳ׮vox"_DK3Ԛ]mO6Ț1{/~EYEkaCo+\^LLﱷ\ZnX4}%F͑ kZQ@#8nD&Q>ϕFzcMy9p2qwn9~կQ>nD\3Y<%-'`20F{Sʷʜ7t !hӵkQcI}/?ȈFu@H]I Ru~8 1(iծtSbYH^\⦹~uiSwĞ,5ʦg`ok|RkN̝ЦejEz]k{_h%0 . Σ f# ypZd[ezyj T,%1ZϡNkc XXׂVq;?JRy!R+R6k'ތ~^h0t{J5CTRPz8S.OPmN45'%Z3 Xa(>yx XZyr0#خdO \n\J,]Q7oB(/t %;ӗG[SZQ,zф3??Py:N\ ᢏń!׵wT|Ty*̓IA}ڧ,1g Zخ"ǺA'゙uX H=*\\ɭKKI;Em(VYp\}=y0jP-#t]H}(Χ4_,/S&؍hNǍ2&>dU?`3RbnsjL}q!$U˨!Tہ|/3,Y7DS}cFKVL^ w^}nZxfcgs_wrL9 ؍ GkLu^2ÜHZR䢿$''c tV+װKT #49^3k HU qŒ C8vEHp,voS1W\K:ITf)oQܭp\&s ؏)bڷ9Pߢ*G{Nzˌ^&.HoVQҐRV_1^/$:/JRjԦYضmzfH۩^֐\ d挗 CK`3ES_M-8EN$W)yӛ}k>f0,clOYқ]\8eR6:Ɔ~ہy.4B(YBhv' CpX}/T:*c{j648ʒ/ +En@2<^AgtmXjn2ynuIZm׃ePSQKlBq.̀%ַ#^+_0?.@ '%Xm-5K$*f4~[Ḷd;BCa(P1.q{28Hٵp*-=K=و+y楾ΒGOtÌ&s]\].ՑWc 헩 d%Rmf/'X7uxqgCJEJV >dEīa@ud6Do<_$A /30t#$G gb "Rf=΄_iD4֩r*i] =3R>:`/ַĢڵIϠ3AɌibH.RLR,;1("Jar%`aDNhqP̥b#LLKhoJ5J's^N^C\ cCH<2Tm/5cܵkFs&=Vp;J=>B*B["U|\#(dHc_[`++KZTK#NKCʣٶģm-H+|C0e{~"Ypppg.~XZd4HHęt12.\8Pϯ$ 6+6+FWt9TTzU-.>Ybp/S`;nOH9~ѐZ&zOm ;L'Uy><{R)zY%kȊ_vb|^S OvWܚ-6yqxҮPW])26X^Wla ݙ+K/`#lD;'@S!lg2N'th8<؛MD O :ݶ/'Y9 ,ezCxqHaK58kFYvҾd/y nwQӔ$m+\SvW ͳT y)s2 YĎt}-ܟD\ w)Ѕux(F@ $tƒXC}_R'WRyڽ2-Joi>)">5n, #hl1޴|CջQ퇨G`QAϷ/c "keHӇ/s<LhgT jDOV9xr:"KVC][4w<rzQnԝ.Ǝsr;C{lCfggL~)~n&V. bϨ2ڭKr>VO#KMiv:;uzAD6.]ަai$iXVX!bU-L\&TAׇ?J!KgMͿ' z6K5,8C.>*N¾x@ Ԣi/H#.-u1>=n?2Iw endstream endobj 157 0 obj << /Length1 2043 /Length2 13644 /Length3 0 /Length 14892 /Filter /FlateDecode >> stream xڍPk epw5 \e/yWzW0J f&@ {  #3/@T^̊@Afb NJ@tr/4vyۃ26 '/ /33xbnVfyF=@!jdeayPXxxNLAycKMmV@EAŁݝΙBnb P:܀f(.fiY x7ZA 3Ui9O?_dEd;i[r..c_ƶnV& 7H+OuΦNV.ΌVU{Afvv@3_Ĭ]dXm@ ͭ@f`rtJ'݄ftp033s%_jz;;KZ߿݀'W!̬L]&@ +w3~NV]c0lكl=}L:rt_ `abp?o%c`+ 2#K#?OŠo. 3cwe W[ۿvVϫۿojYWyJ0Mr)YZ3*Z0[+P |[ej~i8.WL.VN'#7=`#=^/ 0 eqD n0IA,&? $dw"nVq4x޵A,&gjoeWoe c/Nge@п"mVl,Rr z?ߵy{rku~'sxA@s?VXY;r{qN8Ixlklw?b}R\ z@pw>Zyg:X h`ol]P+Lΰ??KFBSyN8eڮ8 ɫFذ$g6)ɢ~"xB5WG@]2y(J} c 5/3 1zs&d0. Dpswo$2 t1l:[^jxx:DcӔ"G_d>,zo:to%Q{+<82eĒlJ+%MaϾ\nLhhUbwm1ݐwC)5 ;ã[M&O,tB ̯I:aԎ-<Gs\:x4A[ᢟ*RC "vKuxmHn/eBɤ(:\j]ng:(];:(bLW$a0ctzSLͶ NɫZ.[oрwy}A4o5l{Z Dne gJ:"2O!eYٸW` ҒM:̹JƮXV }( ]Sz`cl6`p["c/{[7rn λSA+~5xPک;vK੓z¦@\ y WLe59 \z>>րEI4=F;$:t&TLD*_E3} Cb; qڹV4_L# ֩z[ۉ(ȩ`;WJ?crX(j s@bhEbtmp$^po}Dž= 2yVZĠ"3m'6x5 /N$2CBI7o S9{3}-?,U#was4P|Bcg" ZqbVȐ $deZbк6'wq.Y=טux #欑-9">xvصvY4c-DZO~:m6hMYJoA,P8֙кPm'=S4¾m"6CMpb XQ)4jk8ɬң- kg>k= w.U ىvw–_=_][b#~s8%)f>Y-Fo4m _;8ǻs$顎:؆kX\tGlmzImUNܮأ =B0ڏ a4t/at^seko]) 3$ [! R沇BEC;(WTw"!!&P]nF>}uj|:*LWɏ'ǦWzȵvFENO"cL1 6gD 2?HiKFbwKf,#ќ佴~UUou'|'*!`-aWlI5O8?-h(j]W^B}Q Fo tiBaNx nUzk\vҟi{[H9zFL( 3fḍ۪m#Z]'0_G8K7;kх > ^ް;> ,ärT⪏>Ӟv C$<4Pb:*:b[Hc8Q1_V6X[=U S204 άٲG4`ө e l _d&2nyo;X~c vU58<oZ@e$C.dtBL¦S`_{؉faH_8n+jzI58;}ep?辶CR<vH*j0,fH$ډ%m ɋD#. &PߏoGoJt/I^dD3>NEU)ځ֎3 XA||.̩Lv`zMN~됈gGگ,Rr'&#r_A&$41 ظQ@}t ;nczzWHT V]jVo~6";*,7,֩ [hI}L[l%ԤC2ܲ:SNS2xˆETyʋ<]Mql}E:ԅ;rҹ jotگlqDR㺟E9 Dd"b`Yr^jNÇ} @Q[賃ʺ1Ge<c홇$+ 3ʼn^)Zꨑe"v 3R .Uq8A( :-7:A!f7j8䆙8!,^GHLdJj$o>&|XC]~wӘ2Zt7p VèvG,4.X%&і4u|kw륰ЬpR*Z>j #%V_%|RiM]5ɥU7n;b XN-\<x+@#=wy=L.ay'!]0{vK!jUI7K~4ALro}ZHpD(P(B `}ڰC}F;Dwi %-%)XDv%C %/o8A#rh>JPyV؇UU8B9K#iJ!#pՌh[`m_CӓQ8RL2׭:rAH7dD s&z!Ӎ3agFЊgmJcda<;YCj:v޻J[|r4۞-v?Chl\f* 2-}?D{qnu~Jb O:اcPID£hT?XV #(IkX7LJ׵6 }YlG&4V"B`*< hN  i(8oazrK U-$fflt$ :(Qs>,]"}|߶‰k[};ۏios* sD+MNc]sbkV ]6FWhuߖY@7PBw΍>mJNk6́XF&u؉c&铪g.䩕RNWljތaUfGGO]ljeACLɮUI ݥ40 S/[W}vx7l"iš̩u% 07B0aJ,(kMBomAMѝk{ܣ02^|db*|ܗIJ Q$,F@Ny6>tQWnCU?Hq]Ha&+0مǢ ٬*7qZv_  Mk-s?}4oMG)K .cl굪sKlu9EQ~Lmv`W|ZԞ={}{@5tU[*clR.ݻF7Y vo*{w%"p&Vg3%XJrDj+jLVL<$fϟy c%gm;f-]-jE7 9T/'4o:z 4.#Zch79]`D&1فUmQ*EWIkLp(t_{gBlW}>*MBٰ8bHr)>띾0r7EIts-A S"Sp6YKa>||(T!gjޗ£dMe\v& ms-Sy3kxl^0]̓[(+#0BFϿ .&ո -v$>N*(=r ?l.ëxQHrW1AG410?-;=їԴK?b~kH.)ם>~3'U:^h); 6+gi#J;+stulMCDuHiC o 4/l5;ݜQ8|/Կ/W1 Dm)<=I~6|Hl|yt5IփiX~A1O+#7H5'ShMl fI!Woj,ˬEpeu.lHذbeֺK'@Jcv$}e "Bψ:V:,6f',fX?6gн!OY0%_$ 4/wκ"6:%~t>$<;`<2h|$, HLDZ&cZ$9* LļyOw8S:P[5J}u8M'(j1-ǭMw!9FĒ<_QĿͬ 71R0JK{>uӼ@TF4:(Y ќ̇39JCtXZ ( W_uEeN lq6Ҋk'գs9K=VQTs!/!aWpOW;. wt`*Za",chhP3Fy(^ZmE^0Ϋ=&Nf>?.Jg]-$- nΣ@M@w9g#ciʞog3gG=xmv}."HVym,(,CiTwy,,|E'X&g} uuQ(gd5uST:/?$3mNMY4~p qa]߲:q֜#۶LIY4捌͖r>n'2zm'}fB':hI3=?`5%p/ߋ5@B Y5SbjctǁP!$1OZ/΋Z$gI9]ChA\Z1K\ɷX6' '4D|X`5M.E?Ͱ>0{LhSؕJ'% .06̈́䖓a(L*xꗐrW--PmC]Gcy7g>)&G_jMei9VHHk@=̎pq:SR%/%tY *ꂋ"vxNr:}Pcد} XتY*\82>iIfT#`[;$IZ(ƒK" 70ٯ%iOd'j٪- NviuHBŤ"Bg⏳ĽÀVʔ~umېv3i2 d<_yW/7IדNOb#pԩcS*IIBO/R=F,w$hB,οcA7rMxJ@ M*BD{2mk YoNB-oXGs{{_!;$lNe5Ve7I0H/vi]c 2f~ak>IDe 1B 5t 1XQkQ=v? H 1! ,W?^Q7XR!i~# [1՞]bD$i㦡Gn| !^\'p3p:x߸v?;mƓ{/$f%Jɨrko _<uxaaS#̿UkpQW;1$ vUHK q$%xW-qd'0tn%SFLfHx s"LYƓfSV~\l܀YG 07\ALŮi ]l̜*[mo!]Tm<2,c(] b 9nK8 b7zL`2tK},7"تhwEьD2Y_VɁm<*$3$ЫCpsA1ŚfOy#%{hm/8e9_ӗ:TL#8U?# ˟UL\Q[5NFn5+` ڴ]v vwhb-SqV $9+v9dZ>kvuK *V+\nӅb:4UfKt*›dd0,i/#G d`D\ S2[OjM؍g~+MɢBPX{;,+׭:ˣkGW!< ]FeJ~Q*\eYutsIs2CvgpE!]7Ym>e3Xke6RYtjvo2S$-Qw=Q)Ap..QS T9I{[A-#nXV3Gjvu;u tx g(Ͼ@pL _jlZ~Ɑ:;:ń@/fytZ Fnec쒹*6N 7bGE* ̓Nq5͓fF/Sܯԧ*,E/sOv)sDYwj9AIcYXKƬB,LK*+Z m %XDA"9"W{yգ`2 Ƶ/Po>c)ROB7ҩ-E'0j},&jE(aKioIG/d,!g=3rπ`!%])l~ZIsJt#IݯݙA e\x}kMCKn>KS.c6z{EM9 jޜVCQ95Sb B"RB]8eq :Hy ?VvDo, Pcj"s; %sr/%R|]q5_ ۨ$źScA+9X^.U `!hY27[>A|%0:~0)i"]G%b`wa|ch/X dVFu,ezC6!g[҆KQ k[]ҕ$3P͎m 9OuG)Ͻ[6L/Lo.$y+ւ /0]IʊoKzIGܿqFUw~$"cc N,&OΗÐ|bnjՀDqm$30Tm&7~r];'"{n[-f 1ՙw6 Q. %w>+Oз1Ũ/LŤ3Y%G\LQ52CY™/A:ɚiKY1ds!]x5 2~D.s/i5Oұb}rLI=gU#7絃81)"0rټIl@SH$? ٯ^+΃\I 8ʴW`#L-l~O=i!ޘw!zKk8v#~)7Je^x5K۝>2$ozk)A2KY3W*2y!Jh<~ײX͙44]{2mYߺ'ȦVc|$#]]%C`I\hP/U(ѾE{0˶SJwjV4m%Hv1?2Von_p&Y)rd]e-zDrONٱa@ű,N#جn=ԩ5,1X۾L_U+?JCWI.GV˫s1#Ro81+.U{ϹqǺuT&ś$Pt̞ѯF$is5#0x-Э $}=_qÔv7=X @_͐Sy8!,z0s9+Y\ս@WB x@tUNgdhOߒ7CU 1%H$2kM*0-u&3GשwRNBǶY)5-=wW벧iskX\(9IlBR3l>H4,K9ȎI|1\Bn~ç4cOJUoJo#m,]&sW d+hl;1mܧ*I_Tu؊ޗF]Oinޅap-:}@!F] qDPg(4ŪLl5Z#OrRttK:0s57u{Kv#8"a"M}TL`ń Әܽfm\RQ4Y,+̄g-RY&QqZn1v:X<|7ZMa /;ws# o)M,3B %͜b]\͋}K f)0:H^)h7Z,@ mtCh|M{o@(f ¢@-!kfޏ~FS5T:.Č b,t"XA֮X^I Co0ظeҬ)%XzesK;jbv!}tͱff ܗܢNbN 2 p94J*\dkYq0W!Ac2%3mh xsq"FՎjZ{ixd5 iTnJ Z>X(̈́0Qd`B[=zՓwԕmzqd+l=nۋi8i^|wO{3}o=Fw'+f!hT| endstream endobj 159 0 obj << /Length1 2183 /Length2 12708 /Length3 0 /Length 14028 /Filter /FlateDecode >> stream xڍwuX. 4C7 ] 94 JHIHH# Rw{}yf]7CM,j6I\XqEu 6 `Q5]@5(Z gk6 WLbvȹ8ll<@ !ؙ anmPdȁ@.(`G/gkK+WH|ЙxrڃL&V {HF3;:_!^[:zxxػ-֮V5 d6@os,( +kU` Wg"69@AH~@L`ca7?޿Y;lbfw4qvXXہR ,L_&v.`)MRHtblbmK_a t0ۃ\]P~'a 2Lދ#u{8Z1wsdtvrJcY\\@ r '̊W /G_J_bHo} H+ ;z ` v@"Y!,p!$df9_*$'ofv @*&򇫬wAf@Ϟ;B`7 \@37rWoMRnvvY0Ba7W:(!KڠXdnfZYWZ:XBEdbjfMkZ;;k U`fG53[ua_*d;αsqLMPRsq| iV+-hyҿD#>򿈗qXE|<V;Dibf ۊjAr:ق o9ǿiRٿ  l$$!w9ܿm SB`7?,-?M UX @X@d@l~W i׉C`BvwlHh7{_iGJu ]$҈o5$#_kVG2'7+ѲA R﮸~!SLH߉!36 >n@$=(K? $2@"y-3d$ݍmyPf!6u!5D[=ܚnd(v,0JDyW*VBUa D<|bm,802,NFπ=1{^}2'׺BCa`<[]'e"Jdiz?eT&KmQ:>~>l6*?&ZwjJ[>ӪM^(S9$?J*Ag՗_n)%[dc =F&B2l-<dsxJpOНbwX0܂U~2,O*\|V;jrO&T.qK;'d݇o(rZ;XG &TxgXe cy#_QwkӸ~Rl&)sSf_ N*GKu>pV<}L5!'y6!G ijލhX`;8:A띐~۬\&ΫN ,Qxn|lV׀|1rS'8xxCT:º͜pZ9`|Kx]$U {7 q{k_× Y[03Cy-B-L>. *(_#=1ܸ8br$(fe^\+s'۲yubo Pp5/k]f`US1:5X '&YY'\)Pe>𐓖G\} cZq:i$tHL"r 0JB(Gj<|bMӣj(Ȏ!+N}u^B ] m(!)" mW *ôI%<Q}1A3=7nȉKό(x=Aԝ1noDZHm6:0ѡ2H:'۰]=LB'):G8 b!1SXQ3O?>_(5g ~*BB,Țm`f*Yh|iŏO>&P2"9Ǔ|$|j&䀃kՐk菄Ơ55D.}6#!ͺOJ/RXɱ*.ve^Xzͩ6f iqXeV~K-^1 \/LZMM~15 aW1 Rvy^۾Okʋ_2= 2 9toXEpa`~κߩ`kiƍkwnŮʪ䟭ĪX ?/YIq}҂szvz$~ޓta˛OQ, Cikל\ٞGp@c_;v$|/4wXmOf6Rd uwHRANo>'бaS~|2HpQžzoz1v@6FxJq'Id)HIhN*G45+|WzP27eo;ɇf 7 F⭎x5#&O}TjwLF"@7I4:1U.Y. 揦^]{ qXފʦ8 @Wf&V滛Sar4tF{oVP>pN?\3;H[?/_ǯyeQ(z^6UD^T>ހd M~Ɨ1.Pbp2 ^8/"X85Lp[{;+zVy?!g=+;B"eEFBcהOiV2|SA 1nNc}Gsr40ȹ}ɵ/0uJI-"a(gscsL);R b .s`2W M*@bD sADķxe@1aD9ȉFGԷ4R-kΨrr鍑^}?x3+Y]kv 6 ]g7SYZ\Xސ#)Pl@`v@l/d4~؁ws<ݗ T~̼g&j''K5#  +lT5;ԓACQ+{} $#Ρ6ouLVD&/8њv5K\.%l~LC&Gw.,W4-Uc 8.jfD$˙ˋZb cŷ)WqxXs|VUL5p%;6G"Lrk`<|BPҨvcnJASz /If8|]ocE zΓS:Vܩ'砚떝i^<)dNt<e cJ2ɢq:f1qnkT yL=fgIYohRᡣ-3!jt8AVT7L+pͩC{%?GފZ6&e +\m*i5rƈ&}_lK/]??,;2ug)P;D*6YYJQУ9twy{`~Y){VceXu~-ba pfI88h{l~tG8]ģB1-@Y4HL!5.0v@>V dZ 2S576_ϰ. .h-n#Ս<Wʧt?Co%qpῶ'Z !s/5- +LŰ\3M{ds %3?=}ιoIY!MM/~Ǘ`NZQc>0 (h=M}:|2C'px'a]N C;ҽr ۩Hp.cl^MA{`xk2 jT]^Qw-?&fó#0όEL ]Jl"w 63>p^<}J'Y!7s /,mYc_vvXߜWۻegH9WP rt`!gWLU\gɛW jO%oDh@gMiˋ.IHH2&mJ!k{oyRa(9d//k֮F*9)Va+UtzGj6l(\G|gK pp¹(d̒Ɍ6bׄ\e?D:I An^11 |yب5]RP ezoNcXzg~JaIbACZގ|i*N1~/SU˛ÖNPg@fRbx7 9Z Ls"n{%)q 1±]TӱV{7}ߡM,3nd~0oct]6yxdy2E6quObdIԗ)gTM,n+BʏEQmbDX-jr$p>^o./Pq`#q6/Wh7b, ._o64cPhŽWUjC>ΩG*E4Th.:FhzHC#_7>uEc@h|ʘ!߇$5)oV}Ծt6?QF :XKzCd@pim9 l: hUSoɛː0stގPX]tu˪d%4쉁zECmxU#ozr8xs\9{R c%˳$R2 qMP,Kc+ GL aOB:*mxܼ8[NۦF:{醳xRΎAS31iʛSF??1i $%L%8VjPmuu,ma9q֮^BsM\fJBOÿ$er>T;*F/@ v!^z& I°LVAq2/1\շ(HY_^y- aCT|gF.XkIIo0z VuE=V{*^f䕩UGɧEC_R4"H#*ۑjM|]T@Q&ގGhWh Åя[v3g\ܽ9QKqHwXXUӱ9ccx *Yov24{DZCA„-&X2vّ_Tgo!G?W%dQ}Z J(Q쟴a~E MAOL%p:{F}<(~/O=䂿Yio1@֢Y Ǻ)!蜝OiNA*ddNF#U>|,LI2d!6Fmb?B#yt@(/ϿFxLtȾmN3k|I,ff̨Yv"AeSgW͍}j녥u"HTE%twV=Mzd٫EU!' 2/qtmdu~QmXOGMXj)Wv=CMuj X3fh8SSKbY//\@ =eD,0uPlEN| UFi:a0̶{.p]g.xYCՎг'F-%wNgkj1,io_c֓7*ƙ1:y:K)ւ_M "{ҥ Ccɘ'¤-&9t} pFKUKhDegKl0{cP]04y$v"ir@nL'PMiPؗ|8٨\9^=ZPgYTLܤJBVn-ک2OIF߉)Mɣ(//s Opׅ'Ҵդj@Fp\ם0ioc.1b*_H4cj,tL"/C2ɘ*pra ]X(WO7\Tvmޒ2<9rAE s_d΍m^fe4B$yF3,I,իgH)[vqӄs kZ2!\{3mŋx+pDA~DGv WXG2QV6>z.tKRwǡLBI J>/ϛҷ=xOFїTIPC >as'+.o1Eϙ,=zqþHWud5ӽTTfgS82 w5E8K^/޻@;M;v/w5C @ i7 K"MhUp41ll{nD9 ThzT3릡w|ֆe 90aw\^t;9[ Ӟ%˦z/U2! w);6Iŵњz:%96fETV\88e%!IƐWϛLW6sJ˩`rCߓs 1*; {DS! V@ 1+W;GeIP Aָ'Mya/s}hM!wOUն>TonAy?nŬ~٪A3|D7jq.f`&J”-a Ed.w9#[-t:¸cͻM퇘ja㡕3nŸPM ]B24̥/Z\ZCD{X*=}4;gDih5k) ^zA'y}vdfӇZ>k?XiŢ`v-zCpOI5 ̿T*{f+?q38;w`tȆEyWTδ\ZwjNj&9jDcM9 New,S|l92;7o{hWb KJ)bL.w) &W/׆_\^mP~-!lMGhw٘DGꪔl{v|x.N~lv㢰dzn6 R;gL[x㩑krHZ9ҋXfO(82~ 6>9/, >f!Kf)=!3A}aގ4N`Mù@qg8 ߘ9ͤ'` `yRB9FC{OD =nܫ.쾽"4],HxR?N9)B_cH"r'2ܐca㶍}},LvAHrYb?nj:UJ?QWk)s=9,SNljI5ViD^ d*]%+7OS KsQ)vհ~%jk˛Fֶ9{vѯ"U<:p{I`+ Ϟv?FXp.EFɼ 뢿~im%3h\) \usKaآz'X+#"D=w+!aלَK>Ҫ^LnָILuFyL5!|H6 =ӒpCo~aH@tqEp]`s`C Ҽ0Q vU $%\Z: $rt0iݐIv]Jru%įINVan/NrI2Sj5Y^HjIwku + f,:_v'U~]73|mZ55$sf衎=]ˋCIʥ'7woˆ>+j}Wz}c^z Ih[q=+!BePfSS =K[ PN(JȞ|y<{e榃jnWA)qHB>?գ͠~Z$Va`^5s8<ɑJi(t+1)ռ,*5=%AN 2lh'\1rh XBYR{.v5*|j{+" ѥ%cՕސh9yXIs˙0 Qc|?K`*_; /'8`Z}mqWs!v3*w̕lz_9NMR6%ϝL!]&U_2|ғqN#Y1`Q/J~L;6tsiyoRw'3T\{R>dok8σ?qsK3ud_|A6ec"p[QWf2oǹ==^{R:8ju)t?QlWn@=έ Gi;1}ЁɭTu$)nP50q: roy0| kZӥL,XZoزU4yMKcsORƂν*v︨_O,Ӥі1A8'k_M4VSAJ bG}}~;>>֨fEӫe91HQF`ML; B.c!uؔUቐsԵxde8~Q^"z^11ɍ]'(>0?wBj5Ve`uI0P֤J9[J$gg V ~U {;orGQBLJ|8sHoLHEx{yv잫Mյc<߿Ғ@2DL1οX]yƲ=m\m ѲǼd7]@ht׮|XfvzQ"jLq g!R2I2Y,x#U>[!On[`>|Df=\XPiRZƏhA9茜?& cJ\$gOu邾;[f/?=pz:~mZM³:*BlָOCng EXL8A.o#Yi}UJ>𯛦g^, ]D&c=, <Ӣ56"h~m(Ct\6q/W`zx8>З[ho#.Io=raf0(ng^t5˂3,/+E>o޾@LGV*i>maZ`P'^Gg d RDfʸ $F^auH`RdJAm|fX/1JjdPҮ3s0\`y ђS gֈ@˻k\|`O: e b'_lʌrwʬˮFd X`쵣lܵNcADt zx:WbV<t͆換i@yaP0x_ut>h^ }^U4-{m8&\io7 Dĕ8 -,s+9OW`&HoK\zShغz{,iv8PsEu/aX7|i%URooJ{bND2&`_u϶8q7G n? VSy ޘ6;q^=Pn1r]uL=NɩOp0P@4_e@Vh8 NVCj-DqJp<&No豀2GK|2A}LMzt9_CBOmPns>pF_7Տ><Sd'd/yܗ9I y)4 =lhģA3 (4Rz &VQRZ1ޟ{Xh4T>5oۤät䈴A!_s*nǽûAb^-z # &eH y+{"LPk3 U:IO/²|+[WS +zwZF6Fvjiqu?Ѳ "^脽0vn2&8j*n䠆>IŘa[lΎזw\F?*p" z[pJ(#GJ3j$e\̽\BFviz*ZBĖX<,uV*[@qhe.ՅN@nmꧮ qgȱL{5VrVSw];27b:=&JS%9:-꼚X^K~D(%b endstream endobj 161 0 obj << /Length1 1558 /Length2 7239 /Length3 0 /Length 8285 /Filter /FlateDecode >> stream xڍxT> )5 !-  3#34HJw H7HKH (!*7{}k֚g?{~Yʤg+sH^A>I@@@O@@YM@0 * E=)#QDm  E%$Ba%{/#@0G (!! m{ #0 ?Bp 't /#W{wПYF.`_C@0E\< jw@Es8A>+`3 tU>H={wy}=?!`8C~+ ꘕ0wwD/AaPWN`ӯ2=PcO 7 BD$DEEЅFpooUC?8@|+|AA#8PGG ֨{}( ~dR# 7wU̵/+$ DgC`E){ǟ3 \BrS(;#O䷝/cwC|0PD@SMA6Vu=j(E >xF}@z`$/7 ҃!nPCtC"4@P װ =<}QFDt3 C\N0_#P5n>2D{ rB,|Q_o { ( ] PA @w0a==%d[xc XbE|-׫I޼ $oȷ^g#yJ,3z0YӒ=tXN݈ =;)/߽kIJ5"Iain<=pGw2!{Ç7yC'Eu5d4Rɓ4^!D.+ғK#V1V u$ {6;(}2[=5OH՚SɢZv1uX' )Ǥ``7v/j/͵߷< 4Mue,(d. BATs2}(@FJ9 ʌ1zMh_+=ې$W"HME [ |LnU) 9iDaB##,7k /1JBUx |7}+ido1RvvõӈV"Ĺ"3=#BBmwk*`j>otzRt.0(d%΢`K̂0RXi2;LrGB%}t^Ns0n)<K,k5kMA'J-wpJݑ Lw^ξCun@zc5?xP/#k5Ѭ-O0Xq=x'Ȏ zecRYR8GCHȾᨱzd) })¶ Zr{ja'h[Jbibv1.Ӗ=kܓ]Os͇y-PJ/ "7USuRDlӣŝ#4amMb޲= W%(b ٣" ﯇BN슧õr@(c0Ow4JSTRW <`ʱes>ư|τY+XG+kRqHz+Dx/Ɔ g@=)zץu.CBמ6h"'٢ ҤE^lMܚĆN3dAQ3C#rܱt9`;?+pf9JBPCVķ/GubЭj[a=9gexN,[(>2l/I &}%^oeegTIE瞡-E 7_f_& Օ@0oZ ܺC,3khC7熌 ,^IvJP~đ? 8!0r6nq}i5@볥xizuLZɻv͕Ӗ|άs @s;dq?xq`e?˛j@;~h0#$3{:pcl@egƌ/n8klYIwMfWI"z\MARn4oT Wjb`Pś~YpϽ{~;C=%2F9!&ß2ש;+R'&.nϹ#ձm?|Ҟ<U:ȔS-h^`O\q;Ͽ<&Wυ(i[`\Bag']쏦ͻְAWDqb!q\"2#a ֊2,7*x~LQ\/`hX1xu~LLN5?mȈBcM5hD?9{s{}Nxb?Ihz.¶V.f b0a.gAv]QZ酣fA[Ux뇠"\Zej-:W{_Xg4^- #}_a>L}PL@]h ^UU~ްu;8 -&}$UGo&y޽#3ܙ#5E>O/f*MO!9^>Ź^k7L}٤ot\='94e5"Ó/6J򟖥GGVZG~ExM$|i8f^H۸>~ψ2T.|zng|0O=OtkHXAaF]s"I~rZڑ1 Az{ :37H/9hk~U#$W߰rk{+6HlCK# v$WiXkY@gXu"—%*_g{>S/_^uo˩1bƵ׫3qb" 9Që>7,=Ģ{Q\f#AgsÏxʳ KU)¶ɻi)WU&Ӏ 9ɡT5NLwƺ*w 9䖖bs]r:l^Ș1qOMB(Loߚ(}z&΍r.U'}nIy _!:Rd "M^:R8Űӭy&4;;q&~8(FAuj$`qe7 AݥJ4 QMpˣ'G_B$LeϷKurUױd'^Z7݃ h.)K\=%L`!ü$9{d­W s>V#LTh.&M"s|B>ZDMBnB̻scqsc~WGytj-^Gҡi!w2vCE&_6 6=A>s;Ǖrr:k;H_(}Yg޿S!_ v洣P]={vhyשׂI;K4Cdw儁$•4Dstsh\ځjt4_J_gax,P!!>E#T/72᜘57y9E smsKjk77>bkT\AkѲ@4zy'S :ۧcyTf6_1whNFDpWu5 Tq_iisp$zq&AjϿJ͑|Ul}nF ڼѡ66l`c>CMăE]҉ ,w&*tGhB$E梞K&VLQݨ`E## շNx;xf3C=D}++ kw\bhM>ȪD{[` {Ϙz.4W\d[/;<ɾuLQ/UBf&21It}Sy Q7rŬꡫ_͋^asV4m3'&*"nB2N$W-gȖBʈ沦Og_ G,gb\ 7r.DnRᨥXTL!>%jT4I7"&\YNS=EsYq15H1ArT|k[gY=R2JWdMo+ܻv:ZY IsU8zzf{ '!)8ͨp/Mq08x(n<%˿u\]R1C"w38U+Xj0(j&Rdy}.ҺF9|K9Uf""Ex:#O59ڒ\+ix;դG|* Ll>GXrqy 1XJ.lޭ}' /$a>WfoX<3RktË Xi`iؖ8Ȋn_R[Q{)Z[Ox)0MKؿ䛛OO*kE(Oj ЮSyqL:~)"F@IFrCq9r=h@ o? jdY؉_Gȯ^5zr]TٻP- q/C`b~gp.oIMo_z.DDGkƞh8Fl_06ƿL6p;!ړ%u'*3̺8. jD+ht6V\繝`0M23INCͪ4Nj;+}J[b,8z,ͰjzFx7W~*3l(m`)qE #3֏GH+/fx+9w$[e%LAڭuk_*QH5aC0emo2խ^Vpu "P]O(Z+C[Kg Ԫޥ|9^I0Sj,t"t/b-Ƭ9|0Iq<7-IzN[qAͪAZ zqC_.xo9Bmyc;{y=܆bj 9$i-T dQł7%MӍi'{L\sw't3jod@u`ŔH$5HIUf=n%%VTe|'t"AM7 k˗]#xXVx= ལO ^Ik%jxuw3;č#`*EeYHXV!A`Aܯy<s.$$XT`ueBN[yo_I'qYG6{1 R&IHoʺZ,Ltp=)Ctʣ@vn[7vo)q8< endstream endobj 163 0 obj << /Length1 1377 /Length2 6057 /Length3 0 /Length 7005 /Filter /FlateDecode >> stream xڍvT6HwI S:cH`؈]JIJ#(]tJHJg<={s]7 mWG02.\E`nnc$LmBQ2 b6U(E-oW@X0X_@ A]A@ {p=N ̿|$w8D:@Q.a+:@] #qy =@/^pO8 50uL0F !hG/` H8 ፂ=lqQ: ‚N7W"$w0E#QN#b0 B]x ~wԕ (vy9x"1^^H_# Je5LGaH~;`_f]Ph_T߃#s5]. T Hcscq~_῝¿ #vx0 7<8;y"`H `wBHk;9c,X _ F{BF;*&OYa11)@RZg(ojрf}6CcI xq+8&!77nHW,g1X뢱*@7Gp(VJ(',o ؑ^H?8q@a_JsEh/G 6 /V^.LJ]pzYW 倆lz~D1;c0$VQ@ꅝ◓==:l;A;F9G*Zl#- DhLx(4xWvo|&ɨUw^bƝ Zߪޭקߺahf1U)lv7Lg.%{D7ڰ܀#* +\+!s+DO,ocͻc?#NW-2E{k$2hqI`Ozã,~R|=E<;֔QF'=pRϙ h?ǗG3!H~.H^xI[&T{L*M * aH'85j"'iUT_+kыƥ')}TMT  qVi@%t3}J ͝pNZܜ~qˉU_/_QbTKJtG\HAN8M752USm~4ޫۏ_2.Ć)COpm^L1xkP.x}JR8X.hG hC;Ca4t~v^<61C?^|ygI.c>wl~"akuٸIezd֢ưޚfJԴ.cw5وj.M<s04EQtPc+o$BY9br.HJ*b|X4k貃uPJ)CCp1>qSe ~8JQR@?mӫa&xwY.tD"`/) fݓ̆ ܦ:6ڧ?CITAoWWRZSTPZֺK& l$ё|#S,~#qɔr} ;i\?ј ]'D͗R}U~Ń} E,+;d3/0/Ο/ncć WV˶_6A(X@t̽b0\jXN/u7K3{Qﷂeȩ]"49{?Hn5Z\ᴎsWGlWdtLߨS&2!;A&g!H]L2qrܹ9Ʃ#`r(NmBvx3VLJdQAݞUQP;6(h=O4/8stݜ1?vx:q|F{3_⢶T+1s vd:ROZ?|-d{ ߊQ(dR >۱"{( H"Yhpt,'=sõB%\TQ^v?l HD 4KR{CD6WԄ$e%J.E-T-'eMbv=?;?M>I\AΌ 8,Ԋ֧XUCmfMɴ;(0& &nnj6PEzOuN7/iGdD'8L?uuQRRUj 4_w^'bG1n9_|}۾.C&-Cj'4bCȎV(~~Nr@ k s2>U8}gNP;H &K\;מ5lCtKgLrI(ԩ18Hz `idꃭųX ΏƱ[oB 4E&G%+}7 ׌ :o E^l/>?IͿT|Av\7%{qAֹz1&[֖߼5Lmvo1ΰeB8[Zx%<<69 A"WI}s'U3J=#Ζ3GVl' K`Q0PJֻtZu W;6 Nݣ@]NfUGrGךefY_.9"{n wnҒAl"6UvEuŵ]xJ u<]kSLۍ i-nh8 gK;XTI35oY^r2mJq{NJ~rjp:m ͋Q\ХUU) #GM+ަ/R^;e˅=wso^6,&|J* _IʼfC֤C˷!ԭD[̂v»Mʌψ7#Ά GQQ8w9T3%_Bh;KKBuDվ67a)s)O9QIHmקT.0?wȶJElsCxϮ=$3U) fFK$wtI7 ʟS/Oo5I {<8Ͳ[ݎgtMmD S T& V 6ϨlɭsM:v17e;Ax43AW9TIm+;C\ŪJ)Q}MBzMz;״I=7_R}dmJ紸Ydowަc^(<4gW.O>ehܳb7L3U.eMܟL"c[n%r:;x G7dv H롤I>q:'Bʤ{u@#%9 "a+gd9-B5nsgU4*q$L5)sFw$he>~tVge:L-ɽ6\z!a3*fF j6)">R\Nh߿y%-J. ly1O__GIA">]w,TB)"$'XhEwrg ]I..9xJ7~8跿Y;{f`KzFz nKKsU) إg )k摖{τfjSƏ~4>2V 5OGa)Ym3 -WK2iK)CXi~!IFH u({KEҵWWAΒ0Vo2O !lTWG:j7vYeʃ˦giE. FT]ˍY>-S{}F/v;߬AOG~δ $G КOy%yYwal7[.c92ӅpOu'䢝W"f>d`E۵Wy̓҉Y!AC Ot<=4_]}oP%~m('hʅg-ޟIZZxneZ_:(Uv/W0KKn6SS(vD91gEWc,~B6Q4zˑx魏Un /11 D:b=}{,#UzUi{S6K^E開E@B.b ݣ/K`~ʮiKI/K>t}ji+O4WuH&{Ӧh-]\(e]D2vL71 ?JhGSMKTK Y`UN',nO|0(ɭ8|cB XFIHxp%_2ﵖWcŌ|&4kܞkA0`%}^ˡWyBYhR<w6O-V Ï Q%{l06;?Z~OeVz 9@Xq dʹ:15.25~7CS)& m^-XS%Z85X7Tr> stream xڍvT6)%2@FJw`&lmAENETix{=;g~s_TTriXQ0$P7@@H u5SZ8 )hAx> r%`iy<Djo8蠐0 *bepdD~04 C0`rðPtb=|||BA@?)xfp)Ax; #P/0zz"wN7W"8w0 qp jX cPx7q~wh( qB= kD_i𷬎՟ s_;Nfݐ(߃3 u5C iM) :Jov{<!`pgh/XvDp',GR'; ss/ ؀@>~t{b憖f&OE I*.3 B(ܟf_6e“mAR 'ConH[pCpw_^X ]0zYW鄂4FCp <ĥ`0D(,>1BSZ@ ǸIN^h4^gyoQ`0'iB轺жZe6DH),߻W=, Ohա Oǧ؄vrQY]C}ej-q+8F c t^MfH9_"v,>T?0dHaQMBj4~hq2I̗D|kzJv΋DŽ<L* VǚK]B>uZLcK@<xnxrٞZ֡yؔ i-k)i6u' kwi#ڟHh/)huVg0lhlWR [ ]/~-%iū ,ۂ"RϾ|DXL7D!j"$Y&Rֹ㾱F l:K2)&*R\t4 z1zRïS!g tk+>+ 0};EH09%&/(ӡ5;&Hh^f.7ZdNj˦%p*]awUy\e';, 5SG6 l]. 49gڡ2aV["[B= t`S%vN 骧+v[2{=ߖCms&[j~ơyO:#G~)q3p/R!%3iVcET-7?|6;ZP.Рvf#K*'#VEKH+|8'qBKEpQp+d*WQx&";>a֗ot3yz5t[s\-bVhxBri=tfEtmDxoGDJ'+1YuҊLE1Bַ 8ˇ(*p[ mjE|kYVxa6%:OK]'#DCb GQ36OU#C鯡m썾7חWe?\f_߯-_ʧ[hQ ?5QO ,JBY{1C~lNB@tA3SW[Ꝉ ezn%LXQ(!}dBTN͠ށTMƏzKjnjh &5M%}Yjl۴liW-kcfx7?̧K {Px"G'E =Vӥn,~`LvWy@kT}Zp7Wo<@(AwVe@p̤*8Xyc~RH{βdLNpi`IA7YʴiW o8|iGZ |QD>5&áܽ 嫇P\}my3} sglbhpNH-V3]*Ejkۥ, 0k3Q}L$5pu|x1 :fYA@1>$&=RhgO7FM. *\]қl:8뵸fq&WQ)Nശn?={̲}铿5 =4(&uîє[!M%#O9u+ 䎵|\)_ dJ`/K~+ܝ8<%^oBV3o }(뼾H|8ГeUPtDHk" `.QbE,7_G ,GjF2ϣPQn;Ie@ϊ@-"{DsՎE@̏ku48v=x{(^s w|pަjv`L3~WTsztzNe s.L֋ :"8ԤV]Wy7[N8kJϼfi&4@.(#'d0ȝa[TX-IjA5Uk?`%;ߑC n }x_Ͳ&$ZR24q{2=^Ƭ[jzZpJOn^Uqx{ JHҍ9HYk/ zӭ*u)ޢ&%<3jMjA+DW9ڌ)x׵. R[Oqf|9A7Nq1UDEP'-L['=5Ԩ~\ۈ OHB6O NMkS+΁Aҳ@愱c4AJzs* R&GXo]-,֚/p'r%XAs& ;H,펥-\R^fqԘr?&l*Ȃ!dLgε8/C{B_2ҝW MDJ⼯mk/ujyoTOt{k/.tE aؒR.JNz?[DbS\YH/ ]7aKI(?˞8ⷛI.}dc!z|s[~w'2mv:7v/ͽt!ӾTx1VHt{*ԓi:Yjwb[L}溦IS+K0}Gf3+!?@P󯛸lںo!{;Oi:uۖ) ?Oz .}(-ܓ?ERqVݟqU'Jh_qѝ63뭜zjH۫T` d^=5[ű(sW{}Z},Io`b+xд&evhVFj% #MnhС#\f@SA"/ ڣj  s?LGU(/?„K1 Q mt;ʇKZ[W}i)I )-G &!{eviZYZ\~Lyk;'UQD]{Jo 8:!%voy=Ѯݠ37y(?g37,S[9!I |l1'@m4j4 aţoH Y߈YU20OdNT(Ny62>s^'oe)Bȴkg=<%VȐ7 [ԂMx)Vv2O`$B/HB+yo] -_ w+$Y]T|J<~*lrx\y t/m`ϡ\1ʿkQ#P(귥?bxL& TX~-:!֘:&4y&AvMGtJ82+@itUXzSm;)#L 'USPg&I36Pm >|=;ӝ}0:2eD[7,L1X> WR7Ēg#Ji_hM?i OBijs_%P}vij~bk=vOF>p3{GF61u$idqG;?vպ8)0; 3<&4D1z_dyK$JkvX4ī?X+2zVcH'0{s/-^ #:L1);e_ .wSC7UZCo^c F6`u"?{[̖p4G$J?tt$,OnZ6LD@-ۣpk1͸Pщ%m23?3ζE|Rpyvǫ$c-zKEc#>ĵ9u'/$ ztQ@W%6)"Зr5 : j.&b[ cV(>z<9sJN,[MTKقJsL}@:Ƙ>0L`)Xfj+1۾lt`i曔/䛘@&4ΰhrDaiL+W i=2b[m/:z;|9K{9U,Tb-O%qwAN[:[]V^认#(yj}fFS:.' LL{zU.?.;v8wS!5{1.Ȗ`f+mKˬn<|?V8ʲF4MIU&G˦gtmQ=%t%Ο4ù,_ܐrc[aUM|Ttm}ka!,I/7Ƴm3rsyi-Jԟ9,2];o8we%ϩolĹQܭ 1 6©!zo M{t%l`{cMIIˏ*&Ql4uH}mk3_Ȃަ^h30hgR;uiQs 7nC]NR> TqڧttHjYx>(Ճ Lm >|h QPZ),dp9q-%$ 9q-6ZV d>QfK 1\2VL()ЪK?$ |Rj_mN44G&K ޯ$"UJbD?<n5 endstream endobj 167 0 obj << /Length1 1401 /Length2 6149 /Length3 0 /Length 7110 /Filter /FlateDecode >> stream xڍtT.(0tIHw#C0t7RҥJ tHww ?9kfwee㖱[A0$78@NCX+OʪE:B+_rAHPus Dyybr# w5@ A\ X^U_v0OLLp` K9`(vH8rr#l8A] *]P0[ +&,,( `;^ΐF_0j?g35jA!$ <`$ b '; 9zLyQE/k8? TP}gden>!36 Īl?ݢ_%_qpKb- Qo1W!E7Gf r:zu@ %BVb uso  Efn>A^?8U ֆ"v(KjPD mAE /o%Uֿt/$ ! /^>|(AZC<3jF? Ak 53_߸0?BZ&_?~ԿοxBӓpPЦ2t8;#l__ةf(>.ן=U>:Ky}sVBr.MsUug[5vX$*agX 'D676nHS萱29ͻ,>c382iи ٦KUӸT7je4ު94 YhlBJ8-`:UOӳu:eõMl=^8X%4!@h;x۫/yRd]1Kv^ѽ6vh#;ZWQK%CL:B&3zD:/vfr4/w<6t4) }Kk]MatYJY$] Ll5㜳hbU0B}o\{ET;gvc;9Q}?ؗj֍YX^MGS+F@7pB4*An;h:.8Xdei NrA]LN >UMdIT}d"iR9΂hb(Fd򣛇;ni'Ey^d j/,{aٮsH&=K8JY~Ʈ8%զU:ʽ5]@tiҭm3~S, ӜٝHnZǸc?, W@Qfo#qj;f>өPu@?Cjʣt-A\psQv}LxCʞM.* .,! Ho3fʹIfWv)֐֚K+;*ADeOۅ]r $da5w*m3o|#|*鉕;uB]#?n]tp=lD`3KJLP>Yj(VS?U38 "RW1~ }Yߦ>] ~;2F]ȒO\s=/BO 1җ MZ5v/y)%>~;+4uHר[odN>=q`(jMBM=q|zdǡ=TJJ/ zfGu}X搤?x Kk/lx](ͺNٯ@).Fu xۜ\t-ԕ=ݲnRd$ f}UYC-cL'G,WՋ}P 5kߍW/s*c"VfNL!w<-ڝ&jeكzip2^ixPPncN'.FЁ՗?3?4Hhq|ٶ?1,'ຆ*>C` B`#9f隿@0IqQ]oYwu ̹\].1lZ$G#jore J>-'RݹJ Ж 1Rd"d:Mf%jk#ɤoj'jj7}֞ц˝yXQ}V: @*Y2o{9Gm~|xJh ~}Ah±);q`5O'u2#5J\ ٺG_C&eVe?8l:':9Z&@Fnu5Ku2Рg߼߼-] ͙.]7wj=)}}+FIq#1˭T4i"y &59Bl޲L/絕Zr|fԥ^?<푷3$UQ,?X[ō8bV!- Ozm2{NƒqvTk*5 |x{S^.1vKX@ Y8Uo,eÓrMx\۽VJɾ-%IvO^`aMw4JmEՔ(,xk&gޅ!לm {o7?N 8~s@lٿnLts+nQ@钽|wJ]AJj !uVkֆ65WZv9k,bǤ.ߙw)ޘ|8muO@-Ձ&aZꑎݹ#QTmR!ciQcG8\ %=kѻ%,%[鋪~CՁs#hV.˓rؽ5jh`;pAM^w5˕K Y>yw;0 KlfaC-)ts=&\ UeFwcmq!}sk^k.mS%gud)aJ֯"ЧDNr#lzm٢%14#QQ2sˀ+/SWV4uBU ֱL1X@q/kê00jTThj ggi > J]T sV&3vs3zB'lڱ4(eZ| /8Tn~/{d|)RS}<4>|V~B_#10n\̠,ym«>h2=nJVw);%Y&;[~Q5~u|s u k@UyK^.QS:8_8i'NP!S;oMNkE:OXՄ׃j7-[MgKarB endstream endobj 169 0 obj << /Length1 1928 /Length2 14604 /Length3 0 /Length 15794 /Filter /FlateDecode >> stream xڍPҀ #`p\K`!ww_ޚi[ku&WQ/jfogcf+jȲXY9YY5@`Z@'g߿,ĝ71P b`q}ceމ a 2(2ΈN K:yЙxy?0:L`Kۊ6u{S?!,`>777fc[gf{' !z&l P:\f?J(.a rKnov3v6 S󛋋 :@]VX/&ߛ`cfodg0R `w0Ccg7cWcɛDUo] F?¼m-G~ '۾{}vnv^!se8hځ]ۼY.VVVvt7dc J?o5x9;́o^Ʈ@o" d -@vDw> :?EWGZGVwxgbs>=ocyWWo]𿱔:YXM?.(3rSOd[纀ߦ@m6U\lVl6 vo/9Y 4SM-ꚿ̛ b ybe?!3~EZOmw]I;S{?`dvob{J3 `aj;!q,"? `/}`HC "qXKwko Ltx z(}Ph0E%.%30%vEL:toWu wMC~vŸ y\]%%XRH=R30' 5ӦRU/&L"ALb$[~jQpVs6VU-h2Hh珤GZc'Ҽ,GZ8#nLY˾Oa=]UȮ g[Շ/7Dhuӌe1&@SM[CA5PaOUA)lδ^I4c#J|Ʋ MEJj|Oׄ#۫{j\j@5T_eh- AóC\rpB`VT@lm|n鮢Q,3g6("kF&Bn8*9kB,s!8`,Tжt#IIGG5z0JȠ9H˂]9΋&?as1I.(/_8d=>v kDaG3 e`\t6MJo%?޾9z;5_%˲jSPuhǓE;dXTEnzf .] F*:Toۓhy%8cĊ4ꯨ3=r8DDZgFO_NC[\|` ^Ӧ r]\5ˑE5׮l$r]C\hBM+_ס$=X8KRlQ$QLX4 Ek}YnIHI 16F~ Ij6SM#{GǨ[ld } ;'Y^J4Ox/}vJYѸֆAy}QnC8!K#> "U{p`oMy T-YB^e\It/inW,LB٤?r 깹ѝ(! 0/ z▆TY;|4@Dވ,]qRs\7[o07٧G{1 `OfNZ(h -?b?MXQ1_3sH 4 {\)+.Xzp.qsrM?9eh}o8YQY}Q\HJiGpjnb(C'pzQTy&>PKhs}62G <_z+/₁q3΂EQy@.I?D/sc0iLK  FgMLkK6ոzÒ]#8Z z._|h NҭMުnKHӴZ: 5{T"aby4|.Zħ}]of5|I5L(dp<' γ \_<.|A_°tȱۂB~ YJ\OaȨLCT,hؗ~YdjԿLVx2lOqR$Uߋ8o~\vQ_ Ɓ7`&D4}۬Z ;Ȣ5cVQ " SqM@({~L,{&z]eTf҆ [i]>+Mg*aQp4_ԓW԰v㩊4jj2^#Ne4sR&D gtv H#AMwɻgvB5>Mth&0c)cuʔRG7$ă+7_GԈ{ ȺHb KY Mq%w:Ԣ_K:uPfN3.;z[y-H@;ġ[tK1:%pV1`:D.j d0GCybӜ;Ulz,Á6/Lx5+95S3oD6N`Rq9EzGM֗†930@^Cvɳ0ca~y(Y &M$@B@'z\fuz*IH'3wflڦq1hgB~wd+c\I{Řwޠoаu }Pě;8Qy)ӱQ%kK#M"uN\amm< {}ndB7iB}2 m/c5kضV[쐽 s {r9k/^WW49-d!{ Q6nKK*XpIǨ[M3˥U'DbnF e3~_'n? M3XOMLHqRRWK1T;`Q c+ٳDкE!2hce'W楆ן?Fl&&ٜpko,^rR_ȫ-jQiͻkܚsz3k L&JgML{=#ۣ`v+s!3+kB)\ƞ WjNlk[NOOX"tHi (W5Cy0L;X#Zwd\"y<];LjnBi(gWR+_%*H[,g5h7_?hBfw&z#k2QiMbX,]żaqm5fTˏ'MGo6Nr ~C=+@#`ZSqey  VgR@uLJ\kjղvq5YˁoDu6YX#DCI, z]ժ:a\Cn~O +x# %ne]0N>cȷ0:7gIxf;r2v 9)mBGLW,6P1/#~x e~aO wMMd=0H( >UjcNP$$\Y< р`gkoGZ#J^?RPWB\#zΏO[T%~R*Ujĺ^#*L+I_}j1v qC+_1suh{*67_epV*Ⱥ0Wlȴ-@8x{,sF-3oo "xr+#$&FpxYrǐ;I{P3v>v趙;((ul7 Gf;O YtN%;S94Cr\6Aauj/y/p'-@UUGX b%,<ظٶ;ߏ~9_8M1:u$6*]'w0LeEGU<ɢkת¹}4ȳaE;U,n3Ed{mm\kwO}m- vJ;`t,Y"ӗ-s7f hv!w;UH1ovsP˜D% fRZU=23 O^V [E%4n!ĵH88:X[ΚG)b9 `W2QxX Eǖmi "/ppD4˲G=lBp5m71򜫸G;>FY.7]WV~MdW_;a08/RBVV`{~kr3*P>Wik\1\|J+: T7+*ڤmSaA;OG&x _c1TosEB4s~2%ȵ NlE[6ft'so=JU;T !t[,iI+ߍ}눍8͵N۵s$=J +A>1j:X$v2%d"P-[iz,Wxv{S4=%Cj.A5_wA FLFƩEWz]~i63\־oC?V-{Ϊ B HR1 [^@YS[S|(wl2fmҥ(f5`uqDo{67<R\Ek#=Nvt?2 u4|J[6 RL3=!VMѷT6k~﷾~}2 NjN^5hqoYs ,QdɬvL)<Lx-b3Z Jyz I  FOK_TB"đă/.f$%ѻ'O G! &?4Y&z{;"o%5*Rx7?щϯAJt^J.XQ7Nvk?DZ]D~bѵe2q]ܻ t ޛCy$#CTh~6-.#/;<I&h.&겍E{Y"o8!*3u(fڳ$#~: ";p8 OįNHS$f+y+>ypۅ\+ )3M( ?%ż؍@mt׶x&nC ߙބ!×Vț:+%k#Mw}Vڻjx^$3QMQ齌4q {Wn>ټK N O d=Y7?<|VL. ]p;'nٿ4&ʲL|E!xU[>"?j'3upKh.g>0(EJD%yPRWc!*ORHi݁8LLMQOͥS^(!NDŽ[]&ٰ\$6eoز  l<kl<2UVUW ۂ@9޸ 'L3]Prتk^OWj8}* ڎLRw?h!l0R_/Re"dO9bx jGfA&LaOl;^H0 Kw^ FFZ:Gqs/D_+]=ǼO]ds8c&ZCDO+D[&ϼH&EE2] cƂf)b{ȋpԭ{r+vU,7T ,`wH+Fjv9Wۿ 3 tq RC-9Je)t"v@~e!̍)d/.(k0 ;eғ~2s*nV]ν _Kֲvq9J[4Tx@!g5Ξ&BMɊ1H2(a۠ ѧlӊz դHGl/*)tE: è0W?1,,#I|lDc3!<~Kr J{_LMO m4|j3BoY: IB68_5Pϛ@;r"B[ NU͓~BĜƅ|w w:1PO;dRͦkT ȅFe-C1( aF7V{(̹&KGP QUk@MBޮP>uS85)Ly`"mpІHDR~dx0^| hN܄ gĖ}~[ESj8QmƿI,!+i1l|}.m S^-j7&Ccs+, 9,Q&$W Z;^oYdI slZ5+tH|m s^ƹN@L Sk 9{YMWI[pa AnvSerj8/}*n}{#7"%QoewcZT418l,C&e6~™j}D@C`u6*a :JȗքuMNdφ{Se5(`Mj`ʴ?j̿ZYp9~Ufbebz%E5υu8ɋ uO1as8OZ}W \[gUiF6&yV#cWjLIQ,ִvܽaMɢkVEvlQ'wu6*EW= Y5yw(*u, tZ)/AGIHڅx DPDl>8KFrPrFZaLN@J\)#~MSSUh୧ZomQ颐. 'e4۱O5)ig5UyT]C.ѺTT@M׆ #ML!24ME7D U\P4 ނ' WaAhN5e@BO XX"w˄&j{cE[H婺M_gB +5G%Wc.V{~&$[߭u @03l1U&w/ &ֲMw^"^ţ>YH >3(5:+oL>m}PsF4uÎ Km>]1?EHXJ4Dkԫی} 8TcIxԶgjÁ&ǻ%@cjˣԅiSL][b݀u{ZǢmiD;Y|gQjQ4xgp_,>K Jv UZI]iyEHI^_}n۳ ]Xal^j+udE#i2b\YSFC+Ic![ѪT-|e`WR *ޣq%F|MۖJwz۽'wq (P4醰&-88I1-Of0'H52~IeM+ }9D-dMsՙ7 ⨏ ver);,d+ z Jޅ^Ltl£`'XummD5tB,Fdznxs愷[9/Ł!҆ό`D!Fs\1ئa~ Ոvt#gCs7p{sB~(53؈a"C 9x+L 3yKu Nt)Y1Do81^zʨ|$рQ&V~({Z$Ga~yP~xpJ& v(s'\L6CBh`章z67 }|DaLl{Ƣ%Imc8 o_WN|7F|Y(<.j`zo /QnֺR0cxD*CoOI+d݀EC7%SwCr_O AO=;vvѬ2' 軫>GvafP󫇷?!OW*[?^GF>]rX} ȱԙWLsv@篫a: ?Fg1Mf@a?l۰it#qx^f @mWӂ5"ŷ*ږ U|PTkbY Axea#!S[;MuD_ƖБwgNvko$b L^zރ޷ebw n\}mߵx?l}m|26`S |Aw8ti"X*Bq Ti pN+ HGUTQ-<)!P~5leu^ހƲw"jab^q!)5O<x~}e);0,^SX֗'_lZH6+47#ya{nQs,TLaWO0=ߜ73dù (wScc/Fw>E$,(ބjnM'6z܂wyr3Bu5 ͎Ęqk8$ŭtxpw*!.=ᐇrs qT>wuNJloY/xpJx6΍>|3?0zq| ξg6GgbC`fzwmc4NYo,4C@'0Vr2x cB}d f$Bbsm\SYvQw|*gziÎ{:njʸ?ǚ&5jσNV&E2I+u <k[BMG '#EY)?df`%1M}@jlkMk2~p ֲMU]. e~h{)C˴x˸ phB w0ܧ,szd{ףA7! ,̟|XE}Tqt+\@ ;K[+GP_'[4 ݰӒ!-=7(:"-±-w$`q$J:gJMKKހ^d:'1QNmhChG<Է̽$*6gdd;wkαU{bSLJ,1;b+ʕ6mzt$ 쌇44Vq*Ig]C$F/Wf uTbj$2LX̉KlǷ]QmnnJsf^ U %$0?rvgLx$12V9Mz*uQ%њ69q4t0ژ9bO~—ďwI"5Ͳ@q =LW5g΀#`FA8vM+6-?DhUEF2\quPiFּ#Bn s0)ÅrD 4;Њ2PFu' 114|$/9>"M@wKy챐oa,D_`^] `P(T9ۑ͆OʼnmB6Jӑ4t0grh )oFBYH"?]36AS(W &8 >#ʨ+)f剾$: ؂ k2R E~&Ec N:b#Jg&4Tv7R':!ʣ5wXfuhpeBirK wDz)/2f >+nId*'JUBFl󑚓lCoc]15Z"S{.Wq,2sy ,\ҟbǭ+g-)D֦)?D1]U/h%LJ NA ߾w~;&o;xB%SbA7r}z\[m%>V5UþrM{z/Q5`%tl؈ +pڢ:%ZiBL/jn)7с׆,߹] VlO#.fףRUz>4}ܖ%T:$jteU"Tਚ_Z[YΖSakz'QS̃ ,ڪu#2Qɰ]zmK":I7XtEM]"YҳLBUpm'5W j|6HMCp3mdi EpO9/A -Ngr}[&k$P޺Z)n+9+cW]х18%KR:BEWTM'fP~1jffnfQn,zWs/~R3ߒqTs)_:z,`,nV' 5RGBDkJy;43$!bq-pUl1(pR pdr֙, -Uvt @f6Ga0D*&$pA-c)zMed#%Sߢ=@@cjEu\ %M&+Nqh?(wqϺ}HɷM'B_*2Lƨ}wX#ZD;2jdt39iKUn$7Y-I[휒kCbJݨ8pg%Y=CQk-u'aUw J}`Kb I#XZn4́;KE)ɇHw:7,l<>UvLW&ۀ-˥¥H&Ud^V@,b:8njҺ˦,˰m]0ݍ쥏]qP#xȠN;ן'ZG\mi(._f#ScD0&>QZ {N1qq-HמSZJ0lJ UxR}] nZ ;G2^])3"9_}ৌWxO`Dz;/Pg#\~gptH7"!F9.OEde +GUA):.m0!=87)>m]Yf+@5'2! u=xMW 5giB3^ߩCl@WPWxd1ü$9rpʴE'G dWtH!|M_=Vh%\[}R&e|0f*q|EhV߁(ɶ{ƤUuSDL~_kir>&čр /Wr!(tDo7rX|K`zc=Sa&L2$+;ҜW'.ԛSPbnv+ NHaOt;.6Mxw֜؞ O w\Siti"rYy;Z^-֜MreY:rX ' a?ࠄM,0Et_|..2 #]D|O2~r4$*=ZjDIǰ ְ.].j K̏9 btG+KG eZ}d6DLk!ۭǐRiy;C M3b,chk2P8=@'hd-e %C!fm "6JnD-(0]V?Ğmvc] fҲSsLq{_n .wf=A@HKʚDyhEIToot PzBVhq OSMMqAf4JW\Q?CV]YN|| YڏM-k9z%6ڏSK=*q^9Z~ ɶh2!]gM })+ T{1frqj` YvwF"g,_p\=hըh۝)ʝ-,̋D[/Mm+&|j2yjC' endstream endobj 171 0 obj << /Length1 2239 /Length2 15258 /Length3 0 /Length 16603 /Filter /FlateDecode >> stream xڍP n.3!$@g'{kfާ^!#VP45813reUT,pdd*NVԀ6X; e"N6)g+ _C[n1@ ekt#sw075szGow5 kd~hd`P52:OJ^3'';nWWWzkGz[S~*Z@ tp* g` 4z82ʶ&N@hlc tg(K61- _mv6023q71[b2NnN m \ ̭ nTWO}FvNVW6 Z[m'b4z;?kicj_dbnclWv 6@IlEpe@'###' 3h1@/{ ޞvv2&8OG  `45] 4~?s761>aƶ6V>b u51JW)$dc1X8\``?<%mLl\!ޥvg(Y*ƒ}[ fdc4zb<e$le??zks+,}dm7@csgt2xASi(f4V0w22{6#VkϬm ,:&F{_.#}$Vw3dlw8Ibfcx2o1!0:ޫ:ulDA߈ /08Y ʿ+A7z/z311+ k20FL~/8+`xj/b{fdkJXYX[A ?;Oofown&.Kmûo'ang]f|ge|˳kr~{d_ SDzy?fl?~߃ٽJlXaatB@?:n~A򝾣!޳~0898wN8p?#y;N__t}_5 xw۟#WO ::+`^0yemW /жDgxviSt*~{[vI;s")?,+TKÿEF}/'7^!rCv<w?;F$O}Sk9z c7.);rO)%ϒMF*z".snmI4lF+\ }YvuvHK84&b-Eáa4Ʋ.r!4OO릴=FMv`v0ךE~{cB8*,%쳘:s;pS6X.z]^A6Ws*+yV+AUT$!Z3QfRzm"GnHt-ORUf@'dCzQ?=5F@ke4DaDHi2j $bN|$ϋe=ZxGڃJA14iӮ"z0UJ. USh~CwW=NЗ]Oڸ\ֲpuT]h퐿:v1H&9Z~ A{OͮE z_y+cD6Ѻ'#ssn- XUgkqv&"^sytN;ͼ!6Fju#ׇ< ~Y_nH_YHa KCpMY^)'f=.Jb OumZ!)It*`yL6nߗ:1]%"{ h,(0j&SׇC|VO;k8KS K!Rfn)ryF(3+!}b%@wMzt+Eoo{l`PV:]JnXN,W-Ԟ鬡+N*xclHH7a=`k{Qa)t~.T/JdD8jDMC_>:.l\</sBo&؋ |\;ׯH6vMZ Bz`h:" ,;Y];2Z˱Y-cFE}d9tb["l߬0\ݣ%Z8/^ʵ¿ok9Ps䶓eET!ЭqM<,f"n(BnK UHRثoIv؀<}.kMggFǾ}M `6-rLQE%J䜡hVY9P#ő)gz_77K{#H*=Fwl{*^ < ?5k wd薲o(wO2 6|y~Rd*`=K؉T N/ ݤYrOdwBu*BGFL@X" 7t$OSٸFRr(7nq$ᢔ%(6 9+qV&>l/JpJQYr&~*$&Q$Wb~ѡSxf~vk3*NqL!Db6ư+'fYށHp FPoL줘꼛L;쇿H;Yk5 R}Z|g#Vk c%ʣc]1LTXoG%&xtѾ4^b)v&%I& df' NM,qzOl_~i@܆2b۬v#Ҙc"FmMGrHط%@:lN{F7ͨRD-螂a]< >F5 ;;t "I@Ʈ#2)(C$֧*쭼Y↌JFՁTBәRtʴ05̑H4ٹ,"K%+*[{F⩛0a㐹n[z?Q$&kj ,3mýY(VϓϤ 8M}H: ر+STè=9Mgw%8a0o\NcA5̽?e.PϊC yOP2Q" Ds˦}z &m[,ɩXʭ>sixN`u稾6f>QcVؗ` 6!rRD'S7*-+!o:-RUm4@KeR#Rn{ˤ5ծ29κz~Aa@m@'4,WA"l51juhV kj}ϦY-=篼sj )OmAq+n sf-rR`t7W~7Ut]z򒛭S qt8n&Ɖ86gKw)r=ȉg0 OkJcUBIh^&UgrPfiʐ֞_#7s>8,pc*|_[SZZ;@m܃`ڥ89 ~ba֩~Ӥ|X`x콊'gF Ba<<:HƤT;ܷW$Zĕ"IrPhK pw$Taԃe1ELhW59?fO[[GeVV˜dIxU*'Ԇ6> wAw_=}h(?nD.:D ~( RfGqp,"fT1EIZRW1H -3̜7-j(ңqJbg\D,y5 \ɋ//PV+MU^R7&:;^5D -s7P CU˺hWGɏk IX9t{t*јӌ:|A;I\^}uh?ɸCo^x7(Mu{}tw6q{44EI[H1L9SW26Q[4lY^(vhT^w>n\b Pd g˴$]38.9'T \F{R~pFZ^M=3K@Y纭A</xmM{uee4c*7 bC.Ty\%!J/$9^~< U`I`#pfTrœ:q؊4gqRBcSɴg7"9}J=f~5M*1/~̀BM45 ! 4JN6m\V[( {T(a r6%c[Sh[Vs tsoهY[Q$D^0c4V ,1RxK)#q !qJdd#ꈐJs¼ wQc>RW78E7]'Űt́+`kXq`CZ@E&!B/P>hO쾰;Y |Ie0YQgy]^b"&6 YTTI:W$ PYhR\钱kS1MFB4%kb6!SJ .FzlZ{%&y!>؛/ˍa(yi#:`iar vPȇ;%ONc vx6At w4[h:##@@5K􄪷͊9yFodd*.3 dqS < m3%lfTl[]L?ܰ$,D{+u@*x*E>U~Z\Tcb:ըwfBP5BY6 F% .b$ew;Ѡ gJ!Fvr}syYJbenOۏe3$7 8=NtpGz-u :|GȢ(N.EX8Geԅk^Pk> agIv=[9+j }^I }y }\K^9/oZ&ָP' / \P8$YNMiejgy/뻌9wD B G3#sN`O b&۠j&9`dRcH Wz2 Fmj AW:S٤atpm{#"pEDݧE I>Qww44ql-I@N"]2!`|ޏIX@.vZkGBbU*_, [$6Ԯ!VΰqāIa yēw+h&[1!fF)p=n8 IZ~yǛnal~kf)E6((7@S-W2×@i*_GZO?9jK3 Fi+[TfUTfOЌmn5vb3QfgK? 8UNBoVؐ\-dd:@M@|jv4tEnY,4>YYsZd4U-,_E؛ _0e>Gu/P%5J%G470`V#a~`e";˺eiC! 2hTD!:D$` K8a)0n@һt x=abZֻ<f8aآD^:.jʚSIO79|3͚D1< \ Х-hB)Z*D>4筘W3CN"7 eC },6nTHC@1/`* @Ƈfӷve;!GCqrX@OEfyNavГ*q5J~ W: :#Gj/xasi3 rg8 7 5;@9sh9ښo3u9|2w&RTyOqŽ?^lmq0JĄ\+RAVF\ =!,͒=oSzGF6SWGiZWFgZl"媴|W!(h׮\.YŦץ}E N(m0W,tӮPߕ`>L?d*02ntWnfSZ-lBVfmahu޾Q2c)z? z|MMɋ9ҖLw[I& +IOY2NhCe6("0Yh2E5GyD:KSONGе\7C!">kqh ܈>)tVػlC4gV2gc)T].=8fZm`S33 Av'91 eW6R;__:&Q GƆ}ZgzWq.M=绹-)55t`q-] Dxt7K 䑴v^۬6Jܿh&Ou!1.3>`L+bY,#/~r|WxϏvd0 Q-'҉Uka,ŌVsocd'vk>-5zႦ3+=1* C?|vGO'{E} GA&qF| y1HYdi~2+UD4x4fOO+-sT0}ErXqNkM`z>es=2el. LO M6Ӕv7?%W8AHyW#io!ĕ跍6xmQ*)C`ҞJwoxmdf3#T~-c RGT-=OqegxDm@>vk#Ml FWӅ.!;4Ti_9JTC9p@L/@ 9۵UŊ_H<#'VQYySaGpu GƄ_O$i$Iml6JI?cz _6}[ɺnM|""%'jY:Md}Dv J/BÅl.A?AyⰓVw3֭5ۃZ,CSdG:S\ vf8 9| C@:̏ h +,``3Xg g\L3|_H( G:xճ1i\*=ĦDq2VƿX;vEE5% dg2aޡ<9Pqg$:aRvFMMhISe vIXw!^ֱ/Ů'|bf\(lW.-5>%}^LR5pZ|bץ!Qҋo[:qXORa4@/15&reU_Nσ`v'R19ctMQsk\x_Uwb}<=b~5br[9\ң7Qt䜌'?ZWɅoHw/IlL'g@Qf}~͒u ?n6R[r, D2٦7zbO \U9q\Y#k:|&6,4_ ;d*}pCsiΓOWhmZ~ŁF]Ƨ {/ Ue1J}>xv3{E4[4@ mp4'c6\ibe%zON,whGjCen8#^zÚSoѦ+P:N*2}@Ofs}qx$x++L OKX'fbsf;Jy真 {*\18#"ק+})vHm)˩0&&Y`J` ?:^t# `N=\y\8\Q+ XtMyo!3+\DD7:9s#k [XRD#SBRͨeW)#&(. UO tS3aGiU g0ޣ怚_BruRwK5a,&W X1 tx~Yc=jbSxXNlrs p›zk0Y5&`\)WevHu#|i/}R6𒞹iT},[_Q; xBPbr"Ccm6̅iE]M&;?G18nf;2sETr~c]t*ϸ[-_Ven7q>gE l.DE51Luv5~ BWQI˾)>NfdόdqfR "};n;cIQw"k+Mb`sZǛÎ]'!xQW[!(ꌄ'% cL-!G&Y"JOH0҄>A6*\'phauKFNɹZ'/ /2&b o|]-܋ہZB}Ɲ [*vUQ~UýA#^ \H`Na+p*طܫ=C}K~GR 2K:-"n\ƫos㇊&S ŵMJQq҆ķU-Y}7LOc6eƕD4?hՖF11įJ=fYa0 ](@~K`ɲ<#ӛuZ',9LϜp/g-dB8 RgCř_TU Rq۾Z(1xeQ=FxJ`+fAQޕRͽtĤ>ݓ&s~:HFp;^&T˳_zyՒQ>˼ay$Ktl(7bp[8ۋ+ d E! OR)dZg* 1r#L0Ac3xM1H1szsN14Y?)gs<fI; !.7+Jي*|ye>QBI:Em* Xsn[s ľSIJygR*[JĐp3W-N;Jglv 9bDCmyv3pHYI$E樁V30% oG  Tݓېv,~/DuG8}t]UhF:ZǼO`ڷz`~Vunw}" 9MGe 'RNKth&f)xe?<4hP#,+EẬ8=zZA.T~~*j1Hk1O^e9kh,avw ˿_>(~L+ݕوce7D$/Xߺz$ "n%x4ԄZ?!FK"nٿ7˲d3 iۭ!aێ<%yêy_W_gB󼚤V}6cS+ gQ .@^iӍVb6Z%1 L8sGm&􅚤>!8r#:z!Zu>|3&$HS@ ǘٞ uݻuk̑:Tki+GH]BvOCJV/lZ;q=d$w>A)&.?aVf=@="QGn^}o\ֳBW|NvđmܻlϳTbgϤWFUE>Had|5UlG `^ENɉ #"X3aH|tBE UmIN]# g;(ܵ) ػfӠOёCE iUↈ[4yVxEmbMJZ$%Ui0]7꜡FÎ=$>Eǁ)sQN;U@|[CKrG<"{ή q9ٰ#aኈ~‹<`i3 %L'B}-yUc`ܴܿNMMۅC +ͤ  ݱz^!Zq }WN]~7mE^gfHp):9u \B ȳXًw?s!a{nf0^ɒ޸rۑtF>;0ɤJ [nPO9$i'mҝZsK}&gfN")7r:EI´G{^\u0DD%#m`g) 'I٩T͞{oyՍpE\b<)2EY|.}_}9B}GNL"7N>.hV/^<뭫U&W!ЏvԾ?/ jl G)3JIZ ;[ PFS`HHB lubm~`XNXqY81_ ($;nW_7V=Řx{i'g0[kb^:M:63O',v ZP}EuEo:k7^S}_ i./$?g RJ~kh Tݲ*twTP_bX& Clu†APK\߰6+vڙـq,we׭5!7FITfҠVefqסûi/ÿ@[)r5_~4L?Nb endstream endobj 173 0 obj << /Length1 1751 /Length2 4853 /Length3 0 /Length 5941 /Filter /FlateDecode >> stream xڍtTm>!J ($F:$d`((HI""!! U?vu\i`,dCc1xaXP51`,Jc;#S\EX_ 'Tax"Q=Hɂ(,Ta=+hc1w*7 )ဒ 0. B+a΀1F]eA OOO / x(Ȁk4*v0"0 pƝⁱGbuXKwE`~u~_@D >JXWqhg# 0%03̎H: PW2` ǡ]"hAGiǬW 0xwT8xޠ_zb|AH4y4+v@hMTl< @GL]?#3q_W+$G#*_wq߿FT`;C';ь@ǡK0Q~|Ϛ0{, uUU.SY CaQ1q@BTOd~6K<&RKK-#s+N#,ۑ?Oㇹ1w@KfG{׫wA h/GOў91;e!`|;_w$wE5 kd ySJ|!mGx1`8?⨎TR~ ))I$ ~#"I@hH_A1K +am迠$r K;]@恰ķ&r%jW{d o(qsv(zD*#>m?x(ᅀS/8+y+*N۲vw+a0H.>TsG/W:3l>%2/@M }q|ށyʨsC_ଐ@ڼprbQ,b4d!Ji%J^i]t_S|t]}~7CTbe)z2땍FI+=@?ϧF5h@~;N\q6Z\}@\R'g} &FR!13"Gt) _LD+( kja=][ |V8 C$ٱYak{~{]ӵ5*ߜ^'>-kko&OyMQY$+̷ />2/ bQ{~>>}0M%)qzȈZgG$ËU~Z wS=cFW7pǫn<* /׿ ;2 oʹQ'B3VRqU 9]^Tqyѹ,'n'|ܮ92dZxfMGΣ[>aݍHZAb.;$ˉz勹.^CC)!n7aY2semV`<9JwÍͱA6L@sOF*oDn.NT.b<MHz@Cjnϫ1d %e]rkIΦӣ<_]Ue* O6O=:c%-UK$YKI*M y_ ا̀A㧃|u-OW?/AK:]2^j K6ߘisO*X3%ǹUgOÜ<* k+ ᤪr:PvFR)J FN)۞K%_}$(hܨc5 <[0ǫ}uS* $(d4c`4 fs(E}i[uR+ \¸(ɔ6AY.: Z:ljnz.)7;nsx&ps%r :!@YxvA‚jrї'YTN},g"3]R^ĴR +! ׌B͟mРp4'5 'OɄ.QgFO0w6۩.h^0&P/sQ>wt)-AZ&|ؒ+Op[jD+tײ3Qv%tX [Le]ߴ <ִ;6Wǹ`>\$ .3|]ɋ=,*7C<Kl_VSuȞ5{&b1U)Sǘ׺mH0Qxbu}L+`)^z'nr봤Ki0) t` K1O!54:n_o %V7Yk$emJ}>%7V}X_M˞L9&.w[?Q䭩jU=`y*QO.K OOPiL s2 秮EV/6O&qgP*?*H5[<,ea3rzӭH]~?laS|STʦP}O˺Lr┝n+~2m)Qyap'>l.uL3Y\Ey%HpS(_ Pl&MBBZmҶ2{Y(\i4u3۰MpCV覯y#Օfmp5;j%O|7!PYW?^/}-cGާmwڐ(iV[ qR.߳f*:jSHma gq%{V$*wZ%kq6z{[glg8$ ne`QIR|[#ÖoG.]MEꭰf. wʈIt< 0%04#͢a(gϰGkZ#}.-eKpMCϫQ$=)/"%;Z4化^xNa7΃UI~ZmͲÅ&]Ebm/>S3D(.H{s'THDEr>5_M(qwzFjb't)2_7$pïs|4kM<,l_Cے% Q*׌Y_n*~e.٬{z]حvBM+5ç2^ԓeh+od>|sLk(mSDo8KҴ <03yVk w1`[0 Ӫ OJ۾:LGw܀KW*d8ı/NM% 4I1)8X`qawz\<fpԳMtN } xk!.y. {ۆI+k;y%6wQ'a1 =ytr%wʜB+ANY8NpZ:=2kq*edeJ.*疦Bq㯯m$b^=;Tb/4¾ og 13#^{urlYgV"kq(hGv (4qxNJt]wd?Tphދ|H[FGSVVH]_ TV)hnrJ09}DIbPLj"Eg|w\J@M qMT|ȴkʧ-|m&ưbS ]^KflHi3E؜4ƍUC1!*#UM~XŪS8dio|ާ^CkWVvȯOkG b:hZo$j[}К5c j7ӠLlP <7?uP y٢+Q | r8B(7K)&J ?F- @'\F$H!ɏaB[䦏PΠw$oǧ];H"H'WlN  h՟K]&}ڳ%$2\pb?']&tܐ27SUO8H<3pFJ[*[n E(`r:LK^/+:J=Zj aY\sf*ͅN&1T8Flvڦ>yl*m{K~%ۉ3}PFY}P 46/\osp*) l1\ ᧛[Bz52V5C[~ʗ)o3eq앤P5I\."sΓ3_iq撺0/7uWuLS2/T_6x?1mx:: endstream endobj 175 0 obj << /Length1 1678 /Length2 4044 /Length3 0 /Length 5089 /Filter /FlateDecode >> stream xڍt<?RFH(D-g$ w疽( EBTWqFVV~G}?{xb"f2ZNXG>CȂcssE ɂPf11s4[,v'=:xH"T;c,8M 0" QP(! "h'X8Šb:X/J/  JJ һ' F"01fD"<3,"++SeY,E]RF]( OF9; g_2h/֙DaT 33 e|旁4{6D'o@ḫ3z_4pF{3D48"<X?@{ #}sH<G$;-vPqzz0DN}h< I/f1Xoo894D,0h/P UW"p0(/t7šv1@8S@Qfx*߈H"rAcFQο0ux` rw>Sx5/:~uGe rp@^I wSw࿞g,V{OCwX*gQ_ہ`$ &;Q7 }ǮZbWhTʒTcG%$j ha\<MGLD.1~-vNAb 7Q N}7T>PԳwF= s_P<`*p8gH%R]jw3ϼP%"T H4"'9- W"?~AN{ @r@=ZHMB@⨔)BM<=@1{ ՂRg\~_KAxꣴ{5ԍw_@d"U" #^oʱ~^b#O Q][etk阈Y✆lt:v8|~gQNit¨qr92Wz{I]GkaWs]NekaUTEThݫx]Qi(JDI }"MNgtF-@XFDP GB 5iȢFM݊Nynhq?$eyނQ+S5ْWMSQncIڵYGW)}\O#'{(Y2|,h~h!p ݍ/Cc7ĘmU( ĔzĠgijHl)nC:oFLVF mF.&)ϔ\}+Mag4xW%b~?]GP~rGdfT>*~=Gv6Y9aK"*'ϊZA7#}ᣱxuNKGnYUg=d_ʙB/\iW}k]3~OZ>rqW|yjts, í80nFI!fkij:P#暑z5yx݌x<{]H8M//) <{AZtPٶXU` u`u|1 ͸bt6XE[z^d8u}0\;Z>l^OxyDFqU…'Rj;'rݪwd 13S7Jʫ.v5-|iC] ӿYN) ϲŒIJYmcI y}O*sV?&W9FGLngO}*I`ko!7*0l|Pl]e!ڭS0%fFkLڃs\1* ŗ]i}[Mӣ/#w_ϛ\`3La霱t\O$V-as\9+\e¤#59Ծ99XsQa*5m}o/+Vz-Ͱ$, N=>uxHyqdmc%r8ΙU%bO]%<a" }CuY.M%Q 83U祅Do -߁2^ G 9c7`daXEBNI pueD~6a9%v<]^V*f{y˿*naԞˉ[ɶY_} Uj2r*ko|+:. WʊPO6PS:b7 =Ji7 shِ* vZ NE yaO C?X_zEDN/gNxnvUe^,68J!{a %lI b_W}4Л?"dM 6(/;(su0Ĝbop- ҁ._vMfrc 2zk)3 1W2nwY[FG βæ:9cI ;=Eze!j-{x\0N#aKfJy|z0LATRF뾄՝dpvoh<:+'L_>,\ >N*k0Kqh#PYy]T;2 9 v7 W_K5SM] uٕ=6g"lCx< K+++5/<[窧l7ow0ƄEOe>Ƭ(ǭ=xSֲݐg`]7c7''%7 xL]TS%Wh/|}IdCiyJTImk Zʫ p6 \Pʑ^+cR={\b{Y +C* %&~,lK׆ ks9L G{ Nż$9 FD<J\ 0RlJmp ѩ_Q#t3_Zb`wCғAh7T3܋QiuȡӑͰg]ްА~v}XezؗLkVv쀳QVL(@]ɈzIVԯ!vO9U"E;+'2)0F>rձƦ ŤA" Mǘh}WHTL$WOQ-eHleWLRX 'yݙP6o~b0aGbL\Թn++\{$=[5N~k~v%f=BM|4/lܚW3|hZ+6 `0-U(nEDihyḦ#+leHlF|xI[[^ᓓv!ߎv?J(vjʱP|Z7bpIZe04wz us2e7k sAM%@E+3E^\/7PnzC H_E(R0pRHZ$9A"C!*(MrF7nxE]r9j볚5S>;hږx#EIBRµi[> endobj 138 0 obj << /Type /ObjStm /N 53 /First 447 /Length 2498 /Filter /FlateDecode >> stream xڭZR8}Wqf)V/5Up>D$^;;[v- P55dYsuZ-A,\…O.܆ON c#̃f&eAsmpbaOl9*%LS9s88҂O\f;0E\Ǖ8=q9gq_8M'0G\8]mǁuxJUx# Gtlsh8 a1X$v$Èp}߇q,[ җd6P)ӁN&pM!`/2X/3"-f>hCB: H z<3:ա?f$z*Y;}L͗AS#;gsȶWoCg f*O2C >f0 p#EgjzK%;xuqI0頻|]K>=+zMoh@萎1c:iHҘ&tF4]s!e@E:&F/#`dY3mK[L*3bl%:V#]LA&(LgQKuw~y{NpAȁ[zuf킓/i&8wRb5K('p35MBFA:icpt"P_HgPEKsS iX>&΂#e,VHWuRdjFn_QuS5 s$ziإ&sh-e~pҟ'hma0>hhڽnO0xkW)}PI{݄A9UVޮiYqVdj1 Zj7}mƋoܽf{ XHxMTQ7c!!ʇ /| PӽͅFTLx o%|=Y- ¡ʒYa+1|wx Kbo~*5%1DjtuQ}y+R\Vwp0Gs lO13"Bj(^Ph'ݻnûMs+8Yluy76o M+!Jw.nw4 PڎM<(ƚg%8X0Rc Տ UDxt;~7H> m7:i)~8O3\5: V h Q6I޼yl0o̳]ük}dKloݼw55޸4ͻ5^ټb9qUmݸ14`^ aݫE!u;qdZEe묄x-Է2y{+v-f&ۮ^zk260^0k1Tc_YkAWo;v4ׂ)wJ7HpFho5ojfי$a\*Jm f5bJfoy6Uk b8ߚ:+'ʋ`R8& <w=/XA{R $3/I~uBڅMk&&u tj ZQ~x Y0>\^ɇ$b(d!:ayAűʲa0=(?jq7x+ cdt9'&1(N)=n$ Q4 ꔓpfSex15O IZH@/kz^_VpkoŒf)ΏERuh2y ̫_l-Ֆ9V^,5"?pV[}t^g[ -p13b|8,< n_>3WU <6DEDF2CE516383EDB8164C58EAC914B5>] /Length 475 /Filter /FlateDecode >> stream x%;OTQs #(" /(mTER V;;5X7X)ysY{mfdIAuPzhFhf(ˬ вB*l>Xۡ+NR+i-6`#%%q8'SiMVXP5P^=u d [*[?ԷB 2@ly~)?j#(_ʤ/#HuHב#5ʗV5.GjZ]8RQp-RH#=TVi6H"q8I'>q)FXĂt?T endstream endobj startxref 277587 %%EOF e1071/inst/doc/svminternals.Rnw0000644000175100001440000001611312560362404015770 0ustar hornikusers\documentclass[a4paper]{article} \usepackage{hyperref, graphicx, color, alltt,a4wide} \usepackage{Sweave} \newcommand{\pkg}[1]{\texttt{#1}} \definecolor{Red}{rgb}{0.7,0,0} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{hellgrau}{rgb}{0.55,0.55,0.55} \newenvironment{smallexample}{\begin{alltt}\small}{\end{alltt}} \begin{document} %\VignetteIndexEntry{svm() internals} %\VignetteDepends{xtable} %\VignetteKeywords{classification, regression, machine learning, benchmarking, support vector machines} %\VignettePackage{e1071} \SweaveOpts{engine=R,eps=FALSE} \setkeys{Gin}{width=0.8\textwidth} \title{\texttt{svm()} internals\\ \large Some technical notes about the \texttt{svm()} in package \pkg{e1071}} \author{by David Meyer\\ FH Technikum Wien, Austria\\ \url{David.Meyer@R-Project.org} } \maketitle \sloppy This document explains how to use the parameters in an object returned by \texttt{svm()} for own prediction functions. \section{Binary Classifier} For class prediction in the binary case, the class of a new data vector $n$ is usually given by \emph{the sign} of \begin{equation} \sum_i{a_i y_i K(x_i, n)} + \rho \end{equation} \noindent where $x_i$ is the $i$-th support vector, $y_i$ the corresponding label, $a_i$ the corresponding coefficiant, and $K$ is the kernel (for example the linear one, i.e. $K(u,v) = u ^{\top} v$). Now, the \texttt{libsvm} library interfaced by the \texttt{svm()} function actually returns $a_i y_i$ as $i$-th coefficiant and the \emph{negative} $\rho$, so in fact uses the formula: \[ \sum_i{\mathrm{coef}_i K(x_i, n)} - \rho \] \noindent where the training examples (=training data) are labeled \{1,-1\} (!). A simplified \textsf{R} function for prediction with linear kernel would be: \begin{smallexample} svmpred <- function (m, newdata, K=crossprod) \{ ## this guy does the computation: pred.one <- function (x) sign(sum(sapply(1:m$tot.nSV, function (j) K(m$SV[j,], x) * m$coefs[j] ) ) - m$rho ) ## this is just for convenience: if (is.vector(newdata)) newdata <- t(as.matrix(x)) sapply (1:nrow(newdata), function (i) pred.one(newdata[i,])) \} \end{smallexample} \noindent where \texttt{pred.one()} does the actual prediction for one new data vector, the remainder is just a convenience for prediction of multiple new examples. It is easy to extend this to other kernels, just replace \texttt{K()} with the appropriate function (see the help page for the formulas used) and supply the additional constants. As we will see in the next section, the multi-class prediction is more complicated, because the coefficiants of the diverse binary SVMs are stored in a compressed format. \section{Multiclass-classifier} To handle $k$ classes, $k>2$, \texttt{svm()} trains all binary subclassifiers (one-against-one-method) and then uses a voting mechanism to determine the actual class. Now, this means $k(k-1)/2$ classifiers, hence in principle $k(k-1)/2$ sets of SVs, coefficiants and rhos. These are stored in a compressed format: \begin{enumerate} \item Only one SV is stored in case it were used by several classifiers. The \texttt{model\$SV-matrix} is ordered by classes, and you find the starting indices by using \texttt{nSV} (number of SVs): \begin{smallexample} start <- c(1, cumsum(model$nSV)) start <- start[-length(start)] \end{smallexample} \texttt{sum(nSV)} equals the total number of (distinct) SVs. \item The coefficients of the SVs are stored in the \texttt{model\$coefs}-matrix, grouped by classes. Because the separating hyperplanes found by the SVM algorithm has SVs on both sides, you will have two sets of coefficients per binary classifier, and e.g., for 3 classes, you could build a \emph{block}-matrix like this for the classifiers $(i, j)$ ($i$,$j$=class numbers): \begin{table}[h] \center \begin{tabular}{|c|c|c|c|} \hline i $\backslash$ j & 0 & 1 & 2 \\\hline 0 & X & set (0, 1)& set (0, 2)\\\hline 1 & set (1, 0) & X & set (1, 2)\\\hline 2 & set (2, 0) & set (2, 1) & X\\\hline \end{tabular} \end{table} \noindent where set(i, j) are the coefficients for the classifier (i,j), lying on the side of class j. Because there are no entries for (i, i), we can save the diagonal and shift up the lower triangular matrix to get \begin{table}[h] \center \begin{tabular}{|c|c|c|c|} \hline i $\backslash$ j & 0 & 1 & 2 \\\hline 0 & set (1,0) & set (0,1) & set (0,2) \\\hline 1 & set (2,0) & set (2,1) & set (1,2) \\\hline \end{tabular} \end{table} \noindent Each set (., j) has length \texttt{nSV[j]}, so of course, there will be some filling 0s in some sets. \texttt{model\$coefs} is the \emph{transposed} of such a matrix, therefore for a data set with, say, 6 classes, you get 6-1=5 columns. The coefficients of (i, j) start at \texttt{model\$coefs[start[i],j]} and those of (j, i) at \texttt{model\$coefs[start[j],i-1]}. \item The $k(k-1)/2$ rhos are just linearly stored in the vector \texttt{model\$rho}. \end{enumerate} \newpage \noindent The following code shows how to use this for prediction: \begin{smallexample} ## Linear Kernel function K <- function(i,j) crossprod(i,j) predsvm <- function(object, newdata) \{ ## compute start-index start <- c(1, cumsum(object$nSV)+1) start <- start[-length(start)] ## compute kernel values kernel <- sapply (1:object$tot.nSV, function (x) K(object$SV[x,], newdata)) ## compute raw prediction for classifier (i,j) predone <- function (i,j) \{ ## ranges for class i and j: ri <- start[i] : (start[i] + object$nSV[i] - 1) rj <- start[j] : (start[j] + object$nSV[j] - 1) ## coefs for (i,j): coef1 <- object$coefs[ri, j-1] coef2 <- object$coefs[rj, i] ## return raw values: crossprod(coef1, kernel[ri]) + crossprod(coef2, kernel[rj]) \} ## compute votes for all classifiers votes <- rep(0,object$nclasses) c <- 0 # rho counter for (i in 1 : (object$nclasses - 1)) for (j in (i + 1) : object$nclasses) if (predone(i,j) > object$rho[c <- c + 1]) votes[i] <- votes[i] + 1 else votes[j] <- votes[j] + 1 ## return winner (index with max. votes) object$levels[which(votes %in% max(votes))[1]] \} \end{smallexample} In case data were scaled prior fitting the model (note that this is the default for \texttt{svm()}, the new data needs to be scaled as well before applying the predition functions, for example using the following code snipped (object is an object returned by \texttt{svm()}, \texttt{newdata} a data frame): \begin{smallexample} if (any(object$scaled)) newdata[,object$scaled] <- scale(newdata[,object$scaled, drop = FALSE], center = object$x.scale$"scaled:center", scale = object$x.scale$"scaled:scale" ) \end{smallexample} \noindent For regression, the response needs to be scaled as well before training, and the predictions need to be scaled back accordingly. \end{document} e1071/inst/doc/svminternals.pdf0000644000175100001440000045447312560362404016012 0ustar hornikusers%PDF-1.5 % 14 0 obj << /Length 2135 /Filter /FlateDecode >> stream xڽYYoP>Hj98CM$mRdI>ekז Q=kȡHiiI(\Oɷى߯./~ѹ\&eB+cr9y;mfzp_ >z;Y;]Ɂ.mȲmโmh<7om|A.-|k=[{|\ "ɂ(㊜ƶj6H=jT흲!qB)iNEq,O̓y˷e:m[MRt53YXӒǿqUC͕AL_0o`_䗳m^l@!?XxKo;EPl7^[bsC,K{4s-<泹ӿ$tb/8|bHX΍ș1r-H墧LWN*&*Be^^\ty#uzedS"zٴ~!j-֗m7 v=#YwJfj4^ü$jqY-${N;3|؉PgPg6E%2D^RInc^f*+ۜXIFV~#A\9|ɫQYuIUeƇ-5AᙆB7 uy xUPHZπqӯh;̺_J#fMiW H͹‘rQi~߱uZ~_ҁ/4NßpԜ.(kܮH?GZV{R&,$֩ !8n̥ųaUlRm!!\xe3)oj!LُFzMQ1\5J(uXdvEDrN䟲.xU[PW[4:2cq ]qY5Jxlʕ41(g:LE#>1:{NZ4/_&O=c.B'bAv^|֚#3/04X]yxd#eᮃ=IL ,))NB>w`rsXmnϙP8q}z/̫EPYhp*\mRIšEYEl؅16T DThE}5;dE^l[qa0brQ*aE4,{m9ߚPܐ%oVE"v{HJ&BnZ Q* FֲvA*È}rV(/$ M J2^8͓U#rJʗւ Am7_``8,>els8zJaA*/]d 0%G3ҪZ5PrIuCdP EzUE0Qz?ъkHɋP5*Vڗii]-x6WGa^%"7ϮNt@kwFTfŻ3791a h; T) q6GjRzx&韲}s{VЁ!{r:&v@qʢ^x!B;<,}<ѵJR8݊"žo/;:{3Xn2 ?х\&"-$j][NkRw:ɯxCᗫ>UU#5^wD" ϻykz Ľ+=y7V8@ Yb0/%SBǗ:$jI4F2N/էbxMJݶ*!Hbcy\A 6O?N}ǴJK63O#rO%0MRL$E,z g6;-Z|yloh̳Z9sfReJ|/?% endstream endobj 35 0 obj << /Length 3317 /Filter /FlateDecode >> stream xڵ[[o8~>8@̊Qހ`]. >84s#)r=)9<;7&7l7trR?T٤0Ve>\-&OzlW|.:Mhz?߯Y湺sS-ә)M{1sOwCc=6=ؓ3u"fͯq-Yc5~Ro6a]|4<ȭꥬqѐkky#wP'+LkU"9$.·sPclUMq*$慌更kqk]]=G<. qp׾A4% μx,F?X[8#N^cVDJÎ$\~K[֗% ͌ >Z"c QYٿRʔqRp]#]ˆCkF=#,E[E4{R=?7a> _C2RPm7CFj)kHآ0"X]ZZ@MHͰNU =!ti/{~65\ZŴmvrD'a9AԛN62D` :zGޢ.t^#~k=H5D mRطhjmVoơ=4?6:Iv4j1ABm>`V,FDuޠ%[*#6 㦿<ޓu%, ݳphUBy.J˾ >;_Rigo?ur#.v&QL?/mƙ7oiUܝ͔66|eR!bK|("sۺm B6! 72Y}ñ4iƁz|7]{b{1H#ti+r~(J(bowd+~!xf M ^roC(iyD[g}OTX%f ZU@<$̢ Ю3+[i,ۧS*aCRyIߕYlC3[@ϋ>n{Pi}OFT-wTY疭7$OοaYc;R `KUHZFY&4WG&8&cOG64JK Ъ?Ajd^bQRj9$2kCy|~IzhU6zo.MN|6X9~Ȱ&"o%Bt3 %ж>i\jSIlj.$SUJ(,c-!f@n;RIYO6}5RJd(*@꘍RԣjHhC9}3p̠QϊD,YnϤbjS֠YڡQ0v2| Qur?BO? 6C J\@,}*|&f9& [ؾU+i~)(t *`ޠu"fTFi#Uv 4s$  87bf^^| M/( ~G.H{«z`Ȧ{sǾMy|ǖ;f Vk'iFHVV_KqN$HB3wzd] s}XQg ҕ @qz]k w:GN^ʑ9 ` c\~+΁*kxPp=#Тl\sd!d;W9 @2B8W34)J[gtCH簥!VM[鲁7 FHc& 6rqWFs7sy <,{v{?h;zn[gUСqrPy}BSś9NXROrF1vLpUr6*/wx4930 JΜ3Uw,dE~}4Z4ǰu26wb0v<ɥXy{k6^kV[qC}p>?v?{-s2b9U\iYVfd6Ar"FlT endstream endobj 42 0 obj << /Length 1581 /Filter /FlateDecode >> stream xڽYYo6~_!vaA@ lmF_~Pd%,'NP )R"-9#^ 9!νCo~p9'aL8i$8ӹsNF[(;ܮvȣ󆠦A!ynh0[h(9=wgEIpvs9M"84BarF$/ц ܂S8WW0=Q@c@9Nrx t?yoLo Ck26? ?2@'l'[5"JY:]6ȯ颅Q|04Ś%^>q k۞sl%n+l4–cU^7I 7sXMkUze2\!UŁD?GKApRlwcγ߲ԘbO³vگyY:ũO!C.O@91b]/@pE/kDYey(e+JY`sCۛ dKF{o )g'% ZL,A".v+~⁻pYO. YAqwj('\>p#MU{D,VPl,ww"j]1qPbt[5V \`{hxW6E5)MũXH,Kg\K)J?)VW#3 ? %R:QRSQLȏ+HW=o*Qѫa@i.!Q$$j̭0峉[r~ ;_ȷv24/ #oA~pb)Wҥ:~lqGqب9(dTm-n!0Y&yK5bCe\92m5"tnaS ݺ;'>IS^~&ݿ/̯ksUЖţeXA~D{ҩj̀k\mMJ/pkeov0>WtWO:fJ1g '.w*ft:NJo)|('tzQgiKFY q5M=,U)];Zd9 CC;CWHya",DxA1y@O0Zi;07 l(,=p԰],}~K}./5P $ ɹ2qߌ5oc]% endstream endobj 58 0 obj << /Length1 1626 /Length2 8819 /Length3 0 /Length 9880 /Filter /FlateDecode >> stream xڍT.LJq-ťww/R< A; HxqwwX)=sν{+k%f=3D%cdQtrqeܼLLzPW?vl& u!\m { Dyyb!:!ā w5P 䜜=P[;s f򉉉pq `r8ޟN`(RJع:xxxpN[)6NABk G_qc3?N6 xoA8> n AO*5!?j8 w'N 'n @ME5nח@7C:ǃAPG 6t_!+ w1+!pW$~<]d[n͙Guq(Ź7acxyyEŀ %؎zΐ?|=z;;9mۀBm ?H;pzh  P8??#/&^aNp??G]SM1_-픕uz r Ā"B@ΣU?p'؟?%ֿ ߹4 #tS^!^S,WoEn0~? ? q\7-PwR !}ʮ]#} ւ˟vߋ!ZNH?;?{M/;Y2~!a ybK_Hw֐ wr7 qB`Qaa oӟH#7G#{y#{m@@PPclwpo y`@>^ ?d<\\qpz_ vC _???2%=;~b_|Q.C>,i0{ #}L&p~MNC5ƫx+k7:cM3#9;2U]4X\z6|n\| Pm*L.nZY/<(*66Q&s]8Z?40o)$9=+ &;KӳD#w*o8}6^揹Z(GS0RӠ 1{n%M{U dCc>U'Brk(Y ߶+$X k2mt[ɉ2Do,ڭ7^Q%ZR>= 9eFoz4-\=V0m]&kgLpt/G:AiA^~Ca|v{q 7tDzO9+EFP$`4:c3d[5jƸGWMW 5rY M5663Z:MH,aZu816+SmVˏ>[8tiƕk!$ b&{g3;&|i's{}{"Pw<׃,k][dF-w ec!i;BJ " cHT!oU^׏Z2yle},,^Ad z]C^{/hi4>`2Wq}Aʦa(a~뻸g76ji3S5a- ƤPBXY6huT] 'Pt4?zev-q<(=XUPRȷ|ǎ$$ݱ}i}Y1l1WYRGiʄjsM^V}myNɛb@j?P`N&Zx[d#@"xCK|Gԡ .:dSJ] ;hh?3IaJIRo[ !JbųɿWZ.i[gM[b/G<Q择SpV"686cS0F @C|sR^T#E?bdIJ\!#_49B7.? * ~tI .J j!Z'cTo.>K)[v{ƅi\$cQmY MId- 5 ==5KC/WxrSZGh:3afILޘ4z^?1H%KڹO,^gc_U8:/gH'Жeu&075Q5ljGvO) F!޸Ju:ֆ=btr}1!`EP($VǘQ.Cn#JPKqUKoHP AOD Fר& ޏC8{^nsa5,6j !6G,&.iuyxݨi~0b\̕oId(4(jIuz}u'#e;ʜSGaZj+aN1Sb@K XBr7m@ E.w s=)3j7I ]`x]eNךkGaf4kLt$*C.Ɏ*@*MKF'%,d 0:VKzkSMnjqI=.禦<,i?wmu#,-!t̫uSLR (lu|{؂&0(.'ݒI'|5@F*c"qVJ3S25i|Ly-mqNވWS9QɓFLp" ep5; 2m!KC+^LIAl퐪O"DIV݇ĘWk =qLO~BIjŁBYPG$ |s,sv^sS,\i/Z=5*Tտ:1[[NK (ޔj c[d좏1ROsKoKs%ʪ_Rjg>:7-0ZYdM2Ɵ-wF]<1}ZSES48m=lh&~Dr8$oߚ;*= 癨oiFെ5yP S60TyRѰ gιdWQuQ)XRL3B#,?*a8ٗY.2 Mi3vo w!wS5888k2]NR}SMz+уIݴc&/yQज{{|HB+:RkU1dbkZR5( ;eEk|:TBX`Rכ%+v4lƘ1W9FN{Cdž&DhiNN)OŮz:L?Gґ/#q.AOṄ,CC I,븠O-A m$L~04l8+:DyZI &<} ֮=SIr~#W 1 T0l:Y%i9\T'0Ŝϑ>V OEEu佸aMYOB3WqnNN$Fq|.2=}F3_N8 CPbrO&SK"ʬ8;MR_}VV#kgE+0 n+#"gaܪà]Y5^k5o*{7dAT;Ec*5"k(l1Qz)…f4[7-OWϑ_vPᢛO ;Y+n[3JYaM'׽F{q5ħ1 F (wCC7 DM[0vctS~H[E8JkcۅU &Emtsai %Y@mTj:eDtɹ2\`WcM=*?]ll\5Dd\ܵqzq!C3, Z;Ag4$0o&Kxy/n8^ ;N-ijTEQ4!oS,@$0 mMd"ܤ"t³'GCWꛁP] GX,'_REE(h:-;] 9Tlh@|nZ<@yssq|A({Dj-87p&sUlVX$hk: BЮ~wf52΄'1?2yp &_2&X| ,i7PnM]_X`g6Ro|^'z\sJɺT:O5s5?Cydpi'U1 Rn%×=MI.)!Az8ްL,z -Sn?@$``)l;t!vU+/" epaU;iˊPIjWlU5 ͣ;.48'!)'l;ifWH(65+X` >`mgwև_|y6ay\xe#J}pXju]7 d @Lfe \\fSqxbζ2owQr5jȩŅ#B.-fOJ-<ؑ XQX 9to 퇝)Fɞu?q74<0UgXۣ'oD` _SKH}jK 4% ݀-P$n$V.uyE&dZr1RpK3;]{W?:.L:Hmx2;%F$~}k1x1s|886J`푀Dam/?aOzLy@é!}no*xy=. W2qlY>PxZ7$BJwnM^#d|'1i^#o4+_)П ].JmxVj{^f ACp;[&S 1,$t$j((Hfo1Urzb[%x#K@'9%].-~GV=~)*%uu^Tg_(GNo|i0pvjg:X[q McGYPO6<3w7Ԏ,:Eo33noYO̱ѓ1IAH|gIࠇc28B)K\AcU \2W/vFV s_^%{r5RiY$V% %yej[L: w$Nݙ̨ZOR2rמ2/1C~ *_H,spXcu{=WuEt jȃK$&([^D Ė|կ=J9q\X]~ej ~vy4+Mo_W iؚ23a_ӄɾw %aILr? m)\]yݽ-zY_Җo~gM.aT15Sv7g3PΛBԫ\!C7dwtۏ['U6LrorB(ˌ:R|t{F3 m{^}%"-dȃm4~@i7fua(I} 譊~VuRhW~vNeQkCH%Oy6C(3jv9Gfb\~eJǨzEw<N݁o^94sЉ}W <3BJv3.m,nm[bח rt}e`n$Ky7;x1wjԴŊl}#KpeɰmE⃫kP0hbL#3e3]Ԫov ZM}SA7 WwsPͪ3|uY-7YZ҈H2~$#A &8|yK W6m'=TU Я8w6g2ʻnv\q Sz_Wf]YCjG;x(r2O򹃿Od:X(ZgW,ng/SSBsJ*4 Kzos& /k2eDʃW O%bFY#kd MRyUPi -tKYG.;FWې%2: J$A 9s@uqme7_V9!#ɉ:TFm|UrAFx|$c?P^{^,PDbܖ2}r0OkKe~p&,x|dxv- ڎ=99ivT"@Th7s. ,a.fWbY3kH/[tjrhKd%l-xJ(ȿkXl gn_,+BKUSC7~$z&C7S4M@#9"=#$pK!"/(߼+I$kd -K6|dj5q\6ĺJ#B0k9Ow0Ug@OM%^˰thÑ:1 ڡs *C6=ɌڨO-SIV:|kt@GϴL05h&&w~t K )Rm6$~j3GivN&ӠKr=? '_AQ1F)s-;nnz?<\vM]M`3}',1>ȒB!c>Ms-5 endstream endobj 60 0 obj << /Length1 1387 /Length2 5975 /Length3 0 /Length 6929 /Filter /FlateDecode >> stream xڍtT6]ҡ" 3twJw+C0 *]4J  -(H}{y}Yy}]{_02R"aHZ$ kX PL%6aɸ-`(o8!5 W@}$p$eAR@ @Dp(@_pyq!=PpgU>HFFJw8@C>L8 .h0[rV.7 ~ 0{&L 0s{0E:(W!>( 0zl$ W?ѿ#NpwPSO_@7* [4U A=p_3Js@{OA=@!~+'8k 9Q2 C$2RqU, e!8] ;>do/ F1 @4 G;Qp-~ ?+AS;FSUDe$8@JJDF`F#XFݳQ Wԅxt;r;G_YWwG>?qE] Wb@7vaP{u+9 poM? jGC\b_v_Zs#`FHo w%0 }E.ؕ~YRAB MTBFdW|`@W "@BW(_g*- }Aޞ_TPWr̈́^6 L!!rQϢ:~ԫŽ(|Z>̠:}~RgF,U2Pͯj)ϲc[cݻo2m'ex_J"dtdߊuGҨ_cܻ)zqd$ "ǼI&N"+ ?;4/ I+,L.TzblĊDn6Fu#GLEbG祖Y8'G:l+\F5sG xg$ג /W}ZMK̂s [MA!!զTD.!f_X*I?AAґ ^OqxRwpt(5 El𞸅?z/Uf"|&j=:K奉F]ֵI<n{Tr2.eJuqfr.6moasT&L{[ip"Լ}ѷCqA f^=?9ni%}.9qysCy* 0ǀ(9+!Oytv3~v<o[t)V#vFp!\gL|zFu q/0g#,'~~et~6h(]6l:>Q>_)so5"*@pKru!vWEJ;M÷:ߵ."$o9#,:,-CE|4xcw\_ٯ%|gff%:z-^,*?*~?f L);n?ɶh )ySVƃ\mݬq"ױ&rL62(9$y6TRVsv{9InB*0~ʾJ>Bq}?&]~7.9f@ _X:OlY^%UJg-XcΩPi#k y;b L=)7YX{ڳmkthC>~ȀKgNfioQ-g 6Nx[Bf@uI*Cm ]g~2Bޭ;o{} 0b̩vͷ k(*).oOjel5x'Ns߷=g3U登NmQtע^.8noL?)<>1hN w д۩bP-|kIܺvGzֹ#H14:̘#+ b5_(o. d#yTwSu…y5get/Gb׷8qhnn~>Jq(䀃0gl׃TGY I{ Z妛Qg9k;*2G)ɸ5\=$I}HY)F?JK66;5LW"S]8C= ^҆ٷq 7OX=3 LÒ26 CqAulCѾ~#(QQVx)5U|C ~nЧ26K܏cO`pp- |#osLF;:7nY)6 #WplRVavwBɳ"n;=l,(K@v=E!jr;Lx.Vߨl ]{LeG 9mk ih"̱ȌѠD#2e磴oBk+o 3co1j6M$ȤM24WShE93,G;K hL󆤙-ucCw#gYPD{K~tu>v + 8-بC[ڀ>%yPFN|{ʱxZGdakZIMg L:\h^q9}g~5>0fqÁ9{9dG;Idy}hm~JZ*^5(l+ě׊~u{7Е̃qUK4H}OژBl8/mw;AF O{]ŭ5~{7v^ yqCCwO Vc{k)ܔ)TxCw/3@K%M60*ce+hU ~(\T?*o4fgynӈ`^-tPA2DY~jqmNufۮ O*Z%"sY0z߯'oP,G|$JĩԿEfp Xڈ nsa._8K L!5hdURpLj;(N6(ۼ.g7FaϘ=v5EkY&X9n(ZGg6;jZKkQ\jRoB<zGGLEWkD /"GͯgvϾH(+5s 0LVhy~YGY:=Oi2$HIMvxZmʒV kbEW+I藸/m)(aXKf?~z7Qh}Q7)5\P2Oɨ -O{)(TRܣZU/A>`1\3Ij9V~HtZkuHz>2^9#KD=Na(!}x9ښ>|}N,xI@LŜͬdrwO(9ފ̓M>w1|Oj]O"5X?39T`G+-) Qyc ֟CP2.J[,Q2:kIцITs?!4G^_Jdgٵm `H=r6>^y5،olK8ڄRS6GjDưw˕nϺjp'o( x%9hb"D-J:8z?sW:>rB)GL*wc13[.\"W[-=kxEhj_f'ܘbmcE8l\_H91_559xJuvG۱u"K=i LF<%p]mxg׭xKsUіbJh ׊B};bUH% ,Y62f ;\=WXO39zPzOC^ 9<~O F,sZggLq=\r3~29yP|0a2/R ˢ畞X?1MyZ$bi`JYkߍpM#{w/3(`c3Ea[M"q[ԅ5^Tir"j'WzTwҶWEf m ,,AP7M])fÑȪxWdLY.WW \\t5ndgG QC5riӻOȔTҮܘ+lMT ʳIԐeo(P.U^w]OSODYت8..|4T~,Ԗ}N{T!<ێ)UW›󋖱=ɽS'i/[.qߋo$ljsKSQ y,ugSGظٕ%wCuɒET\!le'ŏFv`P좔xޅef"VD6^.Jy&wsk͛&Hu%iNK3sL(,{vp7Iqyf(e?0/s'8Q?\OV_[q?V |Ux:𡢮<è$/OFgA\ģe9*ҋ]E/vZ{Fgy~y\DUI3e}hU-+Y e<۝QZR [YU-̙䭡ryݖA H&HވڂR᫃ͩm 8nUC q L&DƱHmΕPykjʧV\j(>U^`d/q՛ 4?8p@}tL|Ƚ+Q?/8}qc'ɒь%<)]؊Jϙ(4G we%LRyB 3cqK՗nxtݤt+ĝ:z?)g+tvRѵKSBvO}yk&ڑ3gbh 8{7oCLu vx:Q.hr1 ͋RIrVMEYNk~l0` =\ endstream endobj 62 0 obj << /Length1 1599 /Length2 8677 /Length3 0 /Length 9738 /Filter /FlateDecode >> stream xڍTm.Lw(RCJ]J 0Pݭtw J7H !(4|{Ysw\^0irJ[,! 0g'7H @\ [dqCa"u290P PqwpDE@ $!M ZԹ*0gIC<#Ŋ-,,;@ ;;ÉV`G. AxW1;E;`nO(C< ր%4NJaA*ta6O pZA.7]e5 Oc? 85pyulesr;{Cm6PG@SA |0#u0@AZ~VnP u]#w6;[œ 8n{3odu] PQAyW=oJ}]`.2 P/ !V7XCK-b͟anP/ ߟ<>0#j(U220//'/ ;WUv~C/!{.M@ /gGQLߌгiуYyUFItFX%Ng uolGOfRMk,_KER}ivt,)=v)6q}.]d2 c"iQ[%P* Sk7/&X8ԓ*771u{D?M#ޔg'a -bt]>kB(îCOlI8=ȈQOl6Yjׇ褫Ky&9$ga/*.Ni_׺ڰԿʧÉ<86b;&, W{4}@M%J5RF۫`C$^ห}},KGݶE(_8$5TA:smld#]E$PIMM)B;NE!d#I:NcYg(gucq W|?嵥|z#N@˜f APf!= 5.\35,К3N]ՌęOATuϫCm 0-rTހ,_[zZ`٧7B!Ͱm /bF'q޳3q)| vOvuNֺ!R5 l(>~iPq֗Ù2/Wἓ^9pY&ek㎅`l쑢,]M\qO- ~7lu]缍FWjzAk'>Kg$&~I Zv1ZJr?U38_ nk+*+%/±qA`miNgQ\ q̪uR`;^mB9\yxԞM[O{՛3VOM278B ;.]fMjq~ &}J\S‚^x FUjQ==8FekWM zG`:Y3"84ِC1vt5UravzcWDؚ͕T kmΌQcx#}Yzh;S+5_x`AeMlu 4T_9D I \O)5jm)e]A(6^k8u!JJ6ET:oftz T&Vǒy;!*4#>K6uA$6l/l(QIygX:*]T7kwp>WQbrD8P?Pb߁sqm";Ar(Jy"}sr5-Ħۺ>A?/HMGmm3 2ѵ(ĬǴ=]PK5ıNSQflnO7aIuXœ9"Ta _s_xpWPrKr =\vd PCnD+E=O 9CIj:AL8aQ PӖs!m7Vie X ħ䶏8=C&oo}=Wjv;m4}oYb/cn ^wGoN%cE}W'^[;gP}<5"K]  {}Έi(Pc3#ǒ2\P0]39UmDE'jm3`δWn{kӌ2opP1 DZes+Ay SE0Ni_V{2K9_kݟ2JOߩT;.KH?۞y>Cv{Z0g4.Rϗo9h]O0ʻ\V;~?jU,#J_r`Oy @#z>;lae/EyU~ەfDѽ-8FT]~D8;|Z]f6fЩ_:8cܞk_c҇P<ȭoލbB!xb5]{~}\VQ,e2>PR}yz`>"&ldĺxvd1y9f ~3|6%Ge[{5mPl!˙ ) /{,'Yck6:>s0C,^mRK>8Y9pط"ǷWтz"-c9d]O#nHf3:MBց,<ݬH~ɱ$;bKFQĈt-SMybBl"_K fUS4S'?zSS0ޅYX9Ƹb e!!m\QnyGQh8t"5wCJ8.f" K7A~'y\_4S~Vx2읞n͚N.U\yKޛ#^SWe&|2go'Jմp򘭹5P+ITBvƗfEk?;r5KO- yq_nRd JzކBTwf|tǃ;E K_`F3}^׬ٳÍYtݱgwHWKc3-\p.aJQ%zIz+2;$S:V'gSpXDjҭ5pwcw*=Q@R!E&hC-G"3Wη}VAtoA1_Қ6gD Ohf{ⶲ?%/w}0EM;*%D7';/2.S^ʈ 3a ?afkH<s#< ŦTMr[+ށ3'JV7K㽠1o\[kަT͹|-@6]3Y:Iq}.Um%{vBѓF,FڀWpR$S7^R?~rlejH̻ص8ouPHF)~0Қ-0dYs|ٯ`?ʲ"Bˬk.p]fz]0bGSdTi|{:&k E%zf N\ÀhˍS^:qwݔt,}91ځі/[:_mK7C!tD>鄐( hC25' g#I;8~6b` sD=c XzPT_c2zuƩeWL\k!7,:|O6_) v0tr֙Y?BQ$5n;ʜ=d9̭TemV ߹MM:x W_2Q1z˖`[^nųcK{>R-9PU%` lR;Ea]?5Ջ xQC}-c1d=%7ÏJ-Q8'`%Rili"|՘=V,6`=B kCݎ}Bi;[T[z X-qV AcamA'R0ty!-+tņK@HJT"Q~CK.ڸ$A˜6t-dB]!zY%,Kq]\-+ӵ=CM|\^^I^߈^^RT *`>e?Ǡ"h 7szh*஑z]v!n {j"1 7%Mjqё(R׼Lt5D ɟ٢햭bKnX2M]/Z2v$b7X35pV yҏ9d@(OVTv)ⶮ% Q` v.SzL[Ȝ:,lWGx:v{-BX-*ҵwYn06] !S_EQc+YH~QP/_4nrϥfaк-> 5VWFf~gQtk8 W򏚇.8z#&D$#+@۶ L82/*/i22`ɉ##3`ld{%ߎ ӛ_IRY]D΁yLXVk uQqyS,^6iG.UγHI@8`of^RTS9MP?b臥ɕf.Fby_IY% ki*1/l<;%Lg&zGjhLJz>BB17s ]FE(\c;G.9 3SH abY2xJ~!.[fŗg]H}@j6 ċp&iT?h.2Y1]^z/ID4q;^w`v`mOo1em^Q7Dr;J`|} 5tS]^r F/.K a(&U\ZscOLᐊ2X"QK5]HM{P0I?zF>|nEZ.\7".X=Lw6Q4a5Hw Hh<4G4P][3cg_?Y׋g?jY|ď Sc ɨ\Y <=f=3ѺTXxokV{gófka@};2.]qgݒ4Q5O_x=PT> N)#Q{LHi~rhtW%[dFLLDI Z{ MO``d AtI}'~[eh\oS\tJmtKw='΂3ӈ0av7CUujePjiY["d 'kEF?m/t`5]Q 'Z Rʯ9C-uCj Ȕ Znݟ8dFЄ9kbJb#OX"wd&K.H(?M^d7LJ5TիH8lB$#nq ;LezK̓F22ko/}m c9\e9>|'Hn?896 tE ]R2O;8Wje'P[ Oq&veLtgZ2`Z\;(7vΎlȮtՎ ]Qj/jYJ1pM9'B~]端'[&ϋҖs$o"4iXLiF5eFo`VD@]PRɽ(> ׳rbJӼi1Cfi=n)"[:{dШϐ\Ȫk3]fV@yg1:yOj&O.|Xxx+ֵ%A( "iǠ#-Jy{%O}bj ]:zƐS"HiG_G61?xD6_aY<^=#ROWPRwPSHyxaI|BZm\)ۋҪ_]J9qMuD^@UBxY -?2%{%;7 -n1ɷ=q|v*w:!j/Tz0Ǖrqbp)l1,k=,0z;4 `Oq%TzgAK>a:dd<}ДQ#U2̔!V1m߰bcR4#Gwfbtbٖ]Y 9'bs[[[*z񶋝"MP"5+>Ǔ?)R[z2rX~a `u.s2cF.s;49>fε`TgffM4ɩ`19UҝmAr RyM6rq2s##e[Qq":ǫ-F~t#%GbR/ܶTp+OۆnrIO ubRx&yx;v"N}s'ghe)xd`V3vۃU2p>TFJ=cاcz{vBl "W~ =Ez!&@`ʷ"k2ytӬg^D} 8tPsj;3"E+栆5~n4M_I!YBҌI.ס_j;%ZTH~#Eq>ar, E<~k,ETfw;S>3}0jSE+uۧF$ u]Rߢ>Bl;K|"[1Z-o]P>2!e_!q,E´8n};wUz!ΚVuXF&L8q$\xvAGaXi~d +#%YS[''۝~oLNk°]XEPu<3,V֨ [!$4;=&}ѪⴑYP&uq?p3*$V|o]k$kju{H>cCdwgıȽODŽ:"B[+g)IIRL%t}.̍ BuV%enHNˆbݩf7Os(VkC=SH\ ɴO~LR| endstream endobj 64 0 obj << /Length1 1385 /Length2 6140 /Length3 0 /Length 7097 /Filter /FlateDecode >> stream xڍxuT6)HC ] ݩ CC4 H7ݍ4ҠR";9[֬5콯}]d㑵BZ”$P@ ?G9 0W8!.0 S8 $ `q t(@V ^*s%#\6(1zC9`11YG  A4 ([#D(a(`E<< k8VnN|LE/"DED0gjwˍ F[?>w߁Z`0 E,a6p0?6z.pO{`OOB"_>ǚzF\&wLN x@0X A?6 RUH[5c`+?i"ѬCrSSwῪH )98a#/MZ7ZH  5 Q-Y <`A^?U ҆(oKjpL nAg@C j~y'qE {lZNCEZ0"@m |hZ<3Nj@)̾k 5AB>/?B\\ٿ y sHD]MPi,ڨ$^1?h>Wq|9V/#}^Didfס)|ygKA e dO:i&lD.ݖ?c鞍`%/RQ nlWUNI'fj_:fZq~ixf*dAG/}$=k,!(E~:AJˬBTRGdrO&8bzqB+_Jtm\~ &vJ~(`Qf;VktL惝CV]CO)`9,~z{ۀ?lf`m3Dxquט*InOUgI6ۏ|9.?几 ( w]ӻT&/+T#ɟ.r:Ȳ ?ӔK> MМwhZic_rXy3^>>a@AÊu>NwzgǏsA'0_;1<"):BbƔC`4YEU˂sv+ks3#0 XTjC7'zՏrs䉇7eF٘nF0Qc.1~?$b`z qXh.\H>p]}X˗FGJDvq-554 6WZ_¼xy[_riKgK|6;{Htq#ẁEb WœٌHZY%mra W߈cY9_o?)O4zʔcHj^F\yg-a\H64?V/<Ů3xAN 3ϑw03 99v2]vSn_VrѤ#mI.Bo߇nWM収K f ]_ Sa=펩k{F m]w)o>+/L]UZ3NTXY$d),r@GEEB-OLIac װӜg1g)ɴw>Uy}k)&⏊կ緱 [;Lj3Dq_]8tTnlM=l}AM(e g3^.U$H0`e8N~w9g!BF9/FfS} ¤z&ˀϿJ{Z "G*;tg5odPV߭|E ) Iz{b1BYmi(FO/P+cm\S/=DV >kb'TDh,_VKJ:7c!f`طn;&$4]{%shHaj'5Pɨ¨GD_ rS%21'#~;˳pV\2 54R S4j\:$鷴j5Bxo*VV" ',/9W)Y%-^,ˆp9F+ 65l:3Ӝ{<'b۔iŘ}:́a@Jek G wݾ\GÓ$*S ȰNw-ZQcϳt 93{E!v c]Nڵ:yU.^J50n mx kւ BԾq R,!mJ〈Ma ȆV[82h7JvOG#cD#5\~ fG~xi)mg +2g% mk{nR}w7<qkFO<Z0NO̯k_U V}NߙrwvCLqٻOs]\֌dD9ћԍy5~wݗ3c7m B/GJ>4JafヘQ{<1+O8Nk6?}Q`JAnr޺$/ʱ9XYy*f49.ruxgeJS} I%;$3Wzh_d_cHyޗGŏ1W ?Ek|?p(0눩pgÃ34G=4Wk@s}̤絁Ā׻|JVqcڈR l5"W1ntb (XE9/ U_]&Dk?D:1/U[(E_6;>ٯy2'iv) Q%y3Qޣ*7)ʨ / #9ʯU+5*$J##oXyj`,oT5{)wO؄D֊E*/Ί>τL=W[?'ؒ:t6[= 8 YVmq$pӹy8ɾ .^`x޵=k'qVeFiV9gV--oiWH}Jx/8"̔}UyO? z/̓*`Ptի@EqKGUѽqR//K韵,5yXUfi/[{y,h{'wt9yߐxubAAI+ʟt`vf4J~a i!?`"\V8tF s~X IAGr .N> d43+y n3"]p#ap7ǚ݂ykmdr&8 Zjp';S!wusg󦍳j 먘K-wQҮ=֠ݍ(Nĺ}rI VTZ?SX%Kxr~R1BJUtrvi$f%Ki0=zb6K»-'Exy+h"&O}X Z_צxGBFX8ӯrHWQi*|YΊ&3zش;ǒSoϏmoӒ:k'qGq*LY!2!uV|^iprLB.;ITBgi3ᢘ:%gT6i$Y,TOD[8BWXWg)PM)j$RG~~v#?+FЍ8! ҁI]w򎱬,{.FmWʩQCG:w7*|q=d? 2yZ,)\ɡ2ѕ&fk r }FT>NaLXQ@N^R:,:׭+;z՘Z* ~HGD}(N`yPkvssbfl1L~DFsPjXsr|)"PCe~+V&|GEO?p\i+ܖgrk nh˓yY]ϊH gf׌2d.9Bܼk~ECH`(D^Mw g|N ?77 9ݘ5mτW/ hɅ{?HY[8OTG6JЋUh޹^\Gm 8w!kF'ǶBun!()8ϛN" :ī vyaNo1ƕ\]W> P$rƹ||S{ߩܒG9eP]5h`>7sᣊYACfnG=M‹ܟ# 4aFוЄkj g%Avu?>/U2$'QNtqP)z"S "ֆD(3'g 풕~Y}S'剤q> MžZz:gesz&E(Ӏ G~ȦD>-Ad.ūi<z0LQsh&3SnL>CPq<>bfs_:sxWBjLB Gd7%n}J?cjkO wҁ:5] n7u@%:zvY4, ) hm9e!aD)xwoE(ߝ}Ypx:R!w{~z&Kdb#>Mqh,M1r<189 6w~[U'-~ۮEOF>hV.M%Vx  :%[1՝!  :54z.1gm42n'UD`?^J07ߊu'4 [wt;^B-E14U}˧ovٝˈM~!?YHR ;ߓJ yLx1QIޛIs0{V2c2I}'`C$]#yO3KBrQTܕ@-7@画1F)> gi,d33ƭ>k1^?ٵonɐ&L0.| &a[VU]g W87`bC_zů|٪'G7ȡ&3Sqqk\/ߌݿ9&q>z0lZP0"7sjy a1jvע.Ν}rx}ڴe"쾫UroݭZD -3 l[©n[VI=v/"PPX+/aGw xB!(V@!IE8 Ռb/g^V~&NW^xY@X#CnoUWq~ҹ 'a;;S[I*euf,w6G&x"[1=Qa_tfME8A=GMyl`H!e"9(N endstream endobj 66 0 obj << /Length1 2193 /Length2 18208 /Length3 0 /Length 19528 /Filter /FlateDecode >> stream xڌP[ 4n!qw 4k Cpwww@pr9sf&g~gk"SVc17Jڃ\YXxb ,v&6**u+[i*M= bN@cwN]OuX?rXXxh 7v2(0dA@g*1{O'+ K0yКXyx> bt25],vMmjV@qAodldd!Hnb P:܀f ( ni7fonV@+ xP(9A+XX9i[JL.. m݌lM1@RD`^s6urpqfrDܼwYd&fog8# o`n233Wf +PF*daaa@SKܫ{:%d~`^l8})_ 02u-@@;YyXgOdG_ˬ(*w{9Xl,ֿ([;ʀ<gަdrח\Q ې߄$]mm%Gllgeouuy_5_U-K4rREYVΒV@3e+S˿o^-흭VGdej~u8Dߐ S{V#'}̀b3^/  `}0A<f".` 7Yz_nqл"лz`_.3}o;?u S_}ðgD[cذV_?/;cno'St?{c##f?u_WGn]f^I:/^s`?{'.t~#~0X:d7.0xo?{ߋw![#ۻ{?z?Ki ] 4EX^7 n{!tgܟJc^vjw}BM tIA[ە^!}>i kIPil:ߊ430Yp"RO OĨ.|S*ѕE9Oʣtu,ta_s cF94aqdWH_^R/bm78eK (a-8;RuE|32ƷBck}S[G7Δ|Kv Pڼ /y4*|R拭 &ORΥAB@OGoLg_9F25| 3;ڹ++5>|pV ҡ嬔&% ~wބ◺]c,xg2T4 ra>˟ {q6ն+=Ђ!ePeBR7j^?Sxm.ΌNRzVq58 mwү7h"^#64EWj2CcP,XҀ Bl,'&Jg [2.pMqpSrf~*obL;G> ˍ-RQY$Tyˎ}pS(gpO HJlsxS\")EKPndo{{AeXSFĊ¤p#L.&sԐp/2n<{G_ST}lK{7/B2Gyvg0 (pKfp%CV6Ēx N+wƓl)bxC4{c/m2ϖO {JTVHy7y;lh]C ?C+ *LXS韌O`6o{l۩%xI4EDKq81KŲEmgUzv!R,iC$a"RUѻqi . LD^| 1fS7_ڑ=>d +1gI^&`$H5EUPX}Y׃+k񚌒ǰ-},#B-ijj}ZSZwy\ U2z]9]j:;ބf8:Jnۭ[P#pC AeSS+(#[o{WCas܏қn^؆9Xe${U &|c+Tq45gQ1*>qs-X l Kn=I>NcKkkQٝb2SNtT:c5Zveve8]&5\?M`Z9Ē0*1y6w xnmXA"D凗RvՍEv_$Ԥ#V!Rj&Lq_ 6e6)W ;\g'Zĥ(|[ۅf=W=oҷE|K ,t ,&ayo>G0!Yh޷3OY|^gT7ڙ' hiEW1tyv0T<)ӀXk= rM}=dT>̑q^zIOߍX5|$[=(kXeuA,R#|-ث*1%64h|_ AK{]lX)q}3"X)!dVFli/g(HZ*vr\Z/ե -*h ޛb, 4hNOG9p9|9#BSc2`X׳-(cz*:~jNƜe)>hOP%Ӹ:`8!œӴqYAahN؁kL=+S UUy6)+}|U+Wt{^FB2`jomgP@77,@"]͚Rk 2O϶]YlSoɁ& _}73NFK$WҘ+8OΑjki>5465D -RYIwG*I ǐ>; ۑmrCiruFR3g qK ,tF4ӈc[{-zګX'"U)-qQ mV ~srȩwb>DU%%HƳ]' nW5J$Ws_S^nO?OYO](*;\rxr;BVi+ J%5;^`p]x÷/C2ub5~-u OymF{R(4`>jÒae']^|2ŦI$ō&`Ў f\mGul+'IvAG+TC2ߨ.Qs[c;[_jX+@ᆿ}`K-x,)? +<-4KqB89n[^O`8FBD\БNK~i1.-nܙћ+r}S;㑋FS+1֦sNI8J6ST˴ǒ2K|Sc{N4CK.adA&kU2pA{a->}`#so#{EedXzHkŸ^Wz4^L')'6!7!mO=_93  㧸O ӤA_!Z+DȏCU\^oѾ7V9 6siQ2m^rzU5.*8#sUdbe#Y$V8 dż}ʏnj:_(V*S8&2&iN{%q4>08cKl078B ߁[F?>꒔{#13r,[4e}RZZQ}Ĝ"pԇD^ R'*AG϶RLĩ6H?%@@"wT"K}|SJRa2h!e&U-6AJ",8vI줹Su3L yNwç۬GHN4ü)I>4V%5*2Ws7S]B꼿$qaմYjZ-`>s7K7ZƮ2-թCAO3}_> *6I`OT# FBz.f~,z}4ŕ3юo FX@(O|v';ibXp; /l>69Ɗd9rAȭfpng'w ̈Ql9-3k5pKXA6g{dfx9H)] 0ҧ}OH>z5̈By؅ 5D>:ƥgL: +GTQk CʮW1Yr>W!I_f">gmktkA 2QmRl]U }.&]ˬ8R?n[30)ꇃYDÔ?aGD%`)9UxR:Ɉ1E`B{Ȕ ,LjU9^)R*Eԇӷ[753&qζ4%Ս[EKgOkVrCB!nS藝J OlT*;~$c)V;;OY=Y$qJy~Tt-l u@J^QĽ}R& aŔ#JC95F>*Vf5&nd&< ̈́(, #_L)Pbʌdv͞ãe'X4 hga,`520kqX_3_3<1kЭN>hi"9!;PT0 oħ8J]Z/%KvqLʏ:V\-y)ǖvi"RƠTZDQּT}zb"C(DMwZ*|=C+>",bAqyX -We-f#$ ܯQ|V#NF15ޚR,^F5oòzcʘT+] |֩Rp>9K1wk9NT?^ 󠽐9-α;U FtE㲡U&HI3CVXu*L$2[ZVKA򍰳aBn 6uҍ8@~Afw]%Q(|P 3+ W~)}7} ศ) Zryui :lBk8'Erawl1Q^uSU3K]OKH)Q^e{9) w9%CTD:[Kb2N`g*՞x%6Qp`֒ѱeN܌<p:Gx\+P2iڪHZO.?P9x:Kj'@@`! %@0Q?;m# !a֤:B2~'k, FEWɀ9DŽoVy,w#Kwܪ'%+ 3o0y~`HkͨZ?)J):MOE1<-M*|ŴR+ r G[&  {yFúMWCbӐ[!M7WcREitW!"(OEL3n[dE{-9J6@Y*/9lՉ޷f=ӼG|39?)LHFN*;Xf_T'g@3o1]9 q@*W] qsv):Nӡɡ{vRTI=ݯy3" u^bҝZ_̈vȅ֡ M*jo^Ӧ9i2d_zN%u6N|SPʓQ{Fd0L~];|f'c(GKx*Jg;xbȲfcדvG\Ӛ+oێЖUl8z7 u`ua l$>%h[Mt@ЎeWbEY&c[?Dnj2U}5] hGkBe)K`,ӌAK55d1]ԣӊQy@ifks/ެɷ"|s dQYpk $ ?7DYƄ.!\gM\w޺"1Mϟת˸TF,}xSM|}~m/V&U|\9[=2BDv$<iXt[':PIZu.K^fe@VU)劂^'e 'aNR xs.͞ømA%@JwS!@ǦQ(@O;AS@繨Ra]po0`ڦnug0wXMZx|x QzN ID75$ĭ?eJf^R;t3D5ɥŸ{?oTg3ܮ4\0zDmKiqz%9ίh{?|tHoH(ZbIGHjvoj{ID|GBPW $q_x(Hb 8Nbb&(畎\6<=XhZs-ۼwM m#a5]sib2|86~d{o66YA}8[fn< ZCn}X__|3ܹ"^<,#a :1,V)4@` @*p}myk#K]`E =AT(25 F\ZFO.t!~gF#Q#'Z -K;3 1kur0v+ma ϖi(GPq_ 6G)> $K4mH?>QT.=%ݗ ^4ŒNm?J0`Ֆo!MB<Ȍs͢4ZIBzۢdž *7ؽ^yjE=3\8_Qk/PXC׭&yvQZ yA\ҝ=R8q[S#x#ћD5&֜ds$.Sd%ABܭDQ fAJ#.E쬂)};\XKgAԝ< j yD KC:pR>G㗉SPIlat u#jҰ OT N#i;v!LhIk4_&C)P ~X':YN}kjcXH*GCIǩ @.3f'uQieL|~#4)V tIvt)|&V+TUVȏF ץp~8os+ +{Ƴ(s|__ tmC"E:^ ؄LI):r|l TEIvh`4ӐLj6EvH[*;ZKX!E̫JbE Dس` y ?[_B!"p+qͼ:g  .9,#n\M\J=-I<v{\$9{n:c|ijx;X=}:BG2X>ڼ]cĬU@cY#S'붿>_bLf`l ƃdpz3\6M1wX< ӊW{|?a ) dn}="Vn}r.RmuPБ쭴_aovn16(s"aU1Dl@b߃ڛ0R'-kR'N_n=AkBBX.=,Z=:?U@ҦZXdrx娾}qdL2~\fl:b̛% 5]УxԪiMܝЖX++"D&QaAt9UvH/j:)RFݤ(M7C1.]N~qm({6|ƍ=uCTh/RIn6!%V_OA;飈 gƕq:G*0zY= b =3 GlPN SX'U@ G"Q۩6Cܲ@F+yݽEoQeʱ&gEƑE-e?UN10lk>o`=?}~\1._8u9-Iv列sgfD#ի|;D p' }(X$<%݅Mm7ÆkdlCo*('`z@$QGH*sǭ5$Q ;t(k GBvѩoÚ}|lh,h-RkDGx`EjGQbS)8Iw[^)ű@͉+k4o,fAuBر֯ ցeXC.\r9ԄFHʸ) u U[n=bn#.D'6 Vb~rJ,<ΟER0KHdazY9d4DFBj)j-S$Pum.$۰Ƽ)D9Z# 42c3B*vQIAj>#j$Ieϸut Rdq%~-srvEIwfJ,4=$Lp ]qI% Lf 힕):O۟>W}>Z(.g@ M/z=_E351L[L{ܥMo.#^Ƞ 6rQr\H nH59q>F_$Șؕ.*rY 2!Bbytβ`d_B]^t66z|L:_ YJ*Yx&aP"g_G+w:n1f~,!JK;7Xkrc.Ԉ"F'{]ϭ?n6SldF_Spe"'p>xPåJAj2q먢/?V٤T;` {WivkGe`i y&JCb_2||i.<ȎdfhHoǪ F&XdZ9^qn4/69;ХBs򒩪?1dnܐ(;q"-j%uF#mtEC@;و$'ψD{2UHׄsr8s7~\,+Uֳ{D[v͝C^fuMOpqT33U0 )-ݕ0? V6H)DkI8-nR$C=40Dt7qvP`\CIfͷw,yC!ǥnTe/w51,5hrnBsABi2-?æ7ڂS:/"kkƜS2M74#kL68[w s k f(P|n(W\lrG(c;{L N30_fnwX8\=މ:sG5EG xY0C%ϱ6$`V3n:8N Ml%],7 X'qFԯnיc ۰3CX|3Qe } =m:-<ܲǩzxŀVT_ɚ5zm/\JK7&Ϋu p=aRv-}T/ MQs'E Q=9GY1~sr 6^L>ҭƪ!|n *ꤡ#>%ISY-SaiřhnӺwG ' fw> bMdMuE՜ccJOE@-#¬vYWsMk[|0GkcA ?P2+Zp0u=йoL{]V9)\W\)gf|M3;yhwMcFg"Y9ΝhdSq]y&d![u#ztYGӾÄK\ݦ[, a]b7ԏ9~oi',(A* xوWOxi_Eqb#(W* ';ɰT{PSR9 /־~2zٕk~ti1!ٙvj1TL1TC:!ǣodbV y$?)=T;y7D]env\#2_^0HM BX'輤o嬐 #}5=*HjղfO[ЬxmN{z(Z81Tp3 R9 9$mArNFׄ4p9H#Ѝf]J{{TȧRD!U%w=n|謰G0ݫ`3MC: -*X*ˀGj楩 QErygO+dYmgeX.`:_BV1u w<H.$j_Zcs[.t>} xuö;wfߋ? @rYz."| UzU ;*FPuH!5_ʲ }ŦPgԝaSM'f kGR)~ew>o^zؼӺp )O&*u|0c{&#^zg;4K4'h6?mYj!vW ]cZm9YT =| |W@J 0>a"3 V6_S* 6cj}/d;e- ,*Q77xj ru4 Zh{aP&L]2_dnkb A;96xW wi΄[ZL%4|6ƅFX1GGɣ)bRM Θhdrb fc?HfYQv.t]+o%=(sxSxQryKFXZ9*EGגeOй z!u<9+$\g4%Jjot+Ml2;J# 7Ȼ4N؞ȣt|8F3SEI_KOeqB{F{_Cmx\__U^qWL.4(g 6^b~n"<\ -Ցd7~nF-Xrƻ-.h8-4Jk`@w$g|~|2nZcΊ%LE'$(ƶ 1}X^4LUY3;jEIt%TǗZV DjJ%‹@9Lx):I#NCԏy3ߧ&rj,o"[K B/Qxŵf xe?lFzO^-_$ۑljxxn16J Kh<V8R,#qKZiK iI%E0Qj3QW )Ý2GaSQs􃍛ʐsaa2'd2[-|3kωglHwo"0CG(1W0Q*>"~I> > JVLq?K~Npi|U$u;1lnǺ?2}˧2z\ ǶBrwL "}=SE+.pY|.Ȋ-<͋YSl`Saz,J/ h8eep$ 8JW5)B'E'y3Z!w<1-?^w|B.jI'*a쑤(dWU>9=k,'5Viy<0W'6dA~׏i(yEcz#T?x;?P}~  Ȣ&(- ] =+ՠZHw'0A`+(B)b3ܠ 傚< o}"0;?;0بs~HP%ӄo>ٽz5{d唒'C.e(mVsKY֩r֮SZ0-1Lz ӀKaZO4 1yˬ }h9piW+ϗ`IoFywpP ),8ޢ'`VtWA=!.k,oX{ 'C xbtҤt[N ^&S2HxqJ;Ƒe񼓿SdVG_}?vfbTgoq2{6lyb Fp]:cxXDr-ֲ/'.߿4iP BkK rAHl}a8 xfw$R-a˅؉M/Zh*4r#ar.g8"ĎI GN CUyQ>@_#EDwGR4$/ D~ynǷ c%Cu`C~a=HڮTVz\y ڕ=\Ui雴ˎP";_,M!8]FPߢ6!?AeJ3HfѸ=V<"ȁyUkW@3c瞏]\H*8_P_5hne&Ba2$Tňx#Ff&C~Fw2!va\I[ npM*ڸ 3d <[qzBU:굏/b /zJ2c/[WsLtM$)M sYg+nK0(˺vb!^=ֶKø U5 8Ͽ\/}.$bSD.{~GhVW $eyt;˛he~脖ìz \H39I_vՖEzqt]f_>+nU[_ /.aW{Qs%8:x+KM \yk7 Zm3-21\LI(<3N u IP;>C ~,b3LRd'auvB j'Y}*;$ jUN{~GϝbxX;?xѾջbpǦ}ǚ-0Nacj]QO!7ioMWE v*Sld(f m= UQV^PyeZug-i6pqauђP&?(%Zm^A,I]b>3OCЙۢF^ piyܠh+DbF]dWj;EtVc*P|j}O*fy$QcL/Y ٩uEto ]!H[μ!_y8Pl%nw?KvrԌFzx J:3fsO$V #{ CG{AKtYAqrm?C¢ ⽵XX&5s˯% 0<[ +.%sYn' k֔+|2-sװ^%(s\]I޸(UٔRs PJDʻ.,z҉ _!ZX7r3:ܨK2E:8&ĆӋMEBsn8xKT*5^ {7D7 `$ F0ىb LG=Zy9` VOG?o:dg]=%|t'}_N Ç6ˋEHe¹%So$v獶,Y9ŮlmuOrt"!]zp팾!Mܕ} HCT7M"1hpoF᷌vVŷ}u\UQjWbhR9b\axd ]%4]R#iԷCێ&?t?0 d'*36޳3M:>LEgEvPÀ$eA[vKI/];9|U(ր9r Y8s^D- u\Z%\.aL40K2HܜNjs%Jӛ-^!\r'ł =?,;uV"k<)OP$(L{If 8 "c4u(Z#7Hz+"X[u:6 endstream endobj 68 0 obj << /Length1 1841 /Length2 12002 /Length3 0 /Length 13152 /Filter /FlateDecode >> stream xڍPڶ-www q 4 . %@ @p -}UUWuƜkEK*iʁAVN6!&' VیB tq 4d!q*`@ pqpO E cngPa(A@WZi- `dp tY*[뉖-_%Dl!g!vv6s'W6# b ]܁V?; mk] l 0w^ v@k x= ߳pqlni vr6yفlv@[6'`#onnhn'sssts9"e^, ;9AW?ع-_: &ܜu@v݀2P!^~A=iiGym/gN?̯8֯M쬁?(>@ o#NN%`S ^'U{?>g*/+0?]KEPS㓒{|Xy\A?/→͂TE5 )a`w-Uh4na?SG7!97G? ?ns';G^5yտ u @;TΪܜWb UhnK,uX2G;Pjǫ`_Ͳtx}9\_ 8},ldžq]\̽P8^ |]E+k{~k 7 `sA\v?]?HU| ?5R?H^ϳ -x^> ND1vAN;?;_WͿkA_9 2s||%|%ks/_y pCi _Wn4\D!_tsqy}7WI=( `KPzIRIY}LFVe 4ƺMɴ/ve%V(}~t4#Ftht=>KҜBYF0eԧ8X㠏sEyDo HL8瞘s78S/JI(~'qe>[\\}4ĆD8t>RJ>e.=N w.GLhacb7;>R%#䝯)mz*peQK{QsoD(h>DdogдOk FC4aDی<nX㵴 bɒw6zkS}YUPt?er;LZ9BѶwȠ24呻v“Qfvp3iʘSw5r9tWS"YWS(]=F m[Hf'b[)27Cx^ˉOg&%"l6ZRhjofyIM~ }Td)3X\e$| C(ca#Qc7iQXT1ab//אvb5AZ~ #B6*/8l}D{I~h6k4CH$e;KcY&_r6uf}fd_пQߛ҄>EQɚr7qfXJW }<]*QUʏm,`̟̬0DF&׉}:#wN=o,йmK7YLκS(6 Q|d/٦ZԄ%RԂ"ׅ: <r\=evʆ=ȟB1([&Yko㐓_q$\mڗt'Otk7'yn"RrvK\v ߌm62f˷D J-wnu_ZFݑv ŪҢdJJ@0$uBLP;W2{O7njc/pcː e&$2u\8/x=ma) Lm1s$.ލSJ;"l K4tXb'ϰ/ ЅX'V?RƓ@f6aa_Ewi-$6:ڜr9 (DU ] ^+G7]9*ڬ:lm^ -s\1ޠLpzzi!|Ll76.҄Iqn!2Ų\{3.96Y mlIЃEr $Rn]!Ic13T=,$ʾM{/ :萮 ;B`a(O)7>Ɣ>P3אt󓇬u/mvN/q<</'$Y7ʫ{/~5UN)Ide7u~t/Mb"EWt YRe%=0, {DN na(D<($ԪuX Iн 46T#]jXʈ(sPB_UՎV=͡ԴtYڨZ ?yo"Sy/I,VFAM&ȼm}粬T&c;X6u)1j>9gCcSEOV LBw8+bIupVPiRQ.ل,jц,<0݂ wIM7AGxѽW#8tNr,qvxGݘd5碱Y|GN`c`o$Qr$R6*#InH\9>~=vqq1=w< [L-7tcq8d !,xČv7eSl/o -Pe#Xg!OzĴgjP)WT@U!<22 i# _z ri){BKeIe¼Ԛ-q ;<ѩU%cZ9"7&I\VVj ZiE;3!!jR?L ;I+Er29{!vX|D8Lt ]g}W怺.}OTp[]ΒQ<:&6Iqo޲WԎ;/#a ~I5gۗvA'+ S$jEp&1j6LWW⾉xL~LF:;V˧O5hC 0J 1Z-g߅0vEֻ*a"F1a("'7- 9;+Objrykހ+~|g&Si)nQV`+͵Ē{nh8:D)v0B;~*ִ`UM}mV5M_lWœũOV\kꪸ![`VyI :kNhn~CRP̈.F"o@L*P3o+tﴇV{9㳇et^֋n\`\_J/'Z Ϲ*a F`%N26˳,*V(s^7ɑl혰ECkvFt|@KZ~@^# 7\3h/@-K[Q4r6QY|֧Kޓ Mn,aIh舯vkb hoVΒRV12ԉx.*]v _e<`W.2t `]'В`>~b (i9e~Y?Sm.n @$} Hgośx{e S:]rBf0.v6y׾هꐓ 1)^TAZ$v t\|MxII{RemTYd5M9tqÑ*QTW"gNrQu$g\!_at#$ej[ GY}r$԰ g (Yop"A>vXoVP)HgYE< a|jQ b\X)J8BY9?od~s0+Os46[')v2Fމjރ%f>@mrVox'Xnu̲p(7 T&;N f HNli["XƠG]h5͈ڕ3ky*rJNM/,MDdh Xe{ebM6YR~ѵfIlX"pG֮T:lh-ӱgQIzS9D.A,j6\`qKBO~&]>^͎akw*=v5j}i;;3%˅:2"L䠇uÝKkoX,6Yҗl3]rnk?.y|#)6F1Ĉ{wHlcD2}?Ѡ1c]cy=~ f?P++>ϔi~}׌if>| !nQe}5Ҍz~i[A%|F =-v"OYP+=,m487dpE,}G2`mgu3b~EWs*u,M}}x[:|?Dg|I2Bnmni~յi50D%2Lw]GG\݆FAnBO^ļgOl~" GlŷZ}5,˅*Cd_:!c̻ØovnԒbVuʇ~h].*i#91 sި Ji%Y~ΉZG-<(i{1g8L}(ӱ7 Osl.xwtZ+^bcN5m_+ɇUeR >S9L"V ۠jṣτ-CI? 93(O:8zM"F x4㞱eVIziT9[lG<_R{7VGI W߫)` ?mk%҂!/6Z37.Hx-WenX0|62ڕ&ܗ٩heCW>w 1aȐưN%*Ml)R#acTNY2b{ !j SUv 'q‰;o2,k.l)7K~su&S~ 9[n~̣Q[( ?K ӣDBjhU %M).spXt&5ęo]pnV8̈^?F~\ܝ''@V8%m&.[1ؔxΆ?s 0W{Q=kH}Y)4J+&BbHh2=wYb66d.GOY_'s W0Նc`IH'Qs%d5 > BZagx?Ŗ:C(۩kI9xFr"n/f<$-J[}yA悦uAH(_A.^/%/9"j©dDu&d6.\f?a3)e / I圆Pf@]fle0?gGLem-~N v4kv}ڠGIUt;1G|V]?o℟ecB=ǜO$2٫i3P^ܟXέa%Kԅݻb>uc>+łT eiId-j1A&ɒM [褖Ő+GxL(9p] Y1FY? 4YdNd3sp6"?>ŰFK= Dgk%g|Zd{ZeZPjbmRZ3ⓟFMmT/5Q  p[᠃h& :Y(a;fd9/lޣ(HjfxxN$CJbC|.tIܣ뙢ͩ"$js>Y=@^@^F;m8*ۭNm 5"FO3 J5ul$O?wUKWwES}m89G~4~C±||B}QX佣^kKPkgo%B^ZK6-S U2jE\waIZN\]8GEи{c bGDaD/ C&&`&-j9Cx9f|?439JԽM=fzP0By60Zu3;uՔsMx_YT$r8nMonz%P' dl1en*M c j0Ok7ȗjDjW3bD:H2IkSX⇩E87_T`qO^c kF߼:D{rmo|vӿuykOEHioJFqlaPΰSuWMJ%YM #歏L]^Ϧ3%ݦ7Le9iw밄OicW2c&`%OHF&zg=b nP-@g.ܵA&zy FT%YZHBFMfƑg0˝q/O҇\̖Au}iؼR{Rj#ط3Zj^'^;nqIz;t&.L)lKеZ1{ž7rA_OJڕ]zod=uĹ+q-tʊ%BXCiGa,ȤB^n5B1M@u\T[uD`e̖O^h !"%܇n^PED~J* C*аfPߒ8ߣHtl_xA}0riܘrW0?[%d $Qfpyl:|ul-"[Ysyxr~8}+ š jΈTlYe>te%~l/j2XѶf`*E;Fͦ2XopLZb_T E.%փO-є׆̣tv g-ރ +!綔Sc[PD&yuِV6Z{>aphTvea$S23trl8?h>^pc{%hIRxTUبlTO-ՑPF7zso&=tpF1"9\Hz0?Q"?iS 9Sf.%3#ƔĤ!JE`*#Th%e"$^JoP(o" 2!;aw*݂>h]J"5l/T]$}(A>t!~|V>/J3v?f 3 ϣmJX \;-4kDC&IZqL*eۙL7'~ E+zV`~RF=|k0IŸ-A'°`| Ф _=6=`HT`:Ed0k~[k{9Rً⧐8숔*ꛉHXap]i0͡֐ՄSC?5\O,p-'m#[?ⰟC?^Zb`i)o܅_ẒX7p+S*U!0iʀǘf&|2/qa'0벭-YUI &S  :@xsVݡԢDrDSd6>K]t~JhPÂb)Ko݃Mˏ%?( 0u \gP>P̋Yy#0ȖHC0 (\%ڭ+?'TYEr=1}ɤ {HRL(Bt#$Q>.by/9P>wƂF;$۷!&#Д]]eס44A^3g@2w37ۃT/Lqe3lbad$ 3!rW777B'> stream xڍP\.Lp N`]`fp  -$'?{9ޫڳ{uMG*a  nl@A&b9nt W0 * &mSA.  C-<6" rE9ym+! ; , 7;qE+ G rW a;77'AvvOOO6 +V vh\A. kПv`?v- hp[Pk qq2@ CVC`76+W"0w dCm6`G@MVˍ`Ept=[xX-, +Jh,=W+++W< Z nݛ:@aP jm kw'v( ф|<3ee+跓?' j|7BX [0fx.`/Q{Le :zM}쪆ʚ:ORar<>n߿[wS.`Ο`;*Q 7J'_Yo߂d~?n /£f{R@fVd vWq$F, dv#?v_Ca_ dY9<=οZM'/($N(Z~k=\7xT;; 9v? 71~+w _  }~f%j_zY)Aɺ5"2I3~}˹/]82 g w>M(o4Zn|o4ǷZ{Gw%jzXſ99 4=HΏ-USu(|fK[m+X)ˌibjd7VrT&#/쩳IJftW\>qW/ʴ9];HhI _HnS$)6ș{a>H`~DEz|5(mE2KVZԘozar^" 2X\6+xOi`@!`rSt3dtA]̒~,^ZsG2=Q.$ p vV'-f }UOk^J,jc$X2vFV[efTHE~fsvP-8JR-Y Ch0̧]'R2\3l]׋ 3s&u:rwN™3G\Di}(nnacK:&*YnWvcCYk)-P͗mIyq4ąKfnYB:b\2gZ,hP>f0M`?/2C=>]b[U`KF+>5/M*t+}1Š='2մsVaݯ?[#;A.|7m{/`1A?E^P#,M;$bIg)@w/ވcj2l|x0V=x|4K!YxIaq&cmsJ1-3mV iBMZK&``vsgg/<lo 'Uȶ+T^njzR&1 LPWxHǞ}Ye)|5\yofq% %źIj= (%6҂ßlA7ZfTi6%j'-dUw$CnNi~,oC*6Lࡽd东oҏ}ÐO8tgfp9HbP=8cT@v9IeD10NM&4g🮛v$LI`a'|iy[YgݵxFwjĮenN[Λ4.mtϞEk2l1E=q]鳆[?}x'"ęwͰsQR hb^Du3a-Tl:wh_zY@"J.Y<3 eƾaW(;ԟr{CõSK1jBOC7.f?O|@SIdBgT,M}8KF×$qkYBdqI|WG:z9t:ixgsB ҞYBl-]@_f$;SK}Π ݘ*@s酝4xgm'{Jm"&/;+9k:toфL|_{5]e%|wd(Zlf|mar3Q\<^Ut#Nh d!1("XĨ!6 We?EvFj|V)1jҁqn]xIJ_%'GHUxǚkZcoƽ:"zbF| X82~ʈkUۡ VH7/ ǡM&)PnM_ ZF ^(v׊yn/v=S|e$(1u,8`|͕߱,K~@>|,&!.H|uͶ 3e\7o9r*G!:BPp<E^S$ zV<:NG-CP!S5Cat'\? 5б[,chp]䖀ăucBT0JԐ,&VcuưmG@NrCDzO}vIUiՐtB $dT…=-U: ه~)1ûPz##׆s"fق[Oo[vNEL:[ѡ<ޚͳ"x\``YKɋwIe#֋$I h) :t9xdI[]F=c_nAu8곔1GeTv[!M{`^Yyj ֏2Rhrz**Y%,aY})9y 9!v=P˅m'CQ9>p >yv*Y-r3}aFF 96?N9?; ;ԮVH=4K-O;jaFOU#K5? b!UIX>mv+(| .Ȗ40uQ$'M蘗ħTэER aK&p=Zbt#DCdzV )Vf@5 V4.cp+A]䄅t:ZYsCa}Ra xuRWO,8vuunQZK02.*N}Sa .[ ܰ_nIe5+zn;j&hͦ^nz$˼*&0XrݽMM_{E=Giu^h I(NJ (P; YBauh`eh;<ҍa"‘4@W-eFn"4eҡr޵`nNYM5*yWh]-"YF;-:f M:͏T]<φϛLN;0W  mĕxZ~7,Bg$ıAH ALsӗ;4eE$OZl/E޵Z7zGqǛ]ʛ@6:^ 4Je&ЬCfT$rDς,?Le%A[d\ノU(#BfԥT=V2ݼH >wpL*E̙;a74܈U3ڬ);03ݤ]/,O#?BSb܌d~rJl"px˖yMӻ6ْW%4 ƺD$)omaQ'QP1Џ̂IAy=WdTTzVe xZ`l?x7_~TUEC\GJ.]aVƤl!>xvssKsZSy_ F JHus$~k$tK|PYb~˥Vb4DTы"U&DwHrZi][<)=EKuO?-Оs(Lr$JY'33&{ɷ?gA*"f̯g2 R($eᜒNt21vxde4Ww;9Z_.987OahKᾈN. /MحI݈hEւ|K4ᡎsߊf [;y߭ᨍ_,F|-y_̜gCҿYL͙?XLq{x"7V|p \2)%;ɜ<x[si î= \g/-1$Qej9d^5mctFFo (}הw844eR>QG&PTN3L^eH ep̈zQOIK0@)8i) HNs{+'s%t^ )N'*wZ?!Iz)i ^H"gmDZbX;>ջz42YWÑtš&6T?Q#r|s%3~0N17R)0|$#p0+̃xo$6Tb %MvP 3fuEm:5D:5‘p`uM$I*X*;esI^ [B]ɉGZγvvf[gfY o{}lL rAc ߚ&m:gz"4O6șȌ]*LJ{pD[M@\"V5Kg,|ȽpF'Mrm;~ wE7e1􄲒Guwb_yyu;l{PAQ<)Oq(4ZN+oyOڞc]p͂nSW- ??۟@SR{"@bi140#SSbty _|+ڂTkP`pU}gbǀW<#2 .m_ H@cV q3B)tA5sښ#0]K}8S*uY,q+҈9qN~Gao.W |FW{͈9y` Rz5\w74뛭\V!ۉYu wM1?HLtPx&BzT;=kb"P'`u'z|l{1;A+~W*Y4Bm|FBr-E>r6̩WrndzAٔWuOٓ1xOkBMtykr8: ?N71Z ڃẠbG磟g%/jmc"K]0#bZ>#|]GbSfm b`t}S.C,F*הy:5w cJbS\%mw//"% IQlAΫocCz1Oפvdc'-7M> stream xڍwT6R HK7 tw03 ] !-4()%!ݍ}[us]ZD%m(aH.^n @ ~nItma҇!p d `Ma @$7&ȁ=67 A8Lpo7=ߏ5+**;vA0@ 8V;:pk(H'7 wd؀R AC$w񃝡NuGފ@ ~+C )W buwo|+iӿ E(@ 6P_|ˮKiNPDz\ nex@ܒ rYm~ɌOPq@\|yohMcGކp7_w*h2#ۭ~_mͿϿ xAq&ա-gUT\˟0[z"_s}U?q)'Hќ, b92 KVA,qvAhlvS&hQ[$L\ wV\"VE7g脀. +ݺmDǸhdJGfꮫ5w*Cqd۷ޞ|Jp" be(H2(2'c](1G[iuiexE}gmF_CE)"W`|d}hF/jN~0(.5IҪSPbE,f촗oC!vv5!}Yw_,a!o.oqهW؁G[U,JLقdOhBS+B>1| 3^iAK c݇'EB/=${&Q%:(wDq"F4g]L21~by*WH 4:t8|-0B ja)-9'Vuj:0 @{<=- mE ݖJ6rJeCޖ7FcsC;۫MAU-gi@1 ELCӳВe # '%EIP?I{pC2bo7j9>B ]MbeFtsWc ?mO9uJКoD^):4$Fչݣ 9x)&UTǾi1 טmJrHƑH)z!%_B 2~Xrz]Z^|.̣8*oX!YI:4DF:ɢ85鵣v]E+ %r$s۱s(e3C$vol6 Gkч AI9*4Gv;?+$GvoK-$Y-^ayr+!@Yg)ǡ%,gAt\ZM~™ԴzgvQI0l72ʎ_9 LQ`gYS7޴Fwt~n0#7W&DX%/KRTH#P71v,3V\hj$\ۺd`8 XdM:$w*@^EWk'銳#], jL|1܋3iwcݹ7^݈n/Hn>}0Xy'A `?->P*t.WtPD:xX-dL.Z{|J Dr^x@ݻ@Pg ]h9sēSIa/ Id?A9[IP >=~fMk0#(3uVHw BGfo`3ZHڼ)͝۝R*c9kG{?LFOokw-qaKP_з fVd=џoK#3df½̭ eԜC ۂ.pjRUpY˻LXkP~+h;+ӱð<wE&\ǫ8{X͍pNX]ꛃW .s Ke6@FqO 5YH aQCs;N)v x8aN˕SdCЭuop,a2jL@GR+=_v7e2t=3h18P .Q̛dݲ:#cAN([ߦVV=>EN]ZyZL.dk*ƭٗ d:ep9xBr;֋p3V? O&-& |ga0$_/cY##Loz#< a~ɠ?IUD|GֱrwE "Y[7@f|,Lz2͜ߪP dΞ^hBOhggs$t8@6\AubTWj<,Ue_޴ͻ#p_ɂjͥ־3N*C&F:9Տދ:D-XW`/q.R.+DWzJR̾i}.zv:~P/F !-rMN *,P~ ߞ jV_ Yçb4%7h|}Z^O/=+ʊ٫O9XӕnegM^Э2KYTruÛ`T;e U"o6o)cSh4&l&"7%"a wã:mL*yloIkew͚XU@fù))o,].` gmc;uM) _0v! KҜ%G Z\ݯ7GJL|pu+!y]>KR,IyCUrUMӐm3[˲cV-CRJ V>Ԋ Dy>mtU >CH:\wX}s-#5{(^c+)RE;}two$P$$Zڶ膔E0Zq? 2⦓L8uRI1mg21oL)˴R|îrC+`2?,KDIlK-9.hq,ܩ}fjs˨{sS<*{۟:#AZ؏DrZ+nt$% 0Pe+4M+?qbdJѦhi#IXԹ> &CP8vI!Cu3\CVݷ.У&%B]ϓ'>‚^ &sFt':z\͵srKO̺o(J|m=I!Jt.e6 n"V'Gq*OR{8O`̚AYrVD0EW1lL'KVT,IJDlεQNx3etr 8z ;I9kyW++mC\+iy63b6 = ]졯{xlPǽ l+Kz|,G^c ԟ2.j8$hF$\8! d)/de[ o r! mp Ű\2PfŸ4,*8F|Y_WmdL|;+fVll]Wcb$*F/jdZ%̄j,*eHFoTl֙.6ƃ<@;zB~tPV A>/zMY@i.[>wW/ҳ+QȾ: 3𨟿$r bj`Dz0Tq_~0=T$r ޳7 }?@Li eb % :{&22JG{j:&_Q:>/` 5uP]̰q>`}ì֊*Hm#PjV;?M2/&~N6fXHJctFCMʻ,n(ZRD^H3_hI(NY3sa^=nq0FphOLZIL&5Rpv]3S+7a/~Mg%S?Q]);"J^(SJȺT0V HH}<ϗ4Mg@Z/:.{,n5ܘU ?4\0Pb{2# G::6 >[dbAN;zv#&]zU>ص> '^ HDJ~F`7 Ҫ!gC?ʏ׺B7ǭFLZ Go`2*NZ[*&O4J_3֢pؖp]cF+ ajƼcuXameđMAl]5v]2I?T6WTa!+kY7lH "|~1-fv֫̀.b9(&#> stream xڍxT?"@-c  hNFi$VJ@ߌ99y׽Ͻ}g;cg10Wt@Cp?P@H kl   @Q0?8 EИ &"-O(IťBBR+B!HveGPtx@ 8@rw`c AG.g]JP[@x8q(g 8~ A&@0q"(o`P0Dx cM;{8 n /p }5;"`H@hA5EC]`; )~(+ U77$ FpVP2<MGM4D/  IGY&0@w;]$A#A^\(8A!{@}VBhB^dVwuʹ,xF%%_X/)&bqqQ@1AopG@Os'e; ܀@+ oovW;#5O췝ܠ0߿ r=Q)EgTsȟՅ8@=۪AV4??88@Q`?71@ nCvE"H4 }U`ïa<<@^W z* > #Ph@#ƒWchڃHF 0qD,pt 7(a-$t L0?K 8Sd]^IEq|xffi>HΡv\El1orC24 PkJC?8ANOcȾ%2Ya[q^ElR|݅| pd0v1X-&{Xezh_c>&)u]J^\|;THV&O%$e*9W$z\JWɱe't9]4*yPijIO9w͞ Y#FD)1|uOٔk0N3Պ z ] ?ueg:|=N [$??W318IPгShb鱸xZeq7~c'j*$ɢ3{o'ES=^ۖ;1?q:Ȩ Uɹ D3B&:z-"I)\V0X-lhlDㅉ[*{kw {~${ ht=p+BO6&]m)YN.(ݘR?~X}[bCXLZTКwL3_Ovroh4]bPK EەbL@:'=O~Τ﯇l5}s| 'ᜋY &6 R!.ANh  `8;6?RZ=i%kPw?8e\hgaI\z|,h/W]#P6heǑdE3, TtlԴU 4 4>StC;tDzwUӎJ1O.92aw~R? !4r`V˷?,䍂)[JKzga㴹w``h֯56AF_+"ICµ+X4Ľ~yI݈5m.0sS^%]gk߿D6aX]> xS sUfK7DÔaf ^{)= iwreG>Uu=dќM3ie>WkL@G<`˗?H=KJNoT<7lϦ(us\&1h68kU"#Zv yI*lcna/TL%Y2Lz><7lZ+Ұ+3.EFv \S'IU(K9I1hplFs7U Ob'NX|bq?j†LӉzV֪Rl|#j `fz8#0/T)̚R? Ohb!ewelnk!U#k2 Xzz #<` w6F_0sD uH1ktV q Q,B|!d &+~5bZw?(?zr`H`: c6u4ZXk<_IW͙r aE:t}`X7"dK~sUKt&Kc[kA2`eb~vMYY钆[^s̒d M)*C.t p{?ueyVb7V}ƨXHۗ6﹇:Tm8pVnt35d&Fw3}!t}pEWC,1d>?ɏ!}XNJ+Q oWZt`]cׅV&!>1"gHEbci(Zs 8~y"5~[(MHcU<s^{`C^7X"!gpIQ'̄e2.(xNW ǣ*zCa1"!ZRKD4sD;4K{~ːђđDbb{.І8T`66:ogP,۟WnD05;k]ҫ -P uק xxLQ_D,Ʃ܇_L 1JOEUUb]B~4/V>iIUnOjl(/Ai u=oz)LwZ5K^<;dSXa< {R߻6;xFt1Gz%S8@).ҼLTnsO|TLq \0kpN#m; 3&idYI :cZߎmTVRHO=,KQ9p:N<2 < =#`Ћ̖<,cN\H!`urW {#R%,J<*}0[Fm9F mAr QJ{,+7Й d}VQ~5#TH٪!vcIբv$Y'򀪭<oZ[QN 󔲶s˫W:?!zi~^,sTqW Gf N:pyY%/LTOss!dg\ mλrO]jYiPYښ7,4tV nzIs)?#v*qh=_|.g-r80&6:eu'ޕf&G47+q&i0 AJ{2 <_y~|%o&Y/R&t;DҝŶ ̰uRo+8rĘ壯]"rZ~*z:DLh-X%xt #Vc1>c4zUWέ ;vP >["`2[tGY߭>;^ԒR6P89;}~fX,KV J9g&&%mofR~i'sItㆸYAߍS7>?䡾~dlr ~as=ėvwS^hyl61OFvם?ϫ(4}^+Hު).8PW)>ԁ![QO 9&Rv3T_'5_<[`6o4̦##xƦV>CCeȌ^wiО(Bu9zVؚö;&~KS7oLg]ܲVVjqv\,%  ^0՝^_{dCʜNnRi&Ū4Nݔ1e+,&;-H=SSa)7wSD_{|ek#yB앱u= aWǷ 1`rP$~N?O3Kxrn7H_|2N9A[+`@&. 'mp!:IݐC~BzC%;+1E'ݑ Q"ՑjWL }x&qʢWN}q%6u?N_T\CTX뵱B* [[sǬ 1ߙF%G =O9mdE3Гq3tXC1GZ:.ACݠ<,$^4"rA}fh(➊M \4 '蔕}@;P;s۵#Oc> IٲW^J` n^y!hE䶦ڦ|*m. T <@"fUJ_\.µsĢ3WR\Ӳ$t. "QrY3&QTzYqGqnmyQtwI_}H*q{bkqzsNqŒg'&s1 \=ay㔪7?o5DZ0Q"UG70O+,e❟w3^/ۅKR l6@ L5b&s^Dz-?}jvGXf|4ctSYg5[MUxSP̮M*m yH&h6{kF5,$sUsC\R1#@:q|"j^RYZk,AմNsf%9UBTܕj&{FC jd-gD#_FMlm=jgt߹N  7Igc~XcZ-ugò럼6@Js}ep^ۉUX%VNn$UYeor\Ց3#!kڑ㗹d.k(gh_+c zQU}6~yRY8'R֥Ǭ목rv$^w?֚XgqB0cY՟һ/W|f< =R4q`M|nϻF?zVShM2i6>ݛ(.'okRǻq@6$"^շWsjoy]l.]/R;͹e;2Æ V/Έ>u0RܳPO5>^HUt_ ҃`_%{  ObBEo ;1zF1fqz~b[jxn3"{&߿E?NBԨ.h~o%ՎkW9*a9~m3U?ىq(w%lQUp~& A}cg t7<_]J+I I=훯C=8ǧo+y>%A1DGEA]BealLxLVAM4\,5Eo:/<*76мY<~cpZ%򧹹qĽ]q4Kڬ;|aet\wY+D @KdfyY)Ϭ[nj[<*|P}\|*Ky9==[^+vlo4{\O>9t_;DKO(|n2/ύqNYফٓ'nt#wVb{*凖~uE[!lJCQRbӔ22UZڈh厫[P1A\A띓x7,SD,m'.6ǻct(q/Wxy-숩 Z~'b9䦪dv؉Ggt/u\-Yl3f 5\˼NJۊiȩ}AJtbɂL"I?e+nXgl &h>ɴh[[jY\ xk"V_"UEWӟrxyM%HT=yJ"Y]Xu$˛#JqⰝߥɹ`) 6Q(o+PNMTfB ۿ3EGgq+7H_'hxJ[ ?*1™Ǭ-ԝ ӕS@7I#.pvڮ 򑇐2nEѯNaI %}gwB$`]ёΑd'yX4"մܒX͖\g$i ,2@qi}/\`M]Hy֋XARF= endstream endobj 76 0 obj << /Length1 1377 /Length2 5930 /Length3 0 /Length 6877 /Filter /FlateDecode >> stream xڍtT.(0 H4H C0t7R%JH "HwJ]"{׺wZ|Ϯw?Ϊ+g*#(^@ASD//@nC9B HW. H()Qh&Pws  ??@__@RvY48ԕ]셄ڡe p@~䜠H hQvP'tE(C%@>+i+CP;k` g2>"v]a#]npk(.Wh;C;_`` {#D=ֿ`GW:9Ѐߝr0zB0g++׈_iзV@89A(W_)Pڽ6Gx}l`pk_CX9a.nP5ſ?6[( /.""$;^N/3z?g3=fEݡ <@kDɎ6CmG<fh~~{5LLyLo<  CTL4:`6Atug.-PHn/A?@Tc,/wCnݜs @ &-CD 9W F An&3/H_ ZP?cKj08T mAG/o-UCֿt& ,#`/"~4> (t=$V4h?CܐH~]_ߢB=ID2Ծ:[rxHaK; 1wRue>6iޖPZ?M?˒+pF`,aN&?Svy#[̹EAfq5dWDp7`ËZRoZe0,<ͥW̐&ۊ.9E_dU9سtH~?}C,yѱ9M2(ңcwAwge݃nV.<} ɡ\iK'fGtBM? ͜ 6qmE{m)UpϾ 򐽏ANqw&>V0 VtZ^3i%oezď EGB=ۏ?87|%J&V'3*\LPSDJ ڙn’sD5-Nͮ"\%q?K!5^~Tσ !(n%ƒJK U6 rڷEG4, t+)#?qtԍ X7, 9S !CAYCj(V3?Uџ3x 2}1oh~Qo?&.f-,Avg뤱}mv'8f!}!VڽK958#5aᩆ ;).BvΛe0&[#UJXx>Cʔ^3UO )ee6NvGߋbdzb/ə^_7W9eRTq+Xz;@F栱H +y06<+C"}U8iZ̨\$1N*!W׃ѵ;s*3K^m N: 4,wC0f'|SȦz⯓iى.&YJ1Qzk X3DN5zޚ/ixG~NS3>0;+g=P!ĕۓǡ$00Hi#Ax}k̚2e֑~~%Q.J4˼ FK+oG_oth{i8=^6Ĕb3d*-5HyV[vєkᄂbzĭF#o7as=3oMǤG̦ӻ":_JR5xy$`B8|u0 > 裾F f\ݰr8z|-iR*1k*XÎK‘-.{)"F4 J5Nj9-U2Ի$Wq񄔦|QJqһE[9LgiLq$F,Hف-zuT\,sa/ژeU6]ru+U OF$X&8ctz9f,")I\%pPHg.Sa&&Ұe\c.PӔMGb<#)j[D Zk®{5:0aHK#HX%+s7/cB +-gxr6bf]WQ7uC$uQ>c1P*T'ڥ't[6w޽<_\]YHWRC3Ti%y_$r:?ao׾_XpntU0K~y9饱OjBmB

{>[qu!_00}~adjȜ}_-Ԝ<:zCzb8+2uH7Ь[ofN9=qblM}y^P^ij}zr:YZsvL<&eXZK|яBdYuD7%. i7E s䪠 ,Yk3=-[#'13zfOjc~\tq4J^= g JAT3y`݈|snO{#;|U,T߈qkMOVviB5\ea1B9IքL oX2)-f1*m?T9Sp ;N.X]`$]>&.poGf!9ZWn}@쪕14)jf4=ya.Ô-Yo`'.( 퐘XI*#Nz! 5l R"v3ef؝m2%k$~x%jvjo.h`'}c]k 1J5"uLt#[nyx9IɄ@S$ ܚռ -'lWG63Pq~봚K$*CeXOyN:Vy.q1 UW?&]'Gq<ޙaWNX`\YE^?7{B6v]#,u׸Uu Q/RnKo'? < m"|?O`BݰAC4EN:hߟQt]p)8{nFLl_@׬[\Dݖ.1dC]m:׌ $eYmK4a2kɦR^2vCG'jjt7}֞҇(*yXRўV: BUjYro`GLi9砃G-}RY08 !Ԟ<[>xrt! XvLRk)f~$zqr kޮ SΣZb,gp o5+{%Z+e(&CVXB(%)j5FR/ IF2wG+٭RK}7%yw;^̤Ot.}2PH{9)Dc1wƦHkޑ\TE.e#\("'U'Y+Khtem{x 訓c,o+/s3M%9=طvdQ$"s5|6[ 7 V "\åO(FD%ڬ< Ź *?JR endstream endobj 78 0 obj << /Length1 1614 /Length2 10067 /Length3 0 /Length 11112 /Filter /FlateDecode >> stream xڍT6 Ht2twH#ݝ 0 0CtJHKItwI7ts<5k=s_}3hpHYC-AP[ d`Ac2\a`(D W( ՠ##(B-/C@q A ?l~;@ Bj@1^Yw:8,0 \Aր-ԁNZdځa+t6p+(p[ G75 pA6Vۀp<<@`_@++3l *'BaG;|4t @^J |`V`g8v#0cX@@8 w}`Wܽ\/dXn͙Kvq)c(pss @.^Π<ŏ=8C6m6?L|T7XK-b]cG}2}d5󿮘KSM]GJퟖz|8^~ǃ_%  wsWpaw,u#sA݄[L\X;[_z ?zG@ 55j kjm>2o9&YkVvo}sC@P ?%rx|E`Kzܡ+Z^6^Ax׏H Ͽ @.6PW+- ,\VF@@>epYiI>&y\DD? |L!Z>(q=_ ' snj%b_tY.Eciq)V _NTf*.oC! يoJ\u:.LՍwSȂbmKrPqrTڶc}ES/Nlh42!!>lfR %zˑgW)݃{k);;OUNv$>PL0ltȑݼc:m yl ґMW;V<ވQҶW]}ҝDf*T%w3QVقQsIy|LE X]B*93U|U+taI)y샩:'>3Ic&-"0}a`upӇ*12ۊ_*l⢰F\b̬C_~I?XRi,r?O:WUjH?' `[.bANe%9ZtV pZOS4>Ux>][ku$ u%uFQ b^P+sa h?*93;X̮&^O"H°?ZbVnҙ$@ҮgkQ0TJJ?(I։[إ4k/q{Ƕ~EiyZI_W+b>-4::7,HSCad];ЏN٤egLԾ؏U0.&R1 sa@g=eHEQ擗b}!37k@bO']x{?D2$@F ܔHV-[(a7MLQZvxϐ, ? Ռj<ɘhqmjSZgNo{Ԏ.32Mwt4* *6}_Eܻ) e&\vWi*a:t0_X7UFs15œWoGR,Dl)l?nieY{{yd 5r|hߥkIyrgRO'P+(( +J[wvb=N%lW)Z `?%P`K Ikr=l4&z(+L}|'aVQ_h'Dk9zܞUiķKk WY|òf7KE^Ee װb0l 䭋U^v~އ].ͅA%{m9ůOnS5"Bhso]r%xp޷WKi:&rQ)?ڨ_od7 g#"~sx\js6{s69#W,)c0$r.{!;\f~\ezDnāc:u 7\,ИlYELʃp3^%*4$5x+\;VklJW_F aeު;<>2Bn6#Vj^:K+#W'ݜ]]|ʯ%֫ "3z> "| IV? 6A#E&߬ l?-#'l# np,De>Žh w DR v>HEKtb!E0`$4g_,Ot@Z>(!Ct^nAuqɗ qm>~kk W #jZ#I\SUkKl[HeWJGATJgRgv NvΟ渹z ?b umUwgkO%̪'n+EdV,q^(!6;{=ZϨ4mܒ:.ffpSy42e'q}:{ayMW2<8e)Gڣv ]V,)߾ᰰ E+YbMS '*C%)m&RaEqoqhO^vOgm2NT7ں/Dvퟁ1dXQ 9Pq^;u:aVq_.~eJa4X\LTL^b:t$Ic嘀yO eA7rÕ|8y. _ K$޲X":ײ" *6|XUes~Ľ`RC zڶmPa#NMuY. k@Ań$RŝrE1yla1c5 NVEDBkn֞$%:T3fC/ZlsR#BvZh*m2tJTy4FgTng(Hbtw,_}`p=&)7*̀mt v)XYw-'|)Όe^^m9,zXNp3Պk+]uC;q ksI"_5d](8ӿ@?> e X˖j됬Ju$lvzqa|ӷxC\JR)8XckBSEIcJ.#eY KXBhWJH3xS^3ч-.)8wt\AD4i6g9VP%MFvVcp߬s ֓9a[Bn:S8QB, 6(_4Ud3yaG(;l--?D$ ׺\syKY /uCE=/ '3ˋ&WIFwASOĽ{πWSq1GW Ҹw[#nTOȄoտ?f,󛯣KgE_Ĝ~q&{]#gț89h@F!ҡIWMxPHLi yqdϓ!]@VV+b'ff*Tuԟ tȋ/D!|g&m+PK E( QLn[cQ^T/b釈e.xԜ׀{#ff+Lw=N?;U׬>Սg:H+*è*ov^"p-*2(D&`ӆ!N cFۅ6T߷)S}`V5EX:qx*^U'-S$U"ж?yyZխ b뷭b/Pg|çp ?4 4g޷KʯҤξԾC0_Goii= k<8/ dO\*v bUo.i(V:9 \*V |[1R:)/ݢFjwQG.`\P6dnm|'>3T"1ěx1\rfގ}gq(M'[@geuB|`ۆA;P;G+>^/{? IXtE ڽ֩C,&zi`ue*H;=ڻ5sT`%+d8 ZNb䥻D}`&^9Gg>]~rejh~g&㥨µDG|^zY8XF3 H'`Kt [7z 1Eb=C{BbFʮq epA,g0qZP z!=޾%sr@h!Pȿ.s&2YRpk Hپ| F1!|~. A%mdY?vy9;{E$Ȇm~u"7u/8󗆾DڼCe\ƎKi[Do E3mcx^x8;)ڰYʤhlo:Ӗl.ޅ03‚Esy4b3(Y^q?m+ڻ *Xdٍ`eE CS}Ld6IO!ӲM'&-ZTK.CK it|¢:%';ױBGgJװ(2+5wsz>n>K|Ҵ'?8 {,C3(k~N5*WI1gϰW?j@.85fV+˖LN+N-Γ ?^l27=CV]%t ,h'_DvdSkkddSv8%<2ߠLtW&3G/8#b5.K,s<ކ%&UF I &&QwPp64yi.H n؊TYj.BpoSAii*kpKq_pQ+;?=I$vR0@tjeFz1{ :wg=QG|mڤ7r868&,>56ĈK篙?~KKVJ~Cuh~GG|A |5OR17_#!@.4yG#?{>elpHM/1eYS\˅̃m׻<O>94܊4~zG9M]\= sݣXFU &&5,LN"q/SeIGmU)n$ qǙ?GtDPsZt9bN l&>5XV!y_~|OhdN%e^c5UeRVk/7ObSz+`zL1HR1ts=p펄(>iSlsʮک*DZ0ךsqE5ѫSc.PEH Cy 5\(juFf`&6;rJR? #1{U]H"8AWUR]=бTDŽq7C$6.3ۼ7XFdwm"0S(g=,2xx3#ABD_kF(9M"mkB^SwV(J{&OCdq(9YDe$;[f=e+ts J1 U+2ԜԑW/)L!PUE:s^t.~I"خLwpJ˝pOL4B^Nl)8|T=(p ~P!5B,OmI4O>{,Bb>U;a ȧ iW5ogZqbyh\:cٷsԀNy׊&{{ qPnCX^=͏ ZSf~*Pj !̀vF消Kœ;kS>aq%*vUEks80353Ɂb-EpEɳ<leQ$~NF:1BV MqhóR^T“f*D$ QHM}eiPiV7Ypͪ+[u*Mۨ[-8+s%FyQ VޚYMF'i&|? s kѰ_)s0bTDZ,&|Gx'kR.0anЌی=+jhIw梵К"^τĕ&vJ`Na炈L((u`J#)pf- 툛9%y)A8[&; 59I\-{ Nk*;{ɭΝ0F@H} /<|?yZ/80H 4,Ubׅx3ϠY6Sj6EA3DoNOĒ›$exR}aJ叇i҇k:chn?-\PlU]VbHcMXlJ_[(8D)ZDtaY/!^!v 6~C̠7L`YTT҅ /n Y3]MIɻcQ |(먓J'(w'rp䔕B}LyY%V,iC\DipuGj@sK\;^D݋^g1w2kOpT끆e1F7LHR'I`ǒa d4WJw3Kk0a~b8^:rؙB2EM 3{c3(~ePuxo~0 1-eZ|ol"^j" AŰX6)*oY}@e!ON`!hXd|2UfS;F_lpq,18u/r|x5r4nEZ/Nxw^jU]:/'J *} xbJE>獶Y8AGZ%2(,OJ}P*"(ٝVPaPg11K{e=㡧 $Ydɬ.^6,~/LTӢusj5=FMl{a= y~^]_䤳L4eCP_GHF]j.Z4/R t}}O$ ڮ\렡y>ڜj(JYIťs]U!U~i>A|pH6욱 tϽ)v!([CasrmtR0q[Kҥrk#?NXaɞ >4"Hn^@ L Nd|㼂#&7ḌjK.t嵠_ S˝ߚ6W5LE9gfjϤ.WBH+%Nӡ,^9͘n)' !{R3n8UU7cy.#7;%6M{>E6U-kΥR.\ JU% '"ıs,VމH d>K}r]T> e1-9h[CKbg&N RQ ߶46$.#)G`|jP'2J+5rJ]Li HN{{IYZuSS7jCKٵK\c#Qe+r d wYf:|T]S(`v2Q<߸KjB7 s>*1*7/ $]1O:Gf8O{!%;UJ#RzOMH-|V 1bZ.| 9y`k2Z@!&r(=:eS&%<3ly:|J Ca4 2s5<3|e;|eؓ3mtJޱSletxe8}xZ3#:j0/+Ͳ+TEz@>XRaEvaEbpEyZP~)p80WԾmbg*»nƀfC{&k=vJړz~E d_$[[3̯NHl^G$}"8Qnkg x1a"S'2IRxDUyg >y9Kґ7su!"Nv@6kIWgo__:RCȞhGo(#&)Y,S Fxby2cz]'W8a rd.ZY )ke$<: -wjՎ> 힇[LPL=U@~-y;˒e#½-%C`a&ĝ9}muAOP9~a@&벋W-_9ǎLV-5Iq(XUH~~qXb\FY#L][9 `ubI/y";Rb:fWdvw@ 5޶N8"ory÷m)T\J >0[q9R:%i-#5މAʈL 6*y.փ(f AԵ:1o?th*zMK)Sp4ziLÆcN|AE\̛*$! HdFݘOΒ#c%TiHVKKC0&o yzF÷itTm~n|'K7 &*E«to@êV?ԶˣVz9%к*682) '9TbЛҶzH 9F9N}.G*E}x!ZmUguL)/IVQs6`J endstream endobj 80 0 obj << /Length1 1893 /Length2 12092 /Length3 0 /Length 13272 /Filter /FlateDecode >> stream xڍPh-;nKHp$cfgwfޫ\;VAE$fno sabcfH(ijXY9YYّ4.6ˑAN`{;XH8.o2I˛@`ggeމ tv g$* {O'[Кxtقf@; d hа7\<+? ;3֙RvANn s-ZcFhZаpq:oxАS8e/F_1'_ 43uy,`@EZÅ3hltmoHo՟řlG,y-$N {,vaevtIe&B[f rpr@ 4=@*`xk }!y;@'W?`3)lw71_7Xl<6YTu5tj?Jqq{7'wU *)ggaWoSwn1w,e7ނ+g?_iIGxe[WP5kq@`WʹvA?;K=@`3?/{f;,&6Vѽ-ǷF?URvf,;7Db}c;mAlgx`aǓpXx9,#n7ސ#Z-_Db޶?s{?,r,o!N֥1M|Ka֟?[÷bGf;ٛ4ooW&Vۚ؛#[k[o.o֖?[C<13W\<o7@ 3%{3놐/wubDL{SBT{:tL+N]h)tAN7b)_1~H^={7w$u><'u"}.>k$A$fyv#OʋZ}> 8X}"liOm[b)F+C`Ui"  =֙;(_[gS{[O:{{ht UJrEC/N@.lMXi `pUZ; ς t^G/wwfO9.SV2kUPhIY G*_Dr鱬7 &AIM~6ΏCyx{ N`Ѣ5B٠: OitVzByxAyՠWBI+u'yyF7PK$AdQc5u, Pwv'lbWeɚcFZ=ljp&O2;aW;XxJpVv[L0ߕ),@f6MZxl+=nw%INSZb(G^gQk6&!lĸ& Čc;3Gl.RAsklE F"L9)9_KB,o{ 8YJ8zD+?x}zϲ}je8 ң=抐6fZ[29wgCy80͓3 ώlkEX*(qw|^XfayJP(>'S!.[lGs|eJm7OOJW/t$6 K_|J_=+3x7-]j+0<6VeGN`aDn*V]=BQ-3+[ "'?EKiuh!^e*P'4 R0!s1*(\;W6M~ cB4ѦTf< +Р+lϣafKm*3+zGjpȰra:[4Ӎ ~x/h{Gwh(sXQr,5T⫇5Ƒ3u'NC<89 Q- m4ʯHn*pL2y=,.jieES3NNfk2"?kfi'0=fy @SFF+S־S)_gTVʄ;@aYqoFbkqJ[݌%yܗ" hnq-O R雘u<6eG.!,S0eظ~ANDm*kG~=D:x[^k`HH,ń!mx85 dſH_3i~O"Gl嘰AJ +>V DwX qcl$n} Oťŀ'ˉa7^tbGI/?~4$',ȿzftS|Z4US71 Y ȳ]谎MGuqGpi}񓄝/pHw~+TE҂L͖k'ߪ=c$KPvjFOrH9눸ch=c/"gqŏ,,-!m|*)(o>"|ʣujv?_ A nצ>1yP>T_<]u3SvjY Hjm4{>Uf/^bdk"GH0n (^o_K4K,śl`WbkE(  "Ž9LYE˟M,;ӂ ^L*8XV i xJ'U~(yMΏo:$md)>E$N mI<;fS„Fv!M h mڋn)uz abq7 ʹ/.8"&55UIp0 Zҫm1PGpz}LYkj+1Mhڷ]4K5hO2'Ʋ!?E P5m>oSyIy:L鐃fLI 1ϛyZ]f:w}Y$-83Z2)8|6rM-= Jk~RBt׺>L: . 3h}3cqRJ(o !/1#WF'i1a6rD(Ŭiڬi]0S"al >L>-VGG>xFVqTt?|\h,Q'* pAX? ލBIp4hyۚOYlW:Ӈ]ER>ZK;^ѧrwR a4$/lx1K怸l瞢`4@sN4B(a: 7iJQlɨ]pCL/r88eLDfh`SIM 3vsVWozTaaɒYP%@'Ek6F/Q*x7N?陔nZ.8a 2_L(*V >2I.QR Lz+djط/Z\p$-$w;`U#)zI*-QuGWgwFn],C5iE\]Na vfxo7F_ű543Arc }k^ˏ<my~3 v$f~ x17 AF1>p`<7Ãxgd ⾝kN?gy ̅ơe.7l-K}fO޻Yn?6&'!SGf & )M\Z2)=f* O:_vXs1T[uI%F"Ur5OXqASKp{!\S)L<V$jF"7wkThe٥cq|+pmbJ>+6Ҹ+~EEcjH9qkT2pj/'f\ Ƙm"cds:\ףZ 38,D>d Ȥ<~^5l*8qTZy27 ru0̗Z{{坓W%׹҉!%9|.nÖ:JQgBmuG'&50l2a29˫ C*~ _i&mV:4Jy3M LGn%̯O'vkFyFiJ|RI8Pk;.:Ou#r$~3V{;(uvvq0j,pټ'&MؚߞkN%1`dLvSqfpXO"2ʊ(T2DHgNWhz3iW Wt?V]Oov htrla0lJətmߒ tju;i{[jhJ+fGFie~tohݛ(_[B(wHB| {THh,PC7~\~/#Q%VyZ^*ʁ܏5%'=;XG#Q^V8_LǴ(W?kaCTCho Zt2P\6 4x_]\%N%j"CwN%ك5OکL`w-44ht& *P9t%&uk-3jk;EI*,g7֝Ps z.%aa_IlKw/.j W2!_!g7οU^p/s59,K ]Kfx'M.CnH1r/H<ݼo wHW^/'b)Aοү. 'RN]k pV?¢k901hO԰x. 3mcsWon܇y!.2\]}6NyӬ[Fur~z5ZCAIpe2j4UuƒN}oGr$?he4;(Gn ?+}=FΩz:_GǝSC%}$:WAkX2K4X郾ǡo{HӯlxήvIJO   [4zv]<)N:ԑn/UtG*Z|d~OA4#G+Jur)}Sߣc(=dblGKUɧ[! ^VEfaķT'5ZUdhPaƫ_YmrտԕL~vrTkIa g#и{S+9M,ʫ*Y R؉UnpnM״HB<#"V8{ 3Q؎HNj\tk .>K0/b|q]_K.Bܨ3,RyMwMXT %lƨ?]VmWٱ=LxM&.s8IQ Zq18h?ϵ?G%L-i!bP摨Z8^<#T |ÓܸΓyn|{w zQj'_vL b4ݶM@{2xspg3a -+S 16|HAJ](TN1Z OqQ RË VUx:&U!y,;ulE~DlP:dx1ސ %|J+a4|J)ຸH閘/#kSU>As.+.񷅦b0/?M Qd '}(l`m_0( ]$O'. p.jM:ЊݣS4&:6cIx15t3_f4RfĽjzr c EEwjb([ݴH0%Ȇts*f1*z/A;zXPǂ kT7-[qq6eǂ/pH_DP~J"V%fN1E4M-m!A2;2_`st'I] QbQ+_# ECLfZ7j ._!v($nv 9JPt{GIQȫ|ĺ*$kGq.1  c3d{*|.$qC)@0|$%9ZZO%Ԟ'>7giɸ׃[t05nx]<#!t S}nyR2&ժ:lCo_^{) \apF6_IbG"]AwۍezϜnM:7I:p3[2!NQM8-:o5QaYdr| %!ؓ9\EY(Q<{<{ݎ姉?L 1B Q.Ä-/f>kӛ1Lw>Gm_.dlG2`COȦhj6 'h4jؓ9%v&>5@}{5yZBy:=:)'G꤆_Xr:gRZ7~up #@sޡg Dx4Ef+%}5MFkv[9$A;'B~ l#L@kv8z\dRvPA}}|f'Ycԥ%(4E;PUڥNڑb(l76W͑k簑DvQ_+ݘ=-n_U0-C1Wʴ "E"9A2QgekqwF}gyo]8skt-_i: %*T*xmet )mc&2vwR ݽc6 M HPzЎQ[& @h62[1Z&ɜI\²EZu|]w%,Ɇo{ ((*\ĥ=jviԈ2`nO|~)6PZj&6q".{ø,f|x&90BAN<#3EVC},d{+v?+~֥c%Ď02=+580p0+]&0Bܠ;,!Jcě~k ?=X"jZ-*n>φhQ2e>V,[%PўkA39A_Ym֗179QÚbAмh;1§1T1YYd6вyt G!I}\9'g#6d~vu/RAf"hU^nj@=*,5҉&U.$B"Çqt*2Ƀ*i D40'$&`Cp+n'sxHwR,`\3 ҰښMܟIP>G:X8~;Q%ı}Αt }DP[)}ag/J\;!M{*361XVoe~˧1ܛJPɋl~WӔ}Ze*W+4l.ᠬ4sִRQE.pDQ}h+g2sRCeg5+1lF|gePdH,6-ۼ9Ơw;Q>9V0%aFb_3fXءk2Z/qd)s2~h֡.rԐUYp<33m@go&XAgb)A27mY ˙MCzNCO_U\!jwl<S:>Yet%(?wYJz0/]3u7Gnf_ |4[7qxjmڪҐI.#Pr`RҧrRH}Uޑ:OŽxKc'k meAFas0P:qWߚFy( y9q,\t%ɸY_/h[#-/DB]_G(u|#O*jLu|.?djax`pÇ\+Qw5t#6F!on`kUѭ!;!L=G.9r/D C#]:!{E7` NT5Rڪ""qz]$~G/Ry|b^__VEÆં/)k^G3B-k6Csrt޵-ʬd)nm<[H͓51/tO9e*B+q@Ok :XZ xmSrx1׬9rr˳rgz30r8ƌ桦հ8 kdya TfR@  MWMS8$,p>>sOBrU\|f)xT$RZ{=i(u[L&4KVi݃7d\p\*pQdk+0g(i_EeL/Ro endstream endobj 82 0 obj << /Length1 1767 /Length2 4845 /Length3 0 /Length 5939 /Filter /FlateDecode >> stream xڍt< %{%{sV{9qweE*#ee&!"#eB!{B;շ~{qwZ52Pu9pXD뛙A0* K ?vA abQ"ɦ 8,p@DF"R`?D^@}I"hW7"?(zh$ #n(ORE$h1_)D܈D/OI]ω~h`"(gpd5$ `&t\~< 0h$ K `QxT0Յ^(O2'Au8D;ݯDh`B`XWAZpI?Q@` GG"uj HģIs8#0 58OOH9OG!IuX6:2Ǣ}P8$+` ? tX, 94f y.1P!h&ED*$oǿ 8D N2\~b-$?>gOR3 Cq cKm}5ӳFTSA@B * y,F."u.8@gSa_ sHE"dn/Y?B?i`0?"? btC$> R-Q?WW * -?MDOaX>|Y i׃@;EL & xD $) CH#Bt! Osx2rH H )dɓHFr B/@4 x? @AR1?\ ܟt$'Ix<,_i/O6 y4yiR_7"߽CH9AqRꑜ(uH<;E$I]EQHAR1ʽ:*U.?=R'6-49|g/+l@ĿW}?qA{+xpzP I^FGjZuve]7iTe^<5$T_mJvQj<,Q5Bj_a]gNzklmQt^zYfp9}S5\|!D2V b^Pc_y]Z&5ɢlmgIauE^%k ͘P5׊< 53={ED!&ǒ'}r~EL§T/h?|EAzjַ7&: “d%?mXbU]NC?VE!Kx>4C?JfH Ϊj)ib{bfdI' n;F/_,/?(CħgcCŕZn6K sta~TS1^8CnDUU%ו#ǽr q/`ʵ{SAf&2q΍# jTt9!fW礒&<:x\(Mo:&?K`-8&E}9>!\e"Džu_OwCg#~f4G,rFt Ӭ82Ĕ+?Rݖ{ @Y )Z%TNWD^Ϫ)a+;+awN/5jr}X#Lèj2QdNZ1".NɼXQ7T;432]DPGVswq5xI \BΉzw<Y[Rz-̧bnu4y9g ǹ>|rnq_}infSƞ270:ha6O4phŢ6\C~BKhu LSwup5x,q)'E$kSk:jk9uppޖnSqě^wQ̴ ǥLˋ(vfpIcA"4Bm'rR.r˫L 4:migcV2F YrJW5XMw=qպy+r^"P ?迶l_v, yQv+*Z=-snyNΟ>Kh`CO? ãkm2-JIju/ ޗ?(TYMP}cP Q̦brQ 2"هT~-ڭh:kɳEt 8 ̰΋ΰxKMVGVN745-3W{RŕArj! / D=Xf7:j.+N'1=JKƨ`ZT Qld7pASed% 2tւO[U-Y/c듨\;RN;LNj=l8k%tQ[[wJ G !d̵drbV$m5:* #WkUbɾ+&1z.@R<ԑ Prg˶zb7k83FO1ea@yF56W":m.ř. >^qRdsK;/winOy$-2S!1̓V~L+\s*Ǝp]sfMh.5_ mk}z˺>hӯQ٪Nei< 1NJ2Kٶ'V.5D [-b#>ΝEjzY)۔>*}*@>f]MkTĸr{ƙ{wsm,xI\X{OQ۬B+[ b"o'.i d/A"Ԋ13vL79rc Rp"3'CewnRf*^ŋ̯A݇8pJzcW|HQr-2hQ*sEёݮ;:7D-fȞW 8@)upx/Ug^N?^/^lq&;:] sX#(xUܶZm C''~\i#7[R~B>Ahko5xBɕ >8>Va?TjS·FB5YUSL?痡ͭM)h/`H秜ꏱvD>*}ŋs*21Ѽ/k_h"ã q Ymp7=oy*ց_xէM]q2~ymu& :5?=c[{1Ѣ:³RrE8`O' R} 3`U* Q2'os(:^G3ZDc扊YҽaU(Kujs,2'1NYo WckPyAy{#y-nc:vCUS XILһԓxe zّX;*zEMW+lDb}0&mwt'4paKLpp (qX͆%QjxN;{-:5)oUD9&F/|{tH&vٷ#=2wNrJqr,P닖4.}dؔ~2Z:xF/m]]ʶg9ާTIƢ[1>O)S3C>dr2[K;vA쮦$i=~ 2n)ݔ9֊Ԁ|¼ Ll%E %O~og0_xyl> stream xڍP-[p.Cw6{pwwwww@p Ǒ{rjffuݫwP(2%mXXb >XY9XXYQhh>@-Qhk 8`c uqظxYY쬬|!Ac @B#fcf15s|9?F 6>>?"V`{r4[hAn^іtqqaY9؛e`@*`3`" 23_vUG=b^"2`OH3dddce vXL `{IyGWG&"% X _VH(@/`dut`qX!G.KXXYPOb6zi𯛵q@Mad h sˈMy1\ljd#7[?/ P JF/L߈rыOA/9` _ڃ`65Qe;4qmdcJbe?.hxglci  >^7EɿKu/N?^|wU/lb /u 4_Ez_Y1X/m ^x97W/1_R~eUc_oz[+_T?mwG[K:8^fd66W^j-ۋIg{U:RӿK#_DkJ_]_Թ%lWc#'8}Y?_`+eyH .F؅ywBhfW=cپ1:F$qsm[Zx{kbp[r~n;ɂ"$<<,`[eirxѕp\\Vǂv^=0G~+5̜'Dpd&Ez}1w}3=\68Ck=׊=ԄZcӴI%EBY ,PKֽygz7B vfEF"i(zgc(M3Ŗ)8Z#4ٯa|/k,تijwrO2[w-e|lh]fKFyɜ@fˍ3SuKam)Wv3>n(0|*ꝉd$΃!I(AM>JDc|w7+T){hɪ^@Prq{^! ' TE YĬݛNmQxB j(YCiK$a(גY59yj%ܙevt \n)7'pZпf y# ${vk3oN:^_P{' 5N|j΋J[Ž9JUiP}/?ᶣ1bJT@Y͵V}r(TN{氫9Z f398$1CizZI% {G.Vp=Q2cvN_d$&LNTjZ%>֬]`a4qh-<h5Pћs#SDrk6փ)LTeٲN)&oe? $f\ІO{ߍegҼQm6h( 7*y0; ֊; < |DN@is{7'6|}S:FZJ3qր- Pg_>Üɤ"c*B:J׵\g,K~i6FJdۯdG^vbۚVw$p148kz[Wp XV6fR#l&N{Rх)5 \T8d@ns\{1%PA ».c+Em,:R.yWYiX3Փ')tB Kú'D)\_*LH$BUu;n/Y ҷw8#BG^c0.R >ypJ{sb)HK+Vڛrr?̼5ǂgK'9pځ%?j\ͲF˘(mS) py#wv3t-uX*bT45 V/G1峊xg m׀d![3cNap_w9%U^|CPyg=$^|!AK6gH1e }[ D]?b )Cc_(u+n>lm&9xtk{ӈJʻQ*FܼG~4`Bh5hf/ՌzfuEl`R5#&C -Τիb&tstG(/)6 m8B]JBmZ_*BiQIP~σ KSc_Z>YW0K *[8bt?2LE:jF!aSN7NaW^0YB` &_~М);__ASq(Y"ףSy[ˬ9y6[/+֎ 3_`dR7a$ >NLs{˞B-8r`cl)_W&U4IikN4 2qʟ9OԴhΝ,osj ?>zÖ#J[|C)òxS \8f'pgPy[nNN6Q^Ѕ"?mx伅wb}j]oOUM dDŋ Ȳa՟R4, BIyWZrͦ`a$ չ2,KƷQP-ջ4NK*K~! <[ 9fꜝ`t?EG'[PU[g_V}<5av|]R]_Mؠz}8%er/u\ϙTX~$TpGҪ#)fb=Y>[HN Abh>NvTfv 0rQoPuϪٝ /pŦwDKU9 _6{-BvHIY-nr\ޅ(WOs"[lG# ۛ{h,?˒DR$:Apv[8|Kx_U<<p7u(WʚaO#2([씪ۚSLh[+l^-ps0G Yc8$Ƹ踢ie6餦4MZB ϑ^56PÕTS=c 8rӻj?Ļlj <8]I] r (< Lw܃a 205Cpvg?|5`hy{t[XNueф mob2柞q!@E_춏X  b)1u6>hY&$BᐳCsm2r_z4*Β,Xư4sG qF{C-tZ1k{94RgGg`+ xlWbF{Kw4c}ELr&}Tg %}QtKԏ@p@K\>ҺtYfrCoT~ʭ 1%cXCB,9i&'u.sצ0y%Q} #Vu&oen&%Vs麎p+X~6 K a5'_ TDM2Ogov.]0YՐ0v,R_|xoHϽ@1iϮcW<ʄuʁ@V~ZH"LZ!Ze<(4/ ⇹ǥԈ~VPc30bm`yumq}EɎDZQIO9smM1%Ƈl(1msgI'zˌ'U(쯦||HJMn$eDPLf˦`j&$go2|*>(Bc6CuM.o<|~`*d"Ủ;;S3B< G"J7xbrN#si܋0o! ]#C2E _ʫl%nW3֨rJSc,я)%(t^k-[.uorM;?a]SN>,gy-1|B&^(DPOa,!4mH2$X' -1c.(Θq3}k>czm sZ`evXB%+ydPX{|b%E. qͷv&EPWoOCK\v&QzHU۬X6 \#+<p1}3䝮ZD \ _tO04mhzqwėcjV͕E f;JS{ySz COsq'mCD܉Hi߹XIY: Už~>Y)\7jGɐ{s LzhjAJ0Ӻdum"SJQa N 2W* <PM-ZxF;B~M+ 5`c^H gg[.@}i2఻'_ϝxӰﴪ>5/=.D' X vF$oQ#A<YD$_q'EcW+LM-Xq!/y٦D"VnuTN1VL,t!!hh|7zMB%pٍICb +C [:j*#Z$uFcpUø(:~89ѿoXտҙ։*]˧1BwKD,Q>HϭK?Q >ۯKMI/q"L] NK4>v~?DL 8q+Vwؙ* LѦ{2*kvZ}hf63h*k(y!|TnuYj.ˌ#p0"dЯσsܛC>"GOeeۘjfO\t_Pu&ҭ? 3GlnWKJ~b(xgˢ:֖jƫi!jگyQU"\"F`[zj[d,_TdE4U_n~\R~ReӤ a {Ҟo[ "D=>Őr54 M] n&1gCV3Y靣G*`5GCUL ,S;8;.7߱}hhGU9Ҋ2-s#)7² v(d"q1>7~FƵl<:lr.ˢqNZ3w?G#C_nXgɛ}SwYVJ{Kc,hB7 aS -w&(guJk 9fܵTB!C67e~4L8ZAb4=]*~7QY0w1:=ЏAOhBR[|ylm,Sksp\>TƖptKy[|{LkK,H(o̖܄G%k~TDߡ9ԿHp 7"v y̕=SMجҡJdɿ[^2X'J'۫eFu.;FHجT<"#ČskPᓨ % ?0 ]L#XdHYf/rHxdYF9űdOCTH^=`)Q rg ϵ[dݘ))0;]$0{!wmOb!S,F M!Pdy$$PN} OR ֮}v~JlPa3!Q0%UXK- z[-usPL#WxeO 7Q u<%;;ΕjI Xw9yK6ul|:u cܣ(,:JddDsZ-bۊ9nzhBrfnZ)`v Һ uc@5I{r:B* DYkX`ѥ@lܣyrϚC:Y6:D3ahVmR8Y甀e\=\6d眮U4~~5I CL=y0,Pz67EI 4 giܔ%N͔~ 0,ClQ,ȰQiǔ$N;s;EFBX$8Y}  G$BGq<'xx4֐[8WTgc+b}tWH#9 biSBeR nY5{k$==/Ͻ!)XUEE nĦTqsK&a`hm jZEa2#)b6jƌ?+-$0lӰnEFQ6ख़kթnl\P{͂ YEhQ+ vyF$[(AIvcLS=Me+.O3A!`%0H6푈&#Y[ٕ/w6 EU c@8oW9yp`ˏiwǸ8wUjZ?7 CmX@q!s\\UZUʉŝRVN,1O`X(Y\4zo;]fh.o`mSaZ4Kkpdev'$*TܳM7|2n!_o @,"mjvEز_YJl?1 gc`9|w@p ~{9 o[74|I,j !:, (.}TQ~%QP\gO_pQť c!@[7+K|}io_{劙"/Qӿ^ _߬qMV̟,_ĞҵJg1ܻN Zt=B7T,sϢk&dP',b_^'= ǡYn['a< u#GyR*8Z%I4F| .~^ړgϦ~X/`cyﭫX" MYO;'D>+^k/I' Jr/~W3z`xeu!dOE[_@BjE2ˢoqGn{)x< Gg;H+!q[KpO"z9ӒS :La=c[z}O,hI>B\"۠7¾SHX^P2S5rXů,o hl|)sjM{+YS6_qs䏬߹uck/Dj%I(!;fHS&-6?jE0c+<08j7$ReI_spy(pTqa;7C~%Y2O&dw]IHIU}z&#Ƿi(Ew< 7X]tZ]y0}bb<קlꨁ3;ŵR3WR*r}M px#Wo(=RP?Da)o,R^dڱ;h iiry 96&u~=x};C~éOfk  %Jl\p|١''rZWZU.UKEcXք{ٰeJۨҗ!0ĚF?bg,V zG\ħ N63 W>Cpp4탐W3d95|:!)f\Y:ЁLQJ]oFP.Ic`x)dןH -=a}^Re{N?ƍѣtN[:rXIỏL%qSM8MNO-4:3"!4iu /3~ީnp4Sj!;v&a:D %'r;R C1@T3E搧.Qy#eV,rN58;<)x+yv"Ns[L6e` r*IVfX$fzWׁ)pk?wV݊ o3V2VͲf7krYՠM8A( 80,{ q HX[^C$u\u݇{ueX#4#b{g.⊅X3+fD|Gu=6|nR"EIR&* T+ {Q7L'ɭH?hS^KS6D/(^ SO7=7Q1q6 _Y0MB9CP:o@DyNFcbh|N>D;ޙڤ[x2l{$g>C~rN'`vY[ȨMlKWpkeFQ,ľw0K˄\;pgkr.!`7 i äk`=EΨyuLSD(m)תeŕmYUg߾ĞMw\I!L{2x(t]bL^J%$+JboD>(}/~Bxtblv{oPN8iXJ2I-X;"ѸfSO2\ͦib@k~}~m}dK;`o]'ƨmH J0a=?]#r>fdJOx9oqm++bwlb οN{'q}zB(GPz0ZT%Dѝfr鶚J"(遗h۞dQJ`aM9nrgI_.n x`2S@Wo i|23pBb*s'pz+\,m mz 5' Z]$RB+a 7R:Y?}Vv220a}&'!?} Ps o4}Ɠv_55bKf<ƫ N0O,pDZV;=?]aΓc@wsҎ!OSpSuK6ʩegPlԼ<,hHǐ?=Un2c^#g!jEnBs$x+%};Ma))T6ɟdvrg L3XFGMaɜ'"s^R]ؕoT"J9cT Z% <$P"Ort`krUE )=/ؑW`0& 1vᇒxM8? LAuSTSa_L ^|{_WV1^Z˧:ӈqN q쵴[ݔZdPtf2[zuc˵#ViM]TUa|>9m`|q7W17vIz88u'kWw_!6=;>ǂ4v/l}u8!3%3NL+s|)eoDG T=PޕJoRb|˸.nژK!CDmޘdYp&7@ %X'ѥ}5g%1_fЋyQ8v#sXD&7Bl3hD]s'J*s\t$s:}= Uqz`EɆG;ֻ%ykۥ*WQvzG̵"f1S$ICAowg_sjwAe(hН>2>=D&n502U#kqkch슮 ʼj 4&l"t^"VGo`yp#AU%[~xwPw;4f3DR ! dzgzuK$$f6wSY _YIkw`y.a=hԮ(Z:l_w=ҷ) kkܫB!q{Pwt izusXa[Xd&~kI+8Zd#nT#Y^ h<+!ͻ`w&4~1fx=Q3CDS3375⯁mYGϮi|,g*m_6|"~ĂXu(׿\ݾxSs(5ǛDp9R++| a|u 6byfZz5Ťd*қ7Mw$&!T01$~c9%zڅ׫"Q C21`>:͇UdY{qcgnu2cAPj] |!}ٜ諡D@Hq!RKSz3O ]ӧNhSnN# [\҆BlM?b$Y00n4lz&f~r f[.PJ6*{QϚ1Fڼo6 L~M8(QIntR&!luRVnm^Kvp귵.Pagy endstream endobj 92 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.15)/Keywords() /CreationDate (D:20150805122716+02'00') /ModDate (D:20150805122716+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) kpathsea version 6.2.1dev) >> endobj 2 0 obj << /Type /ObjStm /N 73 /First 571 /Length 3336 /Filter /FlateDecode >> stream x[mS9_I]aޥAX6$@8 جm~=-xƃ0݇etZ-1T,3 gL?̈́`BY&$-4 Xgiz0Pf9)YX)|Ŕg!H+·BieLRY`7Vc13up,ՈcU2|k03`CXAd8 uY,X UR UYx?q'e`N1xg3!בa^0[,£+hÒ\iY  !<DŽd&I QX!TOBgy@j112E=!`zK'f dmI3O#ڇ$aĐQ* d5M36};e|=E1S/';d8ΞygO;g4z(FD5 c){~3<{t'9{8Og|N{b3>e%|k>30 }Ed vh/ފ8;Y> Sh@Yт}R_lf*VqoVt +~,JQK|8ާϓMq?̿oM)Vxp z<>R .q˄v[݃Yvb+-J—urPHUe)PTjF[+;e]ӆ*en3;TǢ9<0#lwEZLcVh b=d}'}d2p@a ڴPmi!-YH߿jaR#wdsd{|#zLuej)ErS~>LcW4/r-D()x2c,E*e_VecI Xҧ;'HdMrƨM|dPeD"3b, /BIY\`y%HH(ljm=J'dgPOR)cG #|B ۗĄ|$![*}]JTZk,.OE UΎrh  ʡ)[Q Rm(x%c~˳b!4!y4!:C^ó(G΂SzZWHt4D&/:K = ~O„#s&#O(' H#ȋFS֊nk0 W1:dW$T:;Cö7-H xx.kɮ.2R:a*IkUQХ~f:KҨIqgzWCjDoҘ=+ILԩ^S e>,96V(NX]mU<\!3QzX$`B#3##5E p\"cHht!1USi}m+Fg4(i_]z2$yK4N3|iz,i(cywlW*F>*SU\m)Z^7I"KJjZCYiFaػbSY(MaV %4FT%ĥ8[*S5"NTvK'!R"*e⹜8SF-C!R4OOJn]6L<\kEl21}j2#}9g>#l45XR1XZnǒICI 錌Ԭ#Ѡ:aS~&H  ^zLu/O?Я|4+Yhx>ΉL' ̖QlKYǷ#P>^ȋ 4qCc[q1ڞs`_{ K/_]^1$3> kʯi{1>~9} ؿl=l;B&?/Κh$k`Vy~}y9_ϊxfzx-`wRﱦ˚[BWМL9<~>ˇ|S1gS>0 jL+7A}Dփ%fA=)\ ћ h1wOg#P~iC'm_ǎ< Ls4O'qϰ[?c _;?旴㎾Ws8H_bzƯsgmYEϦ+J(}p *#*"`ܡ]h4N~u>[jlƛuZ(B}|yp|ұJ4:Sk=z7X{^p?'tvk;qJ^цsdkqn̲Θ/PzWʰ|}tr}9͋ݕ0f^E~yJ.֧]#/ְ U yK}qX|W /#^N-pUm7SWlՖ-mp֍%Rzf©U! o]rZ-wk-ٷҵ[lwقkm7{[oyo*dlwV~V}lmvnw-{dʷV[ΦVKt[JK-gY.{[y@K-gS;Dz6l_g ^zzz1.&47JfXR-+d%ׯ9o:4SMk#M)<ٝl'HvUr|JzJc2fIz9j bYQImpL(6?z0ɵ%VDKɢ>aŮ O_ <" -7W~Q&"Yepz?yBIzL[ endstream endobj 93 0 obj << /Type /XRef /Index [0 94] /Size 94 /W [1 3 1] /Root 91 0 R /Info 92 0 R /ID [<6C30B09439DE78DA3A014C4B49050DE3> <6C30B09439DE78DA3A014C4B49050DE3>] /Length 247 /Filter /FlateDecode >> stream x%ѹ2P[b5Ē{-J^KׇײBkp 'p gPR(=}y~R endstream endobj startxref 153417 %%EOF e1071/configure.ac0000755000175100001440000000072111400421345013310 0ustar hornikusersAC_PREREQ(2.50) AC_INIT([DESCRIPTION]) : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then echo "could not determine R_HOME" exit 1 fi CXX=`${R_HOME}/bin/R CMD config CXX` AC_PROG_CXX if test "${GXX}" = yes; then gxx_version=`${CXX} --version` case ${gxx_version} in 2.96*) AC_MSG_WARN([g++ 2.96 cannot reliably be used with this package.]) AC_MSG_ERROR([Please use a newer version of g++ or a different C++ compiler.]) ;; esac fi e1071/tests/0000755000175100001440000000000012212345174012170 5ustar hornikuserse1071/tests/clustering.R0000644000175100001440000000033311400421345014462 0ustar hornikusers## cmeans clustering should also work on data frames library(e1071) data(iris) set.seed(123) cm1 <- cmeans(iris[,1:4], 10) bc1 <- bclust(iris[,1:4], 3, base.centers=20,iter.base=50, base.method="cmeans") e1071/src/0000755000175100001440000000000012560362404011616 5ustar hornikuserse1071/src/cmeans.c0000644000175100001440000001774012560362405013242 0ustar hornikusers/* C code for (weighted) fuzzy c-means, rewritten from scratch by KH. */ #include #include #include /* Enhance readability of matrix-subscripting for matrices stored in row-major order. */ #define MSUB(x, i, j, n) x[(i) + (n) * (j)] static double *d; static double *dwrk, *dwrk_x, *dwrk_w; static int *iwrk; static void cmeans_setup(int nr_x, int nr_p, int dist) { int len_u_d = nr_x * nr_p; d = (double *) R_alloc(len_u_d, sizeof(double)); if(dist == 1) { /* Needed for weighted medians. */ dwrk_x = (double *) R_alloc(nr_x, sizeof(double)); dwrk_w = (double *) R_alloc(nr_x, sizeof(double)); dwrk = (double *) R_alloc(nr_x, sizeof(double)); iwrk = (int *) R_alloc(nr_x, sizeof(int)); } } /* static void cmeans_copy_vector(double *from, double *to, int len) { int i; for(i = 0; i < len; i++) to[i] = from[i]; } static double cmeans_delta_old_new(double *old, double *new, int len) { int i; double sum = 0; for(i = 0; i < len; i++) sum += fabs(new[i] - old[i]); return(sum / len); } */ static int cmeans_sign(double x) { if(x == 0) return(0); return((x > 0) ? 1 : -1); } static double cmeans_weighted_median(double *x, double *w, int len) { int i; double sum, val, marg, mval, cumsum_w, cumsum_w_x; /* Sort x. */ for(i = 0; i < len; i++) iwrk[i] = i; rsort_with_index(x, iwrk, len); /* Permute w using iwrk, and normalize. */ sum = 0; for(i = 0; i < len; i++) { dwrk[i] = w[iwrk[i]]; sum += dwrk[i]; } for(i = 0; i < len; i++) { w[i] = dwrk[i] / sum; } cumsum_w = cumsum_w_x = 0; mval = R_PosInf; marg = *x; /* -Wall */ for(i = 0; i < len; i++) { cumsum_w += w[i]; cumsum_w_x += w[i] * x[i]; val = x[i] * (cumsum_w - .5) - cumsum_w_x; if(val < mval) { marg = x[i]; mval = val; } } return(marg); } /* Update the dissimilarities (between objects and prototypes) for a * single object (i.e., a single row of the dissimilarity matrix. */ static void ufcl_dissimilarities(double *x, double *p, int nr_x, int nc, int nr_p, int dist, int ix, double *d) { int ip, j; double sum, v; for(ip = 0; ip < nr_p; ip++) { sum = 0; for(j = 0; j < nc; j++) { v = MSUB(x, ix, j, nr_x) - MSUB(p, ip, j, nr_p); if(dist == 0) sum += v * v; else if(dist == 1) sum += fabs(v); } MSUB(d, ix, ip, nr_x) = sum; } } static void cmeans_dissimilarities(double *x, double *p, int nr_x, int nc, int nr_p, int dist, double *d) { int ix; for(ix = 0; ix < nr_x; ix++) { /* Loop over all objects ... */ ufcl_dissimilarities(x, p, nr_x, nc, nr_p, dist, ix, d); } } /* Update the memberships for a single object (i.e., a single row of the * membership matrix.) */ static void ufcl_memberships(double *d, int nr_x, int nr_p, double exponent, int ix, double *u) { int ip, n_of_zeroes; double sum, v; n_of_zeroes = 0; for(ip = 0; ip < nr_p; ip++) { if(MSUB(d, ix, ip, nr_x) == 0) n_of_zeroes++; } if(n_of_zeroes > 0) { v = 1 / n_of_zeroes; for(ip = 0; ip < nr_p; ip++) MSUB(u, ix, ip, nr_x) = ((MSUB(d, ix, ip, nr_x) == 0) ? v : 0); } else { /* Use the assumption that in general, pow() is more * expensive than subscripting. */ sum = 0; for(ip = 0; ip < nr_p; ip++) { v = 1 / pow(MSUB(d, ix, ip, nr_x), exponent); sum += v; MSUB(u, ix, ip, nr_x) = v; } for(ip = 0; ip < nr_p; ip++) MSUB(u, ix, ip, nr_x) /= sum; } } static void cmeans_memberships(double *d, int nr_x, int nr_p, double exponent, double *u) { int ix; for(ix = 0; ix < nr_x; ix++) { /* Loop over all objects ... */ ufcl_memberships(d, nr_x, nr_p, exponent, ix, u); } } static void cmeans_prototypes(double *x, double *u, double *w, int nr_x, int nc, int nr_p, double f, int dist, double *p) { int ix, ip, j; double sum, v; if(dist == 0) { /* Euclidean: weighted means. */ for(ip = 0; ip < nr_p; ip++) { for(j = 0; j < nc; j++) MSUB(p, ip, j, nr_p) = 0; sum = 0; for(ix = 0; ix < nr_x; ix++) { v = w[ix] * pow(MSUB(u, ix, ip, nr_x), f); sum += v; for(j = 0; j < nc; j++) MSUB(p, ip, j, nr_p) += v * MSUB(x, ix, j, nr_x); } for(j = 0; j < nc; j++) MSUB(p, ip, j, nr_p) /= sum; } } else { /* Manhattan: weighted medians. */ for(ip = 0; ip < nr_p; ip++) for(j = 0; j < nc; j++) { for(ix = 0; ix < nr_x; ix++) { dwrk_x[ix] = MSUB(x, ix, j, nr_x); dwrk_w[ix] = w[ix] * pow(MSUB(u, ix, ip, nr_x), f); } MSUB(p, ip, j, nr_p) = cmeans_weighted_median(dwrk_x, dwrk_w, nr_x); } } } static double cmeans_error_fn(double *u, double *d, double *w, int nr_x, int nr_p, double f) { int ix, ip; double sum; sum = 0; for(ix = 0; ix < nr_x; ix++) for(ip = 0; ip < nr_p; ip++) sum += w[ix] * pow(MSUB(u, ix, ip, nr_x), f) * MSUB(d, ix, ip, nr_x); return(sum); } void cmeans(double *x, int *nr_x, int *nc, double *p, int *nr_p, double *w, double *f, int *dist, int *itermax, double *reltol, int *verbose, double *u, double *ermin, int *iter) { double exponent = 1 / (*f - 1); double old_value, new_value; cmeans_setup(*nr_x, *nr_p, *dist); cmeans_dissimilarities(x, p, *nr_x, *nc, *nr_p, *dist, d); cmeans_memberships(d, *nr_x, *nr_p, exponent, u); old_value = new_value = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); *iter = 0; while((*iter)++ < *itermax) { cmeans_prototypes(x, u, w, *nr_x, *nc, *nr_p, *f, *dist, p); cmeans_dissimilarities(x, p, *nr_x, *nc, *nr_p, *dist, d); cmeans_memberships(d, *nr_x, *nr_p, exponent, u); new_value = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); if(fabs(old_value - new_value) < *reltol * (old_value + *reltol)) { if(*verbose) Rprintf("Iteration: %3d converged, Error: %13.10f\n", *iter, new_value); break; } else { if(*verbose) { *ermin = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); Rprintf("Iteration: %3d, Error: %13.10f\n", *iter, new_value); } old_value = new_value; } } *ermin = new_value; } /* Update prototypes based on a single object. */ static void ufcl_prototypes(double *x, double *u, double *w, int nr_x, int nc, int nr_p, double f, int dist, double lrate, int ix, double *p) { int ip, j; double grad; for(ip = 0; ip < nr_p; ip++) { for(j = 0; j < nc; j++) { grad = MSUB(x, ix, j, nr_x) - MSUB(p, ip, j, nr_p); if(dist == 1) grad = cmeans_sign(grad); MSUB(p, ip, j, nr_p) += lrate * w[ix] * pow(MSUB(u, ix, ip, nr_x), f) * grad; } } } void ufcl(double *x, int *nr_x, int *nc, double *p, int *nr_p, double *w, double *f, int *dist, int *itermax, double *reltol, int *verbose, double *rate_par, double *u, double *ermin, int *iter) { double exponent = 1 / (*f - 1); double old_value, new_value; int ix; double lrate; cmeans_setup(*nr_x, *nr_p, 0); /* Need some starting values ... */ cmeans_dissimilarities(x, p, *nr_x, *nc, *nr_p, *dist, d); cmeans_memberships(d, *nr_x, *nr_p, exponent, u); old_value = new_value = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); *iter = 0; while((*iter)++ < *itermax) { /* Turns out that sampling the objects is a bad idea ... */ lrate = *rate_par * (1 - (double) *iter / *itermax); for(ix = 0; ix < *nr_x; ix++) { ufcl_dissimilarities(x, p, *nr_x, *nc, *nr_p, *dist, ix, d); ufcl_memberships(d, *nr_x, *nr_p, exponent, ix, u); ufcl_prototypes(x, u, w, *nr_x, *nc, *nr_p, *f, *dist, lrate, ix, p); } new_value = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); if(fabs(old_value - new_value) < *reltol * (old_value + *reltol)) { if(*verbose) Rprintf("Iteration: %3d converged, Error: %13.10f\n", *iter, new_value); break; } else { if(*verbose) { *ermin = cmeans_error_fn(u, d, w, *nr_x, *nr_p, *f); Rprintf("Iteration: %3d, Error: %13.10f\n", *iter, new_value); } old_value = new_value; } } *ermin = new_value; } e1071/src/svm.h0000644000175100001440000000647412560362405012610 0ustar hornikusers#ifndef _LIBSVM_H #define _LIBSVM_H #define LIBSVM_VERSION 317 #ifdef __cplusplus extern "C" { #endif extern int libsvm_version; struct svm_node { int index; double value; }; struct svm_problem { int l; double *y; struct svm_node **x; }; enum { C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR }; /* svm_type */ enum { LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED }; /* kernel_type */ struct svm_parameter { int svm_type; int kernel_type; int degree; /* for poly */ double gamma; /* for poly/rbf/sigmoid */ double coef0; /* for poly/sigmoid */ /* these are for training only */ double cache_size; /* in MB */ double eps; /* stopping criteria */ double C; /* for C_SVC, EPSILON_SVR and NU_SVR */ int nr_weight; /* for C_SVC */ int *weight_label; /* for C_SVC */ double* weight; /* for C_SVC */ double nu; /* for NU_SVC, ONE_CLASS, and NU_SVR */ double p; /* for EPSILON_SVR */ int shrinking; /* use the shrinking heuristics */ int probability; /* do probability estimates */ }; /* // // svm_model // */ struct svm_model { struct svm_parameter param; /* parameter */ int nr_class; /* number of classes, = 2 in regression/one class svm */ int l; /* total #SV */ struct svm_node **SV; /* SVs (SV[l]) */ double **sv_coef; /* coefficients for SVs in decision functions (sv_coef[k-1][l]) */ double *rho; /* constants in decision functions (rho[k*(k-1)/2]) */ double *probA; /* pariwise probability information */ double *probB; int *sv_indices; /* sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */ /* for classification only */ int *label; /* label of each class (label[k]) */ int *nSV; /* number of SVs for each class (nSV[k]) */ /* nSV[0] + nSV[1] + ... + nSV[k-1] = l */ /* XXX */ int free_sv; /* 1 if svm_model is created by svm_load_model*/ /* 0 if svm_model is created by svm_train */ }; struct svm_model *svm_train(const struct svm_problem *prob, const struct svm_parameter *param); void svm_cross_validation(const struct svm_problem *prob, const struct svm_parameter *param, int nr_fold, double *target); int svm_save_model(const char *model_file_name, const struct svm_model *model); struct svm_model *svm_load_model(const char *model_file_name); int svm_get_svm_type(const struct svm_model *model); int svm_get_nr_class(const struct svm_model *model); void svm_get_labels(const struct svm_model *model, int *label); void svm_get_sv_indices(const struct svm_model *model, int *sv_indices); int svm_get_nr_sv(const struct svm_model *model); double svm_get_svr_probability(const struct svm_model *model); double svm_predict_values(const struct svm_model *model, const struct svm_node *x, double* dec_values); double svm_predict(const struct svm_model *model, const struct svm_node *x); double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates); void svm_free_model_content(struct svm_model *model_ptr); void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr); void svm_destroy_param(struct svm_parameter *param); const char *svm_check_parameter(const struct svm_problem *prob, const struct svm_parameter *param); int svm_check_probability_model(const struct svm_model *model); void svm_set_print_string_function(void (*print_func)(const char *)); #ifdef __cplusplus } #endif #endif /* _LIBSVM_H */ e1071/src/cshell.c0000644000175100001440000001766712560362405013256 0ustar hornikusers/*****************************************************************/ /* * Copyright (C)2000 Evgenia Dimitriadou * * * 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 2 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "R.h" int subcshell(int *xrows, int *xcols, double *x, int *ncenters, double *centers, int *itermax, int *iter, int *verbose, int *dist, double *U, double *UANT, double *f, double *ermin, double *radius, int *flag) { int k, col, i, m, n ; double serror; /*convergence parameters*/ double epsi1, epsi2, conv; double sum2; double temp,tempu, tempu1, tempu2, distance; int j; double suma; double exponente; /* *ermin=0.0;*/ serror=0.0; sum2=0; if ((*flag==0) || (*flag==5)){ /* UPDATE CENTERS*/ for(i=0;i<*ncenters;i++) { sum2=0; for(col=0;col<*xcols;col++) centers[i+(*ncenters)*col]=0.0; for(k=0;k<*xrows;k++) { temp=pow(U[k+(*xrows)*i],*f); sum2=sum2+temp; for(col=0;col<*xcols;col++) { centers[i+(*ncenters)*col]+= temp*x[k+(*xrows)*col]; } } for(col=0;col<*xcols;col++) centers[i+(*ncenters)*col]/=sum2; } /*UPDATE radius*/ for(i=0;i<*ncenters;i++) { sum2=0; radius[i]=0.0; for(k=0;k<*xrows;k++) { distance=0.0; temp=pow(U[k+(*xrows)*i],*f); sum2=sum2+temp; for(col=0;col<*xcols;col++) { if (*dist==0){ distance+= (x[k+(*xrows)*col]-centers[i+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); } else if(*dist ==1){ distance+=fabs(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); } } if (*dist==0){ radius[i]+= temp*sqrt(distance);} else if(*dist ==1){ radius[i]+= temp*distance;} } radius[i]/=sum2; } }/*flag=0*/ /*update UANT*/ for(i=0;i<*ncenters;i++){ for(k=0;k<*xrows;k++){ UANT[k+(*xrows)*i]=U[k+(*xrows)*i];}} /* UPDATE Membership Matrix */ exponente=2.0/(*f-1.0); for(i=0;i<*ncenters;i++) { for(k=0;k<*xrows;k++) { suma=0; for(j=0;j<*ncenters;j++) { tempu=0; tempu1=0; tempu2=0; for (col=0;col<*xcols;col++) { if (*dist==0){ tempu1+=(x[k+(*xrows)*col]-centers[i+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=(x[k+(*xrows)*col]-centers[j+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } else if(*dist ==1){ tempu1+=fabs(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=fabs(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } } if (*dist==0){ tempu=fabs(sqrt(tempu1)-radius[i])/fabs(sqrt(tempu2)-radius[j]); } else if(*dist ==1){ tempu=fabs((tempu1-radius[i])/(tempu2-radius[j])); } suma=suma+pow(tempu,exponente); } U[k+(*xrows)*i]=1.0/suma; } } /*ERROR MINIMIZATION*/ epsi1=0.002; epsi2=0.2; conv=0.0; for (m=0;m<*ncenters;m++){ for (k=0;k<*xrows;k++){ serror = 0.0; for(n=0;n<*xcols;n++){ if(*dist == 0){ serror += (x[k+(*xrows)*n] - centers[m+(*ncenters)*n])*(x[k+(*xrows)*n] - centers[m +(*ncenters)*n]); } else if(*dist ==1){ serror += fabs(x[k+(*xrows)*n] - centers[m + (*ncenters)*n]); } } if (*dist == 0){ serror=fabs(sqrt(serror)-radius[m]);} else if(*dist ==1){ serror=fabs(serror-radius[m]);} *ermin+=pow(U[k+(*xrows)*m],*f)*pow(serror,2); /* *ermin=*ermin/(*xrows));*/ /*Convergence check*/ conv += fabs(U[k+(*xrows)*m]-UANT[k+(*xrows)*m]); } } if (conv<= ((*xrows)*(*xcols)*epsi1)){ *flag=2; if (*verbose){ Rprintf("Iteration: %3d converged, Error: %13.10f\n",*iter,conv); }} else if (conv<= ((*xrows)*(*xcols)*epsi2)){ if (*verbose){ Rprintf("Iteration: %3d Epsi2: %13.10f\n",*iter,conv);} if (*flag==3) *flag=4; else *flag=1; } else if(*flag==3) *flag=5; if (*verbose){ Rprintf("Iteration: %3d Error: %13.10f\n",*iter,*ermin/(*xrows)); } return 0; } int cshell(int *xrows, int *xcols, double *x, int *ncenters, double *centers, int *itermax, int *iter, int *verbose, int *dist, double *U, double *UANT, double *f, double *ermin, double *radius, int *flag) { int k; int i,j,col; double suma,tempu,exponente,tempu1,tempu2; exponente=2.0/(*f-1.0); /* *flag=0;*/ if (*flag==0){ *iter=0; /*Initialize Membership Matrix */ for(i=0;i<*ncenters;i++) { for(k=0;k<*xrows;k++) { suma=0; for(j=0;j<*ncenters;j++) { tempu=0; tempu1=0; tempu2=0; for (col=0;col<*xcols;col++) { if (*dist==0){ tempu1+=(x[k+(*xrows)*col]-centers[i+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=(x[k+(*xrows)*col]-centers[j+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } else if(*dist ==1){ tempu1+=fabs(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=fabs(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } } if (*dist==0){ tempu=fabs(sqrt(tempu1)-radius[i])/fabs(sqrt(tempu2)-radius[j]); } else if(*dist ==1){ tempu=fabs((tempu1-radius[i])/(tempu2-radius[j])); } suma=suma+pow(tempu,exponente); } UANT[k+(*xrows)*i]=1.0/suma; } } for(i=0;i<*ncenters;i++) { for(j=0;j<*xrows;j++) U[j+(*xrows)*i]=UANT[j+(*xrows)*i]; } } while(((*iter)++ < *itermax) && ((*flag)!=1 && (*flag)!=2) && (*flag)!=4) { *ermin=0.0; subcshell(xrows, xcols, x, ncenters, centers, itermax, iter, verbose, dist, U, UANT, f, ermin, radius, flag); } return 0; } /*****************************************************************/ /*******only for prediction***************************************/ /*****************************************************************/ int cshell_assign(int *xrows, int *xcols, double *x, int *ncenters, double *centers, int *dist, double *U, double *f, double *radius) { int k, col, i; double tempu, tempu1, tempu2; int j; double suma; double exponente; exponente=2.0/(*f-1.0); for(i=0;i<*ncenters;i++) { for(k=0;k<*xrows;k++) { suma=0; for(j=0;j<*ncenters;j++) { tempu=0; tempu1=0; tempu2=0; for (col=0;col<*xcols;col++) { if (*dist==0){ tempu1+=(x[k+(*xrows)*col]-centers[i+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=(x[k+(*xrows)*col]-centers[j+(*ncenters)*col])*(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } else if(*dist ==1){ tempu1+=fabs(x[k+(*xrows)*col]-centers[i+(*ncenters)*col]); tempu2+=fabs(x[k+(*xrows)*col]-centers[j+(*ncenters)*col]); } } if (*dist==0){ tempu=fabs(sqrt(tempu1)-radius[i])/fabs(sqrt(tempu2)-radius[j]); } else if(*dist ==1){ tempu=fabs((tempu1-radius[i])/(tempu2-radius[j])); } suma=suma+pow(tempu,exponente); } U[k+(*xrows)*i]=1.0/suma; } } return 0; } e1071/src/floyd.c0000644000175100001440000000140312560362405013076 0ustar hornikusersint e1071_floyd(int *n, double *A, double *C, int *P) /* this function takes an nxn matrix C of edge costs and produces */ /* an nxn matrix A of lengths of shortest paths, and an nxn */ /* matrix P giving a point in the middle of each shortest path */ { int i,j,k; for (i=0; i<*n; i++) for (j=0; j<*n; j++) { A[i + *n * j] = C[i + *n * j]; P[i + *n * j] = -1; } for (i=0; i<*n; i++) A[i + *n * i] = 0; /* no self cycle */ for (k=0; k<*n; k++) for (i=0; i<*n; i++) for (j=0; j<*n; j++) if (A[i + *n * k]+A[k + *n * j] < A[i + *n * j]) { A[i + *n * j] = A[i + *n * k] + A[k + *n * j]; P[i + *n * j] = k; /* k is included in shortest path */ } return 0; } e1071/src/svm.cpp.orig0000644000175100001440000017613112400715600014070 0ustar hornikusers#include #include #include #include #include #include #include #include #include #include #include #include "svm.h" int libsvm_version = LIBSVM_VERSION; typedef float Qfloat; typedef signed char schar; #ifndef min template static inline T min(T x,T y) { return (x static inline T max(T x,T y) { return (x>y)?x:y; } #endif template static inline void swap(T& x, T& y) { T t=x; x=y; y=t; } template static inline void clone(T*& dst, S* src, int n) { dst = new T[n]; memcpy((void *)dst,(void *)src,sizeof(T)*n); } static inline double powi(double base, int times) { double tmp = base, ret = 1.0; for(int t=times; t>0; t/=2) { if(t%2==1) ret*=tmp; tmp = tmp * tmp; } return ret; } #define INF HUGE_VAL #define TAU 1e-12 #define Malloc(type,n) (type *)malloc((n)*sizeof(type)) static void print_string_stdout(const char *s) { /* fputs(s,stdout); fflush(stdout); */ Rprintf(s); } static void (*svm_print_string) (const char *) = &print_string_stdout; #if 0 static void info(const char *fmt,...) { char buf[BUFSIZ]; va_list ap; va_start(ap,fmt); vsprintf(buf,fmt,ap); va_end(ap); (*svm_print_string)(buf); } #else static void info(const char *fmt,...) {} #endif // // Kernel Cache // // l is the number of total data items // size is the cache size limit in bytes // class Cache { public: Cache(int l,long int size); ~Cache(); // request data [0,len) // return some position p where [p,len) need to be filled // (p >= len if nothing needs to be filled) int get_data(const int index, Qfloat **data, int len); void swap_index(int i, int j); private: int l; long int size; struct head_t { head_t *prev, *next; // a circular list Qfloat *data; int len; // data[0,len) is cached in this entry }; head_t *head; head_t lru_head; void lru_delete(head_t *h); void lru_insert(head_t *h); }; Cache::Cache(int l_,long int size_):l(l_),size(size_) { head = (head_t *)calloc(l,sizeof(head_t)); // initialized to 0 size /= sizeof(Qfloat); size -= l * sizeof(head_t) / sizeof(Qfloat); size = max(size, 2 * (long int) l); // cache must be large enough for two columns lru_head.next = lru_head.prev = &lru_head; } Cache::~Cache() { for(head_t *h = lru_head.next; h != &lru_head; h=h->next) free(h->data); free(head); } void Cache::lru_delete(head_t *h) { // delete from current location h->prev->next = h->next; h->next->prev = h->prev; } void Cache::lru_insert(head_t *h) { // insert to last position h->next = &lru_head; h->prev = lru_head.prev; h->prev->next = h; h->next->prev = h; } int Cache::get_data(const int index, Qfloat **data, int len) { head_t *h = &head[index]; if(h->len) lru_delete(h); int more = len - h->len; if(more > 0) { // free old space while(size < more) { head_t *old = lru_head.next; lru_delete(old); free(old->data); size += old->len; old->data = 0; old->len = 0; } // allocate new space h->data = (Qfloat *)realloc(h->data,sizeof(Qfloat)*len); size -= more; swap(h->len,len); } lru_insert(h); *data = h->data; return len; } void Cache::swap_index(int i, int j) { if(i==j) return; if(head[i].len) lru_delete(&head[i]); if(head[j].len) lru_delete(&head[j]); swap(head[i].data,head[j].data); swap(head[i].len,head[j].len); if(head[i].len) lru_insert(&head[i]); if(head[j].len) lru_insert(&head[j]); if(i>j) swap(i,j); for(head_t *h = lru_head.next; h!=&lru_head; h=h->next) { if(h->len > i) { if(h->len > j) swap(h->data[i],h->data[j]); else { // give up lru_delete(h); free(h->data); size += h->len; h->data = 0; h->len = 0; } } } } // // Kernel evaluation // // the static method k_function is for doing single kernel evaluation // the constructor of Kernel prepares to calculate the l*l kernel matrix // the member function get_Q is for getting one column from the Q Matrix // class QMatrix { public: virtual Qfloat *get_Q(int column, int len) const = 0; virtual double *get_QD() const = 0; virtual void swap_index(int i, int j) const = 0; virtual ~QMatrix() {} }; class Kernel: public QMatrix { public: Kernel(int l, svm_node * const * x, const svm_parameter& param); virtual ~Kernel(); static double k_function(const svm_node *x, const svm_node *y, const svm_parameter& param); virtual Qfloat *get_Q(int column, int len) const = 0; virtual double *get_QD() const = 0; virtual void swap_index(int i, int j) const // no so const... { swap(x[i],x[j]); if(x_square) swap(x_square[i],x_square[j]); } protected: double (Kernel::*kernel_function)(int i, int j) const; private: const svm_node **x; double *x_square; // svm_parameter const int kernel_type; const int degree; const double gamma; const double coef0; static double dot(const svm_node *px, const svm_node *py); double kernel_linear(int i, int j) const { return dot(x[i],x[j]); } double kernel_poly(int i, int j) const { return powi(gamma*dot(x[i],x[j])+coef0,degree); } double kernel_rbf(int i, int j) const { return exp(-gamma*(x_square[i]+x_square[j]-2*dot(x[i],x[j]))); } double kernel_sigmoid(int i, int j) const { return tanh(gamma*dot(x[i],x[j])+coef0); } double kernel_precomputed(int i, int j) const { return x[i][(int)(x[j][0].value)].value; } }; Kernel::Kernel(int l, svm_node * const * x_, const svm_parameter& param) :kernel_type(param.kernel_type), degree(param.degree), gamma(param.gamma), coef0(param.coef0) { switch(kernel_type) { case LINEAR: kernel_function = &Kernel::kernel_linear; break; case POLY: kernel_function = &Kernel::kernel_poly; break; case RBF: kernel_function = &Kernel::kernel_rbf; break; case SIGMOID: kernel_function = &Kernel::kernel_sigmoid; break; case PRECOMPUTED: kernel_function = &Kernel::kernel_precomputed; break; } clone(x,x_,l); if(kernel_type == RBF) { x_square = new double[l]; for(int i=0;iindex != -1 && py->index != -1) { if(px->index == py->index) { sum += px->value * py->value; ++px; ++py; } else { if(px->index > py->index) ++py; else ++px; } } return sum; } double Kernel::k_function(const svm_node *x, const svm_node *y, const svm_parameter& param) { switch(param.kernel_type) { case LINEAR: return dot(x,y); case POLY: return powi(param.gamma*dot(x,y)+param.coef0,param.degree); case RBF: { double sum = 0; while(x->index != -1 && y->index !=-1) { if(x->index == y->index) { double d = x->value - y->value; sum += d*d; ++x; ++y; } else { if(x->index > y->index) { sum += y->value * y->value; ++y; } else { sum += x->value * x->value; ++x; } } } while(x->index != -1) { sum += x->value * x->value; ++x; } while(y->index != -1) { sum += y->value * y->value; ++y; } return exp(-param.gamma*sum); } case SIGMOID: return tanh(param.gamma*dot(x,y)+param.coef0); case PRECOMPUTED: //x: test (validation), y: SV return x[(int)(y->value)].value; default: return 0; // Unreachable } } // An SMO algorithm in Fan et al., JMLR 6(2005), p. 1889--1918 // Solves: // // min 0.5(\alpha^T Q \alpha) + p^T \alpha // // y^T \alpha = \delta // y_i = +1 or -1 // 0 <= alpha_i <= Cp for y_i = 1 // 0 <= alpha_i <= Cn for y_i = -1 // // Given: // // Q, p, y, Cp, Cn, and an initial feasible point \alpha // l is the size of vectors and matrices // eps is the stopping tolerance // // solution will be put in \alpha, objective value will be put in obj // class Solver { public: Solver() {}; virtual ~Solver() {}; struct SolutionInfo { double obj; double rho; double upper_bound_p; double upper_bound_n; double r; // for Solver_NU }; void Solve(int l, const QMatrix& Q, const double *p_, const schar *y_, double *alpha_, double Cp, double Cn, double eps, SolutionInfo* si, int shrinking); protected: int active_size; schar *y; double *G; // gradient of objective function enum { LOWER_BOUND, UPPER_BOUND, FREE }; char *alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE double *alpha; const QMatrix *Q; const double *QD; double eps; double Cp,Cn; double *p; int *active_set; double *G_bar; // gradient, if we treat free variables as 0 int l; bool unshrink; // XXX double get_C(int i) { return (y[i] > 0)? Cp : Cn; } void update_alpha_status(int i) { if(alpha[i] >= get_C(i)) alpha_status[i] = UPPER_BOUND; else if(alpha[i] <= 0) alpha_status[i] = LOWER_BOUND; else alpha_status[i] = FREE; } bool is_upper_bound(int i) { return alpha_status[i] == UPPER_BOUND; } bool is_lower_bound(int i) { return alpha_status[i] == LOWER_BOUND; } bool is_free(int i) { return alpha_status[i] == FREE; } void swap_index(int i, int j); void reconstruct_gradient(); virtual int select_working_set(int &i, int &j); virtual double calculate_rho(); virtual void do_shrinking(); private: bool be_shrunk(int i, double Gmax1, double Gmax2); }; void Solver::swap_index(int i, int j) { Q->swap_index(i,j); swap(y[i],y[j]); swap(G[i],G[j]); swap(alpha_status[i],alpha_status[j]); swap(alpha[i],alpha[j]); swap(p[i],p[j]); swap(active_set[i],active_set[j]); swap(G_bar[i],G_bar[j]); } void Solver::reconstruct_gradient() { // reconstruct inactive elements of G from G_bar and free variables if(active_size == l) return; int i,j; int nr_free = 0; for(j=active_size;j 2*active_size*(l-active_size)) { for(i=active_size;iget_Q(i,active_size); for(j=0;jget_Q(i,l); double alpha_i = alpha[i]; for(j=active_size;jl = l; this->Q = &Q; QD=Q.get_QD(); clone(p, p_,l); clone(y, y_,l); clone(alpha,alpha_,l); this->Cp = Cp; this->Cn = Cn; this->eps = eps; unshrink = false; // initialize alpha_status { alpha_status = new char[l]; for(int i=0;iINT_MAX/100 ? INT_MAX : 100*l); int counter = min(l,1000)+1; while(iter < max_iter) { // show progress and do shrinking if(--counter == 0) { counter = min(l,1000); if(shrinking) do_shrinking(); info("."); } int i,j; if(select_working_set(i,j)!=0) { // reconstruct the whole gradient reconstruct_gradient(); // reset active set size and check active_size = l; info("*"); if(select_working_set(i,j)!=0) break; else counter = 1; // do shrinking next iteration } ++iter; // update alpha[i] and alpha[j], handle bounds carefully const Qfloat *Q_i = Q.get_Q(i,active_size); const Qfloat *Q_j = Q.get_Q(j,active_size); double C_i = get_C(i); double C_j = get_C(j); double old_alpha_i = alpha[i]; double old_alpha_j = alpha[j]; if(y[i]!=y[j]) { double quad_coef = QD[i]+QD[j]+2*Q_i[j]; if (quad_coef <= 0) quad_coef = TAU; double delta = (-G[i]-G[j])/quad_coef; double diff = alpha[i] - alpha[j]; alpha[i] += delta; alpha[j] += delta; if(diff > 0) { if(alpha[j] < 0) { alpha[j] = 0; alpha[i] = diff; } } else { if(alpha[i] < 0) { alpha[i] = 0; alpha[j] = -diff; } } if(diff > C_i - C_j) { if(alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = C_i - diff; } } else { if(alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = C_j + diff; } } } else { double quad_coef = QD[i]+QD[j]-2*Q_i[j]; if (quad_coef <= 0) quad_coef = TAU; double delta = (G[i]-G[j])/quad_coef; double sum = alpha[i] + alpha[j]; alpha[i] -= delta; alpha[j] += delta; if(sum > C_i) { if(alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = sum - C_i; } } else { if(alpha[j] < 0) { alpha[j] = 0; alpha[i] = sum; } } if(sum > C_j) { if(alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = sum - C_j; } } else { if(alpha[i] < 0) { alpha[i] = 0; alpha[j] = sum; } } } // update G double delta_alpha_i = alpha[i] - old_alpha_i; double delta_alpha_j = alpha[j] - old_alpha_j; for(int k=0;k= max_iter) { if(active_size < l) { // reconstruct the whole gradient to calculate objective value reconstruct_gradient(); active_size = l; info("*"); } REprintf("\nWARNING: reaching max number of iterations\n"); } // calculate rho si->rho = calculate_rho(); // calculate objective value { double v = 0; int i; for(i=0;iobj = v/2; } // put back the solution { for(int i=0;iupper_bound_p = Cp; si->upper_bound_n = Cn; info("\noptimization finished, #iter = %d\n",iter); delete[] p; delete[] y; delete[] alpha; delete[] alpha_status; delete[] active_set; delete[] G; delete[] G_bar; } // return 1 if already optimal, return 0 otherwise int Solver::select_working_set(int &out_i, int &out_j) { // return i,j such that // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha) // j: minimizes the decrease of obj value // (if quadratic coefficeint <= 0, replace it with tau) // -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha) double Gmax = -INF; double Gmax2 = -INF; int Gmax_idx = -1; int Gmin_idx = -1; double obj_diff_min = INF; for(int t=0;t= Gmax) { Gmax = -G[t]; Gmax_idx = t; } } else { if(!is_lower_bound(t)) if(G[t] >= Gmax) { Gmax = G[t]; Gmax_idx = t; } } int i = Gmax_idx; const Qfloat *Q_i = NULL; if(i != -1) // NULL Q_i not accessed: Gmax=-INF if i=-1 Q_i = Q->get_Q(i,active_size); for(int j=0;j= Gmax2) Gmax2 = G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[i]+QD[j]-2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } else { if (!is_upper_bound(j)) { double grad_diff= Gmax-G[j]; if (-G[j] >= Gmax2) Gmax2 = -G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[i]+QD[j]+2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } } if(Gmax+Gmax2 < eps) return 1; out_i = Gmax_idx; out_j = Gmin_idx; return 0; } bool Solver::be_shrunk(int i, double Gmax1, double Gmax2) { if(is_upper_bound(i)) { if(y[i]==+1) return(-G[i] > Gmax1); else return(-G[i] > Gmax2); } else if(is_lower_bound(i)) { if(y[i]==+1) return(G[i] > Gmax2); else return(G[i] > Gmax1); } else return(false); } void Solver::do_shrinking() { int i; double Gmax1 = -INF; // max { -y_i * grad(f)_i | i in I_up(\alpha) } double Gmax2 = -INF; // max { y_i * grad(f)_i | i in I_low(\alpha) } // find maximal violating pair first for(i=0;i= Gmax1) Gmax1 = -G[i]; } if(!is_lower_bound(i)) { if(G[i] >= Gmax2) Gmax2 = G[i]; } } else { if(!is_upper_bound(i)) { if(-G[i] >= Gmax2) Gmax2 = -G[i]; } if(!is_lower_bound(i)) { if(G[i] >= Gmax1) Gmax1 = G[i]; } } } if(unshrink == false && Gmax1 + Gmax2 <= eps*10) { unshrink = true; reconstruct_gradient(); active_size = l; info("*"); } for(i=0;i i) { if (!be_shrunk(active_size, Gmax1, Gmax2)) { swap_index(i,active_size); break; } active_size--; } } } double Solver::calculate_rho() { double r; int nr_free = 0; double ub = INF, lb = -INF, sum_free = 0; for(int i=0;i0) r = sum_free/nr_free; else r = (ub+lb)/2; return r; } // // Solver for nu-svm classification and regression // // additional constraint: e^T \alpha = constant // class Solver_NU: public Solver { public: Solver_NU() {} void Solve(int l, const QMatrix& Q, const double *p, const schar *y, double *alpha, double Cp, double Cn, double eps, SolutionInfo* si, int shrinking) { this->si = si; Solver::Solve(l,Q,p,y,alpha,Cp,Cn,eps,si,shrinking); } private: SolutionInfo *si; int select_working_set(int &i, int &j); double calculate_rho(); bool be_shrunk(int i, double Gmax1, double Gmax2, double Gmax3, double Gmax4); void do_shrinking(); }; // return 1 if already optimal, return 0 otherwise int Solver_NU::select_working_set(int &out_i, int &out_j) { // return i,j such that y_i = y_j and // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha) // j: minimizes the decrease of obj value // (if quadratic coefficeint <= 0, replace it with tau) // -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha) double Gmaxp = -INF; double Gmaxp2 = -INF; int Gmaxp_idx = -1; double Gmaxn = -INF; double Gmaxn2 = -INF; int Gmaxn_idx = -1; int Gmin_idx = -1; double obj_diff_min = INF; for(int t=0;t= Gmaxp) { Gmaxp = -G[t]; Gmaxp_idx = t; } } else { if(!is_lower_bound(t)) if(G[t] >= Gmaxn) { Gmaxn = G[t]; Gmaxn_idx = t; } } int ip = Gmaxp_idx; int in = Gmaxn_idx; const Qfloat *Q_ip = NULL; const Qfloat *Q_in = NULL; if(ip != -1) // NULL Q_ip not accessed: Gmaxp=-INF if ip=-1 Q_ip = Q->get_Q(ip,active_size); if(in != -1) Q_in = Q->get_Q(in,active_size); for(int j=0;j= Gmaxp2) Gmaxp2 = G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[ip]+QD[j]-2*Q_ip[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } else { if (!is_upper_bound(j)) { double grad_diff=Gmaxn-G[j]; if (-G[j] >= Gmaxn2) Gmaxn2 = -G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[in]+QD[j]-2*Q_in[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } } if(max(Gmaxp+Gmaxp2,Gmaxn+Gmaxn2) < eps) return 1; if (y[Gmin_idx] == +1) out_i = Gmaxp_idx; else out_i = Gmaxn_idx; out_j = Gmin_idx; return 0; } bool Solver_NU::be_shrunk(int i, double Gmax1, double Gmax2, double Gmax3, double Gmax4) { if(is_upper_bound(i)) { if(y[i]==+1) return(-G[i] > Gmax1); else return(-G[i] > Gmax4); } else if(is_lower_bound(i)) { if(y[i]==+1) return(G[i] > Gmax2); else return(G[i] > Gmax3); } else return(false); } void Solver_NU::do_shrinking() { double Gmax1 = -INF; // max { -y_i * grad(f)_i | y_i = +1, i in I_up(\alpha) } double Gmax2 = -INF; // max { y_i * grad(f)_i | y_i = +1, i in I_low(\alpha) } double Gmax3 = -INF; // max { -y_i * grad(f)_i | y_i = -1, i in I_up(\alpha) } double Gmax4 = -INF; // max { y_i * grad(f)_i | y_i = -1, i in I_low(\alpha) } // find maximal violating pair first int i; for(i=0;i Gmax1) Gmax1 = -G[i]; } else if(-G[i] > Gmax4) Gmax4 = -G[i]; } if(!is_lower_bound(i)) { if(y[i]==+1) { if(G[i] > Gmax2) Gmax2 = G[i]; } else if(G[i] > Gmax3) Gmax3 = G[i]; } } if(unshrink == false && max(Gmax1+Gmax2,Gmax3+Gmax4) <= eps*10) { unshrink = true; reconstruct_gradient(); active_size = l; } for(i=0;i i) { if (!be_shrunk(active_size, Gmax1, Gmax2, Gmax3, Gmax4)) { swap_index(i,active_size); break; } active_size--; } } } double Solver_NU::calculate_rho() { int nr_free1 = 0,nr_free2 = 0; double ub1 = INF, ub2 = INF; double lb1 = -INF, lb2 = -INF; double sum_free1 = 0, sum_free2 = 0; for(int i=0;i 0) r1 = sum_free1/nr_free1; else r1 = (ub1+lb1)/2; if(nr_free2 > 0) r2 = sum_free2/nr_free2; else r2 = (ub2+lb2)/2; si->r = (r1+r2)/2; return (r1-r2)/2; } // // Q matrices for various formulations // class SVC_Q: public Kernel { public: SVC_Q(const svm_problem& prob, const svm_parameter& param, const schar *y_) :Kernel(prob.l, prob.x, param) { clone(y,y_,prob.l); cache = new Cache(prob.l,(long int)(param.cache_size*(1<<20))); QD = new double[prob.l]; for(int i=0;i*kernel_function)(i,i); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int start, j; if((start = cache->get_data(i,&data,len)) < len) { for(j=start;j*kernel_function)(i,j)); } return data; } double *get_QD() const { return QD; } void swap_index(int i, int j) const { cache->swap_index(i,j); Kernel::swap_index(i,j); swap(y[i],y[j]); swap(QD[i],QD[j]); } ~SVC_Q() { delete[] y; delete cache; delete[] QD; } private: schar *y; Cache *cache; double *QD; }; class ONE_CLASS_Q: public Kernel { public: ONE_CLASS_Q(const svm_problem& prob, const svm_parameter& param) :Kernel(prob.l, prob.x, param) { cache = new Cache(prob.l,(long int)(param.cache_size*(1<<20))); QD = new double[prob.l]; for(int i=0;i*kernel_function)(i,i); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int start, j; if((start = cache->get_data(i,&data,len)) < len) { for(j=start;j*kernel_function)(i,j); } return data; } double *get_QD() const { return QD; } void swap_index(int i, int j) const { cache->swap_index(i,j); Kernel::swap_index(i,j); swap(QD[i],QD[j]); } ~ONE_CLASS_Q() { delete cache; delete[] QD; } private: Cache *cache; double *QD; }; class SVR_Q: public Kernel { public: SVR_Q(const svm_problem& prob, const svm_parameter& param) :Kernel(prob.l, prob.x, param) { l = prob.l; cache = new Cache(l,(long int)(param.cache_size*(1<<20))); QD = new double[2*l]; sign = new schar[2*l]; index = new int[2*l]; for(int k=0;k*kernel_function)(k,k); QD[k+l] = QD[k]; } buffer[0] = new Qfloat[2*l]; buffer[1] = new Qfloat[2*l]; next_buffer = 0; } void swap_index(int i, int j) const { swap(sign[i],sign[j]); swap(index[i],index[j]); swap(QD[i],QD[j]); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int j, real_i = index[i]; if(cache->get_data(real_i,&data,l) < l) { for(j=0;j*kernel_function)(real_i,j); } // reorder and copy Qfloat *buf = buffer[next_buffer]; next_buffer = 1 - next_buffer; schar si = sign[i]; for(j=0;jl; double *minus_ones = new double[l]; schar *y = new schar[l]; int i; for(i=0;iy[i] > 0) y[i] = +1; else y[i] = -1; } Solver s; s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y, alpha, Cp, Cn, param->eps, si, param->shrinking); double sum_alpha=0; for(i=0;il)); for(i=0;il; double nu = param->nu; schar *y = new schar[l]; for(i=0;iy[i]>0) y[i] = +1; else y[i] = -1; double sum_pos = nu*l/2; double sum_neg = nu*l/2; for(i=0;ieps, si, param->shrinking); double r = si->r; info("C = %f\n",1/r); for(i=0;irho /= r; si->obj /= (r*r); si->upper_bound_p = 1/r; si->upper_bound_n = 1/r; delete[] y; delete[] zeros; } static void solve_one_class( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *zeros = new double[l]; schar *ones = new schar[l]; int i; int n = (int)(param->nu*prob->l); // # of alpha's at upper bound for(i=0;il) alpha[n] = param->nu * prob->l - n; for(i=n+1;ieps, si, param->shrinking); delete[] zeros; delete[] ones; } static void solve_epsilon_svr( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *alpha2 = new double[2*l]; double *linear_term = new double[2*l]; schar *y = new schar[2*l]; int i; for(i=0;ip - prob->y[i]; y[i] = 1; alpha2[i+l] = 0; linear_term[i+l] = param->p + prob->y[i]; y[i+l] = -1; } Solver s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, param->C, param->C, param->eps, si, param->shrinking); double sum_alpha = 0; for(i=0;iC*l)); delete[] alpha2; delete[] linear_term; delete[] y; } static void solve_nu_svr( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double C = param->C; double *alpha2 = new double[2*l]; double *linear_term = new double[2*l]; schar *y = new schar[2*l]; int i; double sum = C * param->nu * l / 2; for(i=0;iy[i]; y[i] = 1; linear_term[i+l] = prob->y[i]; y[i+l] = -1; } Solver_NU s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, C, C, param->eps, si, param->shrinking); info("epsilon = %f\n",-si->r); for(i=0;il); Solver::SolutionInfo si; switch(param->svm_type) { case C_SVC: solve_c_svc(prob,param,alpha,&si,Cp,Cn); break; case NU_SVC: solve_nu_svc(prob,param,alpha,&si); break; case ONE_CLASS: solve_one_class(prob,param,alpha,&si); break; case EPSILON_SVR: solve_epsilon_svr(prob,param,alpha,&si); break; case NU_SVR: solve_nu_svr(prob,param,alpha,&si); break; } info("obj = %f, rho = %f\n",si.obj,si.rho); // output SVs int nSV = 0; int nBSV = 0; for(int i=0;il;i++) { if(fabs(alpha[i]) > 0) { ++nSV; if(prob->y[i] > 0) { if(fabs(alpha[i]) >= si.upper_bound_p) ++nBSV; } else { if(fabs(alpha[i]) >= si.upper_bound_n) ++nBSV; } } } info("nSV = %d, nBSV = %d\n",nSV,nBSV); decision_function f; f.alpha = alpha; f.rho = si.rho; return f; } // Platt's binary SVM Probablistic Output: an improvement from Lin et al. static void sigmoid_train( int l, const double *dec_values, const double *labels, double& A, double& B) { double prior1=0, prior0 = 0; int i; for (i=0;i 0) prior1+=1; else prior0+=1; int max_iter=100; // Maximal number of iterations double min_step=1e-10; // Minimal step taken in line search double sigma=1e-12; // For numerically strict PD of Hessian double eps=1e-5; double hiTarget=(prior1+1.0)/(prior1+2.0); double loTarget=1/(prior0+2.0); double *t=Malloc(double,l); double fApB,p,q,h11,h22,h21,g1,g2,det,dA,dB,gd,stepsize; double newA,newB,newf,d1,d2; int iter; // Initial Point and Initial Fun Value A=0.0; B=log((prior0+1.0)/(prior1+1.0)); double fval = 0.0; for (i=0;i0) t[i]=hiTarget; else t[i]=loTarget; fApB = dec_values[i]*A+B; if (fApB>=0) fval += t[i]*fApB + log(1+exp(-fApB)); else fval += (t[i] - 1)*fApB +log(1+exp(fApB)); } for (iter=0;iter= 0) { p=exp(-fApB)/(1.0+exp(-fApB)); q=1.0/(1.0+exp(-fApB)); } else { p=1.0/(1.0+exp(fApB)); q=exp(fApB)/(1.0+exp(fApB)); } d2=p*q; h11+=dec_values[i]*dec_values[i]*d2; h22+=d2; h21+=dec_values[i]*d2; d1=t[i]-p; g1+=dec_values[i]*d1; g2+=d1; } // Stopping Criteria if (fabs(g1)= min_step) { newA = A + stepsize * dA; newB = B + stepsize * dB; // New function value newf = 0.0; for (i=0;i= 0) newf += t[i]*fApB + log(1+exp(-fApB)); else newf += (t[i] - 1)*fApB +log(1+exp(fApB)); } // Check sufficient decrease if (newf=max_iter) info("Reaching maximal iterations in two-class probability estimates\n"); free(t); } static double sigmoid_predict(double decision_value, double A, double B) { double fApB = decision_value*A+B; // 1-p used later; avoid catastrophic cancellation if (fApB >= 0) return exp(-fApB)/(1.0+exp(-fApB)); else return 1.0/(1+exp(fApB)) ; } // Method 2 from the multiclass_prob paper by Wu, Lin, and Weng static void multiclass_probability(int k, double **r, double *p) { int t,j; int iter = 0, max_iter=max(100,k); double **Q=Malloc(double *,k); double *Qp=Malloc(double,k); double pQp, eps=0.005/k; for (t=0;tmax_error) max_error=error; } if (max_error=max_iter) info("Exceeds max_iter in multiclass_prob\n"); for(t=0;tl); double *dec_values = Malloc(double,prob->l); // random shuffle for(i=0;il;i++) perm[i]=i; for(i=0;il;i++) { int j = i+rand()%(prob->l-i); swap(perm[i],perm[j]); } for(i=0;il/nr_fold; int end = (i+1)*prob->l/nr_fold; int j,k; struct svm_problem subprob; subprob.l = prob->l-(end-begin); subprob.x = Malloc(struct svm_node*,subprob.l); subprob.y = Malloc(double,subprob.l); k=0; for(j=0;jx[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } for(j=end;jl;j++) { subprob.x[k] = prob->x[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } int p_count=0,n_count=0; for(j=0;j0) p_count++; else n_count++; if(p_count==0 && n_count==0) for(j=begin;j 0 && n_count == 0) for(j=begin;j 0) for(j=begin;jx[perm[j]],&(dec_values[perm[j]])); // ensure +1 -1 order; reason not using CV subroutine dec_values[perm[j]] *= submodel->label[0]; } svm_free_and_destroy_model(&submodel); svm_destroy_param(&subparam); } free(subprob.x); free(subprob.y); } sigmoid_train(prob->l,dec_values,prob->y,probA,probB); free(dec_values); free(perm); } // Return parameter of a Laplace distribution static double svm_svr_probability( const svm_problem *prob, const svm_parameter *param) { int i; int nr_fold = 5; double *ymv = Malloc(double,prob->l); double mae = 0; svm_parameter newparam = *param; newparam.probability = 0; svm_cross_validation(prob,&newparam,nr_fold,ymv); for(i=0;il;i++) { ymv[i]=prob->y[i]-ymv[i]; mae += fabs(ymv[i]); } mae /= prob->l; double std=sqrt(2*mae*mae); int count=0; mae=0; for(i=0;il;i++) if (fabs(ymv[i]) > 5*std) count=count+1; else mae+=fabs(ymv[i]); mae /= (prob->l-count); info("Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma= %g\n",mae); free(ymv); return mae; } // label: label name, start: begin of each class, count: #data of classes, perm: indices to the original data // perm, length l, must be allocated before calling this subroutine static void svm_group_classes(const svm_problem *prob, int *nr_class_ret, int **label_ret, int **start_ret, int **count_ret, int *perm) { int l = prob->l; int max_nr_class = 16; int nr_class = 0; int *label = Malloc(int,max_nr_class); int *count = Malloc(int,max_nr_class); int *data_label = Malloc(int,l); int i; for(i=0;iy[i]; int j; for(j=0;jparam = *param; model->free_sv = 0; // XXX if(param->svm_type == ONE_CLASS || param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR) { // regression or one-class-svm model->nr_class = 2; model->label = NULL; model->nSV = NULL; model->probA = NULL; model->probB = NULL; model->sv_coef = Malloc(double *,1); if(param->probability && (param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR)) { model->probA = Malloc(double,1); model->probA[0] = svm_svr_probability(prob,param); } decision_function f = svm_train_one(prob,param,0,0); model->rho = Malloc(double,1); model->rho[0] = f.rho; int nSV = 0; int i; for(i=0;il;i++) if(fabs(f.alpha[i]) > 0) ++nSV; model->l = nSV; model->SV = Malloc(svm_node *,nSV); model->sv_coef[0] = Malloc(double,nSV); model->sv_indices = Malloc(int,nSV); int j = 0; for(i=0;il;i++) if(fabs(f.alpha[i]) > 0) { model->SV[j] = prob->x[i]; model->sv_coef[0][j] = f.alpha[i]; model->sv_indices[j] = i+1; ++j; } free(f.alpha); } else { // classification int l = prob->l; int nr_class; int *label = NULL; int *start = NULL; int *count = NULL; int *perm = Malloc(int,l); // group training data of the same class svm_group_classes(prob,&nr_class,&label,&start,&count,perm); if(nr_class == 1) info("WARNING: training data in only one class. See README for details.\n"); svm_node **x = Malloc(svm_node *,l); int i; for(i=0;ix[perm[i]]; // calculate weighted C double *weighted_C = Malloc(double, nr_class); for(i=0;iC; for(i=0;inr_weight;i++) { int j; for(j=0;jweight_label[i] == label[j]) break; if(j == nr_class) REprintf("WARNING: class label %d specified in weight is not found\n", param->weight_label[i]); else weighted_C[j] *= param->weight[i]; } // train k*(k-1)/2 models bool *nonzero = Malloc(bool,l); for(i=0;iprobability) { probA=Malloc(double,nr_class*(nr_class-1)/2); probB=Malloc(double,nr_class*(nr_class-1)/2); } int p = 0; for(i=0;iprobability) svm_binary_svc_probability(&sub_prob,param,weighted_C[i],weighted_C[j],probA[p],probB[p]); f[p] = svm_train_one(&sub_prob,param,weighted_C[i],weighted_C[j]); for(k=0;k 0) nonzero[si+k] = true; for(k=0;k 0) nonzero[sj+k] = true; free(sub_prob.x); free(sub_prob.y); ++p; } // build output model->nr_class = nr_class; model->label = Malloc(int,nr_class); for(i=0;ilabel[i] = label[i]; model->rho = Malloc(double,nr_class*(nr_class-1)/2); for(i=0;irho[i] = f[i].rho; if(param->probability) { model->probA = Malloc(double,nr_class*(nr_class-1)/2); model->probB = Malloc(double,nr_class*(nr_class-1)/2); for(i=0;iprobA[i] = probA[i]; model->probB[i] = probB[i]; } } else { model->probA=NULL; model->probB=NULL; } int total_sv = 0; int *nz_count = Malloc(int,nr_class); model->nSV = Malloc(int,nr_class); for(i=0;inSV[i] = nSV; nz_count[i] = nSV; } info("Total nSV = %d\n",total_sv); model->l = total_sv; model->SV = Malloc(svm_node *,total_sv); model->sv_indices = Malloc(int,total_sv); p = 0; for(i=0;iSV[p] = x[i]; model->sv_indices[p++] = perm[i] + 1; } int *nz_start = Malloc(int,nr_class); nz_start[0] = 0; for(i=1;isv_coef = Malloc(double *,nr_class-1); for(i=0;isv_coef[i] = Malloc(double,total_sv); p = 0; for(i=0;isv_coef[j-1][q++] = f[p].alpha[k]; q = nz_start[j]; for(k=0;ksv_coef[i][q++] = f[p].alpha[ci+k]; ++p; } free(label); free(probA); free(probB); free(count); free(perm); free(start); free(x); free(weighted_C); free(nonzero); for(i=0;il; int *perm = Malloc(int,l); int nr_class; if (nr_fold > l) { nr_fold = l; REprintf("WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n"); } fold_start = Malloc(int,nr_fold+1); // stratified cv may not give leave-one-out rate // Each class to l folds -> some folds may have zero elements if((param->svm_type == C_SVC || param->svm_type == NU_SVC) && nr_fold < l) { int *start = NULL; int *label = NULL; int *count = NULL; svm_group_classes(prob,&nr_class,&label,&start,&count,perm); // random shuffle and then data grouped by fold using the array perm int *fold_count = Malloc(int,nr_fold); int c; int *index = Malloc(int,l); for(i=0;ix[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } for(j=end;jx[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } struct svm_model *submodel = svm_train(&subprob,param); if(param->probability && (param->svm_type == C_SVC || param->svm_type == NU_SVC)) { double *prob_estimates=Malloc(double,svm_get_nr_class(submodel)); for(j=begin;jx[perm[j]],prob_estimates); free(prob_estimates); } else for(j=begin;jx[perm[j]]); svm_free_and_destroy_model(&submodel); free(subprob.x); free(subprob.y); } free(fold_start); free(perm); } int svm_get_svm_type(const svm_model *model) { return model->param.svm_type; } int svm_get_nr_class(const svm_model *model) { return model->nr_class; } void svm_get_labels(const svm_model *model, int* label) { if (model->label != NULL) for(int i=0;inr_class;i++) label[i] = model->label[i]; } void svm_get_sv_indices(const svm_model *model, int* indices) { if (model->sv_indices != NULL) for(int i=0;il;i++) indices[i] = model->sv_indices[i]; } int svm_get_nr_sv(const svm_model *model) { return model->l; } double svm_get_svr_probability(const svm_model *model) { if ((model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) && model->probA!=NULL) return model->probA[0]; else { REprintf("Model doesn't contain information for SVR probability inference\n"); return 0; } } double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values) { int i; if(model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) { double *sv_coef = model->sv_coef[0]; double sum = 0; for(i=0;il;i++) sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param); sum -= model->rho[0]; *dec_values = sum; if(model->param.svm_type == ONE_CLASS) return (sum>0)?1:-1; else return sum; } else { int nr_class = model->nr_class; int l = model->l; double *kvalue = Malloc(double,l); for(i=0;iSV[i],model->param); int *start = Malloc(int,nr_class); start[0] = 0; for(i=1;inSV[i-1]; int *vote = Malloc(int,nr_class); for(i=0;inSV[i]; int cj = model->nSV[j]; int k; double *coef1 = model->sv_coef[j-1]; double *coef2 = model->sv_coef[i]; for(k=0;krho[p]; dec_values[p] = sum; if(dec_values[p] > 0) ++vote[i]; else ++vote[j]; p++; } int vote_max_idx = 0; for(i=1;i vote[vote_max_idx]) vote_max_idx = i; free(kvalue); free(start); free(vote); return model->label[vote_max_idx]; } } double svm_predict(const svm_model *model, const svm_node *x) { int nr_class = model->nr_class; double *dec_values; if(model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) dec_values = Malloc(double, 1); else dec_values = Malloc(double, nr_class*(nr_class-1)/2); double pred_result = svm_predict_values(model, x, dec_values); free(dec_values); return pred_result; } double svm_predict_probability( const svm_model *model, const svm_node *x, double *prob_estimates) { if ((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) && model->probA!=NULL && model->probB!=NULL) { int i; int nr_class = model->nr_class; double *dec_values = Malloc(double, nr_class*(nr_class-1)/2); svm_predict_values(model, x, dec_values); double min_prob=1e-7; double **pairwise_prob=Malloc(double *,nr_class); for(i=0;iprobA[k],model->probB[k]),min_prob),1-min_prob); pairwise_prob[j][i]=1-pairwise_prob[i][j]; k++; } multiclass_probability(nr_class,pairwise_prob,prob_estimates); int prob_max_idx = 0; for(i=1;i prob_estimates[prob_max_idx]) prob_max_idx = i; for(i=0;ilabel[prob_max_idx]; } else return svm_predict(model, x); } static const char *svm_type_table[] = { "c_svc","nu_svc","one_class","epsilon_svr","nu_svr",NULL }; static const char *kernel_type_table[]= { "linear","polynomial","rbf","sigmoid","precomputed",NULL }; int svm_save_model(const char *model_file_name, const svm_model *model) { FILE *fp = fopen(model_file_name,"w"); if(fp==NULL) return -1; char *old_locale = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); const svm_parameter& param = model->param; fprintf(fp,"svm_type %s\n", svm_type_table[param.svm_type]); fprintf(fp,"kernel_type %s\n", kernel_type_table[param.kernel_type]); if(param.kernel_type == POLY) fprintf(fp,"degree %d\n", param.degree); if(param.kernel_type == POLY || param.kernel_type == RBF || param.kernel_type == SIGMOID) fprintf(fp,"gamma %g\n", param.gamma); if(param.kernel_type == POLY || param.kernel_type == SIGMOID) fprintf(fp,"coef0 %g\n", param.coef0); int nr_class = model->nr_class; int l = model->l; fprintf(fp, "nr_class %d\n", nr_class); fprintf(fp, "total_sv %d\n",l); { fprintf(fp, "rho"); for(int i=0;irho[i]); fprintf(fp, "\n"); } if(model->label) { fprintf(fp, "label"); for(int i=0;ilabel[i]); fprintf(fp, "\n"); } if(model->probA) // regression has probA only { fprintf(fp, "probA"); for(int i=0;iprobA[i]); fprintf(fp, "\n"); } if(model->probB) { fprintf(fp, "probB"); for(int i=0;iprobB[i]); fprintf(fp, "\n"); } if(model->nSV) { fprintf(fp, "nr_sv"); for(int i=0;inSV[i]); fprintf(fp, "\n"); } fprintf(fp, "SV\n"); const double * const *sv_coef = model->sv_coef; const svm_node * const *SV = model->SV; for(int i=0;ivalue)); else while(p->index != -1) { fprintf(fp,"%d:%.8g ",p->index,p->value); p++; } fprintf(fp, "\n"); } setlocale(LC_ALL, old_locale); free(old_locale); if (ferror(fp) != 0 || fclose(fp) != 0) return -1; else return 0; } static char *line = NULL; static int max_line_len; static char* readline(FILE *input) { int len; if(fgets(line,max_line_len,input) == NULL) return NULL; while(strrchr(line,'\n') == NULL) { max_line_len *= 2; line = (char *) realloc(line,max_line_len); len = (int) strlen(line); if(fgets(line+len,max_line_len-len,input) == NULL) break; } return line; } svm_model *svm_load_model(const char *model_file_name) { FILE *fp = fopen(model_file_name,"rb"); if(fp==NULL) return NULL; char *old_locale = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); // read parameters svm_model *model = Malloc(svm_model,1); svm_parameter& param = model->param; model->rho = NULL; model->probA = NULL; model->probB = NULL; model->sv_indices = NULL; model->label = NULL; model->nSV = NULL; char cmd[81]; while(1) { fscanf(fp,"%80s",cmd); if(strcmp(cmd,"svm_type")==0) { fscanf(fp,"%80s",cmd); int i; for(i=0;svm_type_table[i];i++) { if(strcmp(svm_type_table[i],cmd)==0) { param.svm_type=i; break; } } if(svm_type_table[i] == NULL) { REprintf("unknown svm type.\n"); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } else if(strcmp(cmd,"kernel_type")==0) { fscanf(fp,"%80s",cmd); int i; for(i=0;kernel_type_table[i];i++) { if(strcmp(kernel_type_table[i],cmd)==0) { param.kernel_type=i; break; } } if(kernel_type_table[i] == NULL) { REprintf("unknown kernel function.\n"); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } else if(strcmp(cmd,"degree")==0) fscanf(fp,"%d",¶m.degree); else if(strcmp(cmd,"gamma")==0) fscanf(fp,"%lf",¶m.gamma); else if(strcmp(cmd,"coef0")==0) fscanf(fp,"%lf",¶m.coef0); else if(strcmp(cmd,"nr_class")==0) fscanf(fp,"%d",&model->nr_class); else if(strcmp(cmd,"total_sv")==0) fscanf(fp,"%d",&model->l); else if(strcmp(cmd,"rho")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->rho = Malloc(double,n); for(int i=0;irho[i]); } else if(strcmp(cmd,"label")==0) { int n = model->nr_class; model->label = Malloc(int,n); for(int i=0;ilabel[i]); } else if(strcmp(cmd,"probA")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probA = Malloc(double,n); for(int i=0;iprobA[i]); } else if(strcmp(cmd,"probB")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probB = Malloc(double,n); for(int i=0;iprobB[i]); } else if(strcmp(cmd,"nr_sv")==0) { int n = model->nr_class; model->nSV = Malloc(int,n); for(int i=0;inSV[i]); } else if(strcmp(cmd,"SV")==0) { while(1) { int c = getc(fp); if(c==EOF || c=='\n') break; } break; } else { REprintf("unknown text in model file: [%s]\n",cmd); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } // read sv_coef and SV int elements = 0; long pos = ftell(fp); max_line_len = 1024; line = Malloc(char,max_line_len); char *p,*endptr,*idx,*val; while(readline(fp)!=NULL) { p = strtok(line,":"); while(1) { p = strtok(NULL,":"); if(p == NULL) break; ++elements; } } elements += model->l; fseek(fp,pos,SEEK_SET); int m = model->nr_class - 1; int l = model->l; model->sv_coef = Malloc(double *,m); int i; for(i=0;isv_coef[i] = Malloc(double,l); model->SV = Malloc(svm_node*,l); svm_node *x_space = NULL; if(l>0) x_space = Malloc(svm_node,elements); int j=0; for(i=0;iSV[i] = &x_space[j]; p = strtok(line, " \t"); model->sv_coef[0][i] = strtod(p,&endptr); for(int k=1;ksv_coef[k][i] = strtod(p,&endptr); } while(1) { idx = strtok(NULL, ":"); val = strtok(NULL, " \t"); if(val == NULL) break; x_space[j].index = (int) strtol(idx,&endptr,10); x_space[j].value = strtod(val,&endptr); ++j; } x_space[j++].index = -1; } free(line); setlocale(LC_ALL, old_locale); free(old_locale); if (ferror(fp) != 0 || fclose(fp) != 0) return NULL; model->free_sv = 1; // XXX return model; } void svm_free_model_content(svm_model* model_ptr) { if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL) free((void *)(model_ptr->SV[0])); if(model_ptr->sv_coef) { for(int i=0;inr_class-1;i++) free(model_ptr->sv_coef[i]); } free(model_ptr->SV); model_ptr->SV = NULL; free(model_ptr->sv_coef); model_ptr->sv_coef = NULL; free(model_ptr->rho); model_ptr->rho = NULL; free(model_ptr->label); model_ptr->label= NULL; free(model_ptr->probA); model_ptr->probA = NULL; free(model_ptr->probB); model_ptr->probB= NULL; free(model_ptr->sv_indices); model_ptr->sv_indices = NULL; free(model_ptr->nSV); model_ptr->nSV = NULL; } void svm_free_and_destroy_model(svm_model** model_ptr_ptr) { if(model_ptr_ptr != NULL && *model_ptr_ptr != NULL) { svm_free_model_content(*model_ptr_ptr); free(*model_ptr_ptr); *model_ptr_ptr = NULL; } } void svm_destroy_param(svm_parameter* param) { free(param->weight_label); free(param->weight); } const char *svm_check_parameter(const svm_problem *prob, const svm_parameter *param) { // svm_type int svm_type = param->svm_type; if(svm_type != C_SVC && svm_type != NU_SVC && svm_type != ONE_CLASS && svm_type != EPSILON_SVR && svm_type != NU_SVR) return "unknown svm type"; // kernel_type, degree int kernel_type = param->kernel_type; if(kernel_type != LINEAR && kernel_type != POLY && kernel_type != RBF && kernel_type != SIGMOID && kernel_type != PRECOMPUTED) return "unknown kernel type"; if(param->gamma < 0) return "gamma < 0"; if(param->degree < 0) return "degree of polynomial kernel < 0"; // cache_size,eps,C,nu,p,shrinking if(param->cache_size <= 0) return "cache_size <= 0"; if(param->eps <= 0) return "eps <= 0"; if(svm_type == C_SVC || svm_type == EPSILON_SVR || svm_type == NU_SVR) if(param->C <= 0) return "C <= 0"; if(svm_type == NU_SVC || svm_type == ONE_CLASS || svm_type == NU_SVR) if(param->nu <= 0 || param->nu > 1) return "nu <= 0 or nu > 1"; if(svm_type == EPSILON_SVR) if(param->p < 0) return "p < 0"; if(param->shrinking != 0 && param->shrinking != 1) return "shrinking != 0 and shrinking != 1"; if(param->probability != 0 && param->probability != 1) return "probability != 0 and probability != 1"; if(param->probability == 1 && svm_type == ONE_CLASS) return "one-class SVM probability output not supported yet"; // check whether nu-svc is feasible if(svm_type == NU_SVC) { int l = prob->l; int max_nr_class = 16; int nr_class = 0; int *label = Malloc(int,max_nr_class); int *count = Malloc(int,max_nr_class); int i; for(i=0;iy[i]; int j; for(j=0;jnu*(n1+n2)/2 > min(n1,n2)) { free(label); free(count); return "specified nu is infeasible"; } } } free(label); free(count); } return NULL; } int svm_check_probability_model(const svm_model *model) { return ((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) && model->probA!=NULL && model->probB!=NULL) || ((model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) && model->probA!=NULL); } void svm_set_print_string_function(void (*print_func)(const char *)) { if(print_func == NULL) svm_print_string = &print_string_stdout; else svm_print_string = print_func; } e1071/src/Rsvm.c0000644000175100001440000002755212560362405012725 0ustar hornikusers #include #include #include #include #include #include "svm.h" #define Malloc(type,n) (type *)malloc((n)*sizeof(type)) /* * results from cross-validation */ struct crossresults { double* results; double total1; double total2; }; struct svm_node ** sparsify (double *x, int r, int c) { struct svm_node** sparse; int i, ii, count; sparse = (struct svm_node **) malloc (r * sizeof(struct svm_node *)); for (i = 0; i < r; i++) { /* determine nr. of non-zero elements */ for (count = ii = 0; ii < c; ii++) if (x[i * c + ii] != 0) count++; /* allocate memory for column elements */ sparse[i] = (struct svm_node *) malloc ((count + 1) * sizeof(struct svm_node)); /* set column elements */ for (count = ii = 0; ii < c; ii++) if (x[i * c + ii] != 0) { sparse[i][count].index = ii + 1; sparse[i][count].value = x[i * c + ii]; count++; } /* set termination element */ sparse[i][count].index = -1; } return sparse; } struct svm_node ** transsparse (double *x, int r, int *rowindex, int *colindex) { struct svm_node** sparse; int i, ii, count = 0, nnz = 0; sparse = (struct svm_node **) malloc (r * sizeof(struct svm_node*)); for (i = 0; i < r; i++) { /* allocate memory for column elements */ nnz = rowindex[i+1] - rowindex[i]; sparse[i] = (struct svm_node *) malloc ((nnz + 1) * sizeof(struct svm_node)); /* set column elements */ for (ii = 0; ii < nnz; ii++) { sparse[i][ii].index = colindex[count]; sparse[i][ii].value = x[count]; count++; } /* set termination element */ sparse[i][ii].index = -1; } return sparse; } /* Cross-Validation-routine from svm-train */ void do_cross_validation(struct svm_problem *prob, struct svm_parameter *param, int nr_fold, double* cresults, double* ctotal1, double* ctotal2) { int i; int total_correct = 0; double total_error = 0; double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0; /* random shuffle */ GetRNGstate(); for(i=0; il; i++) { int j = i+((int) (unif_rand() * (prob->l-i)))%(prob->l-i); struct svm_node *tx; double ty; tx = prob->x[i]; prob->x[i] = prob->x[j]; prob->x[j] = tx; ty = prob->y[i]; prob->y[i] = prob->y[j]; prob->y[j] = ty; } PutRNGstate(); for(i=0; il/nr_fold; int end = (i+1)*prob->l/nr_fold; int j,k; struct svm_problem subprob; subprob.l = prob->l-(end-begin); subprob.x = Malloc(struct svm_node*,subprob.l); subprob.y = Malloc(double,subprob.l); k=0; for(j = 0; j < begin; j++) { subprob.x[k] = prob->x[j]; subprob.y[k] = prob->y[j]; ++k; } for(j = end; jl; j++) { subprob.x[k] = prob->x[j]; subprob.y[k] = prob->y[j]; ++k; } if(param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR) { struct svm_model *submodel = svm_train(&subprob,param); double error = 0; for(j=begin;jx[j]); double y = prob->y[j]; error += (v-y)*(v-y); sumv += v; sumy += y; sumvv += v*v; sumyy += y*y; sumvy += v*y; } svm_free_and_destroy_model(&submodel); /* printf("Mean squared error = %g\n", error/(end-begin)); */ cresults[i] = error/(end-begin); total_error += error; } else { struct svm_model *submodel = svm_train(&subprob,param); int correct = 0; for(j=begin;jx[j]); if(v == prob->y[j]) ++correct; } svm_free_and_destroy_model(&submodel); /* printf("Accuracy = %g%% (%d/%d)\n", */ /* 100.0*correct/(end-begin),correct,(end-begin)); */ cresults[i] = 100.0*correct/(end-begin); total_correct += correct; } free(subprob.x); free(subprob.y); } if(param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR) { /* printf("Cross Validation Mean squared error = %g\n",total_error/prob.l); printf("Cross Validation Squared correlation coefficient = %g\n", ((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/ ((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy)) ); */ *ctotal1 = total_error/prob->l; *ctotal2 = ((prob->l * sumvy - sumv * sumy) * (prob->l * sumvy - sumv*sumy)) / ((prob->l * sumvv - sumv * sumv) * (prob->l * sumyy - sumy * sumy)); } else /* printf("Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob.l); */ *ctotal1 = 100.0 * total_correct / prob->l; } void svmtrain (double *x, int *r, int *c, double *y, int *rowindex, int *colindex, int *svm_type, int *kernel_type, int *degree, double *gamma, double *coef0, double *cost, double *nu, int *weightlabels, double *weights, int *nweights, double *cache, double *tolerance, double *epsilon, int *shrinking, int *cross, int *sparse, int *probability, int *nclasses, int *nr, int *index, int *labels, int *nSV, double *rho, double *coefs, double *sigma, double *probA, double *probB, double *cresults, double *ctotal1, double *ctotal2, char **error) { struct svm_parameter par; struct svm_problem prob; struct svm_model *model = NULL; int i, ii; const char* s; /* set parameters */ par.svm_type = *svm_type; par.kernel_type = *kernel_type; par.degree = *degree; par.gamma = *gamma; par.coef0 = *coef0; par.cache_size = *cache; par.eps = *tolerance; par.C = *cost; par.nu = *nu; par.nr_weight = *nweights; if (par.nr_weight > 0) { par.weight = (double *) malloc (sizeof(double) * par.nr_weight); memcpy(par.weight, weights, par.nr_weight * sizeof(double)); par.weight_label = (int *) malloc (sizeof(int) * par.nr_weight); memcpy(par.weight_label, weightlabels, par.nr_weight * sizeof(int)); } par.p = *epsilon; par.shrinking = *shrinking; par.probability = *probability; /* set problem */ prob.l = *r; prob.y = y; if (*sparse > 0) prob.x = transsparse(x, *r, rowindex, colindex); else prob.x = sparsify(x, *r, *c); /* check parameters & copy error message */ s = svm_check_parameter(&prob, &par); if (s) { strcpy(*error, s); } else { /* call svm_train */ model = svm_train(&prob, &par); /* set up return values */ /* for (ii = 0; ii < model->l; ii++) for (i = 0; i < *r; i++) if (prob.x[i] == model->SV[ii]) index[ii] = i+1; */ svm_get_sv_indices(model, index); *nr = model->l; *nclasses = model->nr_class; memcpy (rho, model->rho, *nclasses * (*nclasses - 1)/2 * sizeof(double)); if (*probability && par.svm_type != ONE_CLASS) { if (par.svm_type == EPSILON_SVR || par.svm_type == NU_SVR) *sigma = svm_get_svr_probability(model); else { memcpy(probA, model->probA, *nclasses * (*nclasses - 1)/2 * sizeof(double)); memcpy(probB, model->probB, *nclasses * (*nclasses - 1)/2 * sizeof(double)); } } for (i = 0; i < *nclasses-1; i++) memcpy (coefs + i * *nr, model->sv_coef[i], *nr * sizeof (double)); if (*svm_type < 2) { memcpy (labels, model->label, *nclasses * sizeof(int)); memcpy (nSV, model->nSV, *nclasses * sizeof(int)); } /* Perform cross-validation, if requested */ if (*cross > 0) do_cross_validation (&prob, &par, *cross, cresults, ctotal1, ctotal2); /* clean up memory */ svm_free_and_destroy_model(&model); } /* clean up memory */ if (par.nr_weight > 0) { free(par.weight); free(par.weight_label); } for (i = 0; i < *r; i++) free (prob.x[i]); free (prob.x); } void svmpredict (int *decisionvalues, int *probability, double *v, int *r, int *c, int *rowindex, int *colindex, double *coefs, double *rho, int *compprob, double *probA, double *probB, int *nclasses, int *totnSV, int *labels, int *nSV, int *sparsemodel, int *svm_type, int *kernel_type, int *degree, double *gamma, double *coef0, double *x, int *xr, int *xrowindex, int *xcolindex, int *sparsex, double *ret, double *dec, double *prob) { struct svm_model m; struct svm_node ** train; int i; /* set up model */ m.l = *totnSV; m.nr_class = *nclasses; m.sv_coef = (double **) malloc (m.nr_class * sizeof(double*)); for (i = 0; i < m.nr_class - 1; i++) { m.sv_coef[i] = (double *) malloc (m.l * sizeof (double)); memcpy (m.sv_coef[i], coefs + i*m.l, m.l * sizeof (double)); } if (*sparsemodel > 0) m.SV = transsparse(v, *r, rowindex, colindex); else m.SV = sparsify(v, *r, *c); m.rho = rho; m.probA = probA; m.probB = probB; m.label = labels; m.nSV = nSV; /* set up parameter */ m.param.svm_type = *svm_type; m.param.kernel_type = *kernel_type; m.param.degree = *degree; m.param.gamma = *gamma; m.param.coef0 = *coef0; m.param.probability = *compprob; m.free_sv = 1; /* create sparse training matrix */ if (*sparsex > 0) train = transsparse(x, *xr, xrowindex, xcolindex); else train = sparsify(x, *xr, *c); /* call svm-predict-function for each x-row, possibly using probability estimator, if requested */ if (*probability && svm_check_probability_model(&m)) { for (i = 0; i < *xr; i++) ret[i] = svm_predict_probability(&m, train[i], prob + i * *nclasses); } else { for (i = 0; i < *xr; i++) ret[i] = svm_predict(&m, train[i]); } /* optionally, compute decision values */ if (*decisionvalues) for (i = 0; i < *xr; i++) svm_predict_values(&m, train[i], dec + i * *nclasses * (*nclasses - 1) / 2); /* clean up memory */ for (i = 0; i < *xr; i++) free (train[i]); free (train); for (i = 0; i < *r; i++) free (m.SV[i]); free (m.SV); for (i = 0; i < m.nr_class - 1; i++) free(m.sv_coef[i]); free(m.sv_coef); } void svmwrite (double *v, int *r, int *c, int *rowindex, int *colindex, double *coefs, double *rho, int *compprob, double *probA, double *probB, int *nclasses, int *totnSV, int *labels, int *nSV, int *sparsemodel, int *svm_type, int *kernel_type, int *degree, double *gamma, double *coef0, char **filename) { struct svm_model m; int i; char *fname = *filename; /* set up model */ m.l = *totnSV; m.nr_class = *nclasses; m.sv_coef = (double **) malloc (m.nr_class * sizeof(double*)); for (i = 0; i < m.nr_class - 1; i++) { m.sv_coef[i] = (double *) malloc (m.l * sizeof (double)); memcpy (m.sv_coef[i], coefs + i*m.l, m.l * sizeof (double)); } if (*sparsemodel > 0) m.SV = transsparse(v, *r, rowindex, colindex); else m.SV = sparsify(v, *r, *c); m.rho = rho; m.label = labels; m.nSV = nSV; if (*compprob) { m.probA = probA; m.probB = probB; } else { m.probA = NULL; m.probB = NULL; } /* set up parameter */ m.param.svm_type = *svm_type; m.param.kernel_type = *kernel_type; m.param.degree = *degree; m.param.gamma = *gamma; m.param.coef0 = *coef0; m.free_sv = 1; /* write svm model */ svm_save_model(fname, &m); for (i = 0; i < m.nr_class - 1; i++) free(m.sv_coef[i]); free(m.sv_coef); for (i = 0; i < *r; i++) free (m.SV[i]); free (m.SV); } e1071/src/svm.cpp0000644000175100001440000017636312560362405013150 0ustar hornikusers#include #include #include #include #include #include #include #include #include #include #include #include "svm.h" int libsvm_version = LIBSVM_VERSION; typedef float Qfloat; typedef signed char schar; #ifndef min template static inline T min(T x,T y) { return (x static inline T max(T x,T y) { return (x>y)?x:y; } #endif template static inline void swap(T& x, T& y) { T t=x; x=y; y=t; } template static inline void clone(T*& dst, S* src, int n) { dst = new T[n]; memcpy((void *)dst,(void *)src,sizeof(T)*n); } static inline double powi(double base, int times) { double tmp = base, ret = 1.0; for(int t=times; t>0; t/=2) { if(t%2==1) ret*=tmp; tmp = tmp * tmp; } return ret; } #define INF HUGE_VAL #define TAU 1e-12 #define Malloc(type,n) (type *)malloc((n)*sizeof(type)) static void print_string_stdout(const char *s) { /* fputs(s,stdout); fflush(stdout); */ Rprintf(s); } static void (*svm_print_string) (const char *) = &print_string_stdout; #if 0 static void info(const char *fmt,...) { char buf[BUFSIZ]; va_list ap; va_start(ap,fmt); vsprintf(buf,fmt,ap); va_end(ap); (*svm_print_string)(buf); } #else static void info(const char *fmt,...) {} #endif // // Kernel Cache // // l is the number of total data items // size is the cache size limit in bytes // class Cache { public: Cache(int l,long int size); ~Cache(); // request data [0,len) // return some position p where [p,len) need to be filled // (p >= len if nothing needs to be filled) int get_data(const int index, Qfloat **data, int len); void swap_index(int i, int j); private: int l; long int size; struct head_t { head_t *prev, *next; // a circular list Qfloat *data; int len; // data[0,len) is cached in this entry }; head_t *head; head_t lru_head; void lru_delete(head_t *h); void lru_insert(head_t *h); }; Cache::Cache(int l_,long int size_):l(l_),size(size_) { head = (head_t *)calloc(l,sizeof(head_t)); // initialized to 0 size /= sizeof(Qfloat); size -= l * sizeof(head_t) / sizeof(Qfloat); size = max(size, 2 * (long int) l); // cache must be large enough for two columns lru_head.next = lru_head.prev = &lru_head; } Cache::~Cache() { for(head_t *h = lru_head.next; h != &lru_head; h=h->next) free(h->data); free(head); } void Cache::lru_delete(head_t *h) { // delete from current location h->prev->next = h->next; h->next->prev = h->prev; } void Cache::lru_insert(head_t *h) { // insert to last position h->next = &lru_head; h->prev = lru_head.prev; h->prev->next = h; h->next->prev = h; } int Cache::get_data(const int index, Qfloat **data, int len) { head_t *h = &head[index]; if(h->len) lru_delete(h); int more = len - h->len; if(more > 0) { // free old space while(size < more) { head_t *old = lru_head.next; lru_delete(old); free(old->data); size += old->len; old->data = 0; old->len = 0; } // allocate new space h->data = (Qfloat *)realloc(h->data,sizeof(Qfloat)*len); size -= more; swap(h->len,len); } lru_insert(h); *data = h->data; return len; } void Cache::swap_index(int i, int j) { if(i==j) return; if(head[i].len) lru_delete(&head[i]); if(head[j].len) lru_delete(&head[j]); swap(head[i].data,head[j].data); swap(head[i].len,head[j].len); if(head[i].len) lru_insert(&head[i]); if(head[j].len) lru_insert(&head[j]); if(i>j) swap(i,j); for(head_t *h = lru_head.next; h!=&lru_head; h=h->next) { if(h->len > i) { if(h->len > j) swap(h->data[i],h->data[j]); else { // give up lru_delete(h); free(h->data); size += h->len; h->data = 0; h->len = 0; } } } } // // Kernel evaluation // // the static method k_function is for doing single kernel evaluation // the constructor of Kernel prepares to calculate the l*l kernel matrix // the member function get_Q is for getting one column from the Q Matrix // class QMatrix { public: virtual Qfloat *get_Q(int column, int len) const = 0; virtual double *get_QD() const = 0; virtual void swap_index(int i, int j) const = 0; virtual ~QMatrix() {} }; class Kernel: public QMatrix { public: Kernel(int l, svm_node * const * x, const svm_parameter& param); virtual ~Kernel(); static double k_function(const svm_node *x, const svm_node *y, const svm_parameter& param); virtual Qfloat *get_Q(int column, int len) const = 0; virtual double *get_QD() const = 0; virtual void swap_index(int i, int j) const // no so const... { swap(x[i],x[j]); if(x_square) swap(x_square[i],x_square[j]); } protected: double (Kernel::*kernel_function)(int i, int j) const; private: const svm_node **x; double *x_square; // svm_parameter const int kernel_type; const int degree; const double gamma; const double coef0; static double dot(const svm_node *px, const svm_node *py); double kernel_linear(int i, int j) const { return dot(x[i],x[j]); } double kernel_poly(int i, int j) const { return powi(gamma*dot(x[i],x[j])+coef0,degree); } double kernel_rbf(int i, int j) const { return exp(-gamma*(x_square[i]+x_square[j]-2*dot(x[i],x[j]))); } double kernel_sigmoid(int i, int j) const { return tanh(gamma*dot(x[i],x[j])+coef0); } double kernel_precomputed(int i, int j) const { return x[i][(int)(x[j][0].value)].value; } }; Kernel::Kernel(int l, svm_node * const * x_, const svm_parameter& param) :kernel_type(param.kernel_type), degree(param.degree), gamma(param.gamma), coef0(param.coef0) { switch(kernel_type) { case LINEAR: kernel_function = &Kernel::kernel_linear; break; case POLY: kernel_function = &Kernel::kernel_poly; break; case RBF: kernel_function = &Kernel::kernel_rbf; break; case SIGMOID: kernel_function = &Kernel::kernel_sigmoid; break; case PRECOMPUTED: kernel_function = &Kernel::kernel_precomputed; break; } clone(x,x_,l); if(kernel_type == RBF) { x_square = new double[l]; for(int i=0;iindex != -1 && py->index != -1) { if(px->index == py->index) { sum += px->value * py->value; ++px; ++py; } else { if(px->index > py->index) ++py; else ++px; } } return sum; } double Kernel::k_function(const svm_node *x, const svm_node *y, const svm_parameter& param) { switch(param.kernel_type) { case LINEAR: return dot(x,y); case POLY: return powi(param.gamma*dot(x,y)+param.coef0,param.degree); case RBF: { double sum = 0; while(x->index != -1 && y->index !=-1) { if(x->index == y->index) { double d = x->value - y->value; sum += d*d; ++x; ++y; } else { if(x->index > y->index) { sum += y->value * y->value; ++y; } else { sum += x->value * x->value; ++x; } } } while(x->index != -1) { sum += x->value * x->value; ++x; } while(y->index != -1) { sum += y->value * y->value; ++y; } return exp(-param.gamma*sum); } case SIGMOID: return tanh(param.gamma*dot(x,y)+param.coef0); case PRECOMPUTED: //x: test (validation), y: SV return x[(int)(y->value)].value; default: return 0; // Unreachable } } // An SMO algorithm in Fan et al., JMLR 6(2005), p. 1889--1918 // Solves: // // min 0.5(\alpha^T Q \alpha) + p^T \alpha // // y^T \alpha = \delta // y_i = +1 or -1 // 0 <= alpha_i <= Cp for y_i = 1 // 0 <= alpha_i <= Cn for y_i = -1 // // Given: // // Q, p, y, Cp, Cn, and an initial feasible point \alpha // l is the size of vectors and matrices // eps is the stopping tolerance // // solution will be put in \alpha, objective value will be put in obj // class Solver { public: Solver() {}; virtual ~Solver() {}; struct SolutionInfo { double obj; double rho; double upper_bound_p; double upper_bound_n; double r; // for Solver_NU }; void Solve(int l, const QMatrix& Q, const double *p_, const schar *y_, double *alpha_, double Cp, double Cn, double eps, SolutionInfo* si, int shrinking); protected: int active_size; schar *y; double *G; // gradient of objective function enum { LOWER_BOUND, UPPER_BOUND, FREE }; char *alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE double *alpha; const QMatrix *Q; const double *QD; double eps; double Cp,Cn; double *p; int *active_set; double *G_bar; // gradient, if we treat free variables as 0 int l; bool unshrink; // XXX double get_C(int i) { return (y[i] > 0)? Cp : Cn; } void update_alpha_status(int i) { if(alpha[i] >= get_C(i)) alpha_status[i] = UPPER_BOUND; else if(alpha[i] <= 0) alpha_status[i] = LOWER_BOUND; else alpha_status[i] = FREE; } bool is_upper_bound(int i) { return alpha_status[i] == UPPER_BOUND; } bool is_lower_bound(int i) { return alpha_status[i] == LOWER_BOUND; } bool is_free(int i) { return alpha_status[i] == FREE; } void swap_index(int i, int j); void reconstruct_gradient(); virtual int select_working_set(int &i, int &j); virtual double calculate_rho(); virtual void do_shrinking(); private: bool be_shrunk(int i, double Gmax1, double Gmax2); }; void Solver::swap_index(int i, int j) { Q->swap_index(i,j); swap(y[i],y[j]); swap(G[i],G[j]); swap(alpha_status[i],alpha_status[j]); swap(alpha[i],alpha[j]); swap(p[i],p[j]); swap(active_set[i],active_set[j]); swap(G_bar[i],G_bar[j]); } void Solver::reconstruct_gradient() { // reconstruct inactive elements of G from G_bar and free variables if(active_size == l) return; int i,j; int nr_free = 0; for(j=active_size;j 2*active_size*(l-active_size)) { for(i=active_size;iget_Q(i,active_size); for(j=0;jget_Q(i,l); double alpha_i = alpha[i]; for(j=active_size;jl = l; this->Q = &Q; QD=Q.get_QD(); clone(p, p_,l); clone(y, y_,l); clone(alpha,alpha_,l); this->Cp = Cp; this->Cn = Cn; this->eps = eps; unshrink = false; // initialize alpha_status { alpha_status = new char[l]; for(int i=0;iINT_MAX/100 ? INT_MAX : 100*l); int counter = min(l,1000)+1; while(iter < max_iter) { // show progress and do shrinking if(--counter == 0) { counter = min(l,1000); if(shrinking) do_shrinking(); info("."); } int i,j; if(select_working_set(i,j)!=0) { // reconstruct the whole gradient reconstruct_gradient(); // reset active set size and check active_size = l; info("*"); if(select_working_set(i,j)!=0) break; else counter = 1; // do shrinking next iteration } ++iter; // update alpha[i] and alpha[j], handle bounds carefully const Qfloat *Q_i = Q.get_Q(i,active_size); const Qfloat *Q_j = Q.get_Q(j,active_size); double C_i = get_C(i); double C_j = get_C(j); double old_alpha_i = alpha[i]; double old_alpha_j = alpha[j]; if(y[i]!=y[j]) { double quad_coef = QD[i]+QD[j]+2*Q_i[j]; if (quad_coef <= 0) quad_coef = TAU; double delta = (-G[i]-G[j])/quad_coef; double diff = alpha[i] - alpha[j]; alpha[i] += delta; alpha[j] += delta; if(diff > 0) { if(alpha[j] < 0) { alpha[j] = 0; alpha[i] = diff; } } else { if(alpha[i] < 0) { alpha[i] = 0; alpha[j] = -diff; } } if(diff > C_i - C_j) { if(alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = C_i - diff; } } else { if(alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = C_j + diff; } } } else { double quad_coef = QD[i]+QD[j]-2*Q_i[j]; if (quad_coef <= 0) quad_coef = TAU; double delta = (G[i]-G[j])/quad_coef; double sum = alpha[i] + alpha[j]; alpha[i] -= delta; alpha[j] += delta; if(sum > C_i) { if(alpha[i] > C_i) { alpha[i] = C_i; alpha[j] = sum - C_i; } } else { if(alpha[j] < 0) { alpha[j] = 0; alpha[i] = sum; } } if(sum > C_j) { if(alpha[j] > C_j) { alpha[j] = C_j; alpha[i] = sum - C_j; } } else { if(alpha[i] < 0) { alpha[i] = 0; alpha[j] = sum; } } } // update G double delta_alpha_i = alpha[i] - old_alpha_i; double delta_alpha_j = alpha[j] - old_alpha_j; for(int k=0;k= max_iter) { if(active_size < l) { // reconstruct the whole gradient to calculate objective value reconstruct_gradient(); active_size = l; info("*"); } REprintf("\nWARNING: reaching max number of iterations\n"); } // calculate rho si->rho = calculate_rho(); // calculate objective value { double v = 0; int i; for(i=0;iobj = v/2; } // put back the solution { for(int i=0;iupper_bound_p = Cp; si->upper_bound_n = Cn; info("\noptimization finished, #iter = %d\n",iter); delete[] p; delete[] y; delete[] alpha; delete[] alpha_status; delete[] active_set; delete[] G; delete[] G_bar; } // return 1 if already optimal, return 0 otherwise int Solver::select_working_set(int &out_i, int &out_j) { // return i,j such that // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha) // j: minimizes the decrease of obj value // (if quadratic coefficeint <= 0, replace it with tau) // -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha) double Gmax = -INF; double Gmax2 = -INF; int Gmax_idx = -1; int Gmin_idx = -1; double obj_diff_min = INF; for(int t=0;t= Gmax) { Gmax = -G[t]; Gmax_idx = t; } } else { if(!is_lower_bound(t)) if(G[t] >= Gmax) { Gmax = G[t]; Gmax_idx = t; } } int i = Gmax_idx; const Qfloat *Q_i = NULL; if(i != -1) // NULL Q_i not accessed: Gmax=-INF if i=-1 Q_i = Q->get_Q(i,active_size); for(int j=0;j= Gmax2) Gmax2 = G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[i]+QD[j]-2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } else { if (!is_upper_bound(j)) { double grad_diff= Gmax-G[j]; if (-G[j] >= Gmax2) Gmax2 = -G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[i]+QD[j]+2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } } if(Gmax+Gmax2 < eps) return 1; out_i = Gmax_idx; out_j = Gmin_idx; return 0; } bool Solver::be_shrunk(int i, double Gmax1, double Gmax2) { if(is_upper_bound(i)) { if(y[i]==+1) return(-G[i] > Gmax1); else return(-G[i] > Gmax2); } else if(is_lower_bound(i)) { if(y[i]==+1) return(G[i] > Gmax2); else return(G[i] > Gmax1); } else return(false); } void Solver::do_shrinking() { int i; double Gmax1 = -INF; // max { -y_i * grad(f)_i | i in I_up(\alpha) } double Gmax2 = -INF; // max { y_i * grad(f)_i | i in I_low(\alpha) } // find maximal violating pair first for(i=0;i= Gmax1) Gmax1 = -G[i]; } if(!is_lower_bound(i)) { if(G[i] >= Gmax2) Gmax2 = G[i]; } } else { if(!is_upper_bound(i)) { if(-G[i] >= Gmax2) Gmax2 = -G[i]; } if(!is_lower_bound(i)) { if(G[i] >= Gmax1) Gmax1 = G[i]; } } } if(unshrink == false && Gmax1 + Gmax2 <= eps*10) { unshrink = true; reconstruct_gradient(); active_size = l; info("*"); } for(i=0;i i) { if (!be_shrunk(active_size, Gmax1, Gmax2)) { swap_index(i,active_size); break; } active_size--; } } } double Solver::calculate_rho() { double r; int nr_free = 0; double ub = INF, lb = -INF, sum_free = 0; for(int i=0;i0) r = sum_free/nr_free; else r = (ub+lb)/2; return r; } // // Solver for nu-svm classification and regression // // additional constraint: e^T \alpha = constant // class Solver_NU: public Solver { public: Solver_NU() {} void Solve(int l, const QMatrix& Q, const double *p, const schar *y, double *alpha, double Cp, double Cn, double eps, SolutionInfo* si, int shrinking) { this->si = si; Solver::Solve(l,Q,p,y,alpha,Cp,Cn,eps,si,shrinking); } private: SolutionInfo *si; int select_working_set(int &i, int &j); double calculate_rho(); bool be_shrunk(int i, double Gmax1, double Gmax2, double Gmax3, double Gmax4); void do_shrinking(); }; // return 1 if already optimal, return 0 otherwise int Solver_NU::select_working_set(int &out_i, int &out_j) { // return i,j such that y_i = y_j and // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha) // j: minimizes the decrease of obj value // (if quadratic coefficeint <= 0, replace it with tau) // -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha) double Gmaxp = -INF; double Gmaxp2 = -INF; int Gmaxp_idx = -1; double Gmaxn = -INF; double Gmaxn2 = -INF; int Gmaxn_idx = -1; int Gmin_idx = -1; double obj_diff_min = INF; for(int t=0;t= Gmaxp) { Gmaxp = -G[t]; Gmaxp_idx = t; } } else { if(!is_lower_bound(t)) if(G[t] >= Gmaxn) { Gmaxn = G[t]; Gmaxn_idx = t; } } int ip = Gmaxp_idx; int in = Gmaxn_idx; const Qfloat *Q_ip = NULL; const Qfloat *Q_in = NULL; if(ip != -1) // NULL Q_ip not accessed: Gmaxp=-INF if ip=-1 Q_ip = Q->get_Q(ip,active_size); if(in != -1) Q_in = Q->get_Q(in,active_size); for(int j=0;j= Gmaxp2) Gmaxp2 = G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[ip]+QD[j]-2*Q_ip[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } else { if (!is_upper_bound(j)) { double grad_diff=Gmaxn-G[j]; if (-G[j] >= Gmaxn2) Gmaxn2 = -G[j]; if (grad_diff > 0) { double obj_diff; double quad_coef = QD[in]+QD[j]-2*Q_in[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; if (obj_diff <= obj_diff_min) { Gmin_idx=j; obj_diff_min = obj_diff; } } } } } if(max(Gmaxp+Gmaxp2,Gmaxn+Gmaxn2) < eps) return 1; if (y[Gmin_idx] == +1) out_i = Gmaxp_idx; else out_i = Gmaxn_idx; out_j = Gmin_idx; return 0; } bool Solver_NU::be_shrunk(int i, double Gmax1, double Gmax2, double Gmax3, double Gmax4) { if(is_upper_bound(i)) { if(y[i]==+1) return(-G[i] > Gmax1); else return(-G[i] > Gmax4); } else if(is_lower_bound(i)) { if(y[i]==+1) return(G[i] > Gmax2); else return(G[i] > Gmax3); } else return(false); } void Solver_NU::do_shrinking() { double Gmax1 = -INF; // max { -y_i * grad(f)_i | y_i = +1, i in I_up(\alpha) } double Gmax2 = -INF; // max { y_i * grad(f)_i | y_i = +1, i in I_low(\alpha) } double Gmax3 = -INF; // max { -y_i * grad(f)_i | y_i = -1, i in I_up(\alpha) } double Gmax4 = -INF; // max { y_i * grad(f)_i | y_i = -1, i in I_low(\alpha) } // find maximal violating pair first int i; for(i=0;i Gmax1) Gmax1 = -G[i]; } else if(-G[i] > Gmax4) Gmax4 = -G[i]; } if(!is_lower_bound(i)) { if(y[i]==+1) { if(G[i] > Gmax2) Gmax2 = G[i]; } else if(G[i] > Gmax3) Gmax3 = G[i]; } } if(unshrink == false && max(Gmax1+Gmax2,Gmax3+Gmax4) <= eps*10) { unshrink = true; reconstruct_gradient(); active_size = l; } for(i=0;i i) { if (!be_shrunk(active_size, Gmax1, Gmax2, Gmax3, Gmax4)) { swap_index(i,active_size); break; } active_size--; } } } double Solver_NU::calculate_rho() { int nr_free1 = 0,nr_free2 = 0; double ub1 = INF, ub2 = INF; double lb1 = -INF, lb2 = -INF; double sum_free1 = 0, sum_free2 = 0; for(int i=0;i 0) r1 = sum_free1/nr_free1; else r1 = (ub1+lb1)/2; if(nr_free2 > 0) r2 = sum_free2/nr_free2; else r2 = (ub2+lb2)/2; si->r = (r1+r2)/2; return (r1-r2)/2; } // // Q matrices for various formulations // class SVC_Q: public Kernel { public: SVC_Q(const svm_problem& prob, const svm_parameter& param, const schar *y_) :Kernel(prob.l, prob.x, param) { clone(y,y_,prob.l); cache = new Cache(prob.l,(long int)(param.cache_size*(1<<20))); QD = new double[prob.l]; for(int i=0;i*kernel_function)(i,i); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int start, j; if((start = cache->get_data(i,&data,len)) < len) { for(j=start;j*kernel_function)(i,j)); } return data; } double *get_QD() const { return QD; } void swap_index(int i, int j) const { cache->swap_index(i,j); Kernel::swap_index(i,j); swap(y[i],y[j]); swap(QD[i],QD[j]); } ~SVC_Q() { delete[] y; delete cache; delete[] QD; } private: schar *y; Cache *cache; double *QD; }; class ONE_CLASS_Q: public Kernel { public: ONE_CLASS_Q(const svm_problem& prob, const svm_parameter& param) :Kernel(prob.l, prob.x, param) { cache = new Cache(prob.l,(long int)(param.cache_size*(1<<20))); QD = new double[prob.l]; for(int i=0;i*kernel_function)(i,i); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int start, j; if((start = cache->get_data(i,&data,len)) < len) { for(j=start;j*kernel_function)(i,j); } return data; } double *get_QD() const { return QD; } void swap_index(int i, int j) const { cache->swap_index(i,j); Kernel::swap_index(i,j); swap(QD[i],QD[j]); } ~ONE_CLASS_Q() { delete cache; delete[] QD; } private: Cache *cache; double *QD; }; class SVR_Q: public Kernel { public: SVR_Q(const svm_problem& prob, const svm_parameter& param) :Kernel(prob.l, prob.x, param) { l = prob.l; cache = new Cache(l,(long int)(param.cache_size*(1<<20))); QD = new double[2*l]; sign = new schar[2*l]; index = new int[2*l]; for(int k=0;k*kernel_function)(k,k); QD[k+l] = QD[k]; } buffer[0] = new Qfloat[2*l]; buffer[1] = new Qfloat[2*l]; next_buffer = 0; } void swap_index(int i, int j) const { swap(sign[i],sign[j]); swap(index[i],index[j]); swap(QD[i],QD[j]); } Qfloat *get_Q(int i, int len) const { Qfloat *data; int j, real_i = index[i]; if(cache->get_data(real_i,&data,l) < l) { for(j=0;j*kernel_function)(real_i,j); } // reorder and copy Qfloat *buf = buffer[next_buffer]; next_buffer = 1 - next_buffer; schar si = sign[i]; for(j=0;jl; double *minus_ones = new double[l]; schar *y = new schar[l]; int i; for(i=0;iy[i] > 0) y[i] = +1; else y[i] = -1; } Solver s; s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y, alpha, Cp, Cn, param->eps, si, param->shrinking); double sum_alpha=0; for(i=0;il)); for(i=0;il; double nu = param->nu; schar *y = new schar[l]; for(i=0;iy[i]>0) y[i] = +1; else y[i] = -1; double sum_pos = nu*l/2; double sum_neg = nu*l/2; for(i=0;ieps, si, param->shrinking); double r = si->r; info("C = %f\n",1/r); for(i=0;irho /= r; si->obj /= (r*r); si->upper_bound_p = 1/r; si->upper_bound_n = 1/r; delete[] y; delete[] zeros; } static void solve_one_class( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *zeros = new double[l]; schar *ones = new schar[l]; int i; int n = (int)(param->nu*prob->l); // # of alpha's at upper bound for(i=0;il) alpha[n] = param->nu * prob->l - n; for(i=n+1;ieps, si, param->shrinking); delete[] zeros; delete[] ones; } static void solve_epsilon_svr( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *alpha2 = new double[2*l]; double *linear_term = new double[2*l]; schar *y = new schar[2*l]; int i; for(i=0;ip - prob->y[i]; y[i] = 1; alpha2[i+l] = 0; linear_term[i+l] = param->p + prob->y[i]; y[i+l] = -1; } Solver s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, param->C, param->C, param->eps, si, param->shrinking); double sum_alpha = 0; for(i=0;iC*l)); delete[] alpha2; delete[] linear_term; delete[] y; } static void solve_nu_svr( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double C = param->C; double *alpha2 = new double[2*l]; double *linear_term = new double[2*l]; schar *y = new schar[2*l]; int i; double sum = C * param->nu * l / 2; for(i=0;iy[i]; y[i] = 1; linear_term[i+l] = prob->y[i]; y[i+l] = -1; } Solver_NU s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, C, C, param->eps, si, param->shrinking); info("epsilon = %f\n",-si->r); for(i=0;il); Solver::SolutionInfo si; switch(param->svm_type) { case C_SVC: solve_c_svc(prob,param,alpha,&si,Cp,Cn); break; case NU_SVC: solve_nu_svc(prob,param,alpha,&si); break; case ONE_CLASS: solve_one_class(prob,param,alpha,&si); break; case EPSILON_SVR: solve_epsilon_svr(prob,param,alpha,&si); break; case NU_SVR: solve_nu_svr(prob,param,alpha,&si); break; } info("obj = %f, rho = %f\n",si.obj,si.rho); // output SVs int nSV = 0; int nBSV = 0; for(int i=0;il;i++) { if(fabs(alpha[i]) > 0) { ++nSV; if(prob->y[i] > 0) { if(fabs(alpha[i]) >= si.upper_bound_p) ++nBSV; } else { if(fabs(alpha[i]) >= si.upper_bound_n) ++nBSV; } } } info("nSV = %d, nBSV = %d\n",nSV,nBSV); decision_function f; f.alpha = alpha; f.rho = si.rho; return f; } // Platt's binary SVM Probablistic Output: an improvement from Lin et al. static void sigmoid_train( int l, const double *dec_values, const double *labels, double& A, double& B) { double prior1=0, prior0 = 0; int i; for (i=0;i 0) prior1+=1; else prior0+=1; int max_iter=100; // Maximal number of iterations double min_step=1e-10; // Minimal step taken in line search double sigma=1e-12; // For numerically strict PD of Hessian double eps=1e-5; double hiTarget=(prior1+1.0)/(prior1+2.0); double loTarget=1/(prior0+2.0); double *t=Malloc(double,l); double fApB,p,q,h11,h22,h21,g1,g2,det,dA,dB,gd,stepsize; double newA,newB,newf,d1,d2; int iter; // Initial Point and Initial Fun Value A=0.0; B=log((prior0+1.0)/(prior1+1.0)); double fval = 0.0; for (i=0;i0) t[i]=hiTarget; else t[i]=loTarget; fApB = dec_values[i]*A+B; if (fApB>=0) fval += t[i]*fApB + log(1+exp(-fApB)); else fval += (t[i] - 1)*fApB +log(1+exp(fApB)); } for (iter=0;iter= 0) { p=exp(-fApB)/(1.0+exp(-fApB)); q=1.0/(1.0+exp(-fApB)); } else { p=1.0/(1.0+exp(fApB)); q=exp(fApB)/(1.0+exp(fApB)); } d2=p*q; h11+=dec_values[i]*dec_values[i]*d2; h22+=d2; h21+=dec_values[i]*d2; d1=t[i]-p; g1+=dec_values[i]*d1; g2+=d1; } // Stopping Criteria if (fabs(g1)= min_step) { newA = A + stepsize * dA; newB = B + stepsize * dB; // New function value newf = 0.0; for (i=0;i= 0) newf += t[i]*fApB + log(1+exp(-fApB)); else newf += (t[i] - 1)*fApB +log(1+exp(fApB)); } // Check sufficient decrease if (newf=max_iter) info("Reaching maximal iterations in two-class probability estimates\n"); free(t); } static double sigmoid_predict(double decision_value, double A, double B) { double fApB = decision_value*A+B; // 1-p used later; avoid catastrophic cancellation if (fApB >= 0) return exp(-fApB)/(1.0+exp(-fApB)); else return 1.0/(1+exp(fApB)) ; } // Method 2 from the multiclass_prob paper by Wu, Lin, and Weng static void multiclass_probability(int k, double **r, double *p) { int t,j; int iter = 0, max_iter=max(100,k); double **Q=Malloc(double *,k); double *Qp=Malloc(double,k); double pQp, eps=0.005/k; for (t=0;tmax_error) max_error=error; } if (max_error=max_iter) info("Exceeds max_iter in multiclass_prob\n"); for(t=0;tl); double *dec_values = Malloc(double,prob->l); // random shuffle GetRNGstate(); for(i=0;il;i++) perm[i]=i; for(i=0;il;i++) { int j = i+((int) (unif_rand() * (prob->l-i))) % (prob->l-i); swap(perm[i],perm[j]); } PutRNGstate(); for(i=0;il/nr_fold; int end = (i+1)*prob->l/nr_fold; int j,k; struct svm_problem subprob; subprob.l = prob->l-(end-begin); subprob.x = Malloc(struct svm_node*,subprob.l); subprob.y = Malloc(double,subprob.l); k=0; for(j=0;jx[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } for(j=end;jl;j++) { subprob.x[k] = prob->x[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } int p_count=0,n_count=0; for(j=0;j0) p_count++; else n_count++; if(p_count==0 && n_count==0) for(j=begin;j 0 && n_count == 0) for(j=begin;j 0) for(j=begin;jx[perm[j]],&(dec_values[perm[j]])); // ensure +1 -1 order; reason not using CV subroutine dec_values[perm[j]] *= submodel->label[0]; } svm_free_and_destroy_model(&submodel); svm_destroy_param(&subparam); } free(subprob.x); free(subprob.y); } sigmoid_train(prob->l,dec_values,prob->y,probA,probB); free(dec_values); free(perm); } // Return parameter of a Laplace distribution static double svm_svr_probability( const svm_problem *prob, const svm_parameter *param) { int i; int nr_fold = 5; double *ymv = Malloc(double,prob->l); double mae = 0; svm_parameter newparam = *param; newparam.probability = 0; svm_cross_validation(prob,&newparam,nr_fold,ymv); for(i=0;il;i++) { ymv[i]=prob->y[i]-ymv[i]; mae += fabs(ymv[i]); } mae /= prob->l; double std=sqrt(2*mae*mae); int count=0; mae=0; for(i=0;il;i++) if (fabs(ymv[i]) > 5*std) count=count+1; else mae+=fabs(ymv[i]); mae /= (prob->l-count); info("Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma= %g\n",mae); free(ymv); return mae; } // label: label name, start: begin of each class, count: #data of classes, perm: indices to the original data // perm, length l, must be allocated before calling this subroutine static void svm_group_classes(const svm_problem *prob, int *nr_class_ret, int **label_ret, int **start_ret, int **count_ret, int *perm) { int l = prob->l; int max_nr_class = 16; int nr_class = 0; int *label = Malloc(int,max_nr_class); int *count = Malloc(int,max_nr_class); int *data_label = Malloc(int,l); int i; for(i=0;iy[i]; int j; for(j=0;jparam = *param; model->free_sv = 0; // XXX if(param->svm_type == ONE_CLASS || param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR) { // regression or one-class-svm model->nr_class = 2; model->label = NULL; model->nSV = NULL; model->probA = NULL; model->probB = NULL; model->sv_coef = Malloc(double *,1); if(param->probability && (param->svm_type == EPSILON_SVR || param->svm_type == NU_SVR)) { model->probA = Malloc(double,1); model->probA[0] = svm_svr_probability(prob,param); } decision_function f = svm_train_one(prob,param,0,0); model->rho = Malloc(double,1); model->rho[0] = f.rho; int nSV = 0; int i; for(i=0;il;i++) if(fabs(f.alpha[i]) > 0) ++nSV; model->l = nSV; model->SV = Malloc(svm_node *,nSV); model->sv_coef[0] = Malloc(double,nSV); model->sv_indices = Malloc(int,nSV); int j = 0; for(i=0;il;i++) if(fabs(f.alpha[i]) > 0) { model->SV[j] = prob->x[i]; model->sv_coef[0][j] = f.alpha[i]; model->sv_indices[j] = i+1; ++j; } free(f.alpha); } else { // classification int l = prob->l; int nr_class; int *label = NULL; int *start = NULL; int *count = NULL; int *perm = Malloc(int,l); // group training data of the same class svm_group_classes(prob,&nr_class,&label,&start,&count,perm); if(nr_class == 1) info("WARNING: training data in only one class. See README for details.\n"); svm_node **x = Malloc(svm_node *,l); int i; for(i=0;ix[perm[i]]; // calculate weighted C double *weighted_C = Malloc(double, nr_class); for(i=0;iC; for(i=0;inr_weight;i++) { int j; for(j=0;jweight_label[i] == label[j]) break; if(j == nr_class) REprintf("WARNING: class label %d specified in weight is not found\n", param->weight_label[i]); else weighted_C[j] *= param->weight[i]; } // train k*(k-1)/2 models bool *nonzero = Malloc(bool,l); for(i=0;iprobability) { probA=Malloc(double,nr_class*(nr_class-1)/2); probB=Malloc(double,nr_class*(nr_class-1)/2); } int p = 0; for(i=0;iprobability) svm_binary_svc_probability(&sub_prob,param,weighted_C[i],weighted_C[j],probA[p],probB[p]); f[p] = svm_train_one(&sub_prob,param,weighted_C[i],weighted_C[j]); for(k=0;k 0) nonzero[si+k] = true; for(k=0;k 0) nonzero[sj+k] = true; free(sub_prob.x); free(sub_prob.y); ++p; } // build output model->nr_class = nr_class; model->label = Malloc(int,nr_class); for(i=0;ilabel[i] = label[i]; model->rho = Malloc(double,nr_class*(nr_class-1)/2); for(i=0;irho[i] = f[i].rho; if(param->probability) { model->probA = Malloc(double,nr_class*(nr_class-1)/2); model->probB = Malloc(double,nr_class*(nr_class-1)/2); for(i=0;iprobA[i] = probA[i]; model->probB[i] = probB[i]; } } else { model->probA=NULL; model->probB=NULL; } int total_sv = 0; int *nz_count = Malloc(int,nr_class); model->nSV = Malloc(int,nr_class); for(i=0;inSV[i] = nSV; nz_count[i] = nSV; } info("Total nSV = %d\n",total_sv); model->l = total_sv; model->SV = Malloc(svm_node *,total_sv); model->sv_indices = Malloc(int,total_sv); p = 0; for(i=0;iSV[p] = x[i]; model->sv_indices[p++] = perm[i] + 1; } int *nz_start = Malloc(int,nr_class); nz_start[0] = 0; for(i=1;isv_coef = Malloc(double *,nr_class-1); for(i=0;isv_coef[i] = Malloc(double,total_sv); p = 0; for(i=0;isv_coef[j-1][q++] = f[p].alpha[k]; q = nz_start[j]; for(k=0;ksv_coef[i][q++] = f[p].alpha[ci+k]; ++p; } free(label); free(probA); free(probB); free(count); free(perm); free(start); free(x); free(weighted_C); free(nonzero); for(i=0;il; int *perm = Malloc(int,l); int nr_class; GetRNGstate(); if (nr_fold > l) { nr_fold = l; REprintf("WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n"); } fold_start = Malloc(int,nr_fold+1); // stratified cv may not give leave-one-out rate // Each class to l folds -> some folds may have zero elements if((param->svm_type == C_SVC || param->svm_type == NU_SVC) && nr_fold < l) { int *start = NULL; int *label = NULL; int *count = NULL; svm_group_classes(prob,&nr_class,&label,&start,&count,perm); // random shuffle and then data grouped by fold using the array perm int *fold_count = Malloc(int,nr_fold); int c; int *index = Malloc(int,l); for(i=0;ix[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } for(j=end;jx[perm[j]]; subprob.y[k] = prob->y[perm[j]]; ++k; } struct svm_model *submodel = svm_train(&subprob,param); if(param->probability && (param->svm_type == C_SVC || param->svm_type == NU_SVC)) { double *prob_estimates=Malloc(double,svm_get_nr_class(submodel)); for(j=begin;jx[perm[j]],prob_estimates); free(prob_estimates); } else for(j=begin;jx[perm[j]]); svm_free_and_destroy_model(&submodel); free(subprob.x); free(subprob.y); } free(fold_start); free(perm); PutRNGstate(); } int svm_get_svm_type(const svm_model *model) { return model->param.svm_type; } int svm_get_nr_class(const svm_model *model) { return model->nr_class; } void svm_get_labels(const svm_model *model, int* label) { if (model->label != NULL) for(int i=0;inr_class;i++) label[i] = model->label[i]; } void svm_get_sv_indices(const svm_model *model, int* indices) { if (model->sv_indices != NULL) for(int i=0;il;i++) indices[i] = model->sv_indices[i]; } int svm_get_nr_sv(const svm_model *model) { return model->l; } double svm_get_svr_probability(const svm_model *model) { if ((model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) && model->probA!=NULL) return model->probA[0]; else { REprintf("Model doesn't contain information for SVR probability inference\n"); return 0; } } double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values) { int i; if(model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) { double *sv_coef = model->sv_coef[0]; double sum = 0; for(i=0;il;i++) sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param); sum -= model->rho[0]; *dec_values = sum; if(model->param.svm_type == ONE_CLASS) return (sum>0)?1:-1; else return sum; } else { int nr_class = model->nr_class; int l = model->l; double *kvalue = Malloc(double,l); for(i=0;iSV[i],model->param); int *start = Malloc(int,nr_class); start[0] = 0; for(i=1;inSV[i-1]; int *vote = Malloc(int,nr_class); for(i=0;inSV[i]; int cj = model->nSV[j]; int k; double *coef1 = model->sv_coef[j-1]; double *coef2 = model->sv_coef[i]; for(k=0;krho[p]; dec_values[p] = sum; if(dec_values[p] > 0) ++vote[i]; else ++vote[j]; p++; } int vote_max_idx = 0; for(i=1;i vote[vote_max_idx]) vote_max_idx = i; free(kvalue); free(start); free(vote); return model->label[vote_max_idx]; } } double svm_predict(const svm_model *model, const svm_node *x) { int nr_class = model->nr_class; double *dec_values; if(model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) dec_values = Malloc(double, 1); else dec_values = Malloc(double, nr_class*(nr_class-1)/2); double pred_result = svm_predict_values(model, x, dec_values); free(dec_values); return pred_result; } double svm_predict_probability( const svm_model *model, const svm_node *x, double *prob_estimates) { if ((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) && model->probA!=NULL && model->probB!=NULL) { int i; int nr_class = model->nr_class; double *dec_values = Malloc(double, nr_class*(nr_class-1)/2); svm_predict_values(model, x, dec_values); double min_prob=1e-7; double **pairwise_prob=Malloc(double *,nr_class); for(i=0;iprobA[k],model->probB[k]),min_prob),1-min_prob); pairwise_prob[j][i]=1-pairwise_prob[i][j]; k++; } multiclass_probability(nr_class,pairwise_prob,prob_estimates); int prob_max_idx = 0; for(i=1;i prob_estimates[prob_max_idx]) prob_max_idx = i; for(i=0;ilabel[prob_max_idx]; } else return svm_predict(model, x); } static const char *svm_type_table[] = { "c_svc","nu_svc","one_class","epsilon_svr","nu_svr",NULL }; static const char *kernel_type_table[]= { "linear","polynomial","rbf","sigmoid","precomputed",NULL }; int svm_save_model(const char *model_file_name, const svm_model *model) { FILE *fp = fopen(model_file_name,"w"); if(fp==NULL) return -1; char *old_locale = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); const svm_parameter& param = model->param; fprintf(fp,"svm_type %s\n", svm_type_table[param.svm_type]); fprintf(fp,"kernel_type %s\n", kernel_type_table[param.kernel_type]); if(param.kernel_type == POLY) fprintf(fp,"degree %d\n", param.degree); if(param.kernel_type == POLY || param.kernel_type == RBF || param.kernel_type == SIGMOID) fprintf(fp,"gamma %g\n", param.gamma); if(param.kernel_type == POLY || param.kernel_type == SIGMOID) fprintf(fp,"coef0 %g\n", param.coef0); int nr_class = model->nr_class; int l = model->l; fprintf(fp, "nr_class %d\n", nr_class); fprintf(fp, "total_sv %d\n",l); { fprintf(fp, "rho"); for(int i=0;irho[i]); fprintf(fp, "\n"); } if(model->label) { fprintf(fp, "label"); for(int i=0;ilabel[i]); fprintf(fp, "\n"); } if(model->probA) // regression has probA only { fprintf(fp, "probA"); for(int i=0;iprobA[i]); fprintf(fp, "\n"); } if(model->probB) { fprintf(fp, "probB"); for(int i=0;iprobB[i]); fprintf(fp, "\n"); } if(model->nSV) { fprintf(fp, "nr_sv"); for(int i=0;inSV[i]); fprintf(fp, "\n"); } fprintf(fp, "SV\n"); const double * const *sv_coef = model->sv_coef; const svm_node * const *SV = model->SV; for(int i=0;ivalue)); else while(p->index != -1) { fprintf(fp,"%d:%.8g ",p->index,p->value); p++; } fprintf(fp, "\n"); } setlocale(LC_ALL, old_locale); free(old_locale); if (ferror(fp) != 0 || fclose(fp) != 0) return -1; else return 0; } static char *line = NULL; static int max_line_len; static char* readline(FILE *input) { int len; if(fgets(line,max_line_len,input) == NULL) return NULL; while(strrchr(line,'\n') == NULL) { max_line_len *= 2; line = (char *) realloc(line,max_line_len); len = (int) strlen(line); if(fgets(line+len,max_line_len-len,input) == NULL) break; } return line; } svm_model *svm_load_model(const char *model_file_name) { FILE *fp = fopen(model_file_name,"rb"); if(fp==NULL) return NULL; char *old_locale = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); // read parameters svm_model *model = Malloc(svm_model,1); svm_parameter& param = model->param; model->rho = NULL; model->probA = NULL; model->probB = NULL; model->sv_indices = NULL; model->label = NULL; model->nSV = NULL; char cmd[81]; while(1) { fscanf(fp,"%80s",cmd); if(strcmp(cmd,"svm_type")==0) { fscanf(fp,"%80s",cmd); int i; for(i=0;svm_type_table[i];i++) { if(strcmp(svm_type_table[i],cmd)==0) { param.svm_type=i; break; } } if(svm_type_table[i] == NULL) { REprintf("unknown svm type.\n"); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } else if(strcmp(cmd,"kernel_type")==0) { fscanf(fp,"%80s",cmd); int i; for(i=0;kernel_type_table[i];i++) { if(strcmp(kernel_type_table[i],cmd)==0) { param.kernel_type=i; break; } } if(kernel_type_table[i] == NULL) { REprintf("unknown kernel function.\n"); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } else if(strcmp(cmd,"degree")==0) fscanf(fp,"%d",¶m.degree); else if(strcmp(cmd,"gamma")==0) fscanf(fp,"%lf",¶m.gamma); else if(strcmp(cmd,"coef0")==0) fscanf(fp,"%lf",¶m.coef0); else if(strcmp(cmd,"nr_class")==0) fscanf(fp,"%d",&model->nr_class); else if(strcmp(cmd,"total_sv")==0) fscanf(fp,"%d",&model->l); else if(strcmp(cmd,"rho")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->rho = Malloc(double,n); for(int i=0;irho[i]); } else if(strcmp(cmd,"label")==0) { int n = model->nr_class; model->label = Malloc(int,n); for(int i=0;ilabel[i]); } else if(strcmp(cmd,"probA")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probA = Malloc(double,n); for(int i=0;iprobA[i]); } else if(strcmp(cmd,"probB")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probB = Malloc(double,n); for(int i=0;iprobB[i]); } else if(strcmp(cmd,"nr_sv")==0) { int n = model->nr_class; model->nSV = Malloc(int,n); for(int i=0;inSV[i]); } else if(strcmp(cmd,"SV")==0) { while(1) { int c = getc(fp); if(c==EOF || c=='\n') break; } break; } else { REprintf("unknown text in model file: [%s]\n",cmd); setlocale(LC_ALL, old_locale); free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; } } // read sv_coef and SV int elements = 0; long pos = ftell(fp); max_line_len = 1024; line = Malloc(char,max_line_len); char *p,*endptr,*idx,*val; while(readline(fp)!=NULL) { p = strtok(line,":"); while(1) { p = strtok(NULL,":"); if(p == NULL) break; ++elements; } } elements += model->l; fseek(fp,pos,SEEK_SET); int m = model->nr_class - 1; int l = model->l; model->sv_coef = Malloc(double *,m); int i; for(i=0;isv_coef[i] = Malloc(double,l); model->SV = Malloc(svm_node*,l); svm_node *x_space = NULL; if(l>0) x_space = Malloc(svm_node,elements); int j=0; for(i=0;iSV[i] = &x_space[j]; p = strtok(line, " \t"); model->sv_coef[0][i] = strtod(p,&endptr); for(int k=1;ksv_coef[k][i] = strtod(p,&endptr); } while(1) { idx = strtok(NULL, ":"); val = strtok(NULL, " \t"); if(val == NULL) break; x_space[j].index = (int) strtol(idx,&endptr,10); x_space[j].value = strtod(val,&endptr); ++j; } x_space[j++].index = -1; } free(line); setlocale(LC_ALL, old_locale); free(old_locale); if (ferror(fp) != 0 || fclose(fp) != 0) return NULL; model->free_sv = 1; // XXX return model; } void svm_free_model_content(svm_model* model_ptr) { if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL) free((void *)(model_ptr->SV[0])); if(model_ptr->sv_coef) { for(int i=0;inr_class-1;i++) free(model_ptr->sv_coef[i]); } free(model_ptr->SV); model_ptr->SV = NULL; free(model_ptr->sv_coef); model_ptr->sv_coef = NULL; free(model_ptr->rho); model_ptr->rho = NULL; free(model_ptr->label); model_ptr->label= NULL; free(model_ptr->probA); model_ptr->probA = NULL; free(model_ptr->probB); model_ptr->probB= NULL; free(model_ptr->sv_indices); model_ptr->sv_indices = NULL; free(model_ptr->nSV); model_ptr->nSV = NULL; } void svm_free_and_destroy_model(svm_model** model_ptr_ptr) { if(model_ptr_ptr != NULL && *model_ptr_ptr != NULL) { svm_free_model_content(*model_ptr_ptr); free(*model_ptr_ptr); *model_ptr_ptr = NULL; } } void svm_destroy_param(svm_parameter* param) { free(param->weight_label); free(param->weight); } const char *svm_check_parameter(const svm_problem *prob, const svm_parameter *param) { // svm_type int svm_type = param->svm_type; if(svm_type != C_SVC && svm_type != NU_SVC && svm_type != ONE_CLASS && svm_type != EPSILON_SVR && svm_type != NU_SVR) return "unknown svm type"; // kernel_type, degree int kernel_type = param->kernel_type; if(kernel_type != LINEAR && kernel_type != POLY && kernel_type != RBF && kernel_type != SIGMOID && kernel_type != PRECOMPUTED) return "unknown kernel type"; if(param->gamma < 0) return "gamma < 0"; if(param->degree < 0) return "degree of polynomial kernel < 0"; // cache_size,eps,C,nu,p,shrinking if(param->cache_size <= 0) return "cache_size <= 0"; if(param->eps <= 0) return "eps <= 0"; if(svm_type == C_SVC || svm_type == EPSILON_SVR || svm_type == NU_SVR) if(param->C <= 0) return "C <= 0"; if(svm_type == NU_SVC || svm_type == ONE_CLASS || svm_type == NU_SVR) if(param->nu <= 0 || param->nu > 1) return "nu <= 0 or nu > 1"; if(svm_type == EPSILON_SVR) if(param->p < 0) return "p < 0"; if(param->shrinking != 0 && param->shrinking != 1) return "shrinking != 0 and shrinking != 1"; if(param->probability != 0 && param->probability != 1) return "probability != 0 and probability != 1"; if(param->probability == 1 && svm_type == ONE_CLASS) return "one-class SVM probability output not supported yet"; // check whether nu-svc is feasible if(svm_type == NU_SVC) { int l = prob->l; int max_nr_class = 16; int nr_class = 0; int *label = Malloc(int,max_nr_class); int *count = Malloc(int,max_nr_class); int i; for(i=0;iy[i]; int j; for(j=0;jnu*(n1+n2)/2 > min(n1,n2)) { free(label); free(count); return "specified nu is infeasible"; } } } free(label); free(count); } return NULL; } int svm_check_probability_model(const svm_model *model) { return ((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) && model->probA!=NULL && model->probB!=NULL) || ((model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) && model->probA!=NULL); } void svm_set_print_string_function(void (*print_func)(const char *)) { if(print_func == NULL) svm_print_string = &print_string_stdout; else svm_print_string = print_func; } e1071/NAMESPACE0000644000175100001440000000306712547046401012255 0ustar hornikusersuseDynLib(e1071) import(graphics) import(grDevices) import(stats) importFrom("methods", "as", "getClass", "new") importFrom("class", "knn", "knn1") if(getRversion() >= "2.5.0") importFrom("utils", "write.table") export(ddiscrete, pdiscrete, qdiscrete, rdiscrete, bclust, hclust.bclust, centers.bclust, clusters.bclust, bincombinations, bootstrap.lca, classAgreement, cmeans, countpattern, cshell, element, fclustIndex, hamming.distance, hamming.window, hanning.window, ica, impute, interpolate, kurtosis, lca, matchControls, matchClasses, compareMatchedClasses, moment, naiveBayes, permutations, rbridge, read.matrix.csr, write.matrix.csr, rectangle.window, rwiener, allShortestPaths, extractPath, sigmoid, dsigmoid, d2sigmoid, skewness, stft, svm, tune, tune.control, write.svm, probplot, hsv_palette) exportPattern("tune\\..+", "best\\..+") S3method(boxplot, bclust) S3method(lines, probplot) S3method(naiveBayes, default) S3method(naiveBayes, formula) S3method(summary, lca) S3method(summary, svm) S3method(summary, tune) S3method(plot, bclust) S3method(plot, ica) S3method(plot, stft) S3method(plot, svm) S3method(plot, tune) S3method(predict, lca) S3method(predict, naiveBayes) S3method(predict, svm) S3method(print, bootstrap.lca) S3method("print", "fclust") S3method(print, ica) S3method(print, lca) S3method(print, summary.lca) S3method(print, naiveBayes) S3method(print, svm) S3method(print, summary.svm) S3method(print, tune) S3method(print, summary.tune) S3method(svm, default) S3method(svm, formula) e1071/R/0000755000175100001440000000000012560362404011230 5ustar hornikuserse1071/R/hamming.window.R0000644000175100001440000000023111400421345014265 0ustar hornikusershamming.window <- function (n) { if (n == 1) c <- 1 else { n <- n-1 c <- 0.54 - 0.46*cos(2*pi*(0:n)/n) } return(c) } e1071/R/interpolate.R0000644000175100001440000000364211400421345013676 0ustar hornikusersinterpolate <- function(x, a, adims=lapply(dimnames(a), as.numeric), method="linear"){ if(is.vector(x)) x<- matrix(x, ncol=length(x)) if(!is.array(a)) stop("a is not an array") ad <- length(dim(a)) method <- pmatch(method, c("linear", "constant")) if (is.na(method)) stop("invalid interpolation method") if(any(unlist(lapply(adims, diff))<0)) stop("dimensions of a not ordered") retval <- rep(0, nrow(x)) bincombi <- bincombinations(ad) convexcoeff <- function(x, y) { ok <- y>0 x[ok] <- y[ok]-x[ok] x } for(n in 1:nrow(x)){ ## the "leftmost" corner of the enclosing hypercube leftidx <- rep(0, ad) xabstand <- rep(0, ad) aabstand <- rep(0, ad) for(k in 1:ad){ if(x[n,k] < min(adims[[k]]) || x[n,k] > max(adims[[k]])) stop("No extrapolation allowed") else{ leftidx[k] <- max(seq(adims[[k]])[adims[[k]] <= x[n,k]]) ## if at the right border, go one step to the left if(leftidx[k] == length(adims[[k]])) leftidx[k] <- leftidx[k] - 1 xabstand[k] <- x[n,k] - adims[[k]][leftidx[k]] aabstand[k] <- adims[[k]][leftidx[k]+1] - adims[[k]][leftidx[k]] } } coefs <- list() if(method==1){ for(k in 1:(2^ad)){ retval[n] <- retval[n] + element(a, leftidx+bincombi[k,]) * prod((aabstand- convexcoeff(xabstand, aabstand*bincombi[k,]))/aabstand) } } else if(method==2){ retval[n] <- element(a, leftidx) } } names(retval) <- rownames(x) retval } e1071/R/sigmoid.R0000644000175100001440000000023311400421345012774 0ustar hornikuserssigmoid <- function(x) 1/(1 + exp(-x)) dsigmoid <- function(x) sigmoid(x) * (1 - sigmoid(x)) d2sigmoid <- function(x) dsigmoid(x) * (1 - 2 * sigmoid(x)) e1071/R/rwiener.R0000644000175100001440000000022311400421345013013 0ustar hornikusersrwiener <- function(end=1, frequency=1000) { z<-cumsum(rnorm(end*frequency)/sqrt(frequency)) ts(z, start=1/frequency, frequency=frequency) } e1071/R/impute.R0000644000175100001440000000060711400421345012651 0ustar hornikusersimpute <- function(x, what=c("median", "mean")){ what <- match.arg(what) if(what == "median"){ retval <- apply(x, 2, function(z) {z[is.na(z)] <- median(z, na.rm=TRUE); z}) } else if(what == "mean"){ retval <- apply(x, 2, function(z) {z[is.na(z)] <- mean(z, na.rm=TRUE); z}) } retval } e1071/R/naiveBayes.R0000644000175100001440000001074412375105122013443 0ustar hornikusersnaiveBayes <- function(x, ...) UseMethod("naiveBayes") naiveBayes.default <- function(x, y, laplace = 0, ...) { call <- match.call() Yname <- deparse(substitute(y)) x <- as.data.frame(x) ## estimation-function est <- function(var) if (is.numeric(var)) { cbind(tapply(var, y, mean, na.rm = TRUE), tapply(var, y, sd, na.rm = TRUE)) } else { tab <- table(y, var) (tab + laplace) / (rowSums(tab) + laplace * nlevels(var)) } ## create tables apriori <- table(y) tables <- lapply(x, est) ## fix dimname names for (i in 1:length(tables)) names(dimnames(tables[[i]])) <- c(Yname, colnames(x)[i]) names(dimnames(apriori)) <- Yname structure(list(apriori = apriori, tables = tables, levels = levels(y), call = call ), class = "naiveBayes" ) } naiveBayes.formula <- function(formula, data, laplace = 0, ..., subset, na.action = na.pass) { call <- match.call() Yname <- as.character(formula[[2]]) if (is.data.frame(data)) { ## handle formula m <- match.call(expand.dots = FALSE) m$... <- NULL m$laplace = NULL m$na.action <- na.action m[[1]] <- as.name("model.frame") m <- eval(m, parent.frame()) Terms <- attr(m, "terms") if (any(attr(Terms, "order") > 1)) stop("naiveBayes cannot handle interaction terms") Y <- model.extract(m, "response") X <- m[,-attr(Terms, "response"), drop = FALSE] return(naiveBayes(X, Y, laplace = laplace, ...)) } else if (is.array(data)) { nam <- names(dimnames(data)) ## Find Class dimension Yind <- which(nam == Yname) ## Create Variable index deps <- strsplit(as.character(formula)[3], ".[+].")[[1]] if (length(deps) == 1 && deps == ".") deps <- nam[-Yind] Vind <- which(nam %in% deps) ## create tables apriori <- margin.table(data, Yind) tables <- lapply(Vind, function(i) (margin.table(data, c(Yind, i)) + laplace) / (as.numeric(apriori) + laplace * dim(data)[i])) names(tables) <- nam[Vind] structure(list(apriori = apriori, tables = tables, levels = names(apriori), call = call ), class = "naiveBayes" ) } else stop("naiveBayes formula interface handles data frames or arrays only") } print.naiveBayes <- function(x, ...) { cat("\nNaive Bayes Classifier for Discrete Predictors\n\n") cat("Call:\n") print(x$call) cat("\nA-priori probabilities:\n") print(x$apriori / sum(x$apriori)) cat("\nConditional probabilities:\n") for (i in x$tables) {print(i); cat("\n")} } predict.naiveBayes <- function(object, newdata, type = c("class", "raw"), threshold = 0.001, eps = 0, ...) { type <- match.arg(type) newdata <- as.data.frame(newdata) attribs <- match(names(object$tables), names(newdata)) isnumeric <- sapply(newdata, is.numeric) newdata <- data.matrix(newdata) L <- sapply(1:nrow(newdata), function(i) { ndata <- newdata[i, ] L <- log(object$apriori) + apply(log(sapply(seq_along(attribs), function(v) { nd <- ndata[attribs[v]] if (is.na(nd)) rep(1, length(object$apriori)) else { prob <- if (isnumeric[attribs[v]]) { msd <- object$tables[[v]] msd[, 2][msd[, 2] <= eps] <- threshold dnorm(nd, msd[, 1], msd[, 2]) } else object$tables[[v]][, nd] prob[prob <= eps] <- threshold prob } })), 1, sum) if (type == "class") L else { ## Numerically unstable: ## L <- exp(L) ## L / sum(L) ## instead, we use: sapply(L, function(lp) { 1/sum(exp(L - lp)) }) } }) if (type == "class") factor(object$levels[apply(L, 2, which.max)], levels = object$levels) else t(L) } e1071/R/cmeans.R0000644000175100001440000001140711400421345012614 0ustar hornikuserscmeans <- function(x, centers, iter.max = 100, verbose = FALSE, dist = "euclidean", method = "cmeans", m = 2, rate.par = NULL, weights = 1, control = list()) { x <- as.matrix(x) xrows <- nrow(x) xcols <- ncol(x) if(missing(centers)) stop("Argument 'centers' must be a number or a matrix.") dist <- pmatch(dist, c("euclidean", "manhattan")) if(is.na(dist)) stop("invalid distance") if(dist == -1) stop("ambiguous distance") method <- pmatch(method, c("cmeans", "ufcl")) if(is.na(method)) stop("invalid clustering method") if(method == -1) stop("ambiguous clustering method") if(length(centers) == 1) { ncenters <- centers centers <- x[sample(1 : xrows, ncenters), , drop = FALSE] if(any(duplicated(centers))) { cn <- unique(x) mm <- nrow(cn) if(mm < ncenters) stop("More cluster centers than distinct data points.") centers <- cn[sample(1 : mm, ncenters), , drop = FALSE] } } else { centers <- as.matrix(centers) if(any(duplicated(centers))) stop("Initial centers are not distinct.") cn <- NULL ncenters <- nrow(centers) if (xrows < ncenters) stop("More cluster centers than data points.") } if(xcols != ncol(centers)) stop("Must have same number of columns in 'x' and 'centers'.") if(iter.max < 1) stop("Argument 'iter.max' must be positive.") if(method == 2) { if(missing(rate.par)) { rate.par <- 0.3 } } reltol <- control$reltol if(is.null(reltol)) reltol <- sqrt(.Machine$double.eps) if(reltol <= 0) stop("Control parameter 'reltol' must be positive.") if(any(weights < 0)) stop("Argument 'weights' has negative elements.") if(!any(weights > 0)) stop("Argument 'weights' has no positive elements.") weights <- rep(weights, length = xrows) weights <- weights / sum(weights) ## ## Do we really want to do this? perm <- sample(xrows) x <- x[perm, ] weights <- weights[perm] ## initcenters <- centers pos <- as.factor(1 : ncenters) rownames(centers) <- pos if(method == 1) { retval <- .C("cmeans", as.double(x), as.integer(xrows), as.integer(xcols), centers = as.double(centers), as.integer(ncenters), as.double(weights), as.double(m), as.integer(dist - 1), as.integer(iter.max), as.double(reltol), as.integer(verbose), u = double(xrows * ncenters), ermin = double(1), iter = integer(1), PACKAGE = "e1071") } else if(method == 2) { retval <- .C("ufcl", x = as.double(x), as.integer(xrows), as.integer(xcols), centers = as.double(centers), as.integer(ncenters), as.double(weights), as.double(m), as.integer(dist - 1), as.integer(iter.max), as.double(reltol), as.integer(verbose), as.double(rate.par), u = double(xrows * ncenters), ermin = double(1), iter = integer(1), PACKAGE = "e1071") } centers <- matrix(retval$centers, ncol = xcols, dimnames = list(1 : ncenters, colnames(initcenters))) u <- matrix(retval$u, ncol = ncenters, dimnames = list(rownames(x), 1 : ncenters)) u <- u[order(perm), ] iter <- retval$iter - 1 withinerror <- retval$ermin cluster <- apply(u, 1, which.max) clustersize <- as.integer(table(cluster)) retval <- list(centers = centers, size = clustersize, cluster = cluster, membership = u, iter = iter, withinerror = withinerror, call = match.call()) class(retval) <- c("fclust") return(retval) } print.fclust <- function(x, ...) { cat("Fuzzy c-means clustering with", length(x$size), "clusters\n") cat("\nCluster centers:\n") print(x$centers, ...) cat("\nMemberships:\n") print(x$membership, ...) cat("\nClosest hard clustering:\n") print(x$cluster, ...) cat("\nAvailable components:\n") print(names(x), ...) invisible(x) } e1071/R/fclustIndex.R0000644000175100001440000001461212052476443013654 0ustar hornikusersfclustIndex <- function ( y, x, index= "all" ) { clres <- y ########################################################################### ################SESSION 1: MEASURES######################################### ########################################################################### gath.geva <- function (clres,x)#for m=2 { xrows <- dim(clres$me)[1] xcols <- dim(clres$ce)[2] ncenters <- dim(clres$centers)[1] scatter <- array(0.0, c(xcols, xcols, ncenters)) scatternew <- array(0.0, c(xcols, xcols, ncenters)) fhv <-as.double(0) apd <-as.double(0) pd <- as.double(0) control <- as.double(0) for (i in 1:ncenters){ paronomastis <- as.double(0) paronomastis2 <- as.double(0) for (j in 1:xrows){ paronomastis <- paronomastis+clres$me[j,i] diff <- x[j,]-clres$ce[i,] scatternew[,,i] <- clres$me[j,i]*(t(t(diff))%*%t(diff)) scatter[,,i] <- scatter[,,i]+scatternew[,,i] }#xrows scatter[,,i] <- scatter[,,i]/paronomastis for (j in 1:xrows){ diff <- x[j,]-clres$ce[i,] control <- (t(diff)%*%solve(scatter[,,i]))%*%t(t(diff)) if (control<1.0) paronomastis2 <- paronomastis2+clres$me[j,i] ## else ## cat("...") }#xrows fhv <- fhv+sqrt(det(scatter[,,i])) apd <- apd+paronomastis2/sqrt(det(scatter[,,i])) pd <- pd+paronomastis2 }#ncenters pd <- pd/fhv apd <- apd/ncenters retval <- list(fuzzy.hypervolume=fhv,average.partition.density=apd, partition.density=pd) return(retval) } xie.beni <- function(clres){#for all m xrows <- dim(clres$me)[1] minimum<--1 error <- clres$within#sd ncenters <- dim(clres$centers)[1] for (i in 1:(ncenters-1)){ for (j in (i+1):ncenters){ diff<- clres$ce[i,]-clres$ce[j,] diffdist <- t(diff)%*%t(t(diff)) if (minimum==-1) minimum <- diffdist if (diffdist=1000) probs <- c(0.001, probs, .999) } qprobs <- QFUN(probs) plot(x, y, axes=FALSE, type="n", ylim=range(c(y,qprobs)), xlab=xlab, ylab=ylab) box() abline(h=qprobs, col="grey") axis(1) axis(2, at=qprobs, labels=100*probs) points(x, y) QTEXT <- paste("Quantile: ", QNAME, sep="") if(nchar(DOTARGS)) QTEXT <- paste(QTEXT, DOTARGS, sep=", ") mtext(QTEXT, side=1, line=3, adj=1) xl <- quantile(x, c(0.25, 0.75)) yl <- qdist(c(0.25, 0.75), ...) slope <- diff(yl)/diff(xl) int <- yl[1] - slope * xl[1] if(line){ abline(int, slope, col="red") } z <- list(qdist=QFUN, int=int, slope=slope) class(z) <- "probplot" invisible(z) } lines.probplot <- function(x, h=NULL, v=NULL, bend=FALSE, ...) { if(is.null(h) & is.null(v)){ abline(x$int, x$slope, ...) } pu <- par("usr") if(!is.null(h)){ h <- x$qdist(h) if(!bend){ abline(h=h, ...) } else{ v <- c(v, (h-x$int)/x$slope) } } if(!is.null(v)){ if(!bend){ abline(v=v, ...) } else{ h <- v*x$slope+x$int segments(v, pu[3], v, h, ...) segments(pu[1], h, v, h, ...) } } } e1071/R/rectangle.window.R0000644000175100001440000000005611400421345014616 0ustar hornikusersrectangle.window <- function (n) rep (1, n) e1071/R/matchClasses.R0000644000175100001440000001504012520201245013754 0ustar hornikusersclassAgreement <- function (tab, match.names=FALSE) { n <- sum(tab) ni <- apply(tab, 1, sum) nj <- apply(tab, 2, sum) ## patch for matching factors if (match.names && !is.null(dimnames(tab))) { lev <- intersect (colnames (tab), rownames(tab)) p0 <- sum(diag(tab[lev,lev]))/n pc <- sum(ni[lev] * nj[lev])/n^2 } else { # cutoff larger dimension m <- min(length(ni), length(nj)) p0 <- sum(diag(tab[1:m, 1:m]))/n pc <- sum((ni[1:m] / n) * (nj[1:m] / n)) } n2 <- choose(n, 2) rand <- 1 + (sum(tab^2) - (sum(ni^2) + sum(nj^2))/2)/n2 nis2 <- sum(choose(ni[ni > 1], 2)) njs2 <- sum(choose(nj[nj > 1], 2)) crand <- (sum(choose(tab[tab > 1], 2)) - (nis2 * njs2)/n2)/((nis2 + njs2)/2 - (nis2 * njs2)/n2) list(diag = p0, kappa = (p0 - pc)/(1 - pc), rand = rand, crand = crand) } matchClasses <- function(tab, method = "rowmax", iter=1, maxexact=9, verbose=TRUE){ methods <- c("rowmax", "greedy", "exact") method <- pmatch(method, methods) rmax <- apply(tab,1,which.max) myseq <- 1:ncol(tab) cn <- colnames(tab) rn <- rownames(tab) if(is.null(cn)){ cn <- myseq } if(is.null(rn)){ rn <- myseq } if(method==1){ retval <- rmax } if(method==2 | method==3){ if(ncol(tab)!=nrow(tab)){ stop("Unique matching only for square tables.") } dimnames(tab) <- list(myseq, myseq) cmax <- apply(tab,2,which.max) retval <- rep(NA, ncol(tab)) names(retval) <- colnames(tab) baseok <- cmax[rmax]==myseq for(k in myseq[baseok]){ therow <- (tab[k,])[-rmax[k]] thecol <- (tab[, rmax[k]])[-k] if(max(outer(therow, thecol, "+")) < tab[k, rmax[k]]){ retval[k] <- rmax[k] } else{ baseok[k] <- FALSE } } if(verbose){ cat("Direct agreement:", sum(baseok), "of", ncol(tab), "pairs\n") } if(!all(baseok)){ if(method==3){ if(sum(!baseok)>maxexact){ method <- 2 warning(paste("Would need permutation of", sum(!baseok), "numbers, resetting to greedy search\n")) } else{ iter <- gamma(ncol(tab)-sum(baseok)+1) if(verbose){ cat("Iterations for permutation matching:", iter, "\n") } perm <- permutations(ncol(tab)-sum(baseok)) } } ## rest for permute matching if(any(baseok)){ rest <- myseq[-retval[baseok]] } else{ rest <- myseq } for(l in 1:iter){ newretval <- retval if(method == 2){ ok <- baseok while(sum(!ok)>1){ rest <- myseq[!ok] k <- sample(rest, 1) if(any(ok)){ rmax <- tab[k, -newretval[ok]] } else{ rmax <- tab[k,] } newretval[k] <- as.numeric(names(rmax)[which.max(rmax)]) ok[k] <- TRUE } newretval[!ok] <- myseq[-newretval[ok]] } else{ newretval[!baseok] <- rest[perm[l,]] } if(l>1){ agree <- sum(diag(tab[,newretval]))/sum(tab) if(agree>oldagree){ retval <- newretval oldagree <- agree } } else{ retval <- newretval agree <- oldagree <- sum(diag(tab[,newretval]))/sum(tab) } } } } if(verbose){ cat("Cases in matched pairs:", round(100*sum(diag(tab[,retval]))/sum(tab), 2), "%\n") } if(any(as.character(myseq)!=cn)){ retval <- cn[retval] } names(retval) <- rn retval } compareMatchedClasses <- function(x, y, method="rowmax", iter=1, maxexact=9, verbose=FALSE) { if(missing(y)){ retval <- list(diag=matrix(NA, nrow=ncol(x), ncol=ncol(x)), kappa=matrix(NA, nrow=ncol(x), ncol=ncol(x)), rand=matrix(NA, nrow=ncol(x), ncol=ncol(x)), crand=matrix(NA, nrow=ncol(x), ncol=ncol(x))) for(k in 1:(ncol(x)-1)){ for(l in (k+1):ncol(x)){ tab <- table(x[,k], x[,l]) m <- matchClasses(tab, method=method, iter=iter, verbose=verbose, maxexact=maxexact) a <- classAgreement(tab[,m]) retval$diag[k,l] <- a$diag retval$kappa[k,l] <- a$kappa retval$rand[k,l] <- a$rand retval$crand[k,l] <- a$crand } } } else{ x <- as.matrix(x) y <- as.matrix(y) retval <- list(diag=matrix(NA, nrow=ncol(x), ncol=ncol(y)), kappa=matrix(NA, nrow=ncol(x), ncol=ncol(y)), rand=matrix(NA, nrow=ncol(x), ncol=ncol(y)), crand=matrix(NA, nrow=ncol(x), ncol=ncol(y))) for(k in 1:ncol(x)){ for(l in 1:ncol(y)){ tab <- table(x[,k], y[,l]) m <- matchClasses(tab, method=method, iter=iter, verbose=verbose, maxexact=maxexact) a <- classAgreement(tab[,m]) retval$diag[k,l] <- a$diag retval$kappa[k,l] <- a$kappa retval$rand[k,l] <- a$rand retval$crand[k,l] <- a$crand } } } retval } permutations <- function(n) { if(n ==1) return(matrix(1)) else if(n<2) stop("n must be a positive integer") z <- matrix(1) for (i in 2:n) { x <- cbind(z, i) a <- c(1:i, 1:(i - 1)) z <- matrix(0, ncol=ncol(x), nrow=i*nrow(x)) z[1:nrow(x),] <- x for (j in 2:i-1) { z[j*nrow(x)+1:nrow(x),] <- x[, a[1:i+j]] } } dimnames(z) <- NULL z } e1071/R/sparse.R0000644000175100001440000000374312374611431012657 0ustar hornikusersread.matrix.csr <- function(file, fac = TRUE, ncol = NULL) { l <- strsplit(readLines(file), "[ ]+") ## extract y-values, if any y <- if (is.na(l[[1]][1]) || length(grep(":",l[[1]][1]))) NULL else sapply(l, function(x) x[1]) ## x-values rja <- do.call("rbind", lapply(l, function(x) do.call("rbind", strsplit(if (is.null(y)) x else x[-1], ":") ) ) ) ja <- as.integer(rja[,1]) ia <- cumsum(c(1, sapply(l, length) - !is.null(y))) max.ja <- max(ja) dimension <- c(length(l), if (is.null(ncol)) max.ja else max(ncol, max.ja)) x = new(getClass("matrix.csr", where = asNamespace("SparseM")), ra = as.numeric(rja[,2]), ja = ja, ia = as.integer(ia), dimension = as.integer(dimension)) if (length(y)) list(x = x, y = if (fac) as.factor(y) else as.numeric(y)) else x } write.matrix.csr <- function (x, file = "out.dat", y = NULL, fac = TRUE) { on.exit(sink()) x <- SparseM::as.matrix.csr(x) if (!is.null(y) & (length(y) != nrow(x))) stop(paste("Length of y (=", length(y), ") does not match number of rows of x (=", nrow(x), ")!", sep="")) sink(file) l <- length(x@ra) zerocols <- all(x@ja < ncol(x)) if (!is.null(y) && is.factor(y) && fac) y <- as.character(y) for (i in 1:nrow(x)) { if (!is.null(y)) cat (y[i],"") if ((x@ia[i] <= l) && (x@ia[i] < x@ia[i + 1])) { for (j in x@ia[i] : (x@ia[i + 1] - 1)) cat(x@ja[j], ":", x@ra[j], " ", sep="") if (zerocols) { cat(ncol(x), ":", 0, " ", sep="") zerocols <- FALSE } } cat("\n") } } na.fail.matrix.csr <- function(object, ...) { if (any(is.na(object@ra))) stop("missing values in object") else return(object) } e1071/R/bincombinations.R0000644000175100001440000000034311633216751014534 0ustar hornikusers## Kopie in mlbench bincombinations <- function(p) { retval <- matrix(0, nrow=2^p, ncol=p) for(n in 1:p){ retval[,n] <- rep(c(rep(0, (2^p/2^n)), rep(1, (2^p/2^n))), length=2^p) } retval } e1071/R/moment.R0000644000175100001440000000033711400421345012645 0ustar hornikusersmoment <- function(x, order = 1, center = FALSE, absolute = FALSE, na.rm = FALSE) { if (na.rm) x <- x[!is.na(x)] if (center) x <- x - mean(x) if (absolute) x <- abs(x) sum(x ^ order) / length(x) } e1071/R/cshell.R0000644000175100001440000001500111400421345012612 0ustar hornikuserscshell <- function (x, centers, iter.max = 100, verbose = FALSE, dist = "euclidean", method = "cshell", m=2, radius= NULL) { x <- as.matrix(x) xrows <- dim(x)[1] xcols <- dim(x)[2] xold <- x perm <- sample(xrows) x <- x[perm, ] ## initial values are given if (is.matrix(centers)) ncenters <- dim(centers)[1] else { ## take centers random vectors as initial values ncenters <- centers centers <- x[rank(runif(xrows))[1:ncenters], ]+0.001 } ## initialize radius if (missing(radius)) radius <- rep(0.2,ncenters) else radius <- as.double(radius) dist <- pmatch(dist, c("euclidean", "manhattan")) if (is.na(dist)) stop("invalid distance") if (dist == -1) stop("ambiguous distance") method <- pmatch(method, c("cshell")) if (is.na(method)) stop("invalid clustering method") if (method == -1) stop("ambiguous clustering method") initcenters <- centers ## dist <- matrix(0, xrows, ncenters) ## necessary for empty clusters pos <- as.factor(1 : ncenters) rownames(centers) <- pos iter <- integer(1) flag <- integer(1) retval <- .C("cshell", xrows = as.integer(xrows), xcols = as.integer(xcols), x = as.double(x), ncenters = as.integer(ncenters), centers = as.double(centers), iter.max = as.integer(iter.max), iter = as.integer(iter), verbose = as.integer(verbose), dist = as.integer(dist-1), U = double(xrows*ncenters), UANT = double(xrows*ncenters), m = as.double(m), ermin = double(1), radius = as.double(radius), flag = as.integer(flag), PACKAGE = "e1071") centers <- matrix(retval$centers, ncol = xcols, dimnames = dimnames(initcenters)) radius <- as.double(retval$radius) U <- retval$U U <- matrix(U, ncol=ncenters) UANT <- retval$UANT UANT <- matrix(UANT, ncol=ncenters) iter <- retval$iter flag <- as.integer(retval$flag) ## Optimization part while (((flag == 1) || (flag==4)) && (iter<=iter.max)) { flag <- 3 system <- function (spar=c(centers,radius), x, U, m, i) { k <- dim(x)[1] d <- dim(x)[2] nparam<-length(spar) v<-spar[1:(nparam-1)] r<-spar[nparam] ##distance matrix x_k - v_i distmat <- t(t(x)-v) ##norm from x_k - v_i normdist <- distmat[,1]^2 for (j in 2:d) normdist<-normdist+distmat[,j]^2 normdist <- sqrt(normdist) ##equation 5 op <- sum( (U[,i]^m) * (normdist-r) )^2 ##equation 4 equationmatrix <- ((U[,i]^m) * (1-r/normdist))*distmat ## ## This had just apply(), but optim() really needs a scalar ## fn. ## What do we really want here? op<- op+sum(apply(equationmatrix, 2, sum)^2) ## } for (i in 1:ncenters) { spar <- c(centers[i,],radius[i]) npar <- length(spar) optimres <- optim(spar, system, method="CG", x=x, U=U, m=m, i=i) centers[i,] <- optimres$par[1:(npar-1)] radius[i] <- optimres$par[npar] } retval <- .C("cshell", xrows = as.integer(xrows), xcols = as.integer(xcols), x = as.double(x), ncenters = as.integer(ncenters), centers = as.double(centers), iter.max = as.integer(iter.max), iter = as.integer(iter-1), verbose = as.integer(verbose), dist = as.integer(dist-1), U = as.double(U), UANT = as.double(UANT), m = as.double(m), ermin = double(1), radius = as.double(radius), flag = as.integer(flag), PACKAGE = "e1071") flag<-retval$flag if (retval$flag!=2) flag<-1 centers <- matrix(retval$centers, ncol = xcols, dimnames = dimnames(initcenters)) radius <- as.double(retval$radius) U <- retval$U U <- matrix(U, ncol=ncenters) UANT <- retval$UANT UANT <- matrix(UANT, ncol=ncenters) iter <- retval$iter } centers <- matrix(retval$centers, ncol = xcols, dimnames = list(pos, colnames(initcenters))) U <- matrix(retval$U, ncol = ncenters, dimnames = list(rownames(x), 1 : ncenters)) U <- U[order(perm),] clusterU <- apply(U, 1, which.max) clustersize <- as.integer(table(clusterU)) radius <- as.double(retval$radius) retval <- list(centers = centers, radius=radius, size = clustersize, cluster = clusterU, iter = retval$iter - 1, membership=U, withinerror = retval$ermin, call = match.call()) class(retval) <- c("cshell", "fclust") return(retval) } #predict.cshell <- function( clobj, x){ # xrows<-dim(x)[1] # xcols<-dim(x)[2] # ncenters <- clobj$ncenters # cluster <- integer(xrows) # clustersize <- integer(ncenters) # f <- clobj$m # radius <- clobj$radius # if(dim(clobj$centers)[2] != xcols){ # stop("Number of variables in cluster object and x are not the same!") # } # retval <- .C("cshell_assign", # xrows = as.integer(xrows), # xcols = as.integer(xcols), # x = as.double(x), # ncenters = as.integer(ncenters), # centers = as.double(clobj$centers), # dist = as.integer(clobj$dist-1), # U = double(xrows*ncenters), # f = as.double(f), # radius = as.double(radius)) # U <- retval$U # U <- matrix(U, ncol=ncenters) # clusterU <- apply(U,1,which.max) # clustersize <- as.integer(table(clusterU)) # clobj$iter <- NULL # clobj$cluster <- clusterU # clobj$size <- retval$clustersize # clobj$membership <- U # return(clobj) #} e1071/R/element.R0000644000175100001440000000050611400421345012775 0ustar hornikuserselement <- function(x, i) { if(!is.array(x)) stop("x is not an array") ni <- length(i) dx <- dim(x) if(length(i)!=length(dx)) stop("Wrong number of subscripts") if(ni==1){ return(x[i]) } else{ m1 <- c(i[1], i[2:ni]-1) m2 <- c(1,cumprod(dx)[1:(ni-1)]) return(x[sum(m1*m2)]) } } e1071/R/discrete.R0000644000175100001440000000407511400421345013153 0ustar hornikusersrdiscrete <- function (n, probs, values = 1:length(probs), ...) { sample(values, size=n, replace=TRUE, prob=probs) } ddiscrete <- function (x, probs, values = 1:length(probs)) { if (length(probs) != length(values)) stop("ddiscrete: probs and values must have the same length.") if (sum(probs < 0) > 0) stop("ddiscrete: probs must not contain negative values.") if (!is.array(x) && !is.vector(x) && !is.factor(x)) stop("ddiscrete: x must be an array or a vector or a factor.") p <- probs/sum(probs) y <- as.vector(x) l <- length(y) z <- rep(0,l) for (i in 1:l) if (any(values == y[i])) z[i] <- p[values == y[i]] z <- as.numeric(z) if (is.array(x)) dim(z) <- dim(x) return(z) } pdiscrete <- function (q, probs, values = 1:length(probs)) { if (length(probs) != length(values)) stop("pdiscrete: probs and values must have the same length.") if (sum(probs < 0) > 0) stop("pdiscrete: probs must not contain negative values.") if (!is.array(q) & !is.vector(q)) stop("pdiscrete: q must be an array or a vector") p <- probs/sum(probs) y <- as.vector(q) l <- length(y) z <- rep(0,l) for (i in 1:l) z[i] <- sum(p[values <= y[i]]) z <- as.numeric(z) if (is.array(q)) dim(z) <- dim(q) return(z) } qdiscrete <- function (p, probs, values = 1:length(probs)) { if (length(probs) != length(values)) stop("qdiscrete: probs and values must have the same length.") if (sum(probs < 0) > 0) stop("qdiscrete: probs must not contain negative values.") if (!is.array(p) & !is.vector(p)) stop("qdiscrete: p must be an array or a vector") probs <- cumsum(probs)/sum(probs) y <- as.vector(p) l <- length(y) z <- rep(0,l) for (i in 1:l) z[i] <- length(values) - sum(y[i] <= probs) + 1 z <- as.numeric(z) z <- values[z] if (is.array(p)) dim(z) <- dim(p) return(z) } e1071/R/lca.R0000644000175100001440000001602311400421345012104 0ustar hornikuserslca <- function(x, k, niter=100, matchdata=FALSE, verbose=FALSE) { ## if x is a data matrix -> create patterns if (is.matrix(x)) { if (matchdata) { x <- countpattern(x, matching=TRUE) xmat <- x$matching x <- x$pat } else x <- countpattern(x, matching=FALSE) } else ## if no data ist given, matchdata must be FALSE matchdata <- FALSE n <- sum(x) npat <- length(x) nvar <- round(log(npat)/log(2)) ## build matrix of all possible binary vectors b <- matrix(0, 2^nvar, nvar) for (i in 1:nvar) b[, nvar+1-i] <- rep(rep(c(0,1),c(2^(i-1),2^(i-1))),2^(nvar-i)) ## initialize probabilities classprob <- runif(k) classprob <- classprob/sum(classprob) names(classprob) <- 1:k p <- matrix(runif(nvar*k), k) pas <- matrix(0, k, npat) classsize <- numeric(k) for (i in 1:niter) { for (j in 1:k) { ## P(pattern|class) mp <- t(b)*p[j,]+(1-t(b))*(1-p[j,]) pas[j,] <- drop(exp(rep(1,nvar)%*%log(mp))) # column product } ## P(pattern|class)*P(class) pas <- t(t(pas)*classprob) ## P(class|pattern) sump <- drop(rep(1,k)%*%pas) # column sums pas <- t(t(pas)/sump) spas <- t(t(pas)*x) classsize <- drop(spas%*%rep(1,npat)) # row sums classprob <- classsize/n p <- pas%*%(x*b)/classsize if (verbose) cat("Iteration:", i, "\n") } for (j in 1:k) { mp <- t(b)*p[j,]+(1-t(b))*(1-p[j,]) pas[j,] <- drop(exp(rep(1,nvar)%*%log(mp)))*classprob[j] # column product } ## LogLikelihood pmust <- drop(rep(1,k)%*%pas) # column sums ll <- sum(x*log(pmust)) ## Likelihoodquotient xg0 <- x[x>0] ll0 <- sum(xg0*log(xg0/n)) lq <- 2*(ll0-ll) ## bic bic <- -2*ll+log(n)*(k*(nvar+1)-1) bicsat <- -2*ll0+log(n)*(2^nvar-1) ## chisq ch <- sum((x-n*pmust)^2/(n*pmust)) ## P(class|pattern) sump <- drop(rep(1,k)%*%pas) # column sums pas <- t(t(pas)/sump) mat <- max.col(t(pas)) if (matchdata) mat <- mat[xmat] colnames(p) <- 1:nvar rownames(p) <- 1:k lcaresult <- list(classprob=classprob, p=p, matching=mat, logl=ll, loglsat=ll0, chisq=ch, lhquot=lq, bic=bic, bicsat=bicsat, n=n, np=(k*(nvar+1)-1), matchdata=matchdata) class(lcaresult) <- "lca" return(lcaresult) } print.lca <- function(x, ...) { cat("LCA-Result\n") cat("----------\n\n") cat("Datapoints:", x$n, "\n") cat("Classes: ", length(x$classprob), "\n") cat("Probability of classes\n") print(round(x$classprob,3)) cat("Itemprobabilities\n") print(round(x$p,2)) } summary.lca <- function(object, ...) { nvar <- ncol(object$p) object$npsat <- 2^nvar-1 object$df <- 2^nvar-1-object$np object$pvallhquot <- 1-pchisq(object$lhquot,object$df) object$pvalchisq <- 1-pchisq(object$chisq,object$df) object$k <- length(object$classprob) ## remove unnecessary list elements object$classprob <- NULL object$p <- NULL object$matching <- NULL class(object) <- "summary.lca" return(object) } print.summary.lca <- function(x, ...) { cat("LCA-Result\n") cat("----------\n\n") cat("Datapoints:", x$n, "\n") cat("Classes: ", x$k, "\n") cat("\nGoodness of fit statistics:\n\n") cat("Number of parameters, estimated model:", x$np, "\n") cat("Number of parameters, saturated model:", x$npsat, "\n") cat("Log-Likelihood, estimated model: ", x$logl, "\n") cat("Log-Likelihood, saturated model: ", x$loglsat, "\n") cat("\nInformation Criteria:\n\n") cat("BIC, estimated model:", x$bic, "\n") cat("BIC, saturated model:", x$bicsat, "\n") cat("\nTestStatistics:\n\n") cat("Likelihood ratio: ", x$lhquot, " p-val:", x$pvallhquot, "\n") cat("Pearson Chi^2: ", x$chisq, " p-val:", x$pvalchisq, "\n") cat("Degress of freedom:", x$df, "\n") } bootstrap.lca <- function(l, nsamples=10, lcaiter=30, verbose=FALSE) { n <- l$n classprob <- l$classprob nclass <- length(l$classprob) prob <- l$p nvar <- ncol(l$p) npat <- 2^nvar ## build matrix of all possible binary vectors b <- matrix(0, npat, nvar) for (i in 1:nvar) b[, nvar+1-i] <- rep(rep(c(0,1),c(2^(i-1),2^(i-1))),2^(nvar-i)) ll <- lq <- ll0 <- ch <- numeric(nsamples) for (i in 1:nsamples) { ## generate data cm <- sample(1:nclass, size=n, replace=TRUE, prob=classprob) x <- matrix(runif(n*nvar), nrow=n) x <- (xX): ", x$pvalzratio, "\n") cat("P-Val: ", x$pvalratio, "\n\n") cat("Pearson's Chisquare\n\n") cat("Mean:", x$chisqmean, "\n") cat("SDev:", x$chisqsd, "\n") cat("Value in Data Set:", x$chisqorg, "\n") cat("Z-Statistics: ", x$zchisq, "\n") cat("P(Z>X): ", x$pvalzchisq, "\n") cat("P-Val: ", x$pvalchisq, "\n\n") } predict.lca <- function(object, x, ...) { if (object$matchdata) stop("predict.lca: only possible, if lca has been called with matchdata=FALSE") else { x <- countpattern(x, matching=TRUE) return(object$matching[x$matching]) } } e1071/R/matchControls.R0000644000175100001440000000417412310166173014177 0ustar hornikusersmatchControls <- function(formula, data = list(), subset, contlabel = "con", caselabel = NULL, dogrep = TRUE, replace = FALSE) { if (system.file(package = "cluster") == "") stop("Could not load required package 'cluster'!") if (system.file(package = "stats") == "") stop("Could not load required package 'stats'!") m <- match.call() m$contlabel <- m$caselabel <- m$dogrep <- m$replace <- NULL m$na.action <- function(x) x m[[1]] <- as.name("model.frame") m1 <- eval(m, sys.frame(sys.parent())) ## the full model.frame is used only to determine the number of rows ## of the complete data frame m$subset <- NULL m2 <- eval(m, sys.frame(sys.parent())) if (dogrep) { ok <- grep(contlabel, as.character(model.response(m1))) controls <- rownames(m1)[ok] if (is.null(caselabel)) { cases <- rownames(m1)[-ok] } else { ok <- grep(caselabel, as.character(model.response(m1))) cases <- rownames(m1)[ok] } } else { controls <- rownames(m1)[model.response(m1) == contlabel] if (is.null(caselabel)){ cases <- rownames(m1)[model.response(m1) != contlabel] } else { ok <- rep(FALSE, nrow(m1)) for (l in caselabel){ ok <- ok | (model.response(m1) == l) } cases <- rownames(m1)[ok] } } d <- as.matrix(stats::as.dist(cluster::daisy(m1[,-1,drop=FALSE]))) which.is.min <- function (x) { y <- seq(length(x))[(x == min(x, na.rm = TRUE)) & !is.na(x)] if (length(y) > 1) sample(y, 1) else y } retval <- rep("", length(cases)) for (k in 1 : length(cases)) { retval[k] <- controls[which.is.min(d[cases[k], controls])] if (!replace) controls <- controls[controls != retval[k]] } fac <- rep(NA, nrow(m2)) names(fac) <- rownames(m2) fac[cases] <- "case" fac[retval] <- "cont" fac <- factor(fac) list(cases = cases, controls = retval, factor = fac) } e1071/R/hamming.distance.R0000644000175100001440000000060012505565304014563 0ustar hornikusershamming.distance <- function(x,y){ z<-NULL if(is.vector(x) && is.vector(y)){ z <- sum(x != y) } else{ z <- matrix(0,nrow=nrow(x),ncol=nrow(x)) for(k in 1:(nrow(x)-1)){ for(l in (k+1):nrow(x)){ z[k,l] <- hamming.distance(x[k,], x[l,]) z[l,k] <- z[k,l] } } dimnames(z) <- list(dimnames(x)[[1]], dimnames(x)[[1]]) } z } e1071/R/stft.R0000644000175100001440000000144611400421345012330 0ustar hornikusersstft <- function(X, win=min(80,floor(length(X)/10)), inc=min(24, floor(length(X)/30)), coef=64, wtype="hanning.window") { numcoef <- 2*coef if (win > numcoef) { win <- numcoef cat ("stft: window size adjusted to", win, ".\n") } numwin <- trunc ((length(X) - win) / inc) ## compute the windows coefficients wincoef <- eval(parse(text=wtype))(win) ## create a matrix Z whose columns contain the windowed time-slices z <- matrix (0, numwin + 1, numcoef) y <- z st <- 1 for (i in 0:numwin) { z[i+1, 1:win] <- X[st:(st+win-1)] * wincoef y[i+1,] <- fft(z[i+1,]) st <- st + inc } Y<- list (values = Mod(y[,1:coef]), windowsize=win, increment=inc, windowtype=wtype) class(Y) <- "stft" return(Y) } e1071/R/skewness.R0000644000175100001440000000105011400421345013201 0ustar hornikusersskewness <- function(x, na.rm = FALSE, type = 3) { if(any(ina <- is.na(x))) { if(na.rm) x <- x[!ina] else return(NA) } if(!(type %in% (1 : 3))) stop("Invalid 'type' argument.") n <- length(x) x <- x - mean(x) y <- sqrt(n) * sum(x ^ 3) / (sum(x ^ 2) ^ (3/2)) if(type == 2) { if(n < 3) stop("Need at least 3 complete observations.") y <- y * sqrt(n * (n - 1)) / (n - 2) } else if(type == 3) y <- y * ((1 - 1 / n)) ^ (3/2) y } e1071/R/bclust.R0000644000175100001440000001604612310166154012653 0ustar hornikusers"bclust" <- function (x, centers = 2, iter.base = 10, minsize = 0, dist.method = "euclidian", hclust.method = "average", base.method = "kmeans", base.centers = 20, verbose = TRUE, final.kmeans = FALSE, docmdscale=FALSE, resample=TRUE, weights=NULL, maxcluster=base.centers, ...) { x <- as.matrix(x) xr <- nrow(x) xc <- ncol(x) CLUSFUN <- get(base.method) object <- list(allcenters = matrix(0, ncol = xc, nrow = iter.base * base.centers), allcluster = NULL, hclust = NULL, members = NULL, cluster = NULL, centers = NULL, iter.base = iter.base, base.centers = base.centers, prcomp = NULL, datamean = apply(x, 2, mean), colnames = colnames(x), dist.method = dist.method, hclust.method = hclust.method, maxcluster = maxcluster) class(object) <- "bclust" optSEM <- getOption("show.error.messages") if(is.null(optSEM)) optSEM <- TRUE on.exit(options(show.error.messages = optSEM)) if (verbose) cat("Committee Member:") for (n in 1:iter.base) { if (verbose){ cat(" ", n, sep = "") } if(resample){ x1 <- x[sample(xr, replace = TRUE, prob=weights), ] } else{ x1 <- x } for(m in 1:20){ if(verbose) cat("(",m,")",sep="") options(show.error.messages = FALSE) tryres <- try(CLUSFUN(x1, centers = base.centers, ...)) if(!inherits(tryres, "try-error")) break } options(show.error.messages = optSEM) if(m==20) stop("Could not find valid cluster solution in 20 replications\n") object$allcenters[((n - 1) * base.centers + 1):(n * base.centers),] <- tryres$centers } object$allcenters <- object$allcenters[complete.cases(object$allcenters),,drop=FALSE] object$allcluster <- knn1(object$allcenters, x, factor(1:nrow(object$allcenters))) if(minsize > 0){ object <- prune.bclust(object, x, minsize=minsize) } if (verbose) cat("\nComputing Hierarchical Clustering\n") object <- hclust.bclust(object, x = x, centers = centers, final.kmeans = final.kmeans, docmdscale=docmdscale) object } "centers.bclust" <- function (object, k) { centers <- matrix(0, nrow = k, ncol = ncol(object$allcenters)) for (m in 1:k) { centers[m, ] <- apply(object$allcenters[object$members[,k-1] == m, , drop = FALSE], 2, mean) } centers } "clusters.bclust" <- function (object, k, x=NULL) { if(missing(x)) allcluster <- object$allcluster else allcluster <- knn1(object$allcenters, x, factor(1:nrow(object$allcenters))) return(object$members[allcluster, k - 1]) } "hclust.bclust" <- function (object, x, centers, dist.method = object$dist.method, hclust.method = object$hclust.method, final.kmeans = FALSE, docmdscale = FALSE, maxcluster=object$maxcluster) { d <- dist(object$allcenters, method = dist.method) if(hclust.method=="diana"){ if (system.file(package = "cluster") == "") stop("Could not load required package 'cluster'!") object$hclust <- stats::as.hclust(cluster::diana(d, diss=TRUE)) } else object$hclust <- stats::hclust(d, method = hclust.method) if(docmdscale){ object$cmdscale <- cmdscale(d) } object$members <- cutree(object$hclust, 2:maxcluster) object$cluster <- clusters.bclust(object, centers) object$centers <- centers.bclust(object, centers) if (final.kmeans) { kmeansres <- kmeans(x, centers = object$centers) object$centers <- kmeansres$centers object$cluster <- kmeansres$cluster } object } "plot.bclust" <- function (x, maxcluster=x$maxcluster, main = deparse(substitute(x)), ...) { opar <- par(c("mar", "oma")) on.exit(par(opar)) par(oma = c(0, 0, 3, 0)) layout(matrix(c(1, 1, 2, 2), 2, 2, byrow = TRUE)) par(mar = c(0, 4, 4, 1)) plot(x$hclust, labels = FALSE, hang = -1) x1 <- 1:maxcluster x2 <- 2:maxcluster y <- rev(x$hclust$height)[x1] z <- abs(diff(y)) par(mar = c(4, 4, 1, 2)) plot(x1, ((y - min(y))/(max(y) - min(y))), ty = "l", xlab = "", ylab = "", ylim = c(0, 1)) lines(x2, z/sum(z), col = "grey") text(x2, z/sum(z), labels = as.character(x2)) # lx2 <- length(x2) # abline(h=qexp(.95, rate = length(x2)), lty=3, col="grey") # abline(h=qexp(.95^(1/lx2), rate = length(x2)), lty=3, col="grey") mtext(main, outer = TRUE, cex = 1.5) layout(1) } "boxplot.bclust" <- function (x, n = nrow(x$centers), bycluster = TRUE, main = deparse(substitute(x)), oneplot=TRUE, which=1:n, ...) { N <- length(which) opar <- par(c("mfrow", "oma", "mgp","xpd")) on.exit(par(opar)) par(xpd=NA) memb <- x$members[, (n - 1)] tmemb <- table(memb) cendf <- as.data.frame(x$allcenters) ylim <- range(x$allcenters) if (bycluster) { if(oneplot){ if (N <= 3) { par(mfrow = c(N, 1)) } else { par(mfrow = c(ceiling(N/2), 2)) } } tcluster <- table(clusters.bclust(x, n)) for (k in which) { boxplot(cendf[memb == k, ], col = "grey", names = rep("",ncol(cendf)), ylim = ylim, ...) if (!is.null(x$datamean)) { lines(x$datamean, col = "red") } if(!is.null(x$colnames)){ text(1:length(x$colnames)+0.2, par("usr")[3], adj=1,srt=35, paste(x$colnames, " ")) } title(main = paste("Cluster ", k, ": ", tmemb[k], " centers, ", tcluster[k], " data points", sep = "")) } } else { a <- ceiling(sqrt(ncol(cendf))) if(oneplot){ par(mfrow = c(a, ceiling(ncol(cendf)/a))) } memb <- as.factor(memb) for (k in 1:ncol(cendf)) { boxplot(cendf[, k] ~ memb, col = "grey", ylim = ylim, ...) title(main = x$colnames[k]) abline(h = x$datamean[k], col = "red") } } } ### prune centers that contain not at least minsize data points prune.bclust <- function(object, x, minsize=1, dohclust=FALSE, ...){ ok <- FALSE while(!all(ok)){ object$allcluster <- knn1(object$allcenters, x, factor(1:nrow(object$allcenters))) ok <- table(object$allcluster) >= minsize object$allcenters <- object$allcenters[ok, ] } if(dohclust){ object <- hclust.bclust(object, x, nrow(object$centers), ...) } object } e1071/R/shortestPaths.R0000644000175100001440000000155311400421345014222 0ustar hornikusersallShortestPaths <- function(x){ x <- as.matrix(x) x[is.na(x)] <- .Machine$double.xmax x[is.infinite(x) & x>0] <- .Machine$double.xmax if(ncol(x) != nrow(x)) stop("x is not a square matrix") n <- ncol(x) z <- .C("e1071_floyd", as.integer(n), double(n^2), as.double(x), integer(n^2), PACKAGE = "e1071") z <- list(length = matrix(z[[2]], n), middlePoints = matrix(z[[4]]+1, n)) z$length[z$length == .Machine$double.xmax] <- NA z } extractPath <- function(obj, start, end){ z <- integer(0) path <- function(i, j){ k <- obj$middlePoints[i, j] if (k != 0) { path(i,k); z <<- c(z, k) path(k,j); } } path(start,end) c(start, z, end) } e1071/R/svm.R0000644000175100001440000006441212560361752012174 0ustar hornikuserssvm <- function (x, ...) UseMethod ("svm") svm.formula <- function (formula, data = NULL, ..., subset, na.action = na.omit, scale = TRUE) { call <- match.call() if (!inherits(formula, "formula")) stop("method is only for formula objects") m <- match.call(expand.dots = FALSE) if (identical(class(eval.parent(m$data)), "matrix")) m$data <- as.data.frame(eval.parent(m$data)) m$... <- NULL m$scale <- NULL m[[1]] <- as.name("model.frame") m$na.action <- na.action m <- eval(m, parent.frame()) Terms <- attr(m, "terms") attr(Terms, "intercept") <- 0 x <- model.matrix(Terms, m) y <- model.extract(m, "response") attr(x, "na.action") <- attr(y, "na.action") <- attr(m, "na.action") if (length(scale) == 1) scale <- rep(scale, ncol(x)) if (any(scale)) { remove <- unique(c(which(labels(Terms) %in% names(attr(x, "contrasts"))), which(!scale) ) ) scale <- !attr(x, "assign") %in% remove } ret <- svm.default (x, y, scale = scale, ..., na.action = na.action) ret$call <- call ret$call[[1]] <- as.name("svm") ret$terms <- Terms if (!is.null(attr(m, "na.action"))) ret$na.action <- attr(m, "na.action") class(ret) <- c("svm.formula", class(ret)) return (ret) } svm.default <- function (x, y = NULL, scale = TRUE, type = NULL, kernel = "radial", degree = 3, gamma = if (is.vector(x)) 1 else 1 / ncol(x), coef0 = 0, cost = 1, nu = 0.5, class.weights = NULL, cachesize = 40, tolerance = 0.001, epsilon = 0.1, shrinking = TRUE, cross = 0, probability = FALSE, fitted = TRUE, ..., subset, na.action = na.omit) { yorig <- y if(inherits(x, "Matrix")) { loadNamespace("SparseM") loadNamespace("Matrix") x <- as(x, "matrix.csr") } if(inherits(x, "simple_triplet_matrix")) { loadNamespace("SparseM") ind <- order(x$i, x$j) x <- new("matrix.csr", ra = x$v[ind], ja = x$j[ind], ia = as.integer(cumsum(c(1, tabulate(x$i[ind])))), dimension = c(x$nrow, x$ncol)) } if (sparse <- inherits(x, "matrix.csr")) loadNamespace("SparseM") ## NULL parameters? if(is.null(degree)) stop(sQuote("degree"), " must not be NULL!") if(is.null(gamma)) stop(sQuote("gamma"), " must not be NULL!") if(is.null(coef0)) stop(sQuote("coef0"), " must not be NULL!") if(is.null(cost)) stop(sQuote("cost"), " must not be NULL!") if(is.null(nu)) stop(sQuote("nu"), " must not be NULL!") if(is.null(epsilon)) stop(sQuote("epsilon"), " must not be NULL!") if(is.null(tolerance)) stop(sQuote("tolerance"), " must not be NULL!") xhold <- if (fitted) x else NULL x.scale <- y.scale <- NULL formula <- inherits(x, "svm.formula") ## determine model type if (is.null(type)) type <- if (is.null(y)) "one-classification" else if (is.factor(y)) "C-classification" else "eps-regression" type <- pmatch(type, c("C-classification", "nu-classification", "one-classification", "eps-regression", "nu-regression"), 99) - 1 if (type > 10) stop("wrong type specification!") kernel <- pmatch(kernel, c("linear", "polynomial", "radial", "sigmoid"), 99) - 1 if (kernel > 10) stop("wrong kernel specification!") nac <- attr(x, "na.action") ## scaling, subsetting, and NA handling if (sparse) { scale <- rep(FALSE, ncol(x)) if(!is.null(y)) na.fail(y) x <- SparseM::t(SparseM::t(x)) ## make shure that col-indices are sorted } else { x <- as.matrix(x) ## subsetting and na-handling for matrices if (!formula) { if (!missing(subset)) { x <- x[subset,] y <- y[subset] if (!is.null(xhold)) xhold <- as.matrix(xhold)[subset,] } if (is.null(y)) x <- na.action(x) else { df <- na.action(data.frame(y, x)) y <- df[,1] x <- as.matrix(df[,-1], rownames.force = TRUE) nac <- attr(x, "na.action") <- attr(y, "na.action") <- attr(df, "na.action") } } ## scaling if (length(scale) == 1) scale <- rep(scale, ncol(x)) if (any(scale)) { co <- !apply(x[,scale, drop = FALSE], 2, var) if (any(co)) { warning(paste("Variable(s)", paste(sQuote(colnames(x[,scale, drop = FALSE])[co]), sep="", collapse=" and "), "constant. Cannot scale data.") ) scale <- rep(FALSE, ncol(x)) } else { xtmp <- scale(x[,scale]) x[,scale] <- xtmp x.scale <- attributes(xtmp)[c("scaled:center","scaled:scale")] if (is.numeric(y) && (type > 2)) { yorig <- y y <- scale(y) y.scale <- attributes(y)[c("scaled:center","scaled:scale")] y <- as.vector(y) } } } } ## further parameter checks nr <- nrow(x) if (cross > nr) stop(sQuote("cross"), " cannot exceed the number of observations!") ytmp <- y attributes(ytmp) <- NULL if (!is.vector(ytmp) && !is.factor(y) && type != 2) stop("y must be a vector or a factor.") if (type != 2 && length(y) != nr) stop("x and y don't match.") if (cachesize < 0.1) cachesize <- 0.1 if (type > 2 && !is.numeric(y)) stop("Need numeric dependent variable for regression.") lev <- NULL weightlabels <- NULL ## in case of classification: transform factors into integers if (type == 2) # one class classification --> set dummy y <- rep(1, nr) else if (is.factor(y)) { lev <- levels(y) y <- as.integer(y) } else { if (type < 3) { if(any(as.integer(y) != y)) stop("dependent variable has to be of factor or integer type for classification mode.") y <- as.factor(y) lev <- levels(y) y <- as.integer(y) } else lev <- unique(y) } if (type < 3 && !is.null(class.weights)) { if (is.null(names(class.weights))) stop("Weights have to be specified along with their according level names !") weightlabels <- match (names(class.weights), lev) if (any(is.na(weightlabels))) stop("At least one level name is missing or misspelled.") } nclass <- 2 if (type < 2) nclass <- length(lev) if (type > 1 && length(class.weights) > 0) { class.weights <- NULL warning(sQuote("class.weights"), " are set to NULL for regression mode. For classification, use a _factor_ for ", sQuote("y"), ", or specify the correct ", sQuote("type"), " argument.") } err <- empty_string <- paste(rep(" ", 255), collapse = "") if (is.null(type)) stop("type argument must not be NULL!") if (is.null(kernel)) stop("kernel argument must not be NULL!") if (is.null(degree)) stop("degree argument must not be NULL!") if (is.null(gamma)) stop("gamma argument must not be NULL!") if (is.null(coef0)) stop("coef0 seed argument must not be NULL!") if (is.null(cost)) stop("cost argument must not be NULL!") if (is.null(nu)) stop("nu argument must not be NULL!") if (is.null(cachesize)) stop("cachesize argument must not be NULL!") if (is.null(tolerance)) stop("tolerance argument must not be NULL!") if (is.null(epsilon)) stop("epsilon argument must not be NULL!") if (is.null(shrinking)) stop("shrinking argument must not be NULL!") if (is.null(cross)) stop("cross argument must not be NULL!") if (is.null(sparse)) stop("sparse argument must not be NULL!") if (is.null(probability)) stop("probability argument must not be NULL!") cret <- .C ("svmtrain", ## data as.double (if (sparse) x@ra else t(x)), as.integer (nr), as.integer(ncol(x)), as.double (y), ## sparse index info as.integer (if (sparse) x@ia else 0), as.integer (if (sparse) x@ja else 0), ## parameters as.integer (type), as.integer (kernel), as.integer (degree), as.double (gamma), as.double (coef0), as.double (cost), as.double (nu), as.integer (weightlabels), as.double (class.weights), as.integer (length (class.weights)), as.double (cachesize), as.double (tolerance), as.double (epsilon), as.integer (shrinking), as.integer (cross), as.integer (sparse), as.integer (probability), ## results nclasses = integer (1), nr = integer (1), # nr of support vectors index = integer (nr), labels = integer (nclass), nSV = integer (nclass), rho = double (nclass * (nclass - 1) / 2), coefs = double (nr * (nclass - 1)), sigma = double (1), probA = double (nclass * (nclass - 1) / 2), probB = double (nclass * (nclass - 1) / 2), cresults = double (cross), ctotal1 = double (1), ctotal2 = double (1), error = err, PACKAGE = "e1071") if (cret$error != empty_string) stop(paste(cret$error, "!", sep="")) cret$index <- cret$index[1:cret$nr] ret <- list ( call = match.call(), type = type, kernel = kernel, cost = cost, degree = degree, gamma = gamma, coef0 = coef0, nu = nu, epsilon = epsilon, sparse = sparse, scaled = scale, x.scale = x.scale, y.scale = y.scale, nclasses = cret$nclasses, #number of classes levels = lev, tot.nSV = cret$nr, #total number of sv nSV = cret$nSV[1:cret$nclasses], #number of SV in diff. classes labels = cret$labels[1:cret$nclasses], #labels of the SVs. SV = if (sparse) SparseM::t(SparseM::t(x[cret$index,])) else t(t(x[cret$index,])), #copy of SV index = cret$index, #indexes of sv in x ##constants in decision functions rho = cret$rho[1:(cret$nclasses * (cret$nclasses - 1) / 2)], ##probabilites compprob = probability, probA = if (!probability) NULL else cret$probA[1:(cret$nclasses * (cret$nclasses - 1) / 2)], probB = if (!probability) NULL else cret$probB[1:(cret$nclasses * (cret$nclasses - 1) / 2)], sigma = if (probability) cret$sigma else NULL, ##coefficiants of sv coefs = if (cret$nr == 0) NULL else t(matrix(cret$coefs[1:((cret$nclasses - 1) * cret$nr)], nrow = cret$nclasses - 1, byrow = TRUE)), na.action = nac ) ## cross-validation-results if (cross > 0) if (type > 2) { scale.factor <- if (any(scale)) crossprod(y.scale$"scaled:scale") else 1; ret$MSE <- cret$cresults * scale.factor; ret$tot.MSE <- cret$ctotal1 * scale.factor; ret$scorrcoeff <- cret$ctotal2; } else { ret$accuracies <- cret$cresults; ret$tot.accuracy <- cret$ctotal1; } class (ret) <- "svm" if (fitted) { ret$fitted <- na.action(predict(ret, xhold, decision.values = TRUE)) ret$decision.values <- attr(ret$fitted, "decision.values") attr(ret$fitted, "decision.values") <- NULL if (type > 1) ret$residuals <- yorig - ret$fitted } ret } predict.svm <- function (object, newdata, decision.values = FALSE, probability = FALSE, ..., na.action = na.omit) { if (missing(newdata)) return(fitted(object)) if (object$tot.nSV < 1) stop("Model is empty!") if(inherits(newdata, "Matrix")) { loadNamespace("SparseM") loadNamespace("Matrix") newdata <- as(newdata, "matrix.csr") } if(inherits(newdata, "simple_triplet_matrix")) { loadNamespace("SparseM") ind <- order(newdata$i, newdata$j) newdata <- new("matrix.csr", ra = newdata$v[ind], ja = newdata$j[ind], ia = as.integer(cumsum(c(1, tabulate(newdata$i[ind])))), dimension = c(newdata$nrow, newdata$ncol)) } sparse <- inherits(newdata, "matrix.csr") if (object$sparse || sparse) loadNamespace("SparseM") act <- NULL if ((is.vector(newdata) && is.atomic(newdata))) newdata <- t(t(newdata)) if (sparse) newdata <- SparseM::t(SparseM::t(newdata)) preprocessed <- !is.null(attr(newdata, "na.action")) rowns <- if (!is.null(rownames(newdata))) rownames(newdata) else 1:nrow(newdata) if (!object$sparse) { if (inherits(object, "svm.formula")) { if(is.null(colnames(newdata))) colnames(newdata) <- colnames(object$SV) newdata <- model.matrix(delete.response(terms(object)), as.data.frame(newdata)) newdata <- na.action(newdata) act <- attr(newdata, "na.action") } else { newdata <- na.action(as.matrix(newdata)) act <- attr(newdata, "na.action") } } if (!is.null(act) && !preprocessed) rowns <- rowns[-act] if (any(object$scaled)) newdata[,object$scaled] <- scale(newdata[,object$scaled, drop = FALSE], center = object$x.scale$"scaled:center", scale = object$x.scale$"scaled:scale" ) if (ncol(object$SV) != ncol(newdata)) stop ("test data does not match model !") ret <- .C ("svmpredict", as.integer (decision.values), as.integer (probability), ## model as.double (if (object$sparse) object$SV@ra else t(object$SV)), as.integer (nrow(object$SV)), as.integer(ncol(object$SV)), as.integer (if (object$sparse) object$SV@ia else 0), as.integer (if (object$sparse) object$SV@ja else 0), as.double (as.vector(object$coefs)), as.double (object$rho), as.integer (object$compprob), as.double (if (object$compprob) object$probA else 0), as.double (if (object$compprob) object$probB else 0), as.integer (object$nclasses), as.integer (object$tot.nSV), as.integer (object$labels), as.integer (object$nSV), as.integer (object$sparse), ## parameter as.integer (object$type), as.integer (object$kernel), as.integer (object$degree), as.double (object$gamma), as.double (object$coef0), ## test matrix as.double (if (sparse) newdata@ra else t(newdata)), as.integer (nrow(newdata)), as.integer (if (sparse) newdata@ia else 0), as.integer (if (sparse) newdata@ja else 0), as.integer (sparse), ## decision-values ret = double(nrow(newdata)), dec = double(nrow(newdata) * object$nclasses * (object$nclasses - 1) / 2), prob = double(nrow(newdata) * object$nclasses), PACKAGE = "e1071" ) ret2 <- if (is.character(object$levels)) # classification: return factors factor (object$levels[ret$ret], levels = object$levels) else if (object$type == 2) # one-class-classification: return TRUE/FALSE ret$ret == 1 else if (any(object$scaled) && !is.null(object$y.scale)) # return raw values, possibly scaled back ret$ret * object$y.scale$"scaled:scale" + object$y.scale$"scaled:center" else ret$ret names(ret2) <- rowns ret2 <- napredict(act, ret2) if (decision.values) { colns = c() for (i in 1:(object$nclasses - 1)) for (j in (i + 1):object$nclasses) colns <- c(colns, paste(object$levels[object$labels[i]], "/", object$levels[object$labels[j]], sep = "")) attr(ret2, "decision.values") <- napredict(act, matrix(ret$dec, nrow = nrow(newdata), byrow = TRUE, dimnames = list(rowns, colns) ) ) } if (probability && object$type < 2) { if (!object$compprob) warning("SVM has not been trained using `probability = TRUE`, probabilities not available for predictions.") else attr(ret2, "probabilities") <- napredict(act, matrix(ret$prob, nrow = nrow(newdata), byrow = TRUE, dimnames = list(rowns, object$levels[object$labels]) ) ) } ret2 } print.svm <- function (x, ...) { cat("\nCall:", deparse(x$call, 0.8 * getOption("width")), "\n", sep="\n") cat("Parameters:\n") cat(" SVM-Type: ", c("C-classification", "nu-classification", "one-classification", "eps-regression", "nu-regression")[x$type+1], "\n") cat(" SVM-Kernel: ", c("linear", "polynomial", "radial", "sigmoid")[x$kernel+1], "\n") if (x$type==0 || x$type==3 || x$type==4) cat(" cost: ", x$cost, "\n") if (x$kernel==1) cat(" degree: ", x$degree, "\n") cat(" gamma: ", x$gamma, "\n") if (x$kernel==1 || x$kernel==3) cat(" coef.0: ", x$coef0, "\n") if (x$type==1 || x$type==2 || x$type==4) cat(" nu: ", x$nu, "\n") if (x$type==3) { cat(" epsilon: ", x$epsilon, "\n\n") if (x$compprob) cat("Sigma: ", x$sigma, "\n\n") } cat("\nNumber of Support Vectors: ", x$tot.nSV) cat("\n\n") } summary.svm <- function(object, ...) structure(object, class="summary.svm") print.summary.svm <- function (x, ...) { print.svm(x) if (x$type<2) { cat(" (", x$nSV, ")\n\n") cat("\nNumber of Classes: ", x$nclasses, "\n\n") cat("Levels:", if(is.numeric(x$levels)) "(as integer)", "\n", x$levels) } cat("\n\n") if (x$type==2) cat("\nNumber of Classes: 1\n\n\n") if ("MSE" %in% names(x)) { cat(length (x$MSE), "-fold cross-validation on training data:\n\n", sep="") cat("Total Mean Squared Error:", x$tot.MSE, "\n") cat("Squared Correlation Coefficient:", x$scorrcoef, "\n") cat("Mean Squared Errors:\n", x$MSE, "\n\n") } if ("accuracies" %in% names(x)) { cat(length (x$accuracies), "-fold cross-validation on training data:\n\n", sep="") cat("Total Accuracy:", x$tot.accuracy, "\n") cat("Single Accuracies:\n", x$accuracies, "\n\n") } cat("\n\n") } scale.data.frame <- function(x, center = TRUE, scale = TRUE) { i <- sapply(x, is.numeric) if (ncol(x[, i, drop = FALSE])) { x[, i] <- tmp <- scale.default(x[, i, drop = FALSE], na.omit(center), na.omit(scale)) if(center || !is.logical(center)) attr(x, "scaled:center")[i] <- attr(tmp, "scaled:center") if(scale || !is.logical(scale)) attr(x, "scaled:scale")[i] <- attr(tmp, "scaled:scale") } x } plot.svm <- function(x, data, formula = NULL, fill = TRUE, grid = 50, slice = list(), symbolPalette = palette(), svSymbol = "x", dataSymbol = "o", ...) { if (x$type < 3) { if (is.null(formula) && ncol(data) == 3) { formula <- formula(delete.response(terms(x))) formula[2:3] <- formula[[2]][2:3] } if (is.null(formula)) stop("missing formula.") if (fill) { sub <- model.frame(formula, data) xr <- seq(min(sub[, 2]), max(sub[, 2]), length = grid) yr <- seq(min(sub[, 1]), max(sub[, 1]), length = grid) l <- length(slice) if (l < ncol(data) - 3) { slnames <- names(slice) slice <- c(slice, rep(list(0), ncol(data) - 3 - l)) names <- labels(delete.response(terms(x))) names(slice) <- c(slnames, names[!names %in% c(colnames(sub), slnames)]) } for (i in names(which(sapply(data, is.factor)))) if (!is.factor(slice[[i]])) { levs <- levels(data[[i]]) lev <- if (is.character(slice[[i]])) slice[[i]] else levs[1] fac <- factor(lev, levels = levs) if (is.na(fac)) stop(paste("Level", dQuote(lev), "could not be found in factor", sQuote(i))) slice[[i]] <- fac } lis <- c(list(yr), list(xr), slice) names(lis)[1:2] <- colnames(sub) new <- expand.grid(lis)[, labels(terms(x))] preds <- predict(x, new) filled.contour(xr, yr, matrix(as.numeric(preds), nrow = length(xr), byrow = TRUE), plot.axes = { axis(1) axis(2) colind <- as.numeric(model.response(model.frame(x, data))) dat1 <- data[-x$index,] dat2 <- data[x$index,] coltmp1 <- symbolPalette[colind[-x$index]] coltmp2 <- symbolPalette[colind[x$index]] points(formula, data = dat1, pch = dataSymbol, col = coltmp1) points(formula, data = dat2, pch = svSymbol, col = coltmp2) }, levels = 1:(length(levels(preds)) + 1), key.axes = axis(4, 1:(length(levels(preds))) + 0.5, labels = levels(preds), las = 3), plot.title = title(main = "SVM classification plot", xlab = names(lis)[2], ylab = names(lis)[1]), ...) } else { plot(formula, data = data, type = "n", ...) colind <- as.numeric(model.response(model.frame(x, data))) dat1 <- data[-x$index,] dat2 <- data[x$index,] coltmp1 <- symbolPalette[colind[-x$index]] coltmp2 <- symbolPalette[colind[x$index]] points(formula, data = dat1, pch = dataSymbol, col = coltmp1) points(formula, data = dat2, pch = svSymbol, col = coltmp2) invisible() } } } write.svm <- function (object, svm.file="Rdata.svm", scale.file = "Rdata.scale", yscale.file = "Rdata.yscale") { ret <- .C ("svmwrite", ## model as.double (if (object$sparse) object$SV@ra else t(object$SV)), as.integer (nrow(object$SV)), as.integer(ncol(object$SV)), as.integer (if (object$sparse) object$SV@ia else 0), as.integer (if (object$sparse) object$SV@ja else 0), as.double (as.vector(object$coefs)), as.double (object$rho), as.integer (object$compprob), as.double (if (object$compprob) object$probA else 0), as.double (if (object$compprob) object$probB else 0), as.integer (object$nclasses), as.integer (object$tot.nSV), as.integer (object$labels), as.integer (object$nSV), as.integer (object$sparse), ## parameter as.integer (object$type), as.integer (object$kernel), as.integer (object$degree), as.double (object$gamma), as.double (object$coef0), ## filename as.character(svm.file), PACKAGE = "e1071" )$ret write.table(data.frame(center = object$x.scale$"scaled:center", scale = object$x.scale$"scaled:scale"), file=scale.file, col.names=FALSE, row.names=FALSE) if (!is.null(object$y.scale)) write.table(data.frame(center = object$y.scale$"scaled:center", scale = object$y.scale$"scaled:scale"), file=yscale.file, col.names=FALSE, row.names=FALSE) } e1071/R/ica.R0000644000175100001440000000306611400421345012104 0ustar hornikusersica <- function(X, lrate, epochs=100, ncomp=dim(X)[2], fun="negative") { if (!is.matrix(X)) { if (is.data.frame(X)) X <- as.matrix(X) else stop("ica: X must be a matrix or a data frame") } if (!is.numeric(X)) stop("ica: X contains non numeric elements") m <- dim(X)[1] n <- dim(X)[2] Winit <- matrix(rnorm(n*ncomp), ncomp, n) W <- Winit if (!is.function(fun)) { funlist <- c("negative kurtosis", "positive kurtosis", "4th moment") p <- pmatch(fun, funlist) if (is.na(p)) stop("ica: invalid fun") funname <- funlist[p] if (p == 1) fun <- tanh else if (p == 2) fun <- function(x) {x - tanh(x)} else if (p == 3) fun <- function(x) {sign(x)*x^2} } else funname <- as.character(substitute(fun)) for (i in 1:epochs) for (j in 1:m) { x <- X[j,, drop=FALSE] y <- W%*%t(x) gy <- fun(y) W <- W + lrate*gy%*%(x-t(gy)%*%W) } colnames(W) <- NULL pr <- X%*%t(W) retval <- list(weights = W, projection = pr, epochs = epochs, fun = funname, lrate = lrate, initweights = Winit) class(retval) <- "ica" return(retval) } print.ica <- function(x, ...) { cat(x$epochs, "Trainingssteps with a learning rate of", x$lrate, "\n") cat("Function used:", x$fun,"\n\n") cat("Weightmatrix\n") print(x$weights, ...) } plot.ica <- function(x, ...) pairs(x$pr, ...) e1071/R/kurtosis.R0000644000175100001440000000111511400421345013224 0ustar hornikuserskurtosis <- function(x, na.rm = FALSE, type = 3) { if(any(ina <- is.na(x))) { if(na.rm) x <- x[!ina] else return(NA) } if(!(type %in% (1 : 3))) stop("Invalid 'type' argument.") n <- length(x) x <- x - mean(x) r <- n * sum(x ^ 4) / (sum(x ^ 2) ^ 2) y <- if(type == 1) r - 3 else if(type == 2) { if(n < 4) stop("Need at least 4 complete observations.") ((n + 1) * (r - 3) + 6) * (n - 1) / ((n - 2) * (n - 3)) } else r * (1 - 1 / n) ^ 2 - 3 y } e1071/R/rbridge.R0000644000175100001440000000026511400421345012764 0ustar hornikusersrbridge <- function(end=1, frequency=1000) { z <- rwiener(end=end, frequency=frequency) ts(z - time(z)*as.vector(z)[frequency], start=1/frequency, frequency=frequency) } e1071/R/plot.stft.R0000644000175100001440000000021011400421345013271 0ustar hornikusersplot.stft <- function (x, col = gray (63:0/63), ...) { x <- x$values image(x=1:dim(x)[1], y=1:dim(x)[2], z=x, col=col, ...) } e1071/R/e1071-deprecated.R0000644000175100001440000000000011400421345014164 0ustar hornikuserse1071/R/countpattern.R0000644000175100001440000000117211633216055014102 0ustar hornikuserscountpattern <- function(x, matching=FALSE) { nvar <- dim(x)[2] n <- dim(x)[1] ## build matrix of all possible binary vectors b <- matrix(0, 2^nvar, nvar) for (i in 1:nvar) b[, nvar+1-i] <- rep(rep(c(0,1),c(2^(i-1),2^(i-1))),2^(nvar-i)) namespat <- b[,1] for (i in 2:nvar) namespat <- paste(namespat, b[,i], sep="") xpat <- x[,1] for (i in 2:nvar) xpat <- 2*xpat+x[,i] xpat <- xpat+1 pat <- tabulate(xpat, nbins=2^nvar) names(pat) <- namespat if (matching) return(list(pat=pat, matching=xpat)) else return(pat) } e1071/R/tune.R0000644000175100001440000004304012505567757012350 0ustar hornikuserstune.control <- function(random = FALSE, nrepeat = 1, repeat.aggregate = mean, sampling = c("cross", "fix", "bootstrap"), sampling.aggregate = mean, sampling.dispersion = sd, cross = 10, fix = 2 / 3, nboot = 10, boot.size = 9 / 10, best.model = TRUE, performances = TRUE, error.fun = NULL) { structure(list(random = random, nrepeat = nrepeat, repeat.aggregate = repeat.aggregate, sampling = match.arg(sampling), sampling.aggregate = sampling.aggregate, sampling.dispersion = sampling.dispersion, cross = cross, fix = fix, nboot = nboot, boot.size = boot.size, best.model = best.model, performances = performances, error.fun = error.fun ), class = "tune.control" ) } tune <- function(method, train.x, train.y = NULL, data = list(), validation.x = NULL, validation.y = NULL, ranges = NULL, predict.func = predict, tunecontrol = tune.control(), ... ) { call <- match.call() ## internal helper functions resp <- function(formula, data) { model.response(model.frame(formula, data)) } classAgreement <- function (tab) { n <- sum(tab) if (!is.null(dimnames(tab))) { lev <- intersect(colnames(tab), rownames(tab)) p0 <- sum(diag(tab[lev, lev])) / n } else { m <- min(dim(tab)) p0 <- sum(diag(tab[1:m, 1:m])) / n } p0 } ## parameter handling if (tunecontrol$sampling == "cross") validation.x <- validation.y <- NULL useFormula <- is.null(train.y) if (useFormula && (is.null(data) || length(data) == 0)) data <- model.frame(train.x) if (is.vector(train.x)) train.x <- t(t(train.x)) if (is.data.frame(train.y)) train.y <- as.matrix(train.y) ## prepare training indices if (!is.null(validation.x)) tunecontrol$fix <- 1 n <- nrow(if (useFormula) data else train.x) perm.ind <- sample(n) if (tunecontrol$sampling == "cross") { if (tunecontrol$cross > n) stop(sQuote("cross"), " must not exceed sampling size!") if (tunecontrol$cross == 1) stop(sQuote("cross"), " must be greater than 1!") } train.ind <- if (tunecontrol$sampling == "cross") tapply(1:n, cut(1:n, breaks = tunecontrol$cross), function(x) perm.ind[-x]) else if (tunecontrol$sampling == "fix") list(perm.ind[1:trunc(n * tunecontrol$fix)]) else ## bootstrap lapply(1:tunecontrol$nboot, function(x) sample(n, n * tunecontrol$boot.size, replace = TRUE)) ## find best model parameters <- if (is.null(ranges)) data.frame(dummyparameter = 0) else expand.grid(ranges) p <- nrow(parameters) if (!is.logical(tunecontrol$random)) { if (tunecontrol$random < 1) stop("random must be a strictly positive integer") if (tunecontrol$random > p) tunecontrol$random <- p parameters <- parameters[sample(1:p, tunecontrol$random),] } model.variances <- model.errors <- c() ## - loop over all models for (para.set in 1:p) { sampling.errors <- c() ## - loop over all training samples for (sample in 1:length(train.ind)) { repeat.errors <- c() ## - repeat training `nrepeat' times for (reps in 1:tunecontrol$nrepeat) { ## train one model pars <- if (is.null(ranges)) NULL else lapply(parameters[para.set,,drop = FALSE], unlist) model <- if (useFormula) do.call(method, c(list(train.x, data = data, subset = train.ind[[sample]]), pars, list(...) ) ) else do.call(method, c(list(train.x[train.ind[[sample]],], y = train.y[train.ind[[sample]]]), pars, list(...) ) ) ## predict validation set pred <- predict.func(model, if (!is.null(validation.x)) validation.x else if (useFormula) data[-train.ind[[sample]],,drop = FALSE] else if (inherits(train.x, "matrix.csr")) train.x[-train.ind[[sample]],] else train.x[-train.ind[[sample]],,drop = FALSE] ) ## compute performance measure true.y <- if (!is.null(validation.y)) validation.y else if (useFormula) { if (!is.null(validation.x)) resp(train.x, validation.x) else resp(train.x, data[-train.ind[[sample]],]) } else train.y[-train.ind[[sample]]] if (is.null(true.y)) true.y <- rep(TRUE, length(pred)) repeat.errors[reps] <- if (!is.null(tunecontrol$error.fun)) tunecontrol$error.fun(true.y, pred) else if ((is.logical(true.y) || is.factor(true.y)) && (is.logical(pred) || is.factor(pred) || is.character(pred))) ## classification error 1 - classAgreement(table(pred, true.y)) else if (is.numeric(true.y) && is.numeric(pred)) ## mean squared error crossprod(pred - true.y) / length(pred) else stop("Dependent variable has wrong type!") } sampling.errors[sample] <- tunecontrol$repeat.aggregate(repeat.errors) } model.errors[para.set] <- tunecontrol$sampling.aggregate(sampling.errors) model.variances[para.set] <- tunecontrol$sampling.dispersion(sampling.errors) } ## return results best <- which.min(model.errors) pars <- if (is.null(ranges)) NULL else lapply(parameters[best,,drop = FALSE], unlist) structure(list(best.parameters = parameters[best,,drop = FALSE], best.performance = model.errors[best], method = if (!is.character(method)) deparse(substitute(method)) else method, nparcomb = nrow(parameters), train.ind = train.ind, sampling = switch(tunecontrol$sampling, fix = "fixed training/validation set", bootstrap = "bootstrapping", cross = if (tunecontrol$cross == n) "leave-one-out" else paste(tunecontrol$cross,"-fold cross validation", sep="") ), performances = if (tunecontrol$performances) cbind(parameters, error = model.errors, dispersion = model.variances), best.model = if (tunecontrol$best.model) { modeltmp <- if (useFormula) do.call(method, c(list(train.x, data = data), pars, list(...))) else do.call(method, c(list(x = train.x, y = train.y), pars, list(...))) call[[1]] <- as.symbol("best.tune") modeltmp$call <- call modeltmp } ), class = "tune" ) } best.tune <- function(...) { call <- match.call() modeltmp <- tune(...)$best.model modeltmp$call <- call modeltmp } print.tune <- function(x, ...) { if (x$nparcomb > 1) { cat("\nParameter tuning of ", sQuote(x$method), ":\n\n", sep="") cat("- sampling method:", x$sampling,"\n\n") cat("- best parameters:\n") tmp <- x$best.parameters rownames(tmp) <- "" print(tmp) cat("\n- best performance:", x$best.performance, "\n") cat("\n") } else { cat("\nError estimation of ", sQuote(x$method), " using ", x$sampling, ": ", x$best.performance, "\n\n", sep="") } } summary.tune <- function(object, ...) structure(object, class = "summary.tune") print.summary.tune <- function(x, ...) { print.tune(x) if (!is.null(x$performances) && (x$nparcomb > 1)) { cat("- Detailed performance results:\n") print(x$performances) cat("\n") } } hsv_palette <- function(h = 2/3, from = 0.7, to = 0.2, v = 1) function(n) hsv(h = h, s = seq(from, to, length.out = n), v = v) plot.tune <- function(x, type=c("contour","perspective"), theta=60, col="lightblue", main = NULL, xlab = NULL, ylab = NULL, swapxy = FALSE, transform.x = NULL, transform.y = NULL, transform.z = NULL, color.palette = hsv_palette(), nlevels = 20, ...) { if (is.null(x$performances)) stop("Object does not contain detailed performance measures!") k <- ncol(x$performances) if (k > 4) stop("Cannot visualize more than 2 parameters") type = match.arg(type) if (is.null(main)) main <- paste("Performance of `", x$method, "'", sep="") if (k == 3) plot(x$performances[,1:2], type = "b", main = main) else { if (!is.null(transform.x)) x$performances[,1] <- transform.x(x$performances[,1]) if (!is.null(transform.y)) x$performances[,2] <- transform.y(x$performances[,2]) if (!is.null(transform.z)) x$performances[,3] <- transform.z(x$performances[,3]) if (swapxy) x$performances[,1:2] <- x$performances[,2:1] x <- xtabs(error~., data = x$performances[,-k]) if (is.null(xlab)) xlab <- names(dimnames(x))[1 + swapxy] if (is.null(ylab)) ylab <- names(dimnames(x))[2 - swapxy] if (type == "perspective") persp(x=as.double(rownames(x)), y=as.double(colnames(x)), z=x, xlab=xlab, ylab=ylab, zlab="accuracy", theta=theta, col=col, ticktype="detailed", main = main, ... ) else filled.contour(x=as.double(rownames(x)), y=as.double(colnames(x)), xlab=xlab, ylab=ylab, nlevels=nlevels, color.palette = color.palette, main = main, x, ...) } } ############################################# ## convenience functions for some methods ############################################# tune.svm <- function(x, y = NULL, data = NULL, degree = NULL, gamma = NULL, coef0 = NULL, cost = NULL, nu = NULL, class.weights = NULL, epsilon = NULL, ...) { call <- match.call() call[[1]] <- as.symbol("best.svm") ranges <- list(degree = degree, gamma = gamma, coef0 = coef0, cost = cost, nu = nu, class.weights = class.weights, epsilon = epsilon) ranges[sapply(ranges, is.null)] <- NULL if (length(ranges) < 1) ranges = NULL modeltmp <- if (inherits(x, "formula")) tune("svm", train.x = x, data = data, ranges = ranges, ...) else tune("svm", train.x = x, train.y = y, ranges = ranges, ...) if (!is.null(modeltmp$best.model)) modeltmp$best.model$call <- call modeltmp } best.svm <- function(x, tunecontrol = tune.control(), ...) { call <- match.call() tunecontrol$best.model = TRUE modeltmp <- tune.svm(x, ..., tunecontrol = tunecontrol)$best.model modeltmp$call <- call modeltmp } tune.nnet <- function(x, y = NULL, data = NULL, size = NULL, decay = NULL, trace = FALSE, tunecontrol = tune.control(nrepeat = 5), ...) { call <- match.call() call[[1]] <- as.symbol("best.nnet") loadNamespace("nnet") predict.func <- predict useFormula <- inherits(x, "formula") if (is.factor(y) || (useFormula && is.factor(model.response(model.frame(formula = x, data = data)))) ) predict.func = function(...) predict(..., type = "class") ranges <- list(size = size, decay = decay) ranges[sapply(ranges, is.null)] <- NULL if (length(ranges) < 1) ranges = NULL modeltmp <- if (useFormula) tune("nnet", train.x = x, data = data, ranges = ranges, predict.func = predict.func, tunecontrol = tunecontrol, trace = trace, ...) else tune("nnet", train.x = x, train.y = y, ranges = ranges, predict.func = predict.func, tunecontrol = tunecontrol, trace = trace, ...) if (!is.null(modeltmp$best.model)) modeltmp$best.model$call <- call modeltmp } best.nnet <- function(x, tunecontrol = tune.control(nrepeat = 5), ...) { call <- match.call() tunecontrol$best.model = TRUE modeltmp <- tune.nnet(x, ..., tunecontrol = tunecontrol)$best.model modeltmp$call <- call modeltmp } tune.randomForest <- function(x, y = NULL, data = NULL, nodesize = NULL, mtry = NULL, ntree = NULL, ...) { call <- match.call() call[[1]] <- as.symbol("best.randomForest") loadNamespace("randomForest") ranges <- list(nodesize = nodesize, mtry = mtry, ntree = ntree) ranges[sapply(ranges, is.null)] <- NULL if (length(ranges) < 1) ranges = NULL modeltmp <- if (inherits(x, "formula")) tune("randomForest", train.x = x, data = data, ranges = ranges, ...) else tune("randomForest", train.x = x, train.y = y, ranges = ranges, ...) if (!is.null(modeltmp$best.model)) modeltmp$best.model$call <- call modeltmp } best.randomForest <- function(x, tunecontrol = tune.control(), ...) { call <- match.call() tunecontrol$best.model = TRUE modeltmp <- tune.randomForest(x, ..., tunecontrol = tunecontrol)$best.model modeltmp$call <- call modeltmp } knn.wrapper <- function(x, y, k = 1, l = 0, ...) list(train = x, cl = y, k = k, l = l, ...) tune.knn <- function(x, y, k = NULL, l = NULL, ...) { loadNamespace("class") ranges <- list(k = k, l = l) ranges[sapply(ranges, is.null)] <- NULL if (length(ranges) < 1) ranges = NULL tune("knn.wrapper", train.x = x, train.y = y, ranges = ranges, predict.func = function(x, ...) knn(train = x$train, cl = x$cl, k = x$k, l = x$l, ...), ...) } rpart.wrapper <- function(formula, minsplit=20, minbucket=round(minsplit/3), cp=0.01, maxcompete=4, maxsurrogate=5, usesurrogate=2, xval=10, surrogatestyle=0, maxdepth=30, ...) rpart::rpart(formula, control = rpart::rpart.control(minsplit=minsplit, minbucket=minbucket, cp=cp, maxcompete=maxcompete, maxsurrogate=maxsurrogate, usesurrogate=usesurrogate, xval=xval, surrogatestyle=surrogatestyle, maxdepth=maxdepth), ... ) tune.rpart <- function(formula, data, na.action = na.omit, minsplit=NULL, minbucket=NULL, cp=NULL, maxcompete=NULL, maxsurrogate=NULL, usesurrogate=NULL, xval=NULL, surrogatestyle=NULL, maxdepth=NULL, predict.func = NULL, ...) { call <- match.call() call[[1]] <- as.symbol("best.rpart") loadNamespace("rpart") ranges <- list(minsplit=minsplit, minbucket=minbucket, cp=cp, maxcompete=maxcompete, maxsurrogate=maxsurrogate, usesurrogate=usesurrogate, xval=xval, surrogatestyle=surrogatestyle, maxdepth=maxdepth) ranges[sapply(ranges, is.null)] <- NULL if (length(ranges) < 1) ranges <- NULL predict.func <- if (is.factor(model.response(model.frame(formula, data)))) function(...) predict(..., type = "class") else predict modeltmp <- tune("rpart.wrapper", train.x = formula, data = data, ranges = ranges, predict.func = predict.func, na.action = na.action, ...) if (!is.null(modeltmp$best.model)) modeltmp$best.model$call <- call modeltmp } best.rpart <- function(formula, tunecontrol = tune.control(), ...) { call <- match.call() tunecontrol$best.model = TRUE modeltmp <- tune.rpart(formula, ..., tunecontrol = tunecontrol)$best.model modeltmp$call <- call modeltmp } e1071/vignettes/0000755000175100001440000000000012560362404013037 5ustar hornikuserse1071/vignettes/svm.pdf0000644000175100001440000006265411400421345014344 0ustar hornikusers%PDF-1.2 %쏢 4 0 obj <> stream xKv˒4߿f@5EBb܂elctvC7Fzۻ긏XoF░~Oo(~?n{]ןҿ{@&߭~: BV>ZEѴߜ2R(=hߥPv 9>]m TϷޱ!} = S%|oB$/dh,&dʌ)ۜM&{>BZSȝiu#I]x}!s d}?K G2}W@FxAo{}ݰF3k.Z5?kuXK{U_ccl8ri-^p=/ y^DJ_v٘/ۆlD{j/˔iʸ>_q|P6+c+f{z|qrO{qd6_Jg$̏T ,aVP،Ih0 fRܖ弯W{R|]8jrJqd 5+I[WNۦk];v6rf߹эX7 p73e[*.?>ﯕO_튲;LA0hB?}r^g^mOʿZ1y7~'wx^:^+jz i-/OW!XUZZҊFuidUӾ鈬W\LǿnUMJ?39 GL?Ls$iRit#r!KinEEsu@ewǛ+As5x4/T JjM]Fo'.4ا SڸSGB88`(B̀8*qr(/.,ѹ5sDx]Y<,PbVѹ[ߎ@L4nVp Qbm Dl46~]M/3dᆌynh'/ƾ`{Y0_}6}_:#m;TwV޽}U`]yUce*Ф+S^wG"}&FğD{" ޗ΋yc.Slcp_缝UiOfaorC$0F>6WŸ8,fVRl5Cي] h*6ԬmbFEэ*Laņ`D~X!n)cm,f oƮR1R\M]?.҉gE36\ jU`s<«U&QyMry)9r]n%3emutge'o^|ԼV3C*_;LJdrV"~yWld!G&U: ٛY3ɬչcen:uck@)++YIB̏W1ME&c*=c&`c&c1LPǂ0E5 oJ7o+dW@NX\9Assud*IժQk^W"\;`rlar'DC2]D~|Z7?[~uxgv:r4|ի_//< _iIĸ}-qU8˥m8ul_p_Z;I,w\" Kt eL@>F+ VA\I0!w8g ݋\r y \6]+!V_g\  z#sOPTᮃC1X9D K83Euu@Tbk@X"y` /8ĆlyT\5vbJ\S]e ͡+e-<$FƹGiҙj?9x")x6U}!j Qt'(s.w>B> >Q.}\wM75ok'LN&\9tt=Tk ۵hdcDٍB3` V1uXِ6v^}:<\}C\s]ų_|C/Pj+*1׾zK/f{V!\:6eNs&zzmxzzBmʅY7y|;%Dt8?Aȩ/HCO}CW__= pIsaAiqP*O8D(״$Z"yd]Lt['oAu'hU3{BuLlHYq̍[Ub$&g@</ 064 Ew[^g.(-,שXk?`u5Gt'k,s-ܤK?'d)e!FnkYZ`dW_俦  ">,\b5+;i ƲK625gͬ8t@3D&d~ ʳ@l"/63s04kab:DyXwS 75bT "Ptb+hT\ЛISALMJ1ld=XԿsfBO|ɆUL~|3?xwkݿm/D1[!O5@1_Vgk]/{A$0>A*{\7sSaW[=͜%aV  By w-呐98gϻ :䍏SI $ {rkG!\* t9;Ms|sO9ћd.vNq̀9>'KĚ%G@/!Ž█ޏ4.g}zt-#k H,*#ueVoMy<*'p[zd4ёF%m)3!^rLmtچ؇ AE Lʕ9M7jĈ4fmMr6򀬞 }f*^~e HԹ 4@i*W~5"x {E\6æW|hU4 ~C#7wv=iw˕[;2%<9(VP0ڛc.W\gGH@q!ϡP=: :Qa@LxTO\ 6MWÑWquYIE`EtpFZUD, e:_곾z!]\*g8FC%dوpKղQ[lBL0& xWrrWr[ `+R233pY1#cj D&>.O53Ef !Sn\vϟO<=X7n^=]ȃ/5,xM˸^ pMj =b5jV?5 BpChyw[1f:b i 1#cfY\# `A k3s̈pά22)33.R̝fYԑkzpIGMZ_1TuXt5k])y} _[)(2~]/*)f,8!0cyaD{T7>^9Ǣۍ?ΣqBbf6;`=sy49I]dd b+|"R*CD%"R*UfI\MKa9VwXu3+|L ptiɵӛk@ISNG]:>vqldjήb=8?ya,KR\r|X2?x ȴ@$öt_kKݰ/%O|9{Gi#1>rqx89.cyoM!lFff==]CgO|tOS#W}|BA8|+gC:p*ir⼧ &~#˩V5 n*\ w17H)~^G w=>ˁ83+Di(4_Mj Y~ .D/7Xr6feCZrkpDd!] Ae/O i<2fR"(~q|^sX=\R"Vb-; Z)^18>'"RLAe,Y@'ė(ggr+Ɏ;I"r 2JHi? oBp͍W3vf ^πy;{g"Bvdh2_O3~:$2s[-żPk.w(E]. eYݶtR5m純O#9ݽd469l6Z%9MaQϩqNs5昰P{fL p/* :s9eoJ@Թcp "**Vtgit*0 DIM 9JwZNiU Ķ3]k&HtS $SmAl MEњu6Md8u0i`0΄n8[!.Rr~Y3_w ˻-"q/;G_OU|r!xЀm;4a˃ )ކQc/&V6>bYYd :b6 6%=A˹6U*q:N#7YYp F#ö\m0!^@ҷpM[DmH6*;itrݠR!%P٩*D xh$D74 ;@LAC]LdGY'FC)!O(m=R"Qz=!_41#΃㱌U* TADcnL p%*nx&q]@8"5Rϸ\ytU" ۭeiU:bA9k "Z/4}a]DXZO5=O&Aw:PDkUb[==@wEU}2]WI,UBm! |/z/jX׺ < H$dݫH%d<{ZC3cc0m#.mK{Fߟ+֭j3[є;~^oy$4<ŎNKqb4zSdZt1kzȺ( 8S'p|M%92"rŦצ]9tJvz9uss,}n8\s . NqahwZx:yd|(zȨ}zki~UoVjd@hO^Gh@K(O0Ӭ\Ģk=Gˆ3T#yVX$RwW`x|D,Y*dgiW| XHU4bVSS ʃc爬5Y&Eu!V s6a]?=Čx99T F8Z4D7Vqs8|1xcp@h"a^npXNI\a'f&z@j x9%@_љyp3z2@Xge@/"I$eJi>xPc݃slc bD-XFđ-{D%Dm_D7GADID$RD[EDdDmFdvDGEqZĢ7F1lSG؛1~ƙp9 agBG =ŬB/1Peg4Si5TNSY>j741,WN"QKA%L 4TZ4m)`SCԃL;+ijC0[n`pKŅLJ5m-R<"G˪G/^VY|s'=I4޼qzhhWo2 =JlVQEhQ9L+ppCBxCf< aQhKǵ?5NnɅ9I E_1S k fSFά9S"Wl&lͮކ1K]S@2+p\7˽h8sZC5N ~`\N␵(dk0_MQS3_,_ Y ƘG }D(b7~6*^`őzqqF7xg$NȫzRk9Y@ږ[uAy{]&Kd*G,&Bjq&HۋhEؕK&~~dU/&V6>hcO100 4b?ԓ`,鏂(9yiq'9cH#Kl蘕t$7R? Ya/  Z ӹ*:w16_-=,2}AW 2-aVzјƧ3`6iB8uXRbkLmj-6d`**HXj8SA0rMu 0Lb;T|0ZΎn&8Ǻ)\sY$.Š1a:*,|:,Kȿ:~z| vF:-%/[6@6R/6iec647i$n 6_H &߃vopRAuj2>47[Uђ 8>`3Ho}C1xHj mD5b+Dw6y8SGfuu 18=x3w 7TŗBzZ<ٴ%\C8=ᖐ=@#U2 &i}Jhn$)kHD}Zбt|чǾ%֍BKD(d"2)!ȭ9&, CLp ҇gKpD@8qgچ34 3<8 `}p^BKІDoS~ivs J4 ̌jOW p[llgޤUEyLSݼFGh)豄\i[ɺlw{K>E:_LƃE?ڤK522v/ 7P QeG &w1B1 1S%dkCh&YHY̢`vYdҹ,42ށ!Qsձspq sP/:8IuP Ŵ- յZ8-nQEVE~-8i9~ {ʞZ?|bVʫJ PAΕn);EQ/aս|iTau:b7QGU(/kϜ<\P32kF^ͨ;DA7(fټvcT3 tQx?*٩xZw&@ɘ!*2dЪK=tyg71<]ج nf[\YB'YVN2lvZU;ﴕV#>=qԒ)_Em_{}7 F{;J)gX(fT%Fν]{[@I𒔜{[[i9!rm_ir%nVS.A.౼_I,}ܣ д(MOJ44KN$<{O/  PIK$L gZ2-R.dYޣ$}]E2hb؅hܪ%"h$r R *1dz-T_PiǠZUAئcMvr}|:ygWݺpw ECX)&>>,'w(ȻEtd2'ݎ}R8˲d 3h skn/&V6>hcOW0glbH4ήJ("a$׋x4յ"Twj<⒁53OC%x==Q@OO-ŀhZӡX"-pU7]ƋzC~!53"*SƒnA%-{6j=5@[Dy|1YE~E>3\MtY@Uo>yxe1bmHD4.߭@{A{I[r$)ߕkP\^ qɼpAJсDkx;#/G,Q */'>H܁%/dqՃiOC}n!* 53ٙd,pg~Xc}6@\U$1bZa, 6GtڻV$oXrNx}h# JOǛ#&9Y"EhjOn$ $(;3bļ7fC`>&WγԕH\Oc\ ihYemR1g3`57VDtXQ bgLcV 64`)Ӓ87׃N*l]:iuw,tsF7c͈pv;mai~{9 qwv/[lƿiDdܿ Z (nKZ?E;_h~8䛍E8!Om*+<܃̓Tf 4:KɈ94A^潴g 63 [ %!1!2wbS]_p\=KR^/-K!"D%U U)Ʀ2_iPnZiTpT?ꈴiFƪWmC5V"!jT%JT혨U5hhղUcN#"?{]"~%NˏLGfWZXSy=*Gs~|@_E~kaZrqQyU1/G ސ%",Mpx~\I*dJ=x\K\/DU5 k8nbZm \kQQy-<-_;ǬvB4tVJp*txmVpJEa-~{V7L1,* .KU< _**`Ixpy qi7yht' ayk(Đg 'JJٔ6ww83!C$+z@6GYnAƘ]!g5%bHڠopL^#įk[.{!WcI}X0TZyMk;;_{yos4_$yԶTL i^:SAk(;=yeIxY&4˥~5\|p \ho08@Y $Dݭp@ b1ʤW6MsV }-=U,i-}:|#4 NPa #8XIOFP|EбzWhc"hoTFb@4~Y3WddSXD@4MEU",czWTə5S%/X-㱢&cMΨSZ'J)(ĴVPk64~N!bM:QuwM5k}C UtpvvYM ad~;8IݦV5fٵG.GW[9z˺xS$BCҋEhqna7 8XJ3C? *[eHB'ŕ&jrWSQBFjጌuo^Ejdб;/ÀWx/[ɵývxoEg9oū$u+TZ(V|錶O3ڊKgt4Vf/ouw++ͤK~XA5Vr3#JG2؊'YNjG "@7"/QO^}m&&sr˳DV{-xXᝯ;k~ٲ׶)[7lfl// vW/hK{"#} HM˧%rkd'kԙ)aA=8)gX GLs6GU@cf-5\L@xWCn$J5YI|\ 6@Y<ލl]u^,|^ |5/ikΘ(v>V-vjhPA]QJ2FMUoقઆ5QV+ ht[4>h_4-XhhQ"Hj_4Pf,Z7~Ҍ`hBHR0?ALR% l;73s04Ka":x,IXv51bL Pd⺫F:oNn$]O:ٚ*uvm 9ĕ3+vg4WΌf8o foj=kVa8x崿^]8q䛍E8!O-5y2҇?3D }BяR͙+OE. !dk[@ Sxs.LpɍQ+S+ނYS9noT^y$#w5[! ;P Zq 켘-z<S3C 2bԠL5'4oAf"E#>R9ffM0-4M4ՓfȣeVƫU_jLe,?A {#Wq]!_asD F^yIzKVS6}A\yMJ˼'?r2|ʩ} J7Cvj[X@5Ns )dխs3[?0Y E&(;œ_gɊ_i#s4ǝc:c}[Hr sղ"*CU%]WaJ4~1EiT8J4!mZ CEljU5戴2L_N 3Th1(Ugi xm\;kw39ԭb,0iI+g+T`=u1UPNYfc9/|W|{$N=q'8+_?Vy4 Dod'l,I>4?6H826A+: PX1W)՘#YHۻ@*n^{ڴ=T:-gnTUar)o}k!6&vԒ"Io,%aR,0?,WWߛU5Hᘎ]}!jB3akGBP2bJOyo`S*3nn;DYIUGmIzgq;Fx%q#hG&n`n="BC̚R6C+}J_Bu肆 7 u+B<˪A OY 1?fT m~rR#_J%fV 3ijI$ejWzpJ(LPKMX\b?TZz^t24o{>.<$\*7|y1e[kr,@CD5>^Nq,^F0oKVϫG+;Ł ^u~uk kEl4i ,x7D>qM$@/ŋ,iAdW||?3*ڷuyJEAJLuLKO4zSͺB8Ws)^~dK~Z'⅋ wtb+}{ DJcLXb.n2#ᇈ`2]/X@Cԓ7D$O=f!/qW3' 5qŚֈ%zxs}!IǪXT <t,;%1Z =q&jH< OCpӦȹwtTS(T.cA=Y,62n jg_'tTo> VJ/;0]яPːXh%o9)SaU]#y1^Po#,o4$w’S|h$j\/XULz_#Fjge+'4ʒ8SD`2HQ>,xKm- I8gL[N6<1KFl.xr EXL1Ha%c뮭+,\|`̇U䨁~54"+Zpp5 S| E&\M0jp(H#8FP.0 <`_q#Z7(>'1$I$G <ymb>=4H1IhM̌z Eژ7A-ɹCRƟ"G4bIBI;`Er,Fb8JzEwRbv4{(\P],ATx7\h#ϻK9e/Kx+@C̣(Lk%(:\K |IkYLo4yN7el0-S9v&'߸ ~a!b(z%](4M]:j8 L!Ed( -yx"J`>Bg넹ʅ7iImu !_"PbNg ܫNFb!Ƽ}\\4>)>B+*s,qAFn.C W+G4_ 1xJK?h `U Jj3R;_I}CJALVMo,l3C=(u00gF(bC'v" !F㿉v-ρI|Bu6>K aԧpL?7eۏl;m*^=ko| z>^14OPCb\Z5 )8U_k$a0j&KGʼnÆ/ňYYװ:BԿo|'e] B \,//=wդįl Sk4^A"]aCCҶU'[op­z>iVIЀfG%0qEԂh6Jp%H݁K S /tB?;o 4Lfl^IAkΑ?Gvg^_Hg= xWE2hP/ӌ9ƛhΒ.If\]:@o*|D+xu.yJ:T}rwIg G:rQ cSdƐphoF☵/JliנhIUQc:J~/$._t3V"hD ~yv;\JiiĴOY⤯x6!w"i:4OMb>BCiEG:z超|?ԫA#%^4ԋ)XB" _ܣ|SH̎Hm  6o|Ȏǧe}:*|V3'랏$` nb\(%8?kDԒX4g.+E\e|UW\ҲCMՓؼ_OCC:WQxU<Պ>6PPn7qL3hY+^xJPsK)tQ7p1^xcc nGb70vԴPa>{}~!",J*\|&ݠjMѯ_W%*Mʟܗ.B@zƔhDڞԣ|HK`y9 pe2@'_ZbAfл(d/V5t'ۊ19/Y  ne~Ŵzǂ=rOBbT ~6<>%)2 5~^򰶷$k -՗=(įzd-۴wψًakSqav,XixFmgKHTB04_8E&kI!ڵܾc y1Ir*"^'V5 cm8ѫQ_H?Al o|Ďg]?7A\k{W*oVE.-Z|E(tҲXeim(^>gNv4hO#:><,U%SCý=Qfd2t63+7F<'n83`#q|,nug҉ih71`C&]ż_+ A=."7!I',%lmi5{G{[Py;D?;ԯ>"iVGORTF:C:Zo!p!_`g{\W-|/4jRYi fNo3 Nv@21MYyi_iAചBȑa ZU)RᎭkn߫.ֺic؋Z>ֻHo9Ѷ<}vonc:rYYV:oʋKm#AOWGKGMB\/;[-yoV:$)f fߣi9;${-F=1{_ ;y<yY_1_MzϞ vkP5>iL쩶ߊu=NKE֏| UjP*nNQxULDS$R%w$-cvf^H|'PP?Mo^[$T~Dw#d;P~zižUpLXW(_}_?̊JX kRoxM~-o>kZ1@ { 7G&)XѯfhK3tAګŽZlԎ/VD>嫏Hhf>NN.UTn=g&~bޛ@cʼ@>)DWRWzHKʺ,uHs?"G-1=3rHs~545%PD;} CZ)_}Dv/f>qHFsuH WWI2>i}|<1uHKUXIii44]^xi0y$F#'x%w=M{k?[` ]8*}+ʉ,pˁ->6m?fYYA=ڐ&q|ppzqDpKk~jD7E+^8*f %@`丏<Y,ٕ@2bv OotSB' m~h{X]N&i>4WSpEj*%$wX y,{ü;ԏ>vx)ovOI&RG0vԉḄOʻ7JBIf"Fai]tLuJs)%Ѷ3NWjcҶ>^Is5wCuc|G]e$)_HFΞzR"(:"25?(GSuU h$Co{Exn)R;.rMx7>dӲbտ F6F|e sv#H-)jhbjiGt[h[3DƤmmgk8 IGj´\ ٶp P[I 4-YVY\w̍9VF0-soA $@}4j`1XIi_y(bc\,V/Y GNB XH x٩V}[h_:Z[1;Okޫ~1i[b K~?|ĵXÿ~-w_pA?_GA ls{?':hX2~rn|k9wcvO]ѿFR'Ck\I[!էAA A+̢\K}!3Nԯ[VM|˭Cm kU䀘o M:xC!NTgTL{d(D$T9K(,4;3'Wm1\Il)Yʋ/#^1j>ZiM-A;B[~o`;@`#"/i%Z}^,|5_HV_wgSPv? r5w |.&?~ȭ9",s1['o{JIC'mWZkz“+SEץ`5ڙRƫњ|`+^RZI٥jtP l^5giS)&*dI)GԕZO΢SJzwH(qp>ж>x\*ռ({J/R2hBߌrͯE){.:㫫9+RG ӟ _ug\(5dDZnB~?䉖.Cs<W磔Ec [Ϧ㕀[}ϫlzBL jC5Bt|y 8u|R]ǒD4(/+ oTK‘6RAjb&K胄(kE*\޴>Ј$4+zSendstream endobj 5 0 obj 25267 endobj 3 0 obj << /Type /Page /MediaBox [0 0 486 481] /Parent 2 0 R /Resources << /ProcSet [/PDF /Text] /Font << /R6 6 0 R >> >> /Contents 4 0 R >> endobj 6 0 obj <> endobj 2 0 obj << /Type /Pages /Kids [ 3 0 R ] /Count 1 >> endobj 1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj 7 0 obj << /CreationDate (D:20011015154900) /Producer (Aladdin Ghostscript 5.50) >> endobj xref 0 8 0000000000 65535 f 0000025651 00000 n 0000025592 00000 n 0000025373 00000 n 0000000015 00000 n 0000025352 00000 n 0000025521 00000 n 0000025700 00000 n trailer << /Size 8 /Root 1 0 R /Info 7 0 R >> startxref 25791 %%EOF e1071/vignettes/svmdoc.Rnw0000644000175100001440000004336512262774461015046 0ustar hornikusers\documentclass[a4paper]{article} \usepackage{hyperref, graphicx, color, alltt} \usepackage{Sweave} \usepackage[round]{natbib} \definecolor{Red}{rgb}{0.7,0,0} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{hellgrau}{rgb}{0.55,0.55,0.55} \newcommand{\pkg}[1]{\texttt{#1}} \newenvironment{smallexample}{\begin{alltt}\small}{\end{alltt}} \begin{document} %\VignetteIndexEntry{Support Vector Machines---the Interface to libsvm in package e1071} %\VignetteDepends{e1071,rpart,xtable} %\VignetteKeywords{classification, regression, machine learning, benchmarking, support vector machines} %\VignettePackage{e1071} \SweaveOpts{engine=R,eps=FALSE} \setkeys{Gin}{width=0.8\textwidth} \title{Support Vector Machines \footnote{A smaller version of this article appeared in R-News, Vol.1/3, 9.2001}\\ \large The Interface to \texttt{libsvm} in package \pkg{e1071}} \author{by David Meyer\\ FH Technikum Wien, Austria\\ \url{David.Meyer@R-Project.org} } \maketitle \sloppy ``Hype or Hallelujah?'' is the provocative title used by \cite{svm:bennett+campbell:2000} in an overview of Support Vector Machines (SVM). SVMs are currently a hot topic in the machine learning community, creating a similar enthusiasm at the moment as Artificial Neural Networks used to do before. Far from being a panacea, SVMs yet represent a powerful technique for general (nonlinear) classification, regression and outlier detection with an intuitive model representation. The package \pkg{e1071} offers an interface to the award-winning\footnote{The library won the IJCNN 2001 Challenge by solving two of three problems: the Generalization Ability Challenge (GAC) and the Text Decoding Challenge (TDC). For more information, see: \url{http://www.csie.ntu.edu.tw/~cjlin/papers/ijcnn.ps.gz}.} C++-implementation by Chih-Chung Chang and Chih-Jen Lin, \texttt{libsvm} (current version: 2.6), featuring: \begin{itemize} \item $C$- and $\nu$-classification \item one-class-classification (novelty detection) \item $\epsilon$- and $\nu$-regression \end{itemize} and includes: \begin{itemize} \item linear, polynomial, radial basis function, and sigmoidal kernels \item formula interface \item $k$-fold cross validation \end{itemize} For further implementation details on \texttt{libsvm}, see \cite{svm:chang+lin:2001}. \section*{Basic concept} SVMs were developed by \cite{svm:cortes+vapnik:1995} for binary classification. Their approach may be roughly sketched as follows: \begin{description} \item[Class separation:] basically, we are looking for the optimal separating hyperplane between the two classes by maximizing the \textit{margin} between the classes' closest points (see Figure \ref{fig:svm1})---the points lying on the boundaries are called \textit{support vectors}, and the middle of the margin is our optimal separating hyperplane; \item[Overlapping classes:] data points on the ``wrong'' side of the discriminant margin are weighted down to reduce their influence (\textit{``soft margin''}); \item[Nonlinearity:] when we cannot find a \textit{linear} separator, data points are projected into an (usually) higher-dimensional space where the data points effectively become linearly separable (this projection is realised via \textit{kernel techniques}); \item[Problem solution:] the whole task can be formulated as a quadratic optimization problem which can be solved by known techniques. \end{description} \noindent A program able to perform all these tasks is called a \textit{Support Vector Machine}. \begin{figure}[htbp] \begin{center} \includegraphics[width=8cm]{svm} \caption{Classification (linear separable case)} \label{fig:svm1} \end{center} \end{figure} Several extensions have been developed; the ones currently included in \texttt{libsvm} are: \begin{description} \item[$\nu$-classification:] this model allows for more control over the number of support vectors \cite[see][]{svm:scholkopf+smola+williamson:2000} by specifying an additional parameter $\nu$ which approximates the fraction of support vectors; \item[One-class-classification:] this model tries to find the support of a distribution and thus allows for outlier/novelty detection; \item[Multi-class classification:] basically, SVMs can only solve binary classification problems. To allow for multi-class classification, \texttt{libsvm} uses the \textit{one-against-one} technique by fitting all binary subclassifiers and finding the correct class by a voting mechanism; \item[$\epsilon$-regression:] here, the data points lie \textit{in between} the two borders of the margin which is maximized under suitable conditions to avoid outlier inclusion; \item[$\nu$-regression:] with analogue modifications of the regression model as in the classification case. \end{description} \section*{Usage in R} The R interface to \texttt{libsvm} in package \pkg{e1071}, \texttt{svm()}, was designed to be as intuitive as possible. Models are fitted and new data are predicted as usual, and both the vector/matrix and the formula interface are implemented. As expected for R's statistical functions, the engine tries to be smart about the mode to be chosen, using the dependent variable's type ($y$): if $y$ is a factor, the engine switches to classification mode, otherwise, it behaves as a regression machine; if $y$ is omitted, the engine assumes a novelty detection task. \section*{Examples} In the following two examples, we demonstrate the practical use of \texttt{svm()} along with a comparison to classification and regression trees as implemented in \texttt{rpart()}. \subsection*{Classification} In this example, we use the glass data from the \href{http://www.ics.uci.edu/mlearn/MLRepository.html}{UCI Repository of Machine Learning Databases} for classification. The task is to predict the type of a glass on basis of its chemical analysis. We start by splitting the data into a train and test set: <<>>= library(e1071) library(rpart) data(Glass, package="mlbench") ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- Glass[testindex,] trainset <- Glass[-testindex,] @ Both for the SVM and the partitioning tree (via \texttt{rpart()}), we fit the model and try to predict the test set values: <<>>= ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) @ (The dependent variable, \texttt{Type}, has column number 10. \texttt{cost} is a general penalizing parameter for $C$-classification and \texttt{gamma} is the radial basis function-specific kernel parameter.) <<>>= ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") @ A cross-tabulation of the true versus the predicted values yields: <<>>= ## compute svm confusion matrix table(pred = svm.pred, true = testset[,10]) ## compute rpart confusion matrix table(pred = rpart.pred, true = testset[,10]) @ %% results table <>= library(xtable) rp.acc <- c() sv.acc <- c() rp.kap <- c() sv.kap <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Glass) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Glass[testindex,]) trainset <- na.omit(Glass[-testindex,]) ## svm svm.model <- svm(Type ~ ., data = trainset, cost = 100, gamma = 1) svm.pred <- predict(svm.model, testset[,-10]) tab <- classAgreement(table(svm.pred, testset[,10])) sv.acc[i] <- tab$diag sv.kap[i] <- tab$kappa ## rpart rpart.model <- rpart(Type ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-10], type = "class") tab <- classAgreement(table(rpart.pred, testset[,10])) rp.acc[i] <- tab$diag rp.kap[i] <- tab$kappa } x <- rbind(summary(sv.acc), summary(sv.kap), summary(rp.acc), summary(rp.kap)) rownames <- c() tab <- cbind(rep(c("svm","rpart"),2), round(x,2)) colnames(tab)[1] <- "method" rownames(tab) <- c("Accuracy","","Kappa"," ") xtable(tab, label = "tab:class", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for classification (10 replications)") @ \noindent Finally, we compare the performance of the two methods by computing the respective accuracy rates and the kappa indices (as computed by \texttt{classAgreement()} also contained in package \pkg{e1071}). In Table \ref{tab:class}, we summarize the results of \Sexpr{reps} replications---Support Vector Machines show better results. \subsection*{Non-linear $\epsilon$-Regression} The regression capabilities of SVMs are demonstrated on the ozone data. Again, we split the data into a train and test set. <<>>= library(e1071) library(rpart) data(Ozone, package="mlbench") ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) crossprod(rpart.pred - testset[,3]) / length(testindex) @ <>= rp.res <- c() sv.res <- c() reps <- 10 for (i in 1:reps) { ## split data into a train and test set index <- 1:nrow(Ozone) testindex <- sample(index, trunc(length(index)/3)) testset <- na.omit(Ozone[testindex,-3]) trainset <- na.omit(Ozone[-testindex,-3]) ## svm svm.model <- svm(V4 ~ ., data = trainset, cost = 1000, gamma = 0.0001) svm.pred <- predict(svm.model, testset[,-3]) sv.res[i] <- crossprod(svm.pred - testset[,3]) / length(testindex) ## rpart rpart.model <- rpart(V4 ~ ., data = trainset) rpart.pred <- predict(rpart.model, testset[,-3]) rp.res[i] <- crossprod(rpart.pred - testset[,3]) / length(testindex) } xtable(rbind(svm = summary(sv.res), rpart = summary(rp.res)), label = "tab:reg", caption = "Performance of \\texttt{svm()} and\ \\texttt{rpart()} for regression (Mean Squared Error, 10 replications)") @ \noindent We compare the two methods by the mean squared error (MSE)---see Table \ref{tab:reg} for a summary of \Sexpr{reps} replications. Again, as for classification, \texttt{svm()} does a better job than \texttt{rpart()}---in fact, much better. \section*{Elements of the \texttt{svm} object} The function \texttt{svm()} returns an object of class ``\texttt{svm}'', which partly includes the following components: \begin{description} \item[\textbf{\texttt{SV}:}] matrix of support vectors found; \item[\textbf{\texttt{labels}:}] their labels in classification mode; \item[\textbf{\texttt{index}:}] index of the support vectors in the input data (could be used e.g., for their visualization as part of the data set). \end{description} If the cross-classification feature is enabled, the \texttt{svm} object will contain some additional information described below. \section*{Other main features} \begin{description} \item[Class Weighting:] if one wishes to weight the classes differently (e.g., in case of asymmetric class sizes to avoid possibly overproportional influence of bigger classes on the margin), weights may be specified in a vector with named components. In case of two classes A and B, we could use something like: \texttt{m <- svm(x, y, class.weights = c(A = 0.3, B = 0.7))} \item[Cross-classification:] to assess the quality of the training result, we can perform a $k$-fold cross-classification on the training data by setting the parameter \texttt{cross} to $k$ (default: 0). The \texttt{svm} object will then contain some additional values, depending on whether classification or regression is performed. Values for classification: \begin{description} \item[\texttt{accuracies}:] vector of accuracy values for each of the $k$ predictions \item[\texttt{tot.accuracy}:] total accuracy \end{description} Values for regression: \begin{description} \item[\texttt{MSE}:] vector of mean squared errors for each of the $k$ predictions \item[\texttt{tot.MSE}:] total mean squared error \item[\texttt{scorrcoef}:] Squared correlation coefficient (of the predicted and the true values of the dependent variable) \end{description} \end{description} \section*{Tips on practical use} \begin{itemize} \item Note that SVMs may be very sensible to the proper choice of parameters, so allways check a range of parameter combinations, at least on a reasonable subset of your data. \item For classification tasks, you will most likely use $C$-classification with the RBF kernel (default), because of its good general performance and the few number of parameters (only two: $C$ and $\gamma$). The authors of \pkg{libsvm} suggest to try small and large values for $C$---like 1 to 1000---first, then to decide which are better for the data by cross validation, and finally to try several $\gamma$'s for the better $C$'s. \item However, better results are obtained by using a grid search over all parameters. For this, we recommend to use the \texttt{tune.svm()} function in \pkg{e1071}. \item Be careful with large datasets as training times may increase rather fast. \item Scaling of the data usually drastically improves the results. Therefore, \texttt{svm()} scales the data by default. \end{itemize} \section*{Model Formulations and Kernels} Dual representation of models implemented: \begin{itemize} \item $C$-classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha-e^\top\alpha \nonumber\\ \mbox{s.t.} &&0\le\alpha_i\le C,~i=1,\ldots,l,\\ &&\mathbf{y}^\top\alpha=0~, \nonumber \end{eqnarray} where $\mathbf{e}$ is the unity vector, $C$ is the upper bound, $\mathbf{Q}$ is an $l$ by $l$ positive semidefinite matrix, $Q_{ij} \equiv y_i y_j K(x_i, x_j)$, and $K(x_i, x_j) \equiv \phi(x_i)^\top\phi(x_j)$ is the kernel. \item $\nu$-classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha \nonumber\\ \mbox{s.t.}&&0\le\alpha_i\le 1/l,~i=1,\ldots,l,\\ &&\mathbf{e}^\top \alpha \ge \nu, \nonumber\\ &&\mathbf{y}^\top\alpha=0~. \nonumber \end{eqnarray} where $\nu \in (0,1]$. \item one-class classification:\\ \begin{eqnarray} \min_\alpha&&\frac{1}{2}\alpha^\top \mathbf{Q} \alpha \nonumber\\ \mbox{s.t.} &&0\le\alpha_i\le 1/(\nu l),~i=1,\ldots,l,\\ &&\mathbf{e}^\top\alpha=1~,\nonumber \end{eqnarray} \item $\epsilon$-regression:\\ \begin{eqnarray} \min_{\alpha, \alpha^*}&&\frac{1}{2}(\alpha-\alpha^*)^\top \mathbf{Q} (\alpha-\alpha^*) + \nonumber\\ &&\epsilon\sum_{i=1}^{l}(\alpha_i+\alpha_i^*) + \sum_{i=1}^{l}y_i(\alpha_i-\alpha_i^*) \nonumber\\ \mbox{s.t.} &&0\le\alpha_i, \alpha_i^*\le C,~i=1,\ldots,l,\\ &&\sum_{i=1}^{l}(\alpha_i-\alpha_i^*)=0~.\nonumber \end{eqnarray} \item $\nu$-regression:\\ \begin{eqnarray} \min_{\alpha, \alpha^*}&&\frac{1}{2}(\alpha-\alpha^*)^\top \mathbf{Q} (\alpha-\alpha^*) + \mathbf{z}^\top(\alpha_i-\alpha_i^*) \nonumber\\ \mbox{s.t.} &&0\le\alpha_i, \alpha_i^*\le C,~i=1,\ldots,l,\\ &&\mathbf{e}^\top(\alpha-\alpha^*)=0\nonumber\\ &&\mathbf{e}^\top(\alpha+\alpha^*)=C\nu~.\nonumber \end{eqnarray} \end{itemize} \noindent Available kernels:\\ \\ \noindent \begin{table}[h] \centering \begin{tabular}{|l|l|l|} \hline kernel & formula & parameters \\ \hline \hline linear & $\bf u^\top v$& (none) \\ polynomial & $\gamma (\mathbf{u^\top v}+c_0)^d$ & $\gamma, d, c_0$\\ radial basis fct. & $\exp\{-\gamma|\mathbf{u-v}|^2\}$&$\gamma$\\ sigmoid & $\tanh\{\gamma \mathbf{u^\top v}+c_0\}$ &$\gamma, c_0$\\ \hline \end{tabular} \end{table} \section*{Conclusion} We hope that \texttt{svm} provides an easy-to-use interface to the world of SVMs, which nowadays have become a popular technique in flexible modelling. There are some drawbacks, though: SVMs scale rather badly with the data size due to the quadratic optimization algorithm and the kernel transformation. Furthermore, the correct choice of kernel parameters is crucial for obtaining good results, which practically means that an extensive search must be conducted on the parameter space before results can be trusted, and this often complicates the task (the authors of \texttt{libsvm} currently conduct some work on methods of efficient automatic parameter selection). Finally, the current implementation is optimized for the radial basis function kernel only, which clearly might be suboptimal for your data. \begin{thebibliography}{5} \bibitem[Bennett \& Campbell(2000)]{svm:bennett+campbell:2000} Bennett, K.~P. \& Campbell, C. (2000). \newblock Support vector machines: Hype or hallelujah? \newblock \emph{SIGKDD Explorations}, \textbf{2}(2). \newblock \url{http://www.acm.org/sigs/sigkdd/explorations/issue2-2/bennett.pdf}. \bibitem[Chang \& Lin(2001)]{svm:chang+lin:2001} Chang, C.-C. \& Lin, C.-J. (2001). \newblock {LIBSVM}: a library for support vector machines. \newblock Software available at \url{http://www.csie.ntu.edu.tw/~cjlin/libsvm}, detailed documentation (algorithms, formulae, \dots) can be found in \url{http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.ps.gz} \bibitem[Cortes \& Vapnik(1995)]{svm:cortes+vapnik:1995} Cortes, C. \& Vapnik, V. (1995). \newblock Support-vector network. \newblock \emph{Machine Learning}, \textbf{20}, 1--25. \bibitem[Sch\"olkopf et~al.(2000)Sch\"olkopf, Smola, Williamson, \& Bartlett]{svm:scholkopf+smola+williamson:2000} Sch\"olkopf, B., Smola, A., Williamson, R.~C., \& Bartlett, P. (2000). \newblock New support vector algorithms. \newblock \emph{Neural Computation}, \textbf{12}, 1207--1245. \bibitem[Vapnik(1998)]{svm:vapnik:1998} Vapnik, V. (1998). \newblock \emph{Statistical learning theory}. \newblock New York: Wiley. \end{thebibliography} \end{document} e1071/vignettes/svminternals.Rnw0000644000175100001440000001611312547044621016261 0ustar hornikusers\documentclass[a4paper]{article} \usepackage{hyperref, graphicx, color, alltt,a4wide} \usepackage{Sweave} \newcommand{\pkg}[1]{\texttt{#1}} \definecolor{Red}{rgb}{0.7,0,0} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{hellgrau}{rgb}{0.55,0.55,0.55} \newenvironment{smallexample}{\begin{alltt}\small}{\end{alltt}} \begin{document} %\VignetteIndexEntry{svm() internals} %\VignetteDepends{xtable} %\VignetteKeywords{classification, regression, machine learning, benchmarking, support vector machines} %\VignettePackage{e1071} \SweaveOpts{engine=R,eps=FALSE} \setkeys{Gin}{width=0.8\textwidth} \title{\texttt{svm()} internals\\ \large Some technical notes about the \texttt{svm()} in package \pkg{e1071}} \author{by David Meyer\\ FH Technikum Wien, Austria\\ \url{David.Meyer@R-Project.org} } \maketitle \sloppy This document explains how to use the parameters in an object returned by \texttt{svm()} for own prediction functions. \section{Binary Classifier} For class prediction in the binary case, the class of a new data vector $n$ is usually given by \emph{the sign} of \begin{equation} \sum_i{a_i y_i K(x_i, n)} + \rho \end{equation} \noindent where $x_i$ is the $i$-th support vector, $y_i$ the corresponding label, $a_i$ the corresponding coefficiant, and $K$ is the kernel (for example the linear one, i.e. $K(u,v) = u ^{\top} v$). Now, the \texttt{libsvm} library interfaced by the \texttt{svm()} function actually returns $a_i y_i$ as $i$-th coefficiant and the \emph{negative} $\rho$, so in fact uses the formula: \[ \sum_i{\mathrm{coef}_i K(x_i, n)} - \rho \] \noindent where the training examples (=training data) are labeled \{1,-1\} (!). A simplified \textsf{R} function for prediction with linear kernel would be: \begin{smallexample} svmpred <- function (m, newdata, K=crossprod) \{ ## this guy does the computation: pred.one <- function (x) sign(sum(sapply(1:m$tot.nSV, function (j) K(m$SV[j,], x) * m$coefs[j] ) ) - m$rho ) ## this is just for convenience: if (is.vector(newdata)) newdata <- t(as.matrix(x)) sapply (1:nrow(newdata), function (i) pred.one(newdata[i,])) \} \end{smallexample} \noindent where \texttt{pred.one()} does the actual prediction for one new data vector, the remainder is just a convenience for prediction of multiple new examples. It is easy to extend this to other kernels, just replace \texttt{K()} with the appropriate function (see the help page for the formulas used) and supply the additional constants. As we will see in the next section, the multi-class prediction is more complicated, because the coefficiants of the diverse binary SVMs are stored in a compressed format. \section{Multiclass-classifier} To handle $k$ classes, $k>2$, \texttt{svm()} trains all binary subclassifiers (one-against-one-method) and then uses a voting mechanism to determine the actual class. Now, this means $k(k-1)/2$ classifiers, hence in principle $k(k-1)/2$ sets of SVs, coefficiants and rhos. These are stored in a compressed format: \begin{enumerate} \item Only one SV is stored in case it were used by several classifiers. The \texttt{model\$SV-matrix} is ordered by classes, and you find the starting indices by using \texttt{nSV} (number of SVs): \begin{smallexample} start <- c(1, cumsum(model$nSV)) start <- start[-length(start)] \end{smallexample} \texttt{sum(nSV)} equals the total number of (distinct) SVs. \item The coefficients of the SVs are stored in the \texttt{model\$coefs}-matrix, grouped by classes. Because the separating hyperplanes found by the SVM algorithm has SVs on both sides, you will have two sets of coefficients per binary classifier, and e.g., for 3 classes, you could build a \emph{block}-matrix like this for the classifiers $(i, j)$ ($i$,$j$=class numbers): \begin{table}[h] \center \begin{tabular}{|c|c|c|c|} \hline i $\backslash$ j & 0 & 1 & 2 \\\hline 0 & X & set (0, 1)& set (0, 2)\\\hline 1 & set (1, 0) & X & set (1, 2)\\\hline 2 & set (2, 0) & set (2, 1) & X\\\hline \end{tabular} \end{table} \noindent where set(i, j) are the coefficients for the classifier (i,j), lying on the side of class j. Because there are no entries for (i, i), we can save the diagonal and shift up the lower triangular matrix to get \begin{table}[h] \center \begin{tabular}{|c|c|c|c|} \hline i $\backslash$ j & 0 & 1 & 2 \\\hline 0 & set (1,0) & set (0,1) & set (0,2) \\\hline 1 & set (2,0) & set (2,1) & set (1,2) \\\hline \end{tabular} \end{table} \noindent Each set (., j) has length \texttt{nSV[j]}, so of course, there will be some filling 0s in some sets. \texttt{model\$coefs} is the \emph{transposed} of such a matrix, therefore for a data set with, say, 6 classes, you get 6-1=5 columns. The coefficients of (i, j) start at \texttt{model\$coefs[start[i],j]} and those of (j, i) at \texttt{model\$coefs[start[j],i-1]}. \item The $k(k-1)/2$ rhos are just linearly stored in the vector \texttt{model\$rho}. \end{enumerate} \newpage \noindent The following code shows how to use this for prediction: \begin{smallexample} ## Linear Kernel function K <- function(i,j) crossprod(i,j) predsvm <- function(object, newdata) \{ ## compute start-index start <- c(1, cumsum(object$nSV)+1) start <- start[-length(start)] ## compute kernel values kernel <- sapply (1:object$tot.nSV, function (x) K(object$SV[x,], newdata)) ## compute raw prediction for classifier (i,j) predone <- function (i,j) \{ ## ranges for class i and j: ri <- start[i] : (start[i] + object$nSV[i] - 1) rj <- start[j] : (start[j] + object$nSV[j] - 1) ## coefs for (i,j): coef1 <- object$coefs[ri, j-1] coef2 <- object$coefs[rj, i] ## return raw values: crossprod(coef1, kernel[ri]) + crossprod(coef2, kernel[rj]) \} ## compute votes for all classifiers votes <- rep(0,object$nclasses) c <- 0 # rho counter for (i in 1 : (object$nclasses - 1)) for (j in (i + 1) : object$nclasses) if (predone(i,j) > object$rho[c <- c + 1]) votes[i] <- votes[i] + 1 else votes[j] <- votes[j] + 1 ## return winner (index with max. votes) object$levels[which(votes %in% max(votes))[1]] \} \end{smallexample} In case data were scaled prior fitting the model (note that this is the default for \texttt{svm()}, the new data needs to be scaled as well before applying the predition functions, for example using the following code snipped (object is an object returned by \texttt{svm()}, \texttt{newdata} a data frame): \begin{smallexample} if (any(object$scaled)) newdata[,object$scaled] <- scale(newdata[,object$scaled, drop = FALSE], center = object$x.scale$"scaled:center", scale = object$x.scale$"scaled:scale" ) \end{smallexample} \noindent For regression, the response needs to be scaled as well before training, and the predictions need to be scaled back accordingly. \end{document} e1071/MD50000644000175100001440000001162112560437400011337 0ustar hornikusers09ebbb291a1cbb9ce022209f4fe598c0 *DESCRIPTION daca9f6af623c7fd1bf06fbdce216f5f *NAMESPACE dbf1fc5e33e50fbeb2b34278a62edeed *R/bclust.R e42d535057714da65c807409febb5be8 *R/bincombinations.R 1ba9dc7b9d766f48f5ec1f691449f3a1 *R/cmeans.R fd4d3eb836e8d3c0cfcdfc2ea51950c3 *R/countpattern.R b9f884b69586d50154b6339ee7cf62bb *R/cshell.R 971efff8ec1f8b3a4a0f3dd6c58e4014 *R/discrete.R d41d8cd98f00b204e9800998ecf8427e *R/e1071-deprecated.R 4287fb25fb942b55d950e9de2d1aaa36 *R/element.R 4aaa630b440da4ffcad0f29b0a47a319 *R/fclustIndex.R 6daec6d2db476530b6d439af0aafdce1 *R/hamming.distance.R 56906cfd1a1ce8fcc772e85fc39f0325 *R/hamming.window.R 3c39c73411e9280258b9e5043a654900 *R/hanning.window.R b7afef78d7b3bfac19b3055a0757410a *R/ica.R 0a3d0a8de11821b3cacd9ae5ca508d59 *R/impute.R 7086a3457d63ee76c4e17555c7ebeaf8 *R/interpolate.R 16536adfb4a3b2b639e7a9f30b36ef87 *R/kurtosis.R e7de49d6d55f0e67aa53446d096be0a2 *R/lca.R 2cfaaf8eb47a18898183615f1f6b8c44 *R/matchClasses.R 7acaf931ab8c21502eb739b1b1c8d640 *R/matchControls.R ac88f22d04fa8e5745033f4b67bb8beb *R/moment.R 892c875badb8a51bb2a318cdfb66b24a *R/naiveBayes.R 8e1ad1d11cc51d56f3567d0465bb1b71 *R/plot.stft.R 89c1c475c981b0ee83ca5663f1b1554d *R/probplot.R 387e1108e948f03d5aea9649e368b699 *R/rbridge.R 3789f8392daf68d346c780027d5ad876 *R/rectangle.window.R 37584ee4f166291d086f2597090ae0d8 *R/rwiener.R 58c4b4830f377dac9e13e7595409c081 *R/shortestPaths.R 48af933aaa58ec5f8619f9e0537b78ff *R/sigmoid.R c81f35fe8c448b8d8f054e77ded9c3fb *R/skewness.R c4cd8ad63c2a83981ab9637b5d62ab54 *R/sparse.R bed8f86b4b9c45ebf4c847960b7a6824 *R/stft.R 780d8db1311a5d8c5bb23ad58a97a514 *R/svm.R 5a7d69231975994a048353bc896c1a44 *R/tune.R ce98a8de7d8c04ed4b53552152ccad7b *build/vignette.rds fb6b792a9e8e2594594fa576710065cf *cleanup 01d04a23dccc58d5ac29e6f77a01ea11 *configure 4563bd3d99118cc5843e6fada62bd8cd *configure.ac 72f24c323606f2b78efb6b217aca3af9 *inst/NEWS.Rd 83303ca1cdf472b2962d78f7c04078a1 *inst/doc/svmdoc.R 8d514f9eee974393892ce82d056407aa *inst/doc/svmdoc.Rnw 41ddecb77a440c33888f931c87f300c1 *inst/doc/svmdoc.pdf 0b80939360bc7f55d1e04be24adf8872 *inst/doc/svminternals.Rnw ede1c72afa7f9884a371b22922bb29cf *inst/doc/svminternals.pdf e7d7541d75e4ecda9570a9f8f90d2439 *man/Discrete.Rd 80a3e4f095a9e8754fe3f201137d27f5 *man/bclust.Rd 168807874afed9032ae4b1732f25a73e *man/bincombinations.Rd 762f550c0c851e6a5c197ffd46d8ff44 *man/bootstrap.lca.Rd 964b1c10eea943f824c2865c9d728249 *man/boxplot.bclust.Rd 8603274376f301d1d9ddf5a096c4b765 *man/classAgreement.Rd 5394b0243c4f5ea7d0adc29d906e9615 *man/cmeans.Rd 1f2181682f48caf798cb7d49bd7f3c07 *man/countpattern.Rd c70249d75c2d8035982303c4a18dd915 *man/cshell.Rd e9df0cc673e6fcbb343ddb75ab347c0f *man/e1071-deprecated.Rd fb37ec4196c22c3702a7f83616f0f132 *man/element.Rd 36da964aaa376b6e05fc9f696fa270da *man/fclustIndex.Rd 88d0e6f9c58e13547be01a5c53483321 *man/hamming.distance.Rd c4a293671687db22aedd5d1bcd4cb670 *man/hamming.window.Rd b14517cf4646473fb9c342fafbceb4b3 *man/hanning.window.Rd ab9bfe34bf36c1d7d728f7e40a97e29b *man/hsv_palette.Rd 03db09cc98b364bc8220ce2d0f04be43 *man/ica.Rd 8122102191f249f0b38a07292f3e6ac5 *man/impute.Rd e39603b710ecc4a5f3ac9545344aea83 *man/interpolate.Rd 02f738fa4d08d0d5a591f300ed769b3d *man/kurtosis.Rd 294b32ebab87b29217a6bb3287db0bc9 *man/lca.Rd 2c4b89670725817a00a37b1e4c2782ad *man/matchClasses.Rd bff8b2955811e8115a955972ea80ff55 *man/matchControls.Rd d7d971f2e38d972135df9dae8babf2d7 *man/moment.Rd d85b6a16d76b0971e2ee98aaf8ad0c4c *man/naiveBayes.Rd 694a2cbf822a403fc9a6a1c9ac408b37 *man/permutations.Rd 4c5574df4e6adeb8520097531cc02234 *man/plot.stft.Rd 027c1963b36b104e9d4e5584fc78e57f *man/plot.svm.Rd dd163128b5fd3a26a3142787cfc0f500 *man/plot.tune.Rd 6c5c209c6af13e83d78890033eaa06c3 *man/predict.svm.Rd 25c76212b1f8cb24c5ed64ff60283412 *man/probplot.Rd b47af3167e2df93d92a5a74949eabf7c *man/rbridge.Rd 3f17fe6c456abcb866ead028c1935bce *man/read.matrix.csr.Rd 233e2fedbbd374142e6747bf74a3fe95 *man/rectangle.window.Rd 16b7402d275eb839a9e2de21f5c3ee27 *man/rwiener.Rd cc985e432831de33f9dce6832388a00c *man/shortestPaths.Rd 8b5d2082ad2377650db04cb01a963e99 *man/sigmoid.Rd 5dbf4948c6c7ead41a658be75a24e3fb *man/skewness.Rd fe077a9a20d0e3349a32a3369758f97e *man/stft.Rd 4e0dfa4dcb01de77f861d983e0c8e0f5 *man/svm.Rd 8432ef968590b77a4a391fd53004a457 *man/tune.Rd a920400b80897304d8c7e7c861a3eabc *man/tune.control.Rd 1b313aae35e5d8b495366127ec4fd33c *man/tune.wrapper.Rd 2858342b8f47ab5582a7d89103b10752 *man/write.svm.Rd 91a866fa6b3b5bebfd66865bf65772f1 *src/Rsvm.c 71dbe4e867b5c029eb630a96aee6f552 *src/cmeans.c 050b21afdf680cb53c7ad07985f34bd6 *src/cshell.c 3e8de7ef56baf940ba9fb88d6e73617e *src/floyd.c 8e7b2f9275e069e1acffad08bb0284d6 *src/svm.cpp c8ad0af0458e3ae11ecea7fa8194db65 *src/svm.cpp.orig ad0676691007efbaa6010cdf31293beb *src/svm.h 0cf3205810ff1e471ee07ab3d4c2bfad *tests/clustering.R 7f8951b054765414b6c2bdf282954286 *vignettes/svm.pdf 8d514f9eee974393892ce82d056407aa *vignettes/svmdoc.Rnw 0b80939360bc7f55d1e04be24adf8872 *vignettes/svminternals.Rnw e1071/build/0000755000175100001440000000000012560362404012126 5ustar hornikuserse1071/build/vignette.rds0000644000175100001440000000052212560362404014464 0ustar hornikusersőMO@(^BbQc)lhw/eZlv컯 0$K'{dZt%omzw"<%.=Z +n[ Jo9S]3Ei7"U&99LQzȝ(vq)aɯ|W7y!h{`=;w9nw8z*SpN%JWFW[Z$^nQJV+=e~ Repository: CRAN Date/Publication: 2015-08-05 18:51:12 e1071/configure0000755000175100001440000015540311400421345012736 0ustar hornikusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="DESCRIPTION" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd "$ac_popdir" done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then echo "could not determine R_HOME" exit 1 fi CXX=`${R_HOME}/bin/R CMD config CXX` ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "${GXX}" = yes; then gxx_version=`${CXX} --version` case ${gxx_version} in 2.96*) { echo "$as_me:$LINENO: WARNING: g++ 2.96 cannot reliably be used with this package." >&5 echo "$as_me: WARNING: g++ 2.96 cannot reliably be used with this package." >&2;} { { echo "$as_me:$LINENO: error: Please use a newer version of g++ or a different C++ compiler." >&5 echo "$as_me: error: Please use a newer version of g++ or a different C++ compiler." >&2;} { (exit 1); exit 1; }; } ;; esac fi e1071/man/0000755000175100001440000000000012505565430011605 5ustar hornikuserse1071/man/hanning.window.Rd0000644000175100001440000000142311400421345015011 0ustar hornikusers\name{hanning.window} \title{Computes the Coefficients of a Hanning Window.} \usage{hanning.window(n)} \alias{hanning.window} \arguments{ \item{n}{The length of the window.} } \description{The filter coefficients \eqn{w_i}{w(i)} of a Hanning window of length \code{n} are computed according to the formula \deqn{w_i = 0.5 - 0.5 \cos\frac{2\pi i}{n-1}}{ w(i) = 0.5 - 0.5*cos(2*pi*i/(n-1))} } \value{A vector containing the filter coefficients.} \references{For a definition of the Hanning window, see for example\cr Alan V. Oppenheim and Roland W. Schafer: "Discrete-Time Signal Processing", Prentice-Hall, 1989.} \author{Andreas Weingessel} \seealso{stft, hamming.window} \examples{hanning.window(10) x<-rnorm(500) y<-stft(x, wtype="hanning.window") plot(y) } \keyword{ts} e1071/man/tune.control.Rd0000644000175100001440000000523012444323171014522 0ustar hornikusers\name{tune.control} \alias{tune.control} \title{Control Parameters for the Tune Function} \description{ Creates an object of class \code{tune.control} to be used with the \code{tune} function, containing various control parameters. } \usage{ tune.control(random = FALSE, nrepeat = 1, repeat.aggregate = mean, sampling = c("cross", "fix", "bootstrap"), sampling.aggregate = mean, sampling.dispersion = sd, cross = 10, fix = 2/3, nboot = 10, boot.size = 9/10, best.model = TRUE, performances = TRUE, error.fun = NULL) } \arguments{ \item{random}{if an integer value is specified, \code{random} parameter vectors are drawn from the parameter space.} \item{nrepeat}{specifies how often training shall be repeated.} \item{repeat.aggregate}{function for aggregating the repeated training results.} \item{sampling}{sampling scheme. If \code{sampling = "cross"}, a \code{cross}-times cross validation is performed. If \code{sampling = "boot"}, \code{nboot} training sets of size \code{boot.size} (part) are sampled (with replacement) from the supplied data. If \code{sampling = "fix"}, a single split into training/validation set is used, the training set containing a \code{fix} part of the supplied data. Note that a separate validation set can be supplied via \code{validation.x} and \code{validation.y}. It is only used for \code{sampling = "boot"} and \code{sampling = "fix"}; in the latter case, \code{fix} is set to 1.} \item{sampling.aggregate,sampling.dispersion}{functions for aggregating the training results on the generated training samples (default: mean and standard deviation).} \item{cross}{number of partitions for cross-validation.} \item{fix}{part of the data used for training in fixed sampling.} \item{nboot}{number of bootstrap replications.} \item{boot.size}{size of the bootstrap samples.} \item{best.model}{if \code{TRUE}, the best model is trained and returned (the best parameter set is used for training on the complete training set).} \item{performances}{if \code{TRUE}, the performance results for all parameter combinations are returned.} \item{error.fun}{function returning the error measure to be minimized. It takes two arguments: a vector of true values and a vector of predicted values. If \code{NULL}, the misclassification error is used for categorical predictions and the mean squared error for numeric predictions.} } \value{ An object of class \code{"tune.control"} containing all the above parameters (either the defaults or the user specified values). } \author{ David Meyer\cr \email{David.Meyer@R-project.org} } \seealso{\code{\link{tune}}} \keyword{models} e1071/man/sigmoid.Rd0000644000175100001440000000073711400421345013523 0ustar hornikusers\name{sigmoid} \alias{sigmoid} \alias{dsigmoid} \alias{d2sigmoid} \title{The Logistic Function and Derivatives} \description{ Sigmoid \eqn{1/(1 + \exp(-x))}{1/(1 + exp(-x))}, first and second derivative.} \usage{ sigmoid(x) dsigmoid(x) d2sigmoid(x) } \arguments{ \item{x}{a numeric vector} } \author{Friedrich Leisch} \examples{ plot(sigmoid, -5, 5, ylim = c(-.2, 1)) plot(dsigmoid, -5, 5, add = TRUE, col = 2) plot(d2sigmoid, -5, 5, add = TRUE, col = 3) } \keyword{math} e1071/man/rwiener.Rd0000644000175100001440000000075711400421345013545 0ustar hornikusers\name{rwiener} \alias{rwiener} \title{Simulation of Wiener Process} \usage{ rwiener(end = 1, frequency = 1000) } \arguments{ \item{end}{the time of the last observation.} \item{frequency}{the number of observations per unit of time.} } \description{ \code{rwiener} returns a time series containing a simulated realization of the Wiener process on the interval [0,\code{end}] } \examples{ # simulate a Wiener process on [0,1] and plot it x <- rwiener() plot(x,type="l") } \keyword{distribution} e1071/man/tune.Rd0000644000175100001440000001035311400421345013036 0ustar hornikusers\name{tune} \alias{tune} \alias{best.tune} \alias{print.tune} \alias{summary.tune} \alias{print.summary.tune} \title{Parameter Tuning of Functions Using Grid Search} \description{ This generic function tunes hyperparameters of statistical methods using a grid search over supplied parameter ranges. } \usage{ tune(method, train.x, train.y = NULL, data = list(), validation.x = NULL, validation.y = NULL, ranges = NULL, predict.func = predict, tunecontrol = tune.control(), ...) best.tune(...) } \arguments{ \item{method}{either the function to be tuned, or a character string naming such a function.} \item{train.x}{either a formula or a matrix of predictors.} \item{train.y}{the response variable if \code{train.x} is a predictor matrix. Ignored if \code{train.x} is a formula.} \item{data}{data, if a formula interface is used. Ignored, if predictor matrix and response are supplied directly.} \item{validation.x}{an optional validation set. Depending on whether a formula interface is used or not, the response can be included in \code{validation.x} or separately specified using \code{validation.y}.} \item{validation.y}{if no formula interface is used, the response of the (optional) validation set.} \item{ranges}{a named list of parameter vectors spanning the sampling space. The vectors will usually be created by \code{seq}.} \item{predict.func}{optional predict function, if the standard \code{predict} behavior is inadequate.} \item{tunecontrol}{object of class \code{"tune.control"}, as created by the function \code{tune.control()}. If omitted, \code{tune.control()} gives the defaults.} \item{\dots}{Further parameters passed to the training functions.} } \value{ For \code{tune}, an object of class \code{tune}, including the components: \item{best.parameters}{a 1 x k data frame, k number of parameters.} \item{best.performance}{best achieved performance.} \item{performances}{if requested, a data frame of all parameter combinations along with the corresponding performance results.} \item{train.ind}{list of index vectors used for splits into training and validation sets.} \item{best.model}{if requested, the model trained on the complete training data using the best parameter combination.} \code{best.tune()} returns the best model detected by \code{tune}. } \details{ As performance measure, the classification error is used for classification, and the mean squared error for regression. It is possible to specify only one parameter combination (i.e., vectors of length 1) to obtain an error estimation of the specified type (bootstrap, cross-classification, etc.) on the given data set. For convenience, there are several \code{tune.foo()} wrappers defined, e.g., for \code{nnet()}, \code{randomForest()}, \code{rpart()}, \code{svm()}, and \code{knn()}. Cross-validation randomizes the data set before building the splits which---once created---remain constant during the training process. The splits can be recovered through the \code{train.ind} component of the returned object. } \author{ David Meyer\cr \email{David.Meyer@R-project.org} } \seealso{\code{\link{tune.control}}, \code{\link{plot.tune}}, \code{\link{tune.svm}}, \link{tune.wrapper}} \examples{ data(iris) ## tune `svm' for classification with RBF-kernel (default in svm), ## using one split for training/validation set obj <- tune(svm, Species~., data = iris, ranges = list(gamma = 2^(-1:1), cost = 2^(2:4)), tunecontrol = tune.control(sampling = "fix") ) ## alternatively: ## obj <- tune.svm(Species~., data = iris, gamma = 2^(-1:1), cost = 2^(2:4)) summary(obj) plot(obj) ## tune `knn' using a convenience function; this time with the ## conventional interface and bootstrap sampling: x <- iris[,-5] y <- iris[,5] obj2 <- tune.knn(x, y, k = 1:5, tunecontrol = tune.control(sampling = "boot")) summary(obj2) plot(obj2) ## tune `rpart' for regression, using 10-fold cross validation (default) data(mtcars) obj3 <- tune.rpart(mpg~., data = mtcars, minsplit = c(5,10,15)) summary(obj3) plot(obj3) ## simple error estimation for lm using 10-fold cross validation tune(lm, mpg~., data = mtcars) } \keyword{models} e1071/man/element.Rd0000644000175100001440000000064511400421345013517 0ustar hornikusers\name{element} \title{Extract Elements of an Array} \usage{ element(x, i) } \alias{element} \arguments{ \item{x}{Array of arbitrary dimensionality.} \item{i}{Vector of the same length as \code{x} has dimension.} } \description{ Returns the element of \code{x} specified by \code{i}. } \author{Friedrich Leisch} \seealso{\link{Extract}} \examples{ x <- array(1:20, dim=c(2,5,2)) element(x, c(1,4,2)) } \keyword{array} e1071/man/bclust.Rd0000644000175100001440000001160012547045550013370 0ustar hornikusers\name{bclust} \alias{bclust} \alias{hclust.bclust} \alias{plot.bclust} \alias{centers.bclust} \alias{clusters.bclust} \title{Bagged Clustering} \usage{ bclust(x, centers=2, iter.base=10, minsize=0, dist.method="euclidian", hclust.method="average", base.method="kmeans", base.centers=20, verbose=TRUE, final.kmeans=FALSE, docmdscale=FALSE, resample=TRUE, weights=NULL, maxcluster=base.centers, ...) hclust.bclust(object, x, centers, dist.method=object$dist.method, hclust.method=object$hclust.method, final.kmeans=FALSE, docmdscale = FALSE, maxcluster=object$maxcluster) \method{plot}{bclust}(x, maxcluster=x$maxcluster, main, ...) centers.bclust(object, k) clusters.bclust(object, k, x=NULL) } \arguments{ \item{x}{Matrix of inputs (or object of class \code{"bclust"} for plot).} \item{centers, k}{Number of clusters.} \item{iter.base}{Number of runs of the base cluster algorithm.} \item{minsize}{Minimum number of points in a base cluster.} \item{dist.method}{Distance method used for the hierarchical clustering, see \code{\link{dist}} for available distances.} \item{hclust.method}{Linkage method used for the hierarchical clustering, see \code{\link{hclust}} for available methods.} \item{base.method}{Partitioning cluster method used as base algorithm.} \item{base.centers}{Number of centers used in each repetition of the base method.} \item{verbose}{Output status messages.} \item{final.kmeans}{If \code{TRUE}, a final kmeans step is performed using the output of the bagged clustering as initialization.} \item{docmdscale}{Logical, if \code{TRUE} a \code{\link{cmdscale}} result is included in the return value.} \item{resample}{Logical, if \code{TRUE} the base method is run on bootstrap samples of \code{x}, else directly on \code{x}.} \item{weights}{Vector of length \code{nrow(x)}, weights for the resampling. By default all observations have equal weight.} \item{maxcluster}{Maximum number of clusters memberships are to be computed for.} \item{object}{Object of class \code{"bclust"}.} \item{main}{Main title of the plot.} \item{\dots}{Optional arguments top be passed to the base method in \code{bclust}, ignored in \code{plot}.} } \description{ Cluster the data in \code{x} using the bagged clustering algorithm. A partitioning cluster algorithm such as \code{\link{kmeans}} is run repeatedly on bootstrap samples from the original data. The resulting cluster centers are then combined using the hierarchical cluster algorithm \code{\link{hclust}}. } \details{ First, \code{iter.base} bootstrap samples of the original data in \code{x} are created by drawing with replacement. The base cluster method is run on each of these samples with \code{base.centers} centers. The \code{base.method} must be the name of a partitioning cluster function returning a list with the same components as the return value of \code{\link{kmeans}}. This results in a collection of \code{iter.base * base.centers} centers, which are subsequently clustered using the hierarchical method \code{\link{hclust}}. Base centers with less than \code{minsize} points in there respective partitions are removed before the hierarchical clustering. The resulting dendrogram is then cut to produce \code{centers} clusters. Hence, the name of the argument \code{centers} is a little bit misleading as the resulting clusters need not be convex, e.g., when single linkage is used. The name was chosen for compatibility with standard partitioning cluster methods such as \code{\link{kmeans}}. A new hierarchical clustering (e.g., using another \code{hclust.method}) re-using previous base runs can be performed by running \code{hclust.bclust} on the return value of \code{bclust}. } \value{ \code{bclust} and \code{hclust.bclust} return objects of class \code{"bclust"} including the components \item{hclust}{Return value of the hierarchical clustering of the collection of base centers (Object of class \code{"hclust"}).} \item{cluster}{Vector with indices of the clusters the inputs are assigned to.} \item{centers}{Matrix of centers of the final clusters. Only useful, if the hierarchical clustering method produces convex clusters.} \item{allcenters}{Matrix of all \code{iter.base * base.centers} centers found in the base runs.} } \author{Friedrich Leisch} \references{ Friedrich Leisch. Bagged clustering. Working Paper 51, SFB ``Adaptive Information Systems and Modeling in Economics and Management Science'', August 1999. \url{http://epub.wu.ac.at/1272/1/document.pdf}} \seealso{\code{\link{hclust}}, \code{\link{kmeans}}, \code{\link{boxplot.bclust}}} \keyword{multivariate} \keyword{cluster} \examples{ data(iris) bc1 <- bclust(iris[,1:4], 3, base.centers=5) plot(bc1) table(clusters.bclust(bc1, 3)) centers.bclust(bc1, 3) } e1071/man/Discrete.Rd0000644000175100001440000000302511400421345013623 0ustar hornikusers\name{Discrete} \alias{ddiscrete} \alias{pdiscrete} \alias{qdiscrete} \alias{rdiscrete} \title{Discrete Distribution} \description{ These functions provide information about the discrete distribution where the probability of the elements of \code{values} is proportional to the values given in \code{probs}, which are normalized to sum up to 1. \code{ddiscrete} gives the density, \code{pdiscrete} gives the distribution function, \code{qdiscrete} gives the quantile function and \code{rdiscrete} generates random deviates. } \usage{ ddiscrete(x, probs, values = 1:length(probs)) pdiscrete(q, probs, values = 1:length(probs)) qdiscrete(p, probs, values = 1:length(probs)) rdiscrete(n, probs, values = 1:length(probs), ...) } \arguments{ \item{x,q}{vector or array of quantiles.} \item{p}{vector or array of probabilities.} \item{n}{number of observations.} \item{probs}{probabilities of the distribution.} \item{values}{values of the distribution.} \item{...}{ignored (only there for backwards compatibility)} } \details{ The random number generator is simply a wrapper for \code{\link{sample}} and provided for backwards compatibility only. } \author{Andreas Weingessel and Friedrich Leisch} \examples{ ## a vector of length 30 whose elements are 1 with probability 0.2 ## and 2 with probability 0.8. rdiscrete (30, c(0.2, 0.8)) ## a vector of length 100 whose elements are A, B, C, D. ## The probabilities of the four values have the relation 1:2:3:3 rdiscrete (100, c(1,2,3,3), c("A","B","C","D")) } \keyword{distribution} e1071/man/bootstrap.lca.Rd0000644000175100001440000000521011400421345014632 0ustar hornikusers\name{bootstrap.lca} \alias{bootstrap.lca} \alias{print.bootstrap.lca} \title{Bootstrap Samples of LCA Results} \description{ This function draws bootstrap samples from a given LCA model and refits a new LCA model for each sample. The quality of fit of these models is compared to the original model. } \usage{ bootstrap.lca(l, nsamples=10, lcaiter=30, verbose=FALSE) } \arguments{ \item{l}{An LCA model as created by \code{\link{lca}}} \item{nsamples}{Number of bootstrap samples} \item{lcaiter}{Number of LCA iterations} \item{verbose}{If \code{TRUE} some output is printed during the computations.} } \details{ From a given LCA model \code{l}, \code{nsamples} bootstrap samples are drawn. For each sample a new LCA model is fitted. The goodness of fit for each model is computed via Likelihood Ratio and Pearson's Chisquare. The values for the fitted models are compared with the values of the original model \code{l}. By this method it can be tested whether the data to which \code{l} was originally fitted come from an LCA model. } \value{ An object of class \code{bootstrap.lca} is returned, containing \item{logl, loglsat}{The LogLikelihood of the models and of the corresponding saturated models} \item{lratio}{Likelihood quotient of the models and the corresponding saturated models} \item{lratiomean, lratiosd}{Mean and Standard deviation of \code{lratio}} \item{lratioorg}{Likelihood quotient of the original model and the corresponding saturated model} \item{zratio}{Z-Statistics of \code{lratioorg}} \item{pvalzratio, pvalratio}{P-Values for \code{zratio}, computed via normal distribution and empirical distribution} \item{chisq}{Pearson's Chisq of the models} \item{chisqmean, chisqsd}{Mean and Standard deviation of \code{chisq}} \item{chisqorg}{Pearson's Chisq of the original model} \item{zchisq}{Z-Statistics of \code{chisqorg}} \item{pvalzchisq, pvalchisq}{P-Values for \code{zchisq}, computed via normal distribution and empirical distribution} \item{nsamples}{Number of bootstrap samples} \item{lcaiter}{Number of LCA Iterations} } \references{Anton K. Formann: ``Die Latent-Class-Analysis'', Beltz Verlag 1984} \author{Andreas Weingessel} \seealso{\code{\link{lca}}} \examples{ ## Generate a 4-dim. sample with 2 latent classes of 500 data points each. ## The probabilities for the 2 classes are given by type1 and type2. type1 <- c(0.8,0.8,0.2,0.2) type2 <- c(0.2,0.2,0.8,0.8) x <- matrix(runif(4000),nr=1000) x[1:500,] <- t(t(x[1:500,]) 3 -> 5 -> 4 extractPath(z, 1, 4) } \keyword{optimize} e1071/man/countpattern.Rd0000644000175100001440000000202411400421345014605 0ustar hornikusers\name{countpattern} \alias{countpattern} \title{Count Binary Patterns} \usage{ countpattern(x, matching=FALSE) } \arguments{ \item{x}{A matrix of binary observations} \item{matching}{If TRUE an additional vector is returned which stores which row belongs to which pattern} } \description{ Every row of the binary matrix \code{x} is transformed into a binary pattern and these patterns are counted. } \value{ A vector of length \code{2\^ncol(x)} giving the number of times each pattern occurs in the rows of \code{x}. The names of this vector are the binary patterns. They are sorted according to their numeric value. If \code{matching} is \code{TRUE}, a list of the following two vectors is returned. \item{pat}{Numbers of patterns as described above.} \item{matching}{Vector giving the position of the pattern of each row of \code{x} in \code{pat}.} } \author{Andreas Weingessel} \examples{ xx <- rbind(c(1,0,0),c(1,0,0),c(1,0,1),c(0,1,1),c(0,1,1)) countpattern(xx) countpattern(xx, matching=TRUE) } \keyword{multivariate} e1071/man/e1071-deprecated.Rd0000644000175100001440000000051211400421345014712 0ustar hornikusers\name{e1071-deprecated} \alias{e1071-deprecated} \title{Deprecated Functions in Package e1071} \description{ These functions are provided for compatibility with older versions of package \pkg{e1071} only, and may be defunct as soon as of the next release. } %\usage{ %} \seealso{ \code{\link{Deprecated}} } \keyword{misc} e1071/man/skewness.Rd0000644000175100001440000000325711400421345013732 0ustar hornikusers\name{skewness} \alias{skewness} \title{Skewness} \description{ Computes the skewness. } \usage{ skewness(x, na.rm = FALSE, type = 3) } \arguments{ \item{x}{a numeric vector containing the values whose skewness is to be computed.} \item{na.rm}{a logical value indicating whether \code{NA} values should be stripped before the computation proceeds.} \item{type}{an integer between 1 and 3 selecting one of the algorithms for computing skewness detailed below.} } \details{ If \code{x} contains missings and these are not removed, the skewness is \code{NA}. Otherwise, write \eqn{x_i} for the non-missing elements of \code{x}, \eqn{n} for their number, \eqn{\mu}{mu} for their mean, \eqn{s} for their standard deviation, and \eqn{m_r = \sum_i (x_i - \mu)^r / n}{m_r = \sum_i (x_i - mu)^r / n} for the sample moments of order \eqn{r}. Joanes and Gill (1998) discuss three methods for estimating skewness: \describe{ \item{Type 1:}{ \eqn{g_1 = m_3 / m_2^{3/2}}{g_1 = m_3 / m_2^(3/2)}. This is the typical definition used in many older textbooks.} \item{Type 2:}{ \eqn{G_1 = g_1 \sqrt{n(n-1)} / (n-2)}{ G_1 = g_1 * sqrt(n(n-1)) / (n-2)}. Used in SAS and SPSS. } \item{Type 3:}{ \eqn{b_1 = m_3 / s^3 = g_1 ((n-1)/n)^{3/2}}{ b_1 = m_3 / s^3 = g_1 ((n-1)/n)^(3/2)}. Used in MINITAB and BMDP.} } All three skewness measures are unbiased under normality. } \value{ The estimated skewness of \code{x}. } \references{ D. N. Joanes and C. A. Gill (1998), Comparing measures of sample skewness and kurtosis. \emph{The Statistician}, \bold{47}, 183--189. } \examples{ x <- rnorm(100) skewness(x) } \keyword{univar} e1071/man/ica.Rd0000644000175100001440000000342311400421345012617 0ustar hornikusers\name{ica} \alias{ica} \alias{plot.ica} \alias{print.ica} \title{Independent Component Analysis} \usage{ ica(X, lrate, epochs=100, ncomp=dim(X)[2], fun="negative") } \arguments{ \item{X}{The matrix for which the ICA is to be computed} \item{lrate}{learning rate} \item{epochs}{number of iterations} \item{ncomp}{number of independent components} \item{fun}{function used for the nonlinear computation part} } \description{ This is an R-implementation of the Matlab-Function of Petteri.Pajunen@hut.fi. For a data matrix X independent components are extracted by applying a nonlinear PCA algorithm. The parameter \code{fun} determines which nonlinearity is used. \code{fun} can either be a function or one of the following strings "negative kurtosis", "positive kurtosis", "4th moment" which can be abbreviated to uniqueness. If \code{fun} equals "negative (positive) kurtosis" the function tanh (x-tanh(x)) is used which provides ICA for sources with negative (positive) kurtosis. For \code{fun == "4th moments"} the signed square function is used. } \value{ An object of class \code{"ica"} which is a list with components \item{weights}{ICA weight matrix} \item{projection}{Projected data} \item{epochs}{Number of iterations} \item{fun}{Name of the used function} \item{lrate}{Learning rate used} \item{initweights}{Initial weight matrix} } \references{ Oja et al., ``Learning in Nonlinear Constrained Hebbian Networks'', in Proc. ICANN-91, pp. 385--390. Karhunen and Joutsensalo, ``Generalizations of Principal Component Analysis, Optimization Problems, and Neural Networks'', Neural Networks, v. 8, no. 4, pp. 549--562, 1995. } \note{Currently, there is no reconstruction from the ICA subspace to the original input space.} \author{Andreas Weingessel} \keyword{multivariate} e1071/man/tune.wrapper.Rd0000644000175100001440000000470512263003667014534 0ustar hornikusers\name{tune.wrapper} \alias{tune.wrapper} \alias{tune.rpart} \alias{best.rpart} \alias{tune.svm} \alias{best.svm} \alias{tune.nnet} \alias{best.nnet} \alias{tune.randomForest} \alias{best.randomForest} \alias{tune.knn} \title{Convenience Tuning Wrapper Functions} \description{ Convenience tuning wrapper functions, using \code{tune}. } \usage{ tune.svm(x, y = NULL, data = NULL, degree = NULL, gamma = NULL, coef0 = NULL, cost = NULL, nu = NULL, class.weights = NULL, epsilon = NULL, ...) best.svm(x, tunecontrol = tune.control(), ...) tune.nnet(x, y = NULL, data = NULL, size = NULL, decay = NULL, trace = FALSE, tunecontrol = tune.control(nrepeat = 5), ...) best.nnet(x, tunecontrol = tune.control(nrepeat = 5), ...) tune.rpart(formula, data, na.action = na.omit, minsplit = NULL, minbucket = NULL, cp = NULL, maxcompete = NULL, maxsurrogate = NULL, usesurrogate = NULL, xval = NULL, surrogatestyle = NULL, maxdepth = NULL, predict.func = NULL, ...) best.rpart(formula, tunecontrol = tune.control(), ...) tune.randomForest(x, y = NULL, data = NULL, nodesize = NULL, mtry = NULL, ntree = NULL, ...) best.randomForest(x, tunecontrol = tune.control(), ...) tune.knn(x, y, k = NULL, l = NULL, ...) } \arguments{ \item{formula, x, y, data}{formula and data arguments of function to be tuned.} \item{predict.func}{predicting function.} \item{na.action}{function handling missingness.} \item{minsplit, minbucket, cp, maxcompete, maxsurrogate, usesurrogate, xval, surrogatestyle, maxdepth}{\code{rpart} parameters.} \item{degree, gamma, coef0, cost, nu, class.weights, epsilon}{\code{svm} parameters.} \item{k, l}{\code{knn} parameters.} \item{mtry, nodesize, ntree}{\code{randomForest} parameters.} \item{size, decay, trace}{parameters passed to \code{nnet}.} \item{tunecontrol}{object of class \code{"tune.control"} containing tuning parameters.} \item{\dots}{Further parameters passed to \code{tune}.} } \value{ \code{tune.foo()} returns a tuning object including the best parameter set obtained by optimizing over the specified parameter vectors. \code{best.foo()} directly returns the best model, i.e. the fit of a new model using the optimal parameters found by \code{tune.foo}. } \details{For examples, see the help page of \code{tune()}.} \author{ David Meyer\cr \email{David.Meyer@R-project.org} } \seealso{\code{\link{tune}}} \keyword{models} e1071/man/read.matrix.csr.Rd0000644000175100001440000000302212016757022015072 0ustar hornikusers\name{read.matrix.csr} \alias{read.matrix.csr} \alias{write.matrix.csr} %- Also NEED an `\alias' for EACH other topic documented here. \title{Read/Write Sparse Data} \description{ reads and writes a file in sparse data format. } \usage{ read.matrix.csr(file, fac = TRUE, ncol = NULL) write.matrix.csr(x, file = "out.dat", y = NULL, fac = TRUE) } %- maybe also `usage' for other objects documented here. \arguments{ \item{x}{An object of class \code{matrix.csr}} \item{y}{A vector (either numeric or a factor)} \item{file}{The filename.} \item{fac}{If \code{TRUE}, the y-values (if any) are interpreted as factor levels.} \item{ncol}{Number of columns, detected automatically. Can be used to add empty columns (possibly not stored in the sparse format).} } \value{ If the data file includes no y variable, \code{read.matrix.csr} returns an object of class \code{matrix.csr}, else a list with components: \item{x}{object of class \code{matrix.csr}} \item{y}{vector of numeric values or factor levels, depending on \code{fac}.} } \author{ David Meyer\cr \email{David.Meyer@R-project.org} } \seealso{\code{\link[SparseM]{matrix.csr}}} \examples{ \dontrun{ library(methods) if (require(SparseM)) { data(iris) x <- as.matrix(iris[,1:4]) y <- iris[,5] xs <- as.matrix.csr(x) write.matrix.csr(xs, y = y, file = "iris.dat") xs2 <- read.matrix.csr("iris.dat")$x if (!all(as.matrix(xs) == as.matrix(xs2))) stop("Error: objects are not equal!") } } } \keyword{IO}% at least one, from doc/KEYWORDS e1071/man/rectangle.window.Rd0000644000175100001440000000106511400421345015335 0ustar hornikusers\name{rectangle.window} \title{Computes the Coefficients of a Rectangle Window.} \usage{rectangle.window(n)} \alias{rectangle.window} \arguments{ \item{n}{The length of the window.} } \description{Returns the filter coefficients of a rectangle window. That is a vector of \code{n} 1. The purpose of this function is just to have a name for the R command \code{rep (1, n)}. } \value{A vector of length \code{n} filled with 1.} \author{Andreas Weingessel} \seealso{stft} \examples{x<-rnorm(500) y<-stft(x, wtype="rectangle.window") plot(y) } \keyword{ts} e1071/man/hamming.distance.Rd0000644000175100001440000000122712505565430015307 0ustar hornikusers\name{hamming.distance} \alias{hamming.distance} \title{Hamming Distances of Vectors} \usage{ hamming.distance(x, y) } \arguments{ \item{x}{a vector or matrix.} \item{y}{an optional vector.} } \description{ If both \code{x} and \code{y} are vectors, \code{hamming.distance} returns the Hamming distance (number of different elements) between this two vectors. If \code{x} is a matrix, the Hamming distances between the rows of \code{x} are computed and \code{y} is ignored. } \examples{ x <- c(1, 0, 0) y <- c(1, 0, 1) hamming.distance(x, y) z <- rbind(x,y) rownames(z) <- c("Fred", "Tom") hamming.distance(z) hamming.distance(1:3, 3:1) } \keyword{multivariate} e1071/man/bincombinations.Rd0000644000175100001440000000052311400421345015237 0ustar hornikusers\name{bincombinations} \title{Binary Combinations} \usage{ bincombinations(p) } \alias{bincombinations} \arguments{ \item{p}{Length of binary vectors} } \description{ Returns a matrix containing the \eqn{2^p} vectors of length \code{p}. } \author{Friedrich Leisch} \examples{ bincombinations(2) bincombinations(3) } \keyword{utilities} e1071/man/cmeans.Rd0000644000175100001440000001206711400421345013335 0ustar hornikusers\name{cmeans} \alias{cmeans} \alias{print.fclust} \title{Fuzzy C-Means Clustering} \description{ The fuzzy version of the known \emph{k}means clustering algorithm as well as an on-line variant (Unsupervised Fuzzy Competitive learning). } \usage{ cmeans(x, centers, iter.max = 100, verbose = FALSE, dist = "euclidean", method = "cmeans", m = 2, rate.par = NULL, weights = 1, control = list()) } \arguments{ \item{x}{The data matrix where columns correspond to variables and rows to observations.} \item{centers}{Number of clusters or initial values for cluster centers.} \item{iter.max}{Maximum number of iterations.} \item{verbose}{If \code{TRUE}, make some output during learning.} \item{dist}{Must be one of the following: If \code{"euclidean"}, the mean square error, if \code{"manhattan"}, the mean absolute error is computed. Abbreviations are also accepted.} \item{method}{If \code{"cmeans"}, then we have the \eqn{c}-means fuzzy clustering method, if \code{"ufcl"} we have the on-line update. Abbreviations are also accepted.} \item{m}{A number greater than 1 giving the degree of fuzzification.} \item{rate.par}{A number between 0 and 1 giving the parameter of the learning rate for the on-line variant. The default corresponds to \eqn{0.3}.} \item{weights}{a numeric vector with non-negative case weights. Recycled to the number of observations in \code{x} if necessary.} \item{control}{a list of control parameters. See \bold{Details}.} } \details{ The data given by \code{x} is clustered by generalized versions of the fuzzy \emph{c}-means algorithm, which use either a fixed-point or an on-line heuristic for minimizing the objective function \deqn{\sum_i \sum_j w_i u_{ij}^m d_{ij},} where \eqn{w_i} is the weight of observation \eqn{i}, \eqn{u_{ij}} is the membership of observation \eqn{i} in cluster \eqn{j}, and \eqn{d_{ij}} is the distance (dissimilarity) between observation \eqn{i} and center \eqn{j}. The dissimilarities used are the sums of squares (\code{"euclidean"}) or absolute values (\code{"manhattan"}) of the element-wise differences. If \code{centers} is a matrix, its rows are taken as the initial cluster centers. If \code{centers} is an integer, \code{centers} rows of \code{x} are randomly chosen as initial values. The algorithm stops when the maximum number of iterations (given by \code{iter.max}) is reached, or when the algorithm is unable to reduce the current value \code{val} of the objective function by \code{reltol * (abs(val) * reltol)} at a step. The relative convergence tolerance \code{reltol} can be specified as the \code{reltol} component of the list of control parameters, and defaults to \code{sqrt(.Machine$double.eps)}. If \code{verbose} is \code{TRUE}, each iteration displays its number and the value of the objective function. If \code{method} is \code{"cmeans"}, then we have the \eqn{c}-means fuzzy clustering method, see for example Bezdek (1981). If \code{"ufcl"}, we have the On-line Update (Unsupervised Fuzzy Competitive Learning) method due to Chung and Lee (1992), see also Pal et al (1996). This method works by performing an update directly after each input signal (i.e., for each single observation). The parameters \code{m} defines the degree of fuzzification. It is defined for real values greater than 1 and the bigger it is the more fuzzy the membership values of the clustered data points are. } \value{ An object of class \code{"fclust"} which is a list with components: \item{centers}{the final cluster centers.} \item{size}{the number of data points in each cluster of the closest hard clustering.} \item{cluster}{a vector of integers containing the indices of the clusters where the data points are assigned to for the closest hard clustering, as obtained by assigning points to the (first) class with maximal membership.} \item{iter}{the number of iterations performed.} \item{membership}{a matrix with the membership values of the data points to the clusters.} \item{withinerror}{the value of the objective function.} \item{call}{the call used to create the object.} } \author{ Evgenia Dimitriadou and Kurt Hornik } \references{ J. C. Bezdek (1981). \emph{Pattern recognition with fuzzy objective function algorithms}. New York: Plenum. Fu Lai Chung and Tong Lee (1992). Fuzzy competitive learning. \emph{Neural Networks}, \bold{7}(3), 539--551. Nikhil R. Pal, James C. Bezdek, and Richard J. Hathaway (1996). Sequential competitive learning and the fuzzy c-means clustering algorithms. \emph{Neural Networks}, \bold{9}(5), 787--796. } \examples{ # a 2-dimensional example x<-rbind(matrix(rnorm(100,sd=0.3),ncol=2), matrix(rnorm(100,mean=1,sd=0.3),ncol=2)) cl<-cmeans(x,2,20,verbose=TRUE,method="cmeans",m=2) print(cl) # a 3-dimensional example x<-rbind(matrix(rnorm(150,sd=0.3),ncol=3), matrix(rnorm(150,mean=1,sd=0.3),ncol=3), matrix(rnorm(150,mean=2,sd=0.3),ncol=3)) cl<-cmeans(x,6,20,verbose=TRUE,method="cmeans") print(cl) } \keyword{cluster} e1071/man/interpolate.Rd0000644000175100001440000000214211400421345014406 0ustar hornikusers\name{interpolate} \title{Interpolate Values of Array} \usage{ interpolate(x, a, adims=lapply(dimnames(a), as.numeric), method="linear") } \alias{interpolate} \arguments{ \item{x}{Matrix of values at which interpolation shall take place.} \item{a}{Array of arbitrary dimension.} \item{adims}{List of the same structure as \code{dimnames(a)}.} \item{method}{Interpolation method, one of \code{"linear"} or \code{"constant"}.} } \description{ For each row in matrix \code{x}, the hypercube of \code{a} containing this point is searched. The corners of the hypercube are linearly interpolated. By default, \code{dimnames(a)} is taken to contain the coordinate values for each point in \code{a}. This can be overridden using \code{adims}. If \code{method=="constant"}, the value of the ``lower left'' corner of the hypercube is returned. } \author{Friedrich Leisch} \seealso{\code{\link{approx}}, \code{\link{spline}}} \examples{ x <- seq(0,3,0.2) z <- outer(x,x, function(x,y) sin(x*y)) dimnames(z) <- list(x,x) sin(1.1*2.1) interpolate(c(1.1, 2.1),z) } \keyword{arith} \keyword{multivariate} e1071/man/permutations.Rd0000644000175100001440000000054411400421345014616 0ustar hornikusers\name{permutations} \alias{permutations} \title{All Permutations of Integers 1:n} \description{ Returns a matrix containing all permutations of the integers \code{1:n} (one permutation per row). } \usage{ permutations(n) } \arguments{ \item{n}{Number of element to permute.} } \author{Friedrich Leisch} \examples{ permutations(3) } \keyword{datagen} e1071/man/classAgreement.Rd0000644000175100001440000000610411400421345015017 0ustar hornikusers\name{classAgreement} \alias{classAgreement} \title{Coefficients Comparing Classification Agreement} \description{ \code{classAgreement()} computes several coefficients of agreement between the columns and rows of a 2-way contingency table. } \usage{ classAgreement(tab, match.names=FALSE) } \arguments{ \item{tab}{A 2-dimensional contingency table.} \item{match.names}{Flag whether row and columns should be matched by name.} } \details{ Suppose we want to compare two classifications summarized by the contingency table \eqn{T=[t_{ij}]} where \eqn{i,j=1,\ldots,K} and \eqn{t_{ij}} denotes the number of data points which are in class \eqn{i} in the first partition and in class \eqn{j} in the second partition. If both classifications use the same labels, then obviously the two classification agree completely if only elements in the main diagonal of the table are non-zero. On the other hand, large off-diagonal elements correspond to smaller agreement between the two classifications. If \code{match.names} is \code{TRUE}, the class labels as given by the row and column names are matched, i.e. only columns and rows with the same dimnames are used for the computation. If the two classification do not use the same set of labels, or if identical labels can have different meaning (e.g., two outcomes of cluster analysis on the same data set), then the situation is a little bit more complicated. Let \eqn{A} denote the number of all pairs of data points which are either put into the same cluster by both partitions or put into different clusters by both partitions. Conversely, let \eqn{D} denote the number of all pairs of data points that are put into one cluster in one partition, but into different clusters by the other partition. Hence, the partitions disagree for all pairs \eqn{D} and agree for all pairs \eqn{A}. We can measure the agreement by the Rand index \eqn{A/(A+D)} which is invariant with respect to permutations of the columns or rows of \eqn{T}. Both indices have to be corrected for agreement by chance if the sizes of the classes are not uniform. } \value{ A list with components \item{diag}{Percentage of data points in the main diagonal of \code{tab}.} \item{kappa}{\code{diag} corrected for agreement by chance.} \item{rand}{Rand index.} \item{crand}{Rand index corrected for agreement by chance.} } \references{ J.~Cohen. A coefficient of agreement for nominal scales. Educational and Psychological Measurement, 20, 37--46, 1960. Lawrence Hubert and Phipps Arabie. Comparing partitions. Journal of Classification, 2, 193--218, 1985. } \author{Friedrich Leisch} \seealso{\code{\link{matchClasses}}} \examples{ ## no class correlations: both kappa and crand almost zero g1 <- sample(1:5, size=1000, replace=TRUE) g2 <- sample(1:5, size=1000, replace=TRUE) tab <- table(g1, g2) classAgreement(tab) ## let pairs (g1=1,g2=1) and (g1=3,g2=3) agree better k <- sample(1:1000, size=200) g1[k] <- 1 g2[k] <- 1 k <- sample(1:1000, size=200) g1[k] <- 3 g2[k] <- 3 tab <- table(g1, g2) ## both kappa and crand should be significantly larger than before classAgreement(tab) } \keyword{category} e1071/man/hsv_palette.Rd0000644000175100001440000000143511400421345014402 0ustar hornikusers\name{hsv_palette} \alias{hsv_palette} \title{Sequential color palette based on HSV colors} \description{ Computes a sequential color palette based on HSV colors by varying the saturation, given hue and value. } \usage{ hsv_palette(h = 2/3, from = 0.7, to = 0.2, v = 1) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{h}{hue} \item{from}{lower bound for saturation} \item{to}{upper bound for saturation} \item{v}{value} } \value{ A function with one argument: the size of the palette, i.e., the number of colors. } \author{David Meyer \email{David.Meyer@R-project.org}} \seealso{\code{\link[grDevices]{hsv}}} \examples{ pie(rep(1, 10), col = hsv_palette()(10)) pie(rep(1, 10), col = hsv_palette(h = 0)(10)) } \keyword{hplot}% __ONLY ONE__ keyword per line e1071/man/plot.tune.Rd0000644000175100001440000000375211400421345014020 0ustar hornikusers\name{plot.tune} \alias{plot.tune} %- Also NEED an `\alias' for EACH other topic documented here. \title{Plot Tuning Object} \description{ Visualizes the results of parameter tuning. } \usage{ \method{plot}{tune}(x, type = c("contour", "perspective"), theta = 60, col = "lightblue", main = NULL, xlab = NULL, ylab = NULL, swapxy = FALSE, transform.x = NULL, transform.y = NULL, transform.z = NULL, color.palette = hsv_palette(), nlevels = 20, ...) } %- maybe also `usage' for other objects documented here. \arguments{ \item{x}{an object of class \code{tune}} \item{type}{choose whether a contour plot or a perspective plot is used if two parameters are to be visualized. Ignored if only one parameter has been tuned.} \item{theta}{angle of azimuthal direction.} \item{col}{the color(s) of the surface facets. Transparent colors are ignored.} \item{main}{main title} \item{xlab, ylab}{titles for the axes. N.B. These must be character strings; expressions are not accepted. Numbers will be coerced to character strings.} \item{swapxy}{if \code{TRUE}, the parameter axes are swaped (only used in case of two parameters).} \item{transform.x, transform.y, transform.z}{functions to transform the parameters (\code{x} and \code{y}) and the error measures (\code{z}). Ignored if \code{NULL}.} \item{color.palette}{color palette used in contour plot.} \item{nlevels}{number of levels used in contour plot.} \item{\dots}{Further graphics parameters.} } \author{ David Meyer (based on C/C++-code by Chih-Chung Chang and Chih-Jen Lin)\cr \email{David.Meyer@R-project.org} } \seealso{\code{\link{tune}}} \examples{ data(iris) obj <- tune.svm(Species~., data = iris, sampling = "fix", gamma = 2^c(-8,-4,0,4), cost = 2^c(-8,-4,-2,0)) plot(obj, transform.x = log2, transform.y = log2) plot(obj, type = "perspective", theta = 120, phi = 45) } \keyword{models}% __ONLY ONE__ keyword per line e1071/man/moment.Rd0000644000175100001440000000231211400421345013356 0ustar hornikusers\name{moment} \alias{moment} \title{Statistical Moment} \description{ Computes the (optionally centered and/or absolute) sample moment of a certain order. } \usage{ moment(x, order=1, center=FALSE, absolute=FALSE, na.rm=FALSE) } \arguments{ \item{x}{a numeric vector containing the values whose moment is to be computed.} \item{order}{order of the moment to be computed, the default is to compute the first moment, i.e., the mean.} \item{center}{a logical value indicating whether centered moments are to be computed.} \item{absolute}{a logical value indicating whether absolute moments are to be computed.} \item{na.rm}{a logical value indicating whether \code{NA} values should be stripped before the computation proceeds.} } \details{ When \code{center} and \code{absolute} are both \code{FALSE}, the moment is simply \code{sum(x ^ order) / length(x)}. } \author{Kurt Hornik and Friedrich Leisch} \seealso{ \code{\link{mean}}, \code{\link{var}}} \examples{ x <- rnorm(100) ## Compute the mean moment(x) ## Compute the 2nd centered moment (!= var) moment(x, order=2, center=TRUE) ## Compute the 3rd absolute centered moment moment(x, order=3, center=TRUE, absolute=TRUE) } \keyword{univar} e1071/man/cshell.Rd0000644000175100001440000000703111400421345013334 0ustar hornikusers\name{cshell} \alias{cshell} \title{Fuzzy C-Shell Clustering} \usage{ cshell(x, centers, iter.max=100, verbose=FALSE, dist="euclidean", method="cshell", m=2, radius = NULL) } \arguments{ \item{x}{The data matrix, were columns correspond to the variables and rows to observations.} \item{centers}{Number of clusters or initial values for cluster centers} \item{iter.max}{Maximum number of iterations} \item{verbose}{If \code{TRUE}, make some output during learning} \item{dist}{Must be one of the following: If \code{"euclidean"}, the mean square error, if \code{"manhattan"}, the mean absolute error is computed. Abbreviations are also accepted.} \item{method}{Currently, only the \code{"cshell"} method; the c-shell fuzzy clustering method} \item{m}{The degree of fuzzification. It is defined for values greater than \emph{1}} \item{radius}{The radius of resulting clusters} } \description{ The \emph{c}-shell clustering algorithm, the shell prototype-based version (ring prototypes) of the fuzzy \emph{k}means clustering method. } \details{ The data given by \code{x} is clustered by the fuzzy \emph{c}-shell algorithm. If \code{centers} is a matrix, its rows are taken as the initial cluster centers. If \code{centers} is an integer, \code{centers} rows of \code{x} are randomly chosen as initial values. The algorithm stops when the maximum number of iterations (given by \code{iter.max}) is reached. If \code{verbose} is \code{TRUE}, it displays for each iteration the number the value of the objective function. If \code{dist} is \code{"euclidean"}, the distance between the cluster center and the data points is the Euclidean distance (ordinary kmeans algorithm). If \code{"manhattan"}, the distance between the cluster center and the data points is the sum of the absolute values of the distances of the coordinates. If \code{method} is \code{"cshell"}, then we have the \emph{c}-shell fuzzy clustering method. The parameters \code{m} defines the degree of fuzzification. It is defined for real values greater than 1 and the bigger it is the more fuzzy the membership values of the clustered data points are. The parameter \code{radius} is by default set to \emph{0.2} for every cluster. } \value{ \code{cshell} returns an object of class \code{"cshell"}. \item{centers}{The final cluster centers.} \item{size}{The number of data points in each cluster.} \item{cluster}{Vector containing the indices of the clusters where the data points are assigned to. The maximum membership value of a point is considered for partitioning it to a cluster.} \item{iter}{The number of iterations performed.} \item{membership}{a matrix with the membership values of the data points to the clusters.} \item{withinerror}{Returns the sum of square distances within the clusters.} \item{call}{Returns a call in which all of the arguments are specified by their names.} } \author{Evgenia Dimitriadou} \references{ Rajesh N. Dave. \emph{Fuzzy Shell-Clustering and Applications to Circle Detection in Digital Images.} Int. J. of General Systems, Vol. \bold{16}, pp. 343-355, 1996. } \examples{ ## a 2-dimensional example x<-rbind(matrix(rnorm(50,sd=0.3),ncol=2), matrix(rnorm(50,mean=1,sd=0.3),ncol=2)) cl<-cshell(x,2,20,verbose=TRUE,method="cshell",m=2) print(cl) # assign classes to some new data y<-rbind(matrix(rnorm(13,sd=0.3),ncol=2), matrix(rnorm(13,mean=1,sd=0.3),ncol=2)) # ycl<-predict(cl, y, type="both") } \keyword{cluster} e1071/man/kurtosis.Rd0000644000175100001440000000317011400421345013745 0ustar hornikusers\name{kurtosis} \alias{kurtosis} \title{Kurtosis} \description{ Computes the kurtosis. } \usage{ kurtosis(x, na.rm = FALSE, type = 3) } \arguments{ \item{x}{a numeric vector containing the values whose kurtosis is to be computed.} \item{na.rm}{a logical value indicating whether \code{NA} values should be stripped before the computation proceeds.} \item{type}{an integer between 1 and 3 selecting one of the algorithms for computing skewness detailed below.} } \details{ If \code{x} contains missings and these are not removed, the skewness is \code{NA}. Otherwise, write \eqn{x_i} for the non-missing elements of \code{x}, \eqn{n} for their number, \eqn{\mu}{mu} for their mean, \eqn{s} for their standard deviation, and \eqn{m_r = \sum_i (x_i - \mu)^r / n}{m_r = \sum_i (x_i - mu)^r / n} for the sample moments of order \eqn{r}. Joanes and Gill (1998) discuss three methods for estimating kurtosis: \describe{ \item{Type 1:}{ \eqn{g_2 = m_4 / m_2^2 - 3}. This is the typical definition used in many older textbooks.} \item{Type 2:}{ \eqn{G_2 = ((n+1) g_2 + 6) * (n-1) / ((n-2)(n-3))}. Used in SAS and SPSS. } \item{Type 3:}{ \eqn{b_2 = m_4 / s^4 - 3 = (g_2 + 3) (1 - 1/n)^2 - 3}. Used in MINITAB and BMDP.} } Only \eqn{G_2} (corresponding to \code{type = 2}) is unbiased under normality. } \value{ The estimated kurtosis of \code{x}. } \references{ D. N. Joanes and C. A. Gill (1998), Comparing measures of sample skewness and kurtosis. \emph{The Statistician}, \bold{47}, 183--189. } \examples{ x <- rnorm(100) kurtosis(x) } \keyword{univar} e1071/man/plot.svm.Rd0000644000175100001440000000437311633216702013661 0ustar hornikusers\name{plot.svm} \alias{plot.svm} %- Also NEED an `\alias' for EACH other topic documented here. \title{Plot SVM Objects} \description{ Generates a scatter plot of the input data of a \code{svm} fit for classification models by highlighting the classes and support vectors. Optionally, draws a filled contour plot of the class regions. } \usage{ \method{plot}{svm}(x, data, formula, fill = TRUE, grid = 50, slice = list(), symbolPalette = palette(), svSymbol = "x", dataSymbol = "o", ...) } %- maybe also `usage' for other objects documented here. \arguments{ \item{x}{An object of class \code{svm}} \item{data}{data to visualize. Should be the same used for fitting.} \item{formula}{formula selecting the visualized two dimensions. Only needed if more than two input variables are used.} \item{fill}{switch indicating whether a contour plot for the class regions should be added.} \item{grid}{granularity for the contour plot.} \item{slice}{a list of named values for the dimensions held constant (only needed if more than two variables are used). The defaults for unspecified dimensions are 0 (for numeric variables) and the first level (for factors). Factor levels can either be specified as factors or character vectors of length 1.} \item{symbolPalette}{Color palette used for the class the data points and support vectors belong to.} \item{svSymbol}{Symbol used for support vectors.} \item{dataSymbol}{Symbol used for data points (other than support vectors).} \item{\dots}{additional graphics parameters passed to \code{filled.contour} and \code{plot}.} } \author{David Meyer\cr \email{David.Meyer@R-project.org}} \seealso{\code{\link{svm}}} \examples{ ## a simple example data(cats, package = "MASS") m <- svm(Sex~., data = cats) plot(m, cats) ## more than two variables: fix 2 dimensions data(iris) m2 <- svm(Species~., data = iris) plot(m2, iris, Petal.Width ~ Petal.Length, slice = list(Sepal.Width = 3, Sepal.Length = 4)) ## plot with custom symbols and colors plot(m, cats, svSymbol = 1, dataSymbol = 2, symbolPalette = rainbow(4), color.palette = terrain.colors) } \keyword{neural}% at least one, from doc/KEYWORDS \keyword{classif}% __ONLY ONE__ keyword per line \keyword{nonlinear}% __ONLY ONE__ keyword per line e1071/man/naiveBayes.Rd0000644000175100001440000000764312375105270014171 0ustar hornikusers\name{naiveBayes} \alias{naiveBayes} \alias{naiveBayes.default} \alias{naiveBayes.formula} \alias{print.naiveBayes} \alias{predict.naiveBayes} \title{Naive Bayes Classifier} \description{ Computes the conditional a-posterior probabilities of a categorical class variable given independent predictor variables using the Bayes rule. } \usage{ \S3method{naiveBayes}{formula}(formula, data, laplace = 0, ..., subset, na.action = na.pass) \S3method{naiveBayes}{default}(x, y, laplace = 0, ...) \S3method{predict}{naiveBayes}(object, newdata, type = c("class", "raw"), threshold = 0.001, eps = 0, ...) } \arguments{ \item{x}{A numeric matrix, or a data frame of categorical and/or numeric variables.} \item{y}{Class vector.} \item{formula}{A formula of the form \code{class ~ x1 + x2 + \dots}. Interactions are not allowed.} \item{data}{Either a data frame of predictors (categorical and/or numeric) or a contingency table.} \item{laplace}{positive double controlling Laplace smoothing. The default (0) disables Laplace smoothing.} \item{\dots}{Currently not used.} \item{subset}{For data given in a data frame, an index vector specifying the cases to be used in the training sample. (NOTE: If given, this argument must be named.)} \item{na.action}{A function to specify the action to be taken if \code{NA}s are found. The default action is not to count them for the computation of the probability factors. An alternative is na.omit, which leads to rejection of cases with missing values on any required variable. (NOTE: If given, this argument must be named.)} \item{object}{An object of class \code{"naiveBayes"}.} \item{newdata}{A dataframe with new predictors (with possibly fewer columns than the training data). Note that the column names of \code{newdata} are matched against the training data ones.} \item{type}{If \code{"raw"}, the conditional a-posterior probabilities for each class are returned, and the class with maximal probability else.} \item{threshold}{Value replacing cells with probabilities within \code{eps} range.} \item{eps}{double for specifying an epsilon-range to apply laplace smoothing (to replace zero or close-zero probabilities by \code{theshold}.)} } \value{ An object of class \code{"naiveBayes"} including components: \item{apriori}{Class distribution for the dependent variable.} \item{tables}{A list of tables, one for each predictor variable. For each categorical variable a table giving, for each attribute level, the conditional probabilities given the target class. For each numeric variable, a table giving, for each target class, mean and standard deviation of the (sub-)variable.} } \details{ The standard naive Bayes classifier (at least this implementation) assumes independence of the predictor variables, and Gaussian distribution (given the target class) of metric predictors. For attributes with missing values, the corresponding table entries are omitted for prediction. } \author{David Meyer \email{David.Meyer@R-project.org}. Laplace smoothing enhancement by Jinghao Xue.} \examples{ ## Categorical data only: data(HouseVotes84, package = "mlbench") model <- naiveBayes(Class ~ ., data = HouseVotes84) predict(model, HouseVotes84[1:10,]) predict(model, HouseVotes84[1:10,], type = "raw") pred <- predict(model, HouseVotes84) table(pred, HouseVotes84$Class) ## using laplace smoothing: model <- naiveBayes(Class ~ ., data = HouseVotes84, laplace = 3) pred <- predict(model, HouseVotes84[,-1]) table(pred, HouseVotes84$Class) ## Example of using a contingency table: data(Titanic) m <- naiveBayes(Survived ~ ., data = Titanic) m predict(m, as.data.frame(Titanic)) ## Example with metric predictors: data(iris) m <- naiveBayes(Species ~ ., data = iris) ## alternatively: m <- naiveBayes(iris[,-5], iris[,5]) m table(predict(m, iris), iris[,5]) } \keyword{classif} \keyword{category} e1071/man/probplot.Rd0000644000175100001440000000433411400421345013726 0ustar hornikusers\name{probplot} \alias{probplot} \alias{lines.probplot} \title{Probability Plot} \description{ Generates a probability plot for a specified theoretical distribution, i.e., basically a \code{\link[stats]{qqplot}} where the y-axis is labeled with probabilities instead of quantiles. The function is mainly intended for teaching the concept of quantile plots. } \usage{ probplot(x, qdist=qnorm, probs=NULL, line=TRUE, xlab=NULL, ylab="Probability in \%", ...) \S3method{lines}{probplot}(x, h=NULL, v=NULL, bend=FALSE, ...) } \arguments{ \item{x}{A data vector for \code{probplot}, an object of class \code{probplot} for the \code{lines} method.} \item{qdist}{A character string or a function for the quantiles of the target distribution.} \item{probs}{Vector of probabilities at which horizontal lines should be drawn.} \item{line}{Add a line passing through the quartiles to the plot?} \item{xlab, ylab}{Graphical parameters.} \item{h}{The y-value for a horizontal line.} \item{v}{The x-value for a vertical line.} \item{bend}{If \code{TRUE}, lines are ``bent'' at the quartile line, else regular \code{abline}s are added. See examples.} \item{\dots}{Further arguments for \code{qdist} and graphical parameters for lines.} } \author{Friedrich Leisch} \seealso{\code{\link[stats]{qqplot}}} \examples{ ## a simple example x <- rnorm(100, mean=5) probplot(x) ## the same with horizontal tickmarks at the y-axis opar <- par("las") par(las=1) probplot(x) ## this should show the lack of fit at the tails probplot(x, "qunif") ## for increasing degrees of freedom the t-distribution converges to ## normal probplot(x, qt, df=1) probplot(x, qt, df=3) probplot(x, qt, df=10) probplot(x, qt, df=100) ## manually add the line through the quartiles p <- probplot(x, line=FALSE) lines(p, col="green", lty=2, lwd=2) ## Make the line at prob=0.5 red lines(p, h=0.5, col="red") ### The following use the estimted distribution given by the green ### line: ## What is the probability that x is smaller than 7? lines(p, v=7, bend=TRUE, col="blue") ## Median and 90\% confidence interval lines(p, h=.5, col="red", lwd=3, bend=TRUE) lines(p, h=c(.05, .95), col="red", lwd=2, lty=3, bend=TRUE) par(opar) } \keyword{hplot} e1071/man/rbridge.Rd0000644000175100001440000000113211400421345013474 0ustar hornikusers\name{rbridge} \alias{rbridge} \title{Simulation of Brownian Bridge} \usage{ rbridge(end = 1, frequency = 1000) } \arguments{ \item{end}{the time of the last observation.} \item{frequency}{the number of observations per unit of time.} } \description{ \code{rwiener} returns a time series containing a simulated realization of the Brownian bridge on the interval [0,\code{end}]. If W(t) is a Wiener process, then the Brownian bridge is defined as W(t) - t W(1). } \seealso{ rwiener } \examples{ # simulate a Brownian bridge on [0,1] and plot it x <- rbridge() plot(x,type="l") } \keyword{distribution} e1071/man/impute.Rd0000644000175100001440000000101011400421345013354 0ustar hornikusers\name{impute} \alias{impute} \title{Replace Missing Values} \usage{ impute(x, what = c("median", "mean")) } \arguments{ \item{x}{A matrix or dataframe.} \item{what}{What to impute.} } \description{ Replaces missing values of a matrix or dataframe with the medians (\code{what="median"}) or means (\code{what="mean"}) of the respective columns.} \value{ A matrix or dataframe. } \author{Friedrich Leisch} \examples{ x<- matrix(1:10, ncol=2) x[c(1,3,7)] <- NA print(x) print(impute(x)) } \keyword{manip} e1071/man/hamming.window.Rd0000644000175100001440000000142711400421345015013 0ustar hornikusers\name{hamming.window} \title{Computes the Coefficients of a Hamming Window.} \usage{hamming.window(n)} \alias{hamming.window} \arguments{ \item{n}{The length of the window.} } \description{The filter coefficients \eqn{w_i}{w(i)} of a Hamming window of length \code{n} are computed according to the formula \deqn{w_i = 0.54 - 0.46 \cos\frac{2\pi i}{n-1}}{ w(i) = 0.54 - 0.46*cos(2*pi*i/(n-1))} } \value{A vector containing the filter coefficients.} \references{For a definition of the Hamming window, see for example\cr Alan V. Oppenheim and Roland W. Schafer: "Discrete-Time Signal Processing", Prentice-Hall, 1989.} \author{Andreas Weingessel} \seealso{stft, hanning.window} \examples{hamming.window(10) x<-rnorm(500) y<-stft(x, wtype="hamming.window") plot(y) } \keyword{ts} e1071/man/matchClasses.Rd0000644000175100001440000000667011400421345014504 0ustar hornikusers\name{matchClasses} \alias{matchClasses} \alias{compareMatchedClasses} \title{Find Similar Classes in Two-way Contingency Tables} \usage{ matchClasses(tab, method="rowmax", iter=1, maxexact=9, verbose=TRUE) compareMatchedClasses(x, y, method="rowmax", iter=1, maxexact=9, verbose=FALSE) } \arguments{ \item{tab}{Two-way contingency table of class memberships} \item{method}{One of \code{"rowmax"}, \code{"greedy"} or \code{"exact"}.} \item{iter}{Number of iterations used in greedy search.} \item{verbose}{If \code{TRUE}, display some status messages during computation.} \item{maxexact}{Maximum number of variables for which all possible permutations are computed.} \item{x, y}{Vectors or matrices with class memberships.} } \description{ Try to find a mapping between the two groupings, such that as many cases as possible are in one of the matched pairs. } \details{ If \code{method="rowmax"}, then each class defining a row in the contingency table is mapped to the column of the corresponding row maximum. Hence, some columns may be mapped to more than one row (while each row is mapped to a single column). If \code{method="greedy"} or \code{method="exact"}, then the contingency table must be a square matrix and a unique mapping is computed. This corresponds to a permutation of columns and rows, such that sum of the main diagonal, i.e., the trace of the matrix, gets as large as possible. For both methods, first all pairs where row and columns maxima correspond and are bigger than the sum of all other elements in the corresponding columns and rows together are located and fixed (this is a necessary condition for maximal trace). If \code{method="exact"}, then for the remaining rows and columns, all possible permutations are computed and the optimum is returned. This can get computationally infeasible very fast. If more than \code{maxexact} rows and columns remain after applying the necessary condition, then \code{method} is reset to \code{"greedy"}. If \code{method="greedy"}, then a greedy heuristic is tried \code{iter} times. Repeatedly a row is picked at random and matched to the free column with the maximum value. \code{compareMatchedClasses()} computes the contingency table for each combination of columns from \code{x} and \code{y} and applies \code{matchClasses} to that table. The columns of the table are permuted accordingly and then the table is passed to \code{\link{classAgreement}}. The resulting agreement coefficients (diag, kappa, \ldots) are returned. The return value of \code{compareMatchedClasses()} is a list containing a matrix for each coefficient; with element (k,l) corresponding to the k-th column of \code{x} and l-th column of \code{y}. If \code{y} is missing, then the columns of \code{x} are compared with each other. } \author{Friedrich Leisch} \seealso{\code{\link{classAgreement}}} \examples{ ## a stupid example with no class correlations: g1 <- sample(1:5, size=1000, replace=TRUE) g2 <- sample(1:5, size=1000, replace=TRUE) tab <- table(g1, g2) matchClasses(tab, "exact") ## let pairs (g1=1,g2=4) and (g1=3,g2=1) agree better k <- sample(1:1000, size=200) g1[k] <- 1 g2[k] <- 4 k <- sample(1:1000, size=200) g1[k] <- 3 g2[k] <- 1 tab <- table(g1, g2) matchClasses(tab, "exact") ## get agreement coefficients: compareMatchedClasses(g1, g2, method="exact") } \keyword{category} e1071/man/write.svm.Rd0000644000175100001440000000400311400421345014014 0ustar hornikusers\name{write.svm} \alias{write.svm} \title{Write SVM Object to File} \description{ This function exports an SVM object (trained by \code{svm}) to two specified files. One is in the format that the function 'svm\_load\_model' of libsvm can read. The other is for scaling data, containing a data with centers and scales for all variables. } \usage{ write.svm(object, svm.file = "Rdata.svm", scale.file = "Rdata.scale", yscale.file = "Rdata.yscale") } \arguments{ \item{object}{Object of class \code{"svm"}, created by \code{svm}.} \item{svm.file}{filename to export the svm object to.} \item{scale.file}{filename to export the scaling data of the explanatory variables to.} \item{yscale.file}{filename to export the scaling data of the dependent variable to, if any.} } \details{ This function is useful when SVM models trained in R shall be used in other environments. The SVM model is saved in the standard format of libsvm. The scaling data are written to a separate file because scaling data are not included in the standard format of libsvm. The format of the scaling data file is a n times 2 matrix: the n-th row corresponds to the n-th dimension of the data, the columns being formed of the corresponding mean and scale. If scaling information for the dependent variable exists (in case of regression models), it is stored in yet another file (1 times 2 matrix). } \author{ Tomomi TAKASHINA (based on 'predict.svm' by David Meyer) \email{t.takashina@computer.org} } \seealso{ \code{\link{svm}} } \examples{ data(iris) attach(iris) ## classification mode # default with factor response: model <- svm (Species~., data=iris) # export SVM object to file write.svm(model, svm.file = "iris-classifier.svm", scale.file = "iris-classifier.scale") # read scale file # the n-th row is corresponding to n-th dimension. The 1st column contains the # center value, the 2nd column is the scale value. read.table("iris-classifier.scale") } \keyword{neural} \keyword{nonlinear} \keyword{classif} e1071/man/svm.Rd0000644000175100001440000002337312400716427012707 0ustar hornikusers\name{svm} \alias{svm} \alias{svm.default} \alias{svm.formula} \alias{summary.svm} \alias{print.summary.svm} \alias{print.svm} \title{Support Vector Machines} \description{ \code{svm} is used to train a support vector machine. It can be used to carry out general regression and classification (of nu and epsilon-type), as well as density-estimation. A formula interface is provided. } \usage{ \method{svm}{formula}(formula, data = NULL, ..., subset, na.action = na.omit, scale = TRUE) \method{svm}{default}(x, y = NULL, scale = TRUE, type = NULL, kernel = "radial", degree = 3, gamma = if (is.vector(x)) 1 else 1 / ncol(x), coef0 = 0, cost = 1, nu = 0.5, class.weights = NULL, cachesize = 40, tolerance = 0.001, epsilon = 0.1, shrinking = TRUE, cross = 0, probability = FALSE, fitted = TRUE, ..., subset, na.action = na.omit) } \arguments{ \item{formula}{a symbolic description of the model to be fit.} \item{data}{an optional data frame containing the variables in the model. By default the variables are taken from the environment which \sQuote{svm} is called from.} \item{x}{a data matrix, a vector, or a sparse matrix (object of class \code{\link[Matrix]{Matrix}} provided by the \pkg{Matrix} package, or of class \code{\link[SparseM]{matrix.csr}} provided by the \pkg{SparseM} package, or of class \code{\link[slam]{simple_triplet_matrix}} provided by the \pkg{slam} package).} \item{y}{a response vector with one label for each row/component of \code{x}. Can be either a factor (for classification tasks) or a numeric vector (for regression).} \item{scale}{A logical vector indicating the variables to be scaled. If \code{scale} is of length 1, the value is recycled as many times as needed. Per default, data are scaled internally (both \code{x} and \code{y} variables) to zero mean and unit variance. The center and scale values are returned and used for later predictions.} \item{type}{\code{svm} can be used as a classification machine, as a regression machine, or for novelty detection. Depending of whether \code{y} is a factor or not, the default setting for \code{type} is \code{C-classification} or \code{eps-regression}, respectively, but may be overwritten by setting an explicit value.\cr Valid options are: \itemize{ \item \code{C-classification} \item \code{nu-classification} \item \code{one-classification} (for novelty detection) \item \code{eps-regression} \item \code{nu-regression} } } \item{kernel}{the kernel used in training and predicting. You might consider changing some of the following parameters, depending on the kernel type.\cr \describe{ \item{linear:}{\eqn{u'v}{u'*v}} \item{polynomial:}{\eqn{(\gamma u'v + coef0)^{degree}}{(gamma*u'*v + coef0)^degree}} \item{radial basis:}{\eqn{e^(-\gamma |u-v|^2)}{exp(-gamma*|u-v|^2)}} \item{sigmoid:}{\eqn{tanh(\gamma u'v + coef0)}{tanh(gamma*u'*v + coef0)}} } } \item{degree}{parameter needed for kernel of type \code{polynomial} (default: 3)} \item{gamma}{parameter needed for all kernels except \code{linear} (default: 1/(data dimension))} \item{coef0}{parameter needed for kernels of type \code{polynomial} and \code{sigmoid} (default: 0)} \item{cost}{cost of constraints violation (default: 1)---it is the \sQuote{C}-constant of the regularization term in the Lagrange formulation.} \item{nu}{parameter needed for \code{nu-classification}, \code{nu-regression}, and \code{one-classification}} \item{class.weights}{a named vector of weights for the different classes, used for asymmetric class sizes. Not all factor levels have to be supplied (default weight: 1). All components have to be named.} \item{cachesize}{cache memory in MB (default 40)} \item{tolerance}{tolerance of termination criterion (default: 0.001)} \item{epsilon}{epsilon in the insensitive-loss function (default: 0.1)} \item{shrinking}{option whether to use the shrinking-heuristics (default: \code{TRUE})} \item{cross}{if a integer value k>0 is specified, a k-fold cross validation on the training data is performed to assess the quality of the model: the accuracy rate for classification and the Mean Squared Error for regression} \item{fitted}{logical indicating whether the fitted values should be computed and included in the model or not (default: \code{TRUE})} \item{probability}{logical indicating whether the model should allow for probability predictions.} \item{\dots}{additional parameters for the low level fitting function \code{svm.default}} \item{subset}{An index vector specifying the cases to be used in the training sample. (NOTE: If given, this argument must be named.)} \item{na.action}{A function to specify the action to be taken if \code{NA}s are found. The default action is \code{na.omit}, which leads to rejection of cases with missing values on any required variable. An alternative is \code{na.fail}, which causes an error if \code{NA} cases are found. (NOTE: If given, this argument must be named.)} } \value{ An object of class \code{"svm"} containing the fitted model, including: \item{SV}{The resulting support vectors (possibly scaled).} \item{index}{The index of the resulting support vectors in the data matrix. Note that this index refers to the preprocessed data (after the possible effect of \code{na.omit} and \code{subset})} \item{coefs}{The corresponding coefficients times the training labels.} \item{rho}{The negative intercept.} \item{sigma}{In case of a probabilistic regression model, the scale parameter of the hypothesized (zero-mean) laplace distribution estimated by maximum likelihood.} \item{probA, probB}{numeric vectors of length k(k-1)/2, k number of classes, containing the parameters of the logistic distributions fitted to the decision values of the binary classifiers (1 / (1 + exp(a x + b))).} } \details{ For multiclass-classification with k levels, k>2, \code{libsvm} uses the \sQuote{one-against-one}-approach, in which k(k-1)/2 binary classifiers are trained; the appropriate class is found by a voting scheme. \code{libsvm} internally uses a sparse data representation, which is also high-level supported by the package \pkg{SparseM}. If the predictor variables include factors, the formula interface must be used to get a correct model matrix. \code{plot.svm} allows a simple graphical visualization of classification models. The probability model for classification fits a logistic distribution using maximum likelihood to the decision values of all binary classifiers, and computes the a-posteriori class probabilities for the multi-class problem using quadratic optimization. The probabilistic regression model assumes (zero-mean) laplace-distributed errors for the predictions, and estimates the scale parameter using maximum likelihood. } \note{ Data are scaled internally, usually yielding better results. Parameters of SVM-models usually \emph{must} be tuned to yield sensible results! } \references{ \itemize{ \item Chang, Chih-Chung and Lin, Chih-Jen:\cr \emph{LIBSVM: a library for Support Vector Machines}\cr \url{http://www.csie.ntu.edu.tw/~cjlin/libsvm} \item Exact formulations of models, algorithms, etc. can be found in the document:\cr Chang, Chih-Chung and Lin, Chih-Jen:\cr \emph{LIBSVM: a library for Support Vector Machines}\cr \url{http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.ps.gz} \item More implementation details and speed benchmarks can be found on: Rong-En Fan and Pai-Hsune Chen and Chih-Jen Lin:\cr \emph{Working Set Selection Using the Second Order Information for Training SVM}\cr \url{http://www.csie.ntu.edu.tw/~cjlin/papers/quadworkset.pdf} } } \author{ David Meyer (based on C/C++-code by Chih-Chung Chang and Chih-Jen Lin)\cr \email{David.Meyer@R-project.org} } \seealso{ \code{\link{predict.svm}} \code{\link{plot.svm}} \code{\link{tune.svm}} \code{\link[SparseM]{matrix.csr}} (in package \pkg{SparseM}) } \examples{ data(iris) attach(iris) ## classification mode # default with factor response: model <- svm(Species ~ ., data = iris) # alternatively the traditional interface: x <- subset(iris, select = -Species) y <- Species model <- svm(x, y) print(model) summary(model) # test with train data pred <- predict(model, x) # (same as:) pred <- fitted(model) # Check accuracy: table(pred, y) # compute decision values and probabilities: pred <- predict(model, x, decision.values = TRUE) attr(pred, "decision.values")[1:4,] # visualize (classes by color, SV by crosses): plot(cmdscale(dist(iris[,-5])), col = as.integer(iris[,5]), pch = c("o","+")[1:150 \%in\% model$index + 1]) ## try regression mode on two dimensions # create data x <- seq(0.1, 5, by = 0.05) y <- log(x) + rnorm(x, sd = 0.2) # estimate model and predict input values m <- svm(x, y) new <- predict(m, x) # visualize plot(x, y) points(x, log(x), col = 2) points(x, new, col = 4) ## density-estimation # create 2-dim. normal with rho=0: X <- data.frame(a = rnorm(1000), b = rnorm(1000)) attach(X) # traditional way: m <- svm(X, gamma = 0.1) # formula interface: m <- svm(~., data = X, gamma = 0.1) # or: m <- svm(~ a + b, gamma = 0.1) # test: newdata <- data.frame(a = c(0, 4), b = c(0, 4)) predict (m, newdata) # visualize: plot(X, col = 1:1000 \%in\% m$index + 1, xlim = c(-5,5), ylim=c(-5,5)) points(newdata, pch = "+", col = 2, cex = 5) # weights: (example not particularly sensible) i2 <- iris levels(i2$Species)[3] <- "versicolor" summary(i2$Species) wts <- 100 / table(i2$Species) wts m <- svm(Species ~ ., data = i2, class.weights = wts) } \keyword{neural} \keyword{nonlinear} \keyword{classif} e1071/man/lca.Rd0000644000175100001440000000410211400421345012615 0ustar hornikusers\name{lca} \alias{lca} \alias{print.lca} \alias{summary.lca} \alias{print.summary.lca} \alias{predict.lca} \title{Latent Class Analysis (LCA)} \usage{ lca(x, k, niter=100, matchdata=FALSE, verbose=FALSE) } \arguments{ \item{x}{Either a data matrix of binary observations or a list of patterns as created by \code{\link{countpattern}}} \item{k}{Number of classes used for LCA} \item{niter}{Number of Iterations} \item{matchdata}{If \code{TRUE} and \code{x} is a data matrix, the class membership of every data point is returned, otherwise the class membership of every pattern is returned.} \item{verbose}{If \code{TRUE} some output is printed during the computations.} } \description{ A latent class analysis with \code{k} classes is performed on the data given by \code{x}. } \value{ An object of class \code{"lca"} is returned, containing \item{w}{Probabilities to belong to each class} \item{p}{Probabilities of a `1' for each variable in each class} \item{matching}{Depending on \code{matchdata} either the class membership of each pattern or of each data point} \item{logl, loglsat}{The LogLikelihood of the model and of the saturated model} \item{bic, bicsat}{The BIC of the model and of the saturated model} \item{chisq}{Pearson's Chisq} \item{lhquot}{Likelihood quotient of the model and the saturated model} \item{n}{Number of data points.} \item{np}{Number of free parameters.} } \references{Anton K. Formann: ``Die Latent-Class-Analysis'', Beltz Verlag 1984} \author{Andreas Weingessel} \seealso{ \code{\link{countpattern}}, \code{\link{bootstrap.lca}} } \examples{ ## Generate a 4-dim. sample with 2 latent classes of 500 data points each. ## The probabilities for the 2 classes are given by type1 and type2. type1 <- c(0.8,0.8,0.2,0.2) type2 <- c(0.2,0.2,0.8,0.8) x <- matrix(runif(4000),nr=1000) x[1:500,] <- t(t(x[1:500,])}{N}=\frac{||U||^2}{N}} \itemize{ \item \eqn{F(U;k)} shows the fuzziness or the overlap of the partition and depends on \eqn{kN} elements. \item \eqn{1/k\leq F(U;k)\leq 1}, where if \eqn{F(U;k)=1} then \eqn{U} is a hard partition and if \eqn{F(U;k)=1/k} then \eqn{U=[1/k]} is the centroid of the fuzzy partion space \eqn{P_{fk}}. The converse is also valid. } } \item{\bold{partition.entropy}:}{ It is a measure that provides information about the membership matrix without also considering the data itself. The minimum values imply a good partition in the meaning of a more crisp partition. \eqn{H(U;k)=\sum_{i=1}^{N} h(u_i)/N}, where \eqn{h(u)=-\sum_{j=1}^{k} u_j\,\log _a (u_j)} the Shannon's entropy. \itemize{ \item \eqn{H(U;k)} shows the uncertainty of a fuzzy partition and depends also on \eqn{kN} elements. Specifically, \eqn{h(u_i)} is interpreted as the amount of fuzzy information about the membership of \eqn{x_i} in \eqn{k} classes that is retained by column \eqn{u_j}. Thus, at \eqn{U=[1/k]} the most information is withheld since the membership is the fuzziest possible. \item \eqn{0\leq H(U;k)\leq \log_a(k)}, where for \eqn{H(U;k)=0} \eqn{U} is a hard partition and for \eqn{H(U;k)=\log_a(k)} \eqn{U=[1/k]}. } } \item{\bold{proportion.exponent}:}{ It is a measure \eqn{P(U;k)} of fuzziness adept to detect structural variations in the partition matrix as it becomes more fuzzier. A crisp cluster in the partition matrix can drive it to infinity when the partition coefficient and the partition entropy are more sensitive to small changes when approaching a hard partition. Its evaluation does not also involve the data or the algorithm used to partition them and its maximum implies the optimal partition but without knowing what maximum is a statistically significant maximum. \itemize{ \item \eqn{0\leq P(U;k)<\infty}, since the \eqn{[0,1]} values explode to \eqn{[0,\infty)} due to the natural logarithm. Specifically, \eqn{P=0} when and only when \eqn{U=[1/k]}, while \eqn{P\rightarrow\infty} when any column of \eqn{U} is crisp. \item \eqn{P(U;k)} can easily explode and it is good for partitions with large column maximums and at detecting structural variations. } } \item{\bold{separation.index (known as CS Index)}:}{ This index identifies unique cluster structure with well-defined properties that depend on the data and a measure of distance. It answers the question if the clusters are compact and separated, but it rather seems computationally infeasible for big data sets since a distance matrix between all the data membership values has to be calculated. It also presupposes that a hard partition is derived from the fuzzy one.\cr \eqn{D_1(U;k;X,d)=\min_{i+1\,\leq\,l\,\leq\,k-1}\left\{\min_{1\,\leq\,j\,\leq\,k}\left\{\frac{dis(u_j,u_l)}{\max_{1\leq m\leq k}\{dia(u_m)\}}\right\}\right\}}, where \eqn{dia} is the diameter of the subset, \eqn{dis} the distance of two subsets, and \eqn{d} a metric. \eqn{U} is a CS partition of \eqn{X} \eqn{\Leftrightarrow D_1>1}. When this holds then \eqn{U} is unique. } } } \value{ Returns a vector with the validity measures values. } \references{ James C. Bezdek, \emph{Pattern Recognition with Fuzzy Objective Function Algorithms}, Plenum Press, 1981, NY.\cr L. X. Xie and G. Beni, \emph{Validity measure for fuzzy clustering}, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. \bold{3}, n. 8, p. 841-847, 1991.\cr I. Gath and A. B. Geva, \emph{Unsupervised Optimal Fuzzy Clustering}, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. \bold{11}, n. 7, p. 773-781, 1989.\cr Y. Fukuyama and M. Sugeno, \emph{A new method of choosing the number of clusters for the fuzzy $c$-means method}, Proc. 5th Fuzzy Syst. Symp., p. 247-250, 1989 (in japanese).} \author{Evgenia Dimitriadou} \seealso{\code{\link{cmeans}}} \examples{ # a 2-dimensional example x<-rbind(matrix(rnorm(100,sd=0.3),ncol=2), matrix(rnorm(100,mean=1,sd=0.3),ncol=2)) cl<-cmeans(x,2,20,verbose=TRUE,method="cmeans") resultindexes <- fclustIndex(cl,x, index="all") resultindexes } \keyword{cluster} e1071/man/boxplot.bclust.Rd0000644000175100001440000000214511400421345015045 0ustar hornikusers\name{boxplot.bclust} \alias{boxplot.bclust} \title{Boxplot of Cluster Profiles} \usage{ \method{boxplot}{bclust}(x, n=nrow(x$centers), bycluster=TRUE, main=deparse(substitute(x)), oneplot=TRUE, which=1:n, ...) } \arguments{ \item{x}{Clustering result, object of class \code{"bclust"}.}% \item{n}{Number of clusters to plot, by default the number of clusters used in the call of \code{\link{bclust}}.} \item{bycluster}{If \code{TRUE} (default), a boxplot for each cluster is plotted. If \code{FALSE}, a boxplot for each variable is plotted.} \item{main}{Main title of the plot, by default the name of the cluster object.} \item{oneplot}{If \code{TRUE}, all boxplots appear on one screen (using an appropriate rectangular layout).} \item{which}{Number of clusters which should be plotted, default is all clusters.} \item{...}{Additional arguments for \code{\link{boxplot}}.} } \description{ Makes boxplots of the results of a bagged clustering run. } \author{Friedrich Leisch} \keyword{hplot} \examples{ data(iris) bc1 <- bclust(iris[,1:4], 3, base.centers=5) boxplot(bc1) } e1071/man/predict.svm.Rd0000644000175100001440000000755211534250612014335 0ustar hornikusers\name{predict.svm} \alias{predict.svm} \title{Predict Method for Support Vector Machines} \description{ This function predicts values based upon a model trained by \code{svm}. } \usage{ \method{predict}{svm}(object, newdata, decision.values = FALSE, probability = FALSE, ..., na.action = na.omit) } \arguments{ \item{object}{Object of class \code{"svm"}, created by \code{svm}.} \item{newdata}{An object containing the new input data: either a matrix or a sparse matrix (object of class \code{\link[Matrix]{Matrix}} provided by the \pkg{Matrix} package, or of class \code{\link[SparseM]{matrix.csr}} provided by the \pkg{SparseM} package, or of class \code{\link[slam]{simple_triplet_matrix}} provided by the \pkg{slam} package). A vector will be transformed to a n x 1 matrix.} \item{decision.values}{Logical controlling whether the decision values of all binary classifiers computed in multiclass classification shall be computed and returned.} \item{probability}{Logical indicating whether class probabilities should be computed and returned. Only possible if the model was fitted with the \code{probability} option enabled.} \item{na.action}{A function to specify the action to be taken if \sQuote{NA}s are found. The default action is \code{na.omit}, which leads to rejection of cases with missing values on any required variable. An alternative is \code{na.fail}, which causes an error if \code{NA} cases are found. (NOTE: If given, this argument must be named.)} \item{\dots}{Currently not used.} } \value{ A vector of predicted values (for classification: a vector of labels, for density estimation: a logical vector). If \code{decision.value} is \code{TRUE}, the vector gets a \code{"decision.values"} attribute containing a n x c matrix (n number of predicted values, c number of classifiers) of all c binary classifiers' decision values. There are k * (k - 1) / 2 classifiers (k number of classes). The colnames of the matrix indicate the labels of the two classes. If \code{probability} is \code{TRUE}, the vector gets a \code{"probabilities"} attribute containing a n x k matrix (n number of predicted values, k number of classes) of the class probabilities. } \note{ If the training set was scaled by \code{svm} (done by default), the new data is scaled accordingly using scale and center of the training data. } \author{ David Meyer (based on C++-code by Chih-Chung Chang and Chih-Jen Lin)\cr \email{David.Meyer@R-project.org} } \seealso{ \code{\link{svm}} } \examples{ data(iris) attach(iris) ## classification mode # default with factor response: model <- svm(Species ~ ., data = iris) # alternatively the traditional interface: x <- subset(iris, select = -Species) y <- Species model <- svm(x, y, probability = TRUE) print(model) summary(model) # test with train data pred <- predict(model, x) # (same as:) pred <- fitted(model) # compute decision values and probabilites pred <- predict(model, x, decision.values = TRUE, probability = TRUE) attr(pred, "decision.values")[1:4,] attr(pred, "probabilities")[1:4,] ## try regression mode on two dimensions # create data x <- seq(0.1, 5, by = 0.05) y <- log(x) + rnorm(x, sd = 0.2) # estimate model and predict input values m <- svm(x, y) new <- predict(m, x) # visualize plot (x, y) points (x, log(x), col = 2) points (x, new, col = 4) ## density-estimation # create 2-dim. normal with rho=0: X <- data.frame(a = rnorm(1000), b = rnorm(1000)) attach(X) # traditional way: m <- svm(X, gamma = 0.1) # formula interface: m <- svm(~., data = X, gamma = 0.1) # or: m <- svm(~ a + b, gamma = 0.1) # test: newdata <- data.frame(a = c(0, 4), b = c(0, 4)) predict (m, newdata) # visualize: plot(X, col = 1:1000 \%in\% m$index + 1, xlim = c(-5,5), ylim=c(-5,5)) points(newdata, pch = "+", col = 2, cex = 5) } \keyword{neural} \keyword{nonlinear} \keyword{classif} e1071/man/stft.Rd0000644000175100001440000000317211400421345013044 0ustar hornikusers\name{stft} \title{Computes the Short Time Fourier Transform of a Vector} \usage{stft(X, win=min(80,floor(length(X)/10)), inc=min(24, floor(length(X)/30)), coef=64, wtype="hanning.window")} \alias{stft} \arguments{ \item{X}{The vector from which the stft is computed.} \item{win}{Length of the window. For long vectors the default window size is 80, for short vectors the window size is chosen so that 10 windows fit in the vector.} \item{inc}{Increment by which the window is shifted. For long vectors the default increment is 24, for short vectors the increment is chosen so that 30 increments fit in the vector.} \item{coef}{Number of Fourier coefficients} \item{wtype}{Type of window used} } \description{This function computes the Short Time Fourier Transform of a given vector \code{X}. First, time-slices of length \code{win} are extracted from the vector. The shift of one time-slice to the next one is given by \code{inc}. The values of these time-slices are smoothed by mulitplying them with a window function specified in \code{wtype}. For the thus obtained windows, the Fast Fourier Transform is computed.} \value{Object of type stft. Contains the values of the stft and information about the parameters. \item{values}{A matrix containing the results of the stft. Each row of the matrix contains the \code{coef} Fourier coefficients of one window.} \item{windowsize}{The value of the parameter \code{win}} \item{increment}{The value of the parameter \code{inc}} \item{windowtype}{The value of the parameter \code{wtype}} } \author{Andreas Weingessel} \seealso{plot.stft} \examples{x<-rnorm(500) y<-stft(x) plot(y) } \keyword{ts} e1071/man/matchControls.Rd0000644000175100001440000000545011400421345014705 0ustar hornikusers\name{matchControls} \alias{matchControls} \title{Find Matched Control Group} \usage{ matchControls(formula, data = list(), subset, contlabel = "con", caselabel = NULL, dogrep = TRUE, replace = FALSE) } \arguments{ \item{formula}{A formula indicating cases, controls and the variables to be matched. Details are described below.} \item{data}{an optional data frame containing the variables in the model. By default the variables are taken from the environment which \code{matchControls} is called from.} \item{subset}{an optional vector specifying a subset of observations to be used in the matching process.} \item{contlabel}{A string giving the label of the control group.} \item{caselabel}{A string giving the labels of the cases.} \item{dogrep}{If \code{TRUE}, then \code{contlabel} and \code{contlabel} are matched using \code{\link{grep}}, else string comparison (exact equality) is used.} \item{replace}{If \code{FALSE}, then every control is used only once.} } \description{ Finds controls matching the cases as good as possible. } \details{ The left hand side of the \code{formula} must be a factor determining whether an observation belongs to the case or the control group. By default, all observations where a grep of \code{contlabel} matches, are used as possible controls, the rest is taken as cases. If \code{caselabel} is given, then only those observations are taken as cases. If \code{dogrep = TRUE}, then both \code{contlabel} and \code{caselabel} can be regular expressions. The right hand side of the \code{formula} gives the variables that should be matched. The matching is done using the \code{\link{daisy}} distance from the \code{cluster} package, i.e., a model frame is built from the formula and used as input for \code{\link{daisy}}. For each case, the nearest control is selected. If \code{replace = FALSE}, each control is used only once. } \value{ Returns a list with components \item{cases}{Row names of cases.} \item{controls}{Row names of matched controls.} \item{factor}{A factor with 2 levels indicating cases and controls (the rest is set to \code{NA}.} } \author{Friedrich Leisch} \examples{ Age.case <- 40 + 5 * rnorm(50) Age.cont <- 45 + 10 * rnorm(150) Age <- c(Age.case, Age.cont) Sex.case <- sample(c("M", "F"), 50, prob = c(.4, .6), replace = TRUE) Sex.cont <- sample(c("M", "F"), 150, prob = c(.6, .4), replace = TRUE) Sex <- as.factor(c(Sex.case, Sex.cont)) casecont <- as.factor(c(rep("case", 50), rep("cont", 150))) ## now look at the group properties: boxplot(Age ~ casecont) barplot(table(Sex, casecont), beside = TRUE) m <- matchControls(casecont ~ Sex + Age) ## properties of the new groups: boxplot(Age ~ m$factor) barplot(table(Sex, m$factor)) } \keyword{manip} e1071/cleanup0000755000175100001440000000011211400421345012366 0ustar hornikusers#!/bin/sh rm config.* -f rm \#*\# -rf rm .\#* -rf rm autom4te.cache -rf