e1071/0000755000175100001440000000000014120672012011020 5ustar hornikuserse1071/NAMESPACE0000655000175100001440000000432614077326053012262 0ustar hornikusersuseDynLib("e1071", .registration = TRUE, .fixes = "R_") import(graphics) import(grDevices) importFrom("stats", "cmdscale", "complete.cases", "cutree", "delete.response", "dnorm", "fft", "fitted", "kmeans", "median", "model.extract", "model.frame", "model.matrix", "model.response", "na.fail", "na.omit", "na.pass", "napredict", "optim", "pchisq", "pnorm", "ppoints", "predict", "qnorm", "quantile", "rnorm", "runif", "sd", "terms", "time", "ts", "var", "xtabs") importFrom("proxy", "dist") importFrom("utils", "head") 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, gknn, 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, scale_data_frame) exportPattern("tune\\..+", "best\\..+") S3method(boxplot, bclust) S3method(coef, svm) S3method(gknn, default) S3method(gknn, formula) S3method(lines, probplot) S3method(naiveBayes, default) S3method(naiveBayes, formula) 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(predict, gknn) S3method(print, bootstrap.lca) S3method("print", "fclust") S3method(print, gknn) 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(summary, lca) S3method(summary, svm) S3method(summary, tune) S3method(svm, default) S3method(svm, formula) e1071/man/0000755000175100001440000000000014052132143011573 5ustar hornikuserse1071/man/svm.Rd0000655000175100001440000002546713741245307012722 0ustar hornikusers\name{svm} \alias{svm} \alias{svm.default} \alias{svm.formula} \alias{summary.svm} \alias{print.summary.svm} \alias{coef.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. Specifying \code{"inverse"} will choose the weights \emph{inversely} proportional to the class distribution.} \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. For linear kernel, the coefficients of the regression/decision hyperplane can be extracted using the \code{coef} method (see examples). } \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{https://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{https://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{https://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) ## extract coefficients for linear kernel # a. regression x <- 1:100 y <- x + rnorm(100) m <- svm(y ~ x, scale = FALSE, kernel = "linear") coef(m) plot(y ~ x) abline(m, col = "red") # b. classification # transform iris data to binary problem, and scale data setosa <- as.factor(iris$Species == "setosa") iris2 = scale(iris[,-5]) # fit binary C-classification model m <- svm(setosa ~ Petal.Width + Petal.Length, data = iris2, kernel = "linear") # plot data and separating hyperplane plot(Petal.Length ~ Petal.Width, data = iris2, col = setosa) (cf <- coef(m)) abline(-cf[1]/cf[3], -cf[2]/cf[3], col = "red") # plot margin and mark support vectors abline(-(cf[1] + 1)/cf[3], -cf[2]/cf[3], col = "blue") abline(-(cf[1] - 1)/cf[3], -cf[2]/cf[3], col = "blue") points(m$SV, pch = 5, cex = 2) } \keyword{neural} \keyword{nonlinear} \keyword{classif} e1071/man/plot.svm.Rd0000755000175100001440000000437311633216702013664 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/tune.Rd0000655000175100001440000001063312714054325013052 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}. Only used for bootstrap and fixed validation set (see \code{\link{tune.control}})} \item{validation.y}{if no formula interface is used, the response of the (optional) validation set. Only used for bootstrap and fixed validation set (see \code{\link{tune.control}})} \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/hanning.window.Rd0000755000175100001440000000142311400421345015014 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/kurtosis.Rd0000655000175100001440000000317013724127530013761 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 kurtosis detailed below.} } \details{ If \code{x} contains missings and these are not removed, the kurtosis 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/hamming.distance.Rd0000755000175100001440000000122712505565430015312 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/scale_data_frame.Rd0000644000175100001440000000571614024346715015340 0ustar hornikusers\name{scale_data_frame} \alias{scale_data_frame} \title{Scaling and Centering of Data Frames} \description{ \code{scale_data_frame} centers and/or scales the columns of a data frame (or matrix). } \usage{ scale_data_frame(x, center = TRUE, scale = TRUE) } \arguments{ \item{x}{a data frame or a numeric matrix (or vector). For matrices or vectors, \code{scale()} is used.} \item{center}{either a logical value or numeric-alike vector of length equal to the number of columns of \code{x}, where \sQuote{numeric-alike} means that \code{\link{as.numeric}(.)} will be applied successfully if \code{\link{is.numeric}(.)} is not true.} \item{scale}{either a logical value or a numeric-alike vector of length equal to the number of columns of \code{x}.} } \value{ For \code{scale.default}, the centered, scaled data frame. Non-numeric columns are ignored. Note that logicals are treated as 0/1-numerics to be consistent with \code{scale()}. The numeric centering and scalings used (if any) are returned as attributes \code{"scaled:center"} and \code{"scaled:scale"} - but only for the numeric/logical columns. } \details{ The value of \code{center} determines how column centering is performed. If \code{center} is a numeric-alike vector with length equal to the number of numeric/logical columns of \code{x}, then each column of \code{x} has the corresponding value from \code{center} subtracted from it. If \code{center} is \code{TRUE} then centering is done by subtracting the column means (omitting \code{NA}s) of \code{x} from their corresponding columns, and if \code{center} is \code{FALSE}, no centering is done. The value of \code{scale} determines how column scaling is performed (after centering). If \code{scale} is a numeric-alike vector with length equal to the number of numeric/logiocal columns of \code{x}, then each column of \code{x} is divided by the corresponding value from \code{scale}. If \code{scale} is \code{TRUE} then scaling is done by dividing the (centered) columns of \code{x} by their standard deviations if \code{center} is \code{TRUE}, and the root mean square otherwise. If \code{scale} is \code{FALSE}, no scaling is done. The root-mean-square for a (possibly centered) column is defined as \eqn{\sqrt{\sum(x^2)/(n-1)}}{sqrt(sum(x^2)/(n-1))}, where \eqn{x} is a vector of the non-missing values and \eqn{n} is the number of non-missing values. In the case \code{center = TRUE}, this is the same as the standard deviation, but in general it is not. (To scale by the standard deviations without centering, use \code{scale(x, center = FALSE, scale = apply(x, 2, sd, na.rm = TRUE))}.) } \references{ Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) \emph{The New S Language}. Wadsworth & Brooks/Cole. } \seealso{ \code{\link{sweep}} which allows centering (and scaling) with arbitrary statistics. } \examples{ require(stats) data(iris) summary(scale_data_frame(iris)) } \keyword{array} e1071/man/tune.control.Rd0000755000175100001440000000523012444323171014525 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/hamming.window.Rd0000755000175100001440000000142711400421345015016 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/bclust.Rd0000655000175100001440000001160114020532377013367 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="euclidean", 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{https://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/gknn.Rd0000644000175100001440000000752514077325003013036 0ustar hornikusers\name{gknn} \alias{gknn} \alias{gknn.default} \alias{gknn.formula} \alias{print.gknn} \alias{predict.gknn} \title{Generalized k-Nearest Neighbors Classification or Regression} \description{ \code{gknn} is an implementation of the k-nearest neighbours algorithm making use of general distance measures. A formula interface is provided. } \usage{ \method{gknn}{formula}(formula, data = NULL, ..., subset, na.action = na.pass, scale = TRUE) \method{gknn}{default}(x, y, k = 1, method = NULL, scale = TRUE, use_all = TRUE, FUN = mean, ...) \method{predict}{gknn}(object, newdata, type = c("class", "votes", "prob"), ..., na.action = na.pass) } \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{gknn} is called from.} \item{x}{a data matrix.} \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{k}{number of neighbours considered.} \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. By default, numeric \emph{matrices} are scaled to zero mean and unit variance. The center and scale values are returned and used for later predictions. Note that the default metric for data frames is the Gower metric which \emph{standardizes} the values to the unit interval.} \item{method}{Argument passed to \code{dist()} from the \code{proxy} package to select the distance metric used: a function, or a mnemonic string referencing the distance measure. Defaults to \code{"Euclidean"} for metric matrices, to \code{"Jaccard"} for logical matrices and to \code{"Gower"} for data frames. } \item{use_all}{controls handling of ties. If true, all distances equal to the kth largest are included. If false, a random selection of distances equal to the kth is chosen to use exactly k neighbours.} \item{FUN}{function used to aggregate the k nearest target values in case of regression.} \item{object}{object of class \code{gknn}.} \item{newdata}{matrix or data frame with new instances.} \item{type}{character specifying the return type in case of class predictions: for \code{"class"}, the class labels; for \code{"prob"}, the class distribution for all k neighbours considered; for \code{"votes"}, the raw counts.} \item{\dots}{additional parameters passed to \code{dist()}} \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.pass}. (NOTE: If given, this argument must be named.)} } \value{ For \code{gknn()}, an object of class \code{"gknn"} containing the data and the specified parameters. For \code{predict.gknn()}, a vector of predictions, or a matrix with votes for all classes. In case of an overall class tie, the predicted class is chosen by random. } \author{ David Meyer (\email{David.Meyer@R-project.org}) } \seealso{ \code{\link[proxy]{dist}} (in package \pkg{proxy}) } \examples{ data(iris) model <- gknn(Species ~ ., data = iris) predict(model, iris[c(1, 51, 101),]) test = c(45:50, 95:100, 145:150) model <- gknn(Species ~ ., data = iris[-test,], k = 3, method = "Manhattan") predict(model, iris[test,], type = "votes") model <- gknn(Species ~ ., data = iris[-test], k = 3, method = "Manhattan") predict(model, iris[test,], type = "prob") } \keyword{nonlinear} \keyword{classif} e1071/man/lca.Rd0000655000175100001440000000412514022142261012624 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), nrow = 1000) x[1:500,] <- t(t(x[1:500,]) < type1) * 1 x[501:1000,] <- t(t(x[501:1000,]) < type2) * 1 l <- lca(x, 2, niter=5) print(l) summary(l) p <- predict(l, x) table(p, c(rep(1,500),rep(2,500))) } \keyword{multivariate} \keyword{cluster} e1071/man/predict.svm.Rd0000755000175100001440000000755211534250612014340 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/write.svm.Rd0000655000175100001440000000410713475403024014033 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 separate files 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 (temporary) files svm_file <- tempfile() scale_file <- tempfile() write.svm(model, svm.file = svm_file, scale.file = scale_file) # 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(scale_file) # clean up unlink(svm_file) unlink(scale_file) } \keyword{neural} \keyword{nonlinear} \keyword{classif} e1071/man/skewness.Rd0000755000175100001440000000325711400421345013735 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/naiveBayes.Rd0000755000175100001440000000764312375105270014174 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/rbridge.Rd0000755000175100001440000000113211400421345013477 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/read.matrix.csr.Rd0000755000175100001440000000302212016757022015075 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/ica.Rd0000755000175100001440000000342311400421345012622 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/hsv_palette.Rd0000755000175100001440000000143511400421345014405 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/rectangle.window.Rd0000755000175100001440000000106511400421345015340 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/classAgreement.Rd0000755000175100001440000000610411400421345015022 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/cmeans.Rd0000755000175100001440000001206711400421345013340 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/probplot.Rd0000755000175100001440000000433411400421345013731 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/countpattern.Rd0000755000175100001440000000202411400421345014610 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/moment.Rd0000755000175100001440000000231211400421345013361 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/impute.Rd0000755000175100001440000000101011400421345013357 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/bootstrap.lca.Rd0000655000175100001440000000523314022142200014632 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), nrow = 1000) x[1:500,] <- t(t(x[1:500,]) < type1) * 1 x[501:1000,] <- t(t(x[501:1000,]) < type2) * 1 l <- lca(x, 2, niter=5) bl <- bootstrap.lca(l,nsamples=3,lcaiter=5) bl } \keyword{multivariate} e1071/man/matchClasses.Rd0000755000175100001440000000667011400421345014507 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/sigmoid.Rd0000755000175100001440000000073711400421345013526 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/plot.tune.Rd0000755000175100001440000000375211400421345014023 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/cshell.Rd0000755000175100001440000000660514052132645013355 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) } \keyword{cluster} e1071/man/element.Rd0000755000175100001440000000064511400421345013522 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/fclustIndex.Rd0000755000175100001440000001753311400421345014365 0ustar hornikusers\name{fclustIndex} \title{Fuzzy Cluster Indexes (Validity/Performance Measures)} \usage{fclustIndex(y, x, index = "all")} \alias{fclustIndex} \arguments{ \item{y}{An object of a fuzzy clustering result of class \code{"fclust"}} \item{x}{Data matrix} \item{index}{The validity measures used: \code{"gath.geva"}, \code{"xie.beni"}, \code{"fukuyama.sugeno"}, \code{"partition.coefficient"}, \code{"partition.entropy"}, \code{"proportion.exponent"}, \code{"separation.index"} and \code{"all"} for all the indexes.}} \description{ Calculates the values of several fuzzy validity measures. The values of the indexes can be independently used in order to evaluate and compare clustering partitions or even to determine the number of clusters existing in a data set.} \details{ The validity measures and a short description of them follows, where \eqn{N} is the number of data points, \eqn{u_{ij}} the values of the membership matrix, \eqn{v_j} the centers of the clusters and \eqn{k} te number of clusters. \describe{ \item{\bold{gath.geva}:}{ Gath and Geva introduced 2 main criteria for comparing and finding optimal partitions based on the heuristics that a better clustering assumes clear separation between the clusters, minimal volume of the clusters and maximal number of data points concentrated in the vicinity of the cluster centroids. These indexes are only for the cmeans clustering algorithm valid. For the first, the ``fuzzy hypervolume'' we have: \eqn{F_{HV}=\sum_{j=1}^{c}{[\det(F_j)]}^{1/2}}, where \eqn{F_j=\frac{\sum_{i=1}^N u_{ij}(x_i-v_j)(x_i-v_j)^T}{\sum_{i=1}^{N}u_{ij}}}, for the case when the defuzzification parameter is 2. For the second, the ``average partition density'': \eqn{D_{PA}=\frac{1}{k}\sum_{j=1}^k\frac{S_j}{{[\det(F_j)]}^{1/2}}}, where \eqn{S_j=\sum_{i=1}^N u_{ij}}. Moreover, the ``partition density'' which expresses the general partition density according to the physical definition of density is calculated by: \eqn{P_D=\frac{S}{F_{HV}}}, where \eqn{S=\sum_{j=1}^k\sum_{i=1}^N u_{ij}}. } \item{\bold{xie.beni}:}{ This index is a function of the data set and the centroids of the clusters. Xie and Beni explained this index by writing it as a ratio of the total variation of the partition and the centroids $(U,V)$ and the separation of the centroids vectors. The minimum values of this index under comparison support the best partitions. \eqn{u_{XB}(U,V;X)=\frac{\sum_{j=1}^k\sum_{i=1}^Nu_{ij}^2{||x_i-v_j||}^2}{N(\min_{j\neq l}\{{||v_j-v_l||}^2\})}} } \item{\bold{fukuyama.sugeno}:}{ This index consists of the difference of two terms, the first combining the fuzziness in the membership matrix with the geometrical compactness of the representation of the data set via the prototypes, and the second the fuzziness in its row of the partition matrix with the distance from the $i$th prototype to the grand mean of the data. The minimum values of this index also propose a good partition. \eqn{u_{FS}(U,V;X)=\sum_{i=1}^{N}\sum_{j=1}^k (u_{ij}^2)^q(||x_i-v_j||^2-||v_j-\bar v||^2)} } \item{\bold{partition.coefficient}:}{ An index which measures the fuzziness of the partition but without considering the data set itself. It is a heuristic measure since it has no connection to any property of the data. The maximum values of it imply a good partition in the meaning of a least fuzzy clustering. \eqn{F(U;k)=\frac{tr (UU^T)}{N}=\frac{}{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/bincombinations.Rd0000755000175100001440000000052311400421345015242 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/permutations.Rd0000755000175100001440000000054411400421345014621 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/boxplot.bclust.Rd0000755000175100001440000000214511400421345015050 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/stft.Rd0000755000175100001440000000317211400421345013047 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.Rd0000755000175100001440000000545011400421345014710 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/man/interpolate.Rd0000755000175100001440000000214211400421345014411 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/rwiener.Rd0000755000175100001440000000075711400421345013550 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/shortestPaths.Rd0000755000175100001440000000422011400421345014735 0ustar hornikusers\name{allShortestPaths} \alias{allShortestPaths} \alias{extractPath} \title{Find Shortest Paths Between All Nodes in a Directed Graph} \description{ \code{allShortestPaths} finds all shortest paths in a directed (or undirected) graph using Floyd's algorithm. \code{extractPath} can be used to actually extract the path between a given pair of nodes. } \usage{ allShortestPaths(x) extractPath(obj, start, end) } \arguments{ \item{x}{matrix or distance object} \item{obj}{return value of \code{allShortestPaths}} \item{start}{integer, starting point of path} \item{end}{integer, end point of path} } \details{ If \code{x} is a matrix, then \code{x[i,j]} has to be the length of the direct path from point \code{i} to point \code{j}. If no direct connection from point \code{i} to point \code{j} exist, then \code{x[i,j]} should be either \code{NA} or \code{Inf}. Note that the graph can be directed, hence \code{x[i,j]} need not be the same as \code{x[j,i]}. The main diagonal of \code{x} is ignored. Alternatively, \code{x} can be a distance object as returned by \code{\link{dist}} (corresponding to an undirected graph). } \value{ \code{allShortestPaths} returns a list with components \item{length}{A matrix with the total lengths of the shortest path between each pair of points.} \item{middlePoints}{A matrix giving a point in the middle of each shortest path (or 0 if the direct connection is the shortest path), this is mainly used as input for \code{extractPath}.} \code{extractPath} returns a vector of node numbers giving with the shortest path between two points. } \references{Kumar, V., Grama, A., Gupta, A. and Karypis, G. Introduction to Parallel Programming - Design and Analysis of Algorithms, Benjamin Cummings Publishing, 1994, ISBN 0-8053-3170-0} \author{Friedrich Leisch} \examples{ ## build a graph with 5 nodes x <- matrix(NA, 5, 5) diag(x) <- 0 x[1,2] <- 30; x[1,3] <- 10 x[2,4] <- 70; x[2,5] <- 40 x[3,4] <- 50; x[3,5] <- 20 x[4,5] <- 60 x[5,4] <- 10 print(x) ## compute all path lengths z <- allShortestPaths(x) print(z) ## the following should give 1 -> 3 -> 5 -> 4 extractPath(z, 1, 4) } \keyword{optimize} e1071/man/tune.wrapper.Rd0000755000175100001440000000470512263003667014537 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/e1071-deprecated.Rd0000755000175100001440000000051211400421345014715 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/plot.stft.Rd0000755000175100001440000000160411400421345014022 0ustar hornikusers\name{plot.stft} \alias{plot.stft} \title{Plot Short Time Fourier Transforms} \description{ An object of class \code{"stft"} is plotted as a gray scale image. The x-axis corresponds to time, the y-axis to frequency. If the default colormap is used, dark regions in the plot correspond to high values at the particular time/frequency location. } \usage{ \method{plot}{stft}(x, col = gray(63:0/63), \dots) } \arguments{ \item{x}{An object of class \code{"stft"} as obtained by the function \code{stft}.} \item{col}{An optional colormap. By default 64 gray values are used, where white corresponds to the minimum value and black to the maximum.} \item{\dots}{further arguments to be passed to or from methods.} } \value{No return value. This function is only for plotting.} \author{Andreas Weingessel} \seealso{stft} \examples{x<-rnorm(500) y<-stft(x) plot(y) } \keyword{ts} e1071/man/Discrete.Rd0000755000175100001440000000302511400421345013626 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/DESCRIPTION0000655000175100001440000000316414120672012012534 0ustar hornikusersPackage: e1071 Version: 1.7-9 Title: Misc Functions of the Department of Statistics, Probability Theory Group (Formerly: E1071), TU Wien Imports: graphics, grDevices, class, stats, methods, utils, proxy Suggests: cluster, mlbench, nnet, randomForest, rpart, SparseM, xtable, Matrix, MASS, slam Authors@R: c(person(given = "David", family = "Meyer", role = c("aut", "cre"), email = "David.Meyer@R-project.org"), person(given = "Evgenia", family = "Dimitriadou", role = c("aut","cph")), person(given = "Kurt", family = "Hornik", role = "aut"), person(given = "Andreas", family = "Weingessel", role = "aut"), person(given = "Friedrich", family = "Leisch", role = "aut"), person(given = "Chih-Chung", family = "Chang", role = c("ctb","cph"), comment = "libsvm C++-code"), person(given = "Chih-Chen", family = "Lin", role = c("ctb","cph"), comment = "libsvm C++-code")) Description: Functions for latent class analysis, short time Fourier transform, fuzzy clustering, support vector machines, shortest path computation, bagged clustering, naive Bayes classifier, generalized k-nearest neighbour ... License: GPL-2 | GPL-3 LazyLoad: yes NeedsCompilation: yes Packaged: 2021-09-16 06:33:26 UTC; meyer Author: David Meyer [aut, cre], Evgenia Dimitriadou [aut, cph], Kurt Hornik [aut], Andreas Weingessel [aut], Friedrich Leisch [aut], Chih-Chung Chang [ctb, cph] (libsvm C++-code), Chih-Chen Lin [ctb, cph] (libsvm C++-code) Maintainer: David Meyer Repository: CRAN Date/Publication: 2021-09-16 16:42:50 UTC e1071/build/0000755000175100001440000000000014120562466012132 5ustar hornikuserse1071/build/vignette.rds0000644000175100001440000000052214120562466014470 0ustar hornikusersRMO@-?H8xݣ rn1&F:lmvWЛiԳM:yf_A4VlHǰOMoă}nF!J{Rw+_X/Qzcȹ)J(R7A.`GW#tJ QZ'R+݊g/6^慌GYD6iynGOd ΩDI芽řEkJjgMQyv9yY̥_G7$Ґ| &d'k'Oبs0uxPǚհv\Af٬m[]7R=yOGbmze1071/tests/0000755000175100001440000000000012212345174012170 5ustar hornikuserse1071/tests/clustering.R0000755000175100001440000000033311400421345014465 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/0000755000175100001440000000000014120562466011622 5ustar hornikuserse1071/src/floyd.c0000755000175100001440000000140311400421345013070 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/init.c0000644000175100001440000000627513044152377012743 0ustar hornikusers #include #include #include 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); 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 e1071_floyd(int *n, double *A, double *C, int *P); 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); 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); 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); 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); static const R_CMethodDef CEntries[] = { {"cmeans", (DL_FUNC) &cmeans, 14}, {"cshell", (DL_FUNC) &cshell, 15}, {"e1071_floyd", (DL_FUNC) &e1071_floyd, 4}, {"svmpredict", (DL_FUNC) &svmpredict, 30}, {"svmtrain", (DL_FUNC) &svmtrain, 37}, {"svmwrite", (DL_FUNC) &svmwrite, 21}, {"ufcl", (DL_FUNC) &ufcl, 15}, {NULL, NULL, 0} }; void R_init_e1071(DllInfo *dll) { R_registerRoutines(dll, CEntries, NULL, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } e1071/src/svm.cpp0000655000175100001440000020001013325342027013121 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 || Gmin_idx == -1) 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 || Gmin_idx == -1) 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++; } if (nr_class == 2) { prob_estimates[0] = pairwise_prob[0][1]; prob_estimates[1] = pairwise_prob[1][0]; } else 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 = setlocale(LC_ALL, NULL); if (old_locale) { old_locale = strdup(old_locale); } setlocale(LC_ALL, "C"); const svm_parameter& param = model->param; (void) fprintf(fp,"svm_type %s\n", svm_type_table[param.svm_type]); (void) fprintf(fp,"kernel_type %s\n", kernel_type_table[param.kernel_type]); if(param.kernel_type == POLY) (void) fprintf(fp,"degree %d\n", param.degree); if(param.kernel_type == POLY || param.kernel_type == RBF || param.kernel_type == SIGMOID) (void) fprintf(fp,"gamma %.17g\n", param.gamma); if(param.kernel_type == POLY || param.kernel_type == SIGMOID) (void) fprintf(fp,"coef0 %.17g\n", param.coef0); int nr_class = model->nr_class; int l = model->l; (void) fprintf(fp, "nr_class %d\n", nr_class); (void) fprintf(fp, "total_sv %d\n",l); { (void) fprintf(fp, "rho"); for(int i=0;irho[i]); (void) fprintf(fp, "\n"); } if(model->label) { (void) fprintf(fp, "label"); for(int i=0;ilabel[i]); (void) fprintf(fp, "\n"); } if(model->probA) // regression has probA only { (void) fprintf(fp, "probA"); for(int i=0;iprobA[i]); (void) fprintf(fp, "\n"); } if(model->probB) { (void) fprintf(fp, "probB"); for(int i=0;iprobB[i]); (void) fprintf(fp, "\n"); } if(model->nSV) { (void) fprintf(fp, "nr_sv"); for(int i=0;inSV[i]); (void) fprintf(fp, "\n"); } (void) 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) { (void) fprintf(fp,"%d:%.8g ",p->index,p->value); p++; } (void) 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; } // // FSCANF helps to handle fscanf failures. // Its do-while block avoids the ambiguity when // if (...) // FSCANF(); // is used // #define FSCANF(_stream, _format, _var) do{ if (fscanf(_stream, _format, _var) != 1) return false; }while(0) bool read_model_header(FILE *fp, svm_model* model) { svm_parameter& param = model->param; // parameters for training only won't be assigned, but arrays are assigned as NULL for safety param.nr_weight = 0; param.weight_label = NULL; param.weight = 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"); return false; } } 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"); return false; } } 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); return false; } } return true; } 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 = setlocale(LC_ALL, NULL); if (old_locale) { old_locale = strdup(old_locale); } setlocale(LC_ALL, "C"); // read parameters svm_model *model = Malloc(svm_model,1); model->rho = NULL; model->probA = NULL; model->probB = NULL; model->sv_indices = NULL; model->label = NULL; model->nSV = NULL; // read header if (!read_model_header(fp, model)) { REprintf("ERROR: fscanf failed to read model\n"); 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/cmeans.c0000755000175100001440000001774011400421345013234 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.h0000655000175100001440000000660513421370756012613 0ustar hornikusers#ifndef _LIBSVM_H #define _LIBSVM_H #define LIBSVM_VERSION 323 #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 void svm_set_print_string_function(void (*print_func)(const char *)); #endif /* _LIBSVM_H */ e1071/src/cshell.c0000755000175100001440000001766711400421345013250 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/Rsvm.c0000755000175100001440000002754612562114411012725 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; 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/vignettes/0000755000175100001440000000000014120562465013042 5ustar hornikuserse1071/vignettes/svm.pdf0000755000175100001440000006265411400421345014347 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/svminternals.Rnw0000755000175100001440000001611312547044621016264 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/vignettes/svmdoc.Rnw0000655000175100001440000004340313475431256015040 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 sensitive 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-\mathbf{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/R/0000755000175100001440000000000014120555141011224 5ustar hornikuserse1071/R/moment.R0000755000175100001440000000033711400421345012650 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/naiveBayes.R0000655000175100001440000001324414024411367013447 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) if (is.logical(y)) y <- factor(y, levels = c("FALSE", "TRUE")) ## 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 { if (is.logical(var)) var <- factor(var, levels = c("FALSE", "TRUE")) tab <- table(y, var) (tab + laplace) / (rowSums(tab) + laplace * nlevels(var)) } ## create tables apriori <- table(y) tables <- lapply(x, est) isnumeric <- vapply(x, is.numeric, NA) ## 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 = names(apriori), isnumeric = isnumeric, 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[[1L]] <- quote(stats::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[,gsub("`", "", labels(Terms)), 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]] deps <- labels(terms(formula, data = data)) 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] isnumeric = rep(FALSE, length(Vind)) names(isnumeric) <- nam[Vind] structure(list(apriori = apriori, tables = tables, levels = names(apriori), isnumeric = isnumeric, 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) ## fix factor levels to be identical with training data for (i in names(object$tables)) { if (!is.null(newdata[[i]]) && !is.numeric(newdata[[i]])) newdata[[i]] <- factor(newdata[[i]], levels = colnames(object$tables[[i]])) if (object$isnumeric[i] != is.numeric(newdata[[i]])) warning(paste0("Type mismatch between training and new data for variable '", i, "'. Did you use factors with numeric labels for training, and numeric values for new data?")) } attribs <- match(names(object$tables), names(newdata)) isnumeric <- vapply(newdata, is.numeric, NA) islogical <- vapply(newdata, is.logical, NA) newdata <- data.matrix(newdata) len <- length(object$apriori) L <- vapply(seq_len(nrow(newdata)), function(i) { ndata <- newdata[i, ] L <- log(object$apriori) + apply(log(vapply(seq_along(attribs), function(v) { nd <- ndata[attribs[v]] if (is.na(nd)) rep.int(1, len) 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 + islogical[attribs[v]]] prob[prob <= eps] <- threshold prob } }, double(len))), 1, sum) if (type == "class") L else { ## Numerically unstable: ## L <- exp(L) ## L / sum(L) ## instead, we use: vapply(L, function(lp) { 1/sum(exp(L - lp)) }, double(1)) } }, double(len)) if (type == "class") { if (is.logical(object$levels)) L[2,] > L[1,] else factor(object$levels[apply(L, 2, which.max)], levels = object$levels) } else t(L) } e1071/R/scale_data_frame.R0000644000175100001440000000110314024400426014572 0ustar hornikusersscale_data_frame <- function(x, center = TRUE, scale = TRUE) { if (isFALSE(center) && isFALSE(scale)) return(x) if (!is.data.frame(x)) return (scale(x, center, scale)) i <- vapply(x, is.numeric, NA) | vapply(x, is.logical, NA) if (any(i)) { 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 } e1071/R/tune.R0000655000175100001440000004312214024402125012322 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),] p <- nrow(parameters) } 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[vapply(ranges, is.null, NA)] <- 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[vapply(ranges, is.null, NA)] <- 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[vapply(ranges, is.null, NA)] <- 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[vapply(ranges, is.null, NA)] <- 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[vapply(ranges, is.null, NA)] <- 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/R/sigmoid.R0000755000175100001440000000023311400421345012777 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/interpolate.R0000755000175100001440000000364211400421345013701 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/impute.R0000755000175100001440000000060711400421345012654 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/discrete.R0000755000175100001440000000407511400421345013156 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/countpattern.R0000755000175100001440000000117211633216055014105 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/rbridge.R0000755000175100001440000000026511400421345012767 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/element.R0000755000175100001440000000050611400421345013000 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/ica.R0000755000175100001440000000306611400421345012107 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/matchClasses.R0000755000175100001440000001504012520201245013757 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/stft.R0000755000175100001440000000144611400421345012333 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/cmeans.R0000655000175100001440000001131014022142005012603 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_len(weights, 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(R_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)) } else if(method == 2) { retval <- .C(R_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) ) } 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/probplot.R0000755000175100001440000000367111400421345013216 0ustar hornikusersprobplot <- function(x, qdist=qnorm, probs=NULL, line=TRUE, xlab=NULL, ylab="Probability in %", ...) { DOTARGS <- as.list(substitute(list(...)))[-1] DOTARGS <- paste(names(DOTARGS), DOTARGS, sep="=", collapse=", ") xlab=deparse(substitute(x)) x <- sort(x) QNAME <- deparse(substitute(qdist)) DOTS <- list(...) qdist <- match.fun(qdist) QFUN <- function(p){ args=DOTS args$p=p do.call("qdist", args) } y <- QFUN(ppoints(length(x))) if(is.null(probs)){ probs <- c(.01, .05, seq(.1,.9, by=.1), .95, .99) if(length(x)>=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/e1071-deprecated.R0000755000175100001440000000000011400421345014167 0ustar hornikuserse1071/R/svm.R0000655000175100001440000006447614024402603012174 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 (inherits(eval.parent(m$data), "matrix")) m$data <- as.data.frame(eval.parent(m$data)) m$... <- NULL m$scale <- NULL m[[1L]] <- quote(stats::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_data_frame(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.character(class.weights) && class.weights == "inverse") { class.weights <- 1 / table(y) names(class.weights) = lev } 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 (R_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 ) 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,,drop = FALSE])), #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 <- na.action(newdata) act <- attr(newdata, "na.action") newdata <- model.matrix(delete.response(terms(object)), as.data.frame(newdata)) } 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_data_frame(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 (R_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) ) 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") if (x$type==1 || x$type==2 || x$type==3) 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") } 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.out = grid) yr <- seq(min(sub[, 1]), max(sub[, 1]), length.out = 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(vapply(data, is.factor, NA)))) 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 (R_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) )$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) } coef.svm <- function(object, ...) { if (object$kernel != 0 || object$nclasses > 2) stop("Only implemented for regression or binary classification with linear kernel.") ret <- drop(crossprod(object$coefs, object$SV)) trm <- object$terms if(!is.null(trm)) names(ret) <- labels(trm) c(`(Intercept)` = -object$rho, ret) } e1071/R/hanning.window.R0000755000175100001440000000022711400421345014277 0ustar hornikusershanning.window <- function (n) { if (n == 1) c <- 1 else { n <- n-1 c <- 0.5 - 0.5*cos(2*pi*(0:n)/n) } return(c) } e1071/R/sparse.R0000655000175100001440000000377214024405245012661 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 vapply(l, function(x) x[1], double(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, vapply(l, length, integer(1)) - !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/hamming.window.R0000755000175100001440000000023111400421345014270 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/lca.R0000655000175100001440000001571613063003326012120 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 <- 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/bincombinations.R0000655000175100001440000000035114022141661014525 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.out = 2^p) } retval } e1071/R/rwiener.R0000755000175100001440000000022311400421345013016 0ustar hornikusersrwiener <- function(end=1, frequency=1000) { z<-cumsum(rnorm(end*frequency)/sqrt(frequency)) ts(z, start=1/frequency, frequency=frequency) } e1071/R/cshell.R0000655000175100001440000001461714052132602012631 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(R_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) ) 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(R_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) ) 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) } ## unfinished! ## ## predict.cshell <- function(object, newdata, ...){ ## xrows<-dim(newdata)[1] ## xcols<-dim(newdata)[2] ## ncenters <- object$centers ## cluster <- integer(xrows) ## clustersize <- integer(ncenters) ## f <- object$m ## radius <- object$radius ## if(dim(object$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(newdata), ## ncenters = as.integer(ncenters), ## centers = as.double(object$centers), ## dist = as.integer(object$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)) ## object$iter <- NULL ## object$cluster <- clusterU ## object$size <- retval$clustersize ## object$membership <- U ## return(object) ## } e1071/R/kurtosis.R0000755000175100001440000000111511400421345013227 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/plot.stft.R0000755000175100001440000000021011400421345013274 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/shortestPaths.R0000655000175100001440000000146613044147472014243 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(R_e1071_floyd, as.integer(n), double(n^2), as.double(x), integer(n^2) ) 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/rectangle.window.R0000755000175100001440000000005611400421345014621 0ustar hornikusersrectangle.window <- function (n) rep (1, n) e1071/R/matchControls.R0000655000175100001440000000420013044210525014163 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[[1L]] <- quote(stats::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.R0000755000175100001440000000060012505565304014566 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/gknn.R0000644000175100001440000000754314077530274012330 0ustar hornikusersgknn <- function(x, ...) UseMethod("gknn") gknn.formula <- function (formula, data = NULL, ..., subset, na.action = na.pass, scale = TRUE) { call <- match.call() if (!inherits(formula, "formula")) stop("method is only for formula objects") m <- match.call(expand.dots = FALSE) if (inherits(eval.parent(m$data), "matrix")) m$data <- as.data.frame(eval.parent(m$data)) m$... <- NULL m$scale <- NULL m[[1L]] <- quote(stats::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 <- gknn.default (x, y, scale = scale, ..., na.action = na.action) ret$call <- call ret$call[[1]] <- as.name("gknn") ret$terms <- Terms ret$na.action <- attr(x, "na.action") class(ret) <- c("gknn.formula", class(ret)) return (ret) } gknn.default <- function(x, y, k = 1, method = NULL, scale = TRUE, use_all = TRUE, FUN = mean, ...) { if (length(scale) == 1) scale <- rep(scale, ncol(x)) if (is.numeric(x) && any(scale)) { tmp <- scale(x[,scale]) x[,scale] <- tmp attr(x, "scaled:center") <- attr(tmp, "scaled:center") attr(x, "scaled:scale") <- attr(tmp, "scaled:scale") } structure(list( x = x, y = y, k = k, FUN = FUN, method = method, use_all = use_all, scaled = is.numeric(x) && any(scale), scale = scale), class = "gknn" ) } predict.gknn <- function(object, newdata, type = c("class", "votes", "prob"), ..., na.action = na.pass) { if (missing(newdata)) return(fitted(object)) type = match.arg(type) if (inherits(object, "gknn.formula")) { if(is.null(colnames(newdata))) colnames(newdata) <- colnames(object$x) newdata <- na.action(newdata) act <- attr(newdata, "na.action") newdata <- model.matrix(delete.response(terms(object)), as.data.frame(newdata)) } else { newdata <- na.action(as.matrix(newdata)) act <- attr(newdata, "na.action") } if (object$scaled) newdata[,object$scale] <- scale(newdata[,object$scale, drop = FALSE], center = attr(object$x, "scaled:center"), scale = attr(object$x, "scaled:scale") ) d <- dist(object$x, newdata, method = object$method) FUN <- function(x) { o <- order(x) ks <- which(x[o][object$k] == x) ## check for ties on kth place if (!object$use_all) ks <- sample(c(ks, ks), 1) ## handle ties lab <- object$y[c(head(o[1:object$k], -1), ks)] if (is.numeric(lab)) object$FUN(lab) else { tab <- table(lab) switch(type, class = levels(object$y)[sample(rep(which(tab == max(tab)), 2), 1)], ## break class tie by random prob = prop.table(tab), tab) } } ret <- apply(d, 2, FUN) if (is.matrix(ret)) t(ret) else if (is.numeric(object$y)) napredict(act, ret) else napredict(act, factor(ret, levels = levels(object$y))) } print.gknn <- function(x, ...) { cat("Object of class 'gknn'.\n") } fitted.gknn <- function(object, ...) napredict(object$na.action, object$y) e1071/R/skewness.R0000755000175100001440000000105011400421345013204 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.R0000655000175100001440000001605014022141637012651 0ustar hornikusers"bclust" <- function (x, centers = 2, iter.base = 10, minsize = 0, dist.method = "euclidean", 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))), type = "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/fclustIndex.R0000755000175100001440000001461212052476443013657 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> stream xڽYYoP>Hj983LIڤ"E5}%֮-E{אCzӦ9Q1oϊ_':(K79_M 7Q+c|9y;U|wwJ9S]ڲ՛ ӻf>{gDkU}smリ\[ f6Oq4&& +JҲ=9DB(")'4k``V'?J2(]|X zfUAD+q3b%2o`_6=8g2+hP`1Aoώ-1Á!U=z_w:qrq'8|bH[UhS PvqR Zc ,HjgtI*o>, AY g1{h [kQSyh.v9,6L v`vۧi98K6$aâ,#6GMd"4_MXH"/Є0` 19a(sz&rcVv 6@WroMAkn7+j?nGlZvn7eQr?KkY ~>%T 1zFmqWvlՈ\ҽ򥓵 BBPe+)>AYNHoXP*c9شˀrhPZ AJ Qz>).J( J(ZrPz3N&IG~@}qE?RʘGJ#M7 sE>QuA8A( =³q#AQ$Uge8$OÚJ@!⌥r~ތMrQNW7`1l\1[SOV0s|J"WC4=޾l_C޺#t`c޺)=>Pܩ*A 13#o9$U0hT_wC*]t=09[ߌƉ^\crSa=KH4pU#wGTFC(wKq&oeڥ?>vJ6ᚈK[7 pd#f|7Vƺ[Zx!ܷ(D[ٞ2_U *'>M1TХįKt+ZV!8obL/LGG/DZH7ZmN;I5tS$J_\ Vx H~,<:e7.2DDݘZ/gg7KwNQv _8ߋ N$D/7M@y9k2V0TEks13nMߍnS 5L*)S6Y{$K™^˸<ֽHB4Z\<p3EN>|< endstream endobj 35 0 obj << /Length 3308 /Filter /FlateDecode >> stream xڵ[[o8~ϯ>8@M7`Y.fENTIvr﹑l9N֞EH~~F QGuJbt=}?]|\~?mkU f0G o%}BṺOSӉ-rmoxf m{j`Dz׋_xQ_/m5y֛+1Dn,d9 ƾG?a{ |42EMQu![@|85@jHbɘVV%?*pģ<No%-ipcCdQ4aQ߶,['"Rv|! Ws᷽"Q-ihbc C-f:JS)[ AӋXvtI/kB"mXJmd1J cs<~K~z~AV<jY|H-rn[tEKCt YVƫC|g\ a遟ͶG.W(C9n};|"ɔ v'zYYwM4]#o1]'FWmH5D mRdjmglơ4l669Iv51AB}ĬX,LYU[Y ~roQSF|K s(3rUA /+ M!{c:_Jo{?u kG]\gBqt\WKʆhu9u!<,Fl۟cX˜RZH 7kIs4Bj±z| Ȉ#vdl$IXsI@ -P0rRg /D0yiWxAPtQPf5+\O-NְB䜪K,T(I;sL|`ۧP2-4iӠ.ºm`(6U21[ٜXSc3Tl2B` -U%o' 7a+f(YOpR47b+#:E`2XzbDVh:1w\ܽڍLJz} 6SޥLvˉZ :t\*-2MiP=oU<.-=ŰGfd5u# ƍˋh(A9L#8e<~0zw9\0{ #Fi_$Sh9@0Ixgٮ9XzdUFw8j'iI:oTe΢UISR39 PbOR/?Ƃdn7" $Q}^@H|*98v+visNRk98<,a+N#%X9X:\y@* Gr@FTUz:GBu/ $#_)#x|3CX*^8quy<(+00$V>*ę<-jJ I0P/'xE6Y2f.߿3~G âhC:fōSW.E{V-*8Ց7lp'/4U㥎-fkK:݇cWĻ_c> Sk+wr6~ YvK14gSJN endstream endobj 42 0 obj << /Length 1581 /Filter /FlateDecode >> stream xڽYo6_!+ #/#Xl@Slی~Pd%jˆ #yGHKN=8~;Yg}~WY<+ B׋g|io' C4kg}$UMt8dx4 60H71?>k>6--KW-%㿇t5e*ȟ.֗!"~3+%Գs9wgܨf`|;g55LQp8ac 8^dofMɯ! eN[)ERm^voi)-.\Gt(ko6ndyoPq ӍgmGr%zwS [a ıA~BL_\/}4RTAAŹD:RĵP*92g d@4أ#~ v LIXj;KT Y9㼅 ,Txcq#tee7aRlD; ]<[/Es`\wS^'!u+P{~lX1bK.G\glP#0mK[QѢTR}(ՠ(gD; VnvJ>$q/s0.Ơ~E%T{JQd],'ZyKDOkJ8طh̞]g2ʓnf}N^&iv=<~CA{){=|$זPB`ަ`"PC&^^Xm44s$=ԪUDATk2c0p6 󤫋Ő%#V H \`Y*YkQzMTņ6tat:,$tT)!(zn$VOWdWO:fR1g '>w*fd:JR(V0qgt:aI K&iq5=4)Y;Zcd[7Ay!sm!N!+s{k9lM0A_K Ɖ\%Z1*k> ]: endstream endobj 58 0 obj << /Length1 1618 /Length2 8814 /Length3 0 /Length 9872 /Filter /FlateDecode >> stream xڍTk6 )1 Hw Hw7 R Ht|xy9k}ߚfk׽aaᖱAXCpwnP ! @~ E%fчApȹBdVv8@@ !Q * 4x8 E w8?'`vHDDw 4!N'` qOݝEyyxxv\/=@q~ xf2l=Ox`nq<QQpd@/+od`gde?nA>7>/a4/_- gmOƞ_XCrS. FMHCGme@Z@<M ,f:w1n"M фʟr3!7{,p{ * p0 \]| @h^8P\>E"!HiD?H =P xmç^{g5à /( ӇOJr>4 /CJ!s?XCb7=79 kyŽ1*1Ųa7#MnȊL`“3y;FZm7m_Jwd>bpJsvDiETe)t,&p̆֏7j8&L+YP2sbrzLOӫ&sbKTELeLIrF<<'J1WY"1/801勚> MJװ*n N/p+L< F߀RdZ4XiG cI1DM׵Kp(3s0}X7[lQ\\+ M{V~6Z pK2#B"%* nm]HMޠR$͐Be1CM㙆Ae"O`L-=H%yoo qpN[ LtP1*BBNF Zf̃iB}!K=6Q{w3q.H1YsƤ4yJղcNJ{u*a2|/Y~X 8|:,u3O4sbaKp-}cfܰnȼGި;^f|V劓}BB2NOIҼ7T=^XppұE yR>Iᔷc|cfdM剪[^ė aYPx3Kg.in4k{?Uc0![揪m"#\Uw蝨 J]K,M/>tR"I7lPq}?;,;S9e N%`dB-;פF#;O/-mdϾXp2ɉky"^$.uL۩mb$Gtbr?DXB WR vݰjCkGy=uW˗YvnG-ެ-X< '̇b?D QmKF$6$H9ߣ XQ:+c 㻟H-js8{J4Rd"-&^UhMg 6y^:&UBĐeWM~ÍAS{+ZK%s]{v"Iuc1?ř ^dϖK秖 jha \Wbt ā`@ExP ;&vCݶqU0M ttX֫xdfs+NV4cv0v>ljh>)⯵%NW9\+`<(ɍUZMcN xz nڱYDd}L=gQYL/UW%M&x5ఋYL$4K+ύKy,k^N򪡅1(r&yW9llS#I(\eM9Wyӱ^Tݙ*qLN=iw*&kfqǎUˣj{ڶZ1Ò[LHdvb`{ "G3ȶeKѯP (D}<<켤Ca 76+1*x@%E^Fv͝Wd9.WR}c,r_!0Oɻ?=[7Kd{ay) W|G{̙:yfW ;s&!!/it̢.2ЙfL(򳲹":L !au#97غ2慻еĒm?Zո*pb~r$^i"§?>[NC)Du{YXU`xH[Cƪl n0.߷Pȥ_v? }5隩)hN5LPWOk;/F@ԥQh|޽_%>#L7Z }w;>;GnG-hNX 6m‘w_3yo>ҥM0Vs_87 uw5)VJgRU[yf/YEHt!SR§ p[6( #?5O}9' L> [tt?aqA ޵ڌtȠwgIL+3$z^){D#ћrBpD _o/yb'L/;EJv3z»$T(oF3D+q{9J?NA4_!RD J6硜`{L-JɎ,ޝvzy@\| cRDy/%wjn¾( [|&pr"X+ڷ Xz/~ingK}K/b7bUKC[#x':8~c\u.fi!5sI\ EBk~J^՗Bؗ&1K|)gRJ$(m+s6(^8uEEK&#蠶&O,5OWo? t ũM=IzLBӌ܃rM+(2$RB$ 8/ݮhWEɼ 'TT;t9̮d:[fx@i.b3B}K>Usl52B -SSL354+pC<*wV-?bX6yjK%7+?>L;ߡ .ɂ6">To3oo :2mfd"IZ`TU) -^ݔl'O, %(r+1yn%meQhA|W.T.P^o6QoN7uF|kdB ix>;kGyE\U] ]Ȑ3зLdW;;U=p46{] =|%jw8j`t&MGJcn 3VQ3a /it7pCmTMfZxf(#t39j \X뒶ؕ:{LTqr쟹G|ggV}tb?E߼@UF6ozuzh웬fgb?1㕽gcC_P[h k[l곔, R2VGG%qh5 g8(VnACfAtbWEl){oo&lOq}x3I>1&lPEHvTSEv8g҆)ա_ïhRlį}uQtڽ>^^oej f+^JƎv2T}\k;!h4rxMgn cJz~$~Qn=[K{W?0v ټ8 3`zksc 'x좽/RV[IZ$Q5QȓF&-F][u 5Z[;baӼ"sqrQQ`⛩Hu٫ x3agGFQrȈ![}K58h KFg1wHo'=6P4x%@vh_d" [cb8V}Ϛe'pqLnSdrk~]$a f(帠Du1W~]ZX#&..EۑqXPg<`xgy_7qϤ"h>Ra}N湕'P]^[;&*iKۏTDo"#r?XfsK (&R汙LKyxo*n$Իe#ˢ\QT|f_LYe@z[DClԥ#:VR*6RIe+9旙p+YJCڂ|G1M%[SB[}m]7hb7vC8ο,LՒӍ QM}'Y *ǪOɛXɹ؞FtzQ$˩]􋁴0GNT-3ؑ3=7faY<6^;:zcϵ6+f[/6Az.bQTEF..5c.B`YpsMn 6 hR`}^c237oh no^%&3 ofhL'vPb$dmW^Â#aUW"긘:)piުuJR_q0%bKs(3gbhAei .> h9_Kn5Ey[`Ue^=9͡z}K]9'Q( S$`mՠ O۹F iImk~OL%rM_2otr2MkHB1WJfѢ zaص3 npg K]N{V-g.|~R?DgAl>("l#jk'.QF64rYy2S} pۖ{4e"đl6!Őo%C֘5TA*%ׄi5^PSw_10~m,GUFyr㴎լ*L#7IqXpP@ b[W&8.[C|I ߴ-:P҆ 03nΟT-.nLvfͭD" d[c(t# msx{1ABĿՃ|୲wVO ;aN:k̜Nw9+'1̱c|%v< 2p}tn}k5y5^$5M4KRW&;_WX9kD\"+2e l8(O ƑӊuFWUa\7w;Fsq M>j&#Z]4̎!j#2\R%5;CެLvTF‰#ZjBެ@D`ÉMђ=!$\Ɲ 6nz#넖GFOƽ*KGΊ?7cvB=Y0 ;i>,mYR"ߴ{"]6뽿6nSzchFb%@>S͗T nfVoy'wE {jqNP_*wD}[uLYX\W5Z(Q!/M}ĉ]U%I`ݱpmwO5xO|Qps9~kNN@~rℏLXx2ݧoGjԎnZIaQ ~l(l~(nYXpMo꘬ ^)hg0*yy'UП#͘,[5|A ۔N$+Tj_I"3Bޒ K43.g!%4!g~&)@hY4Jۊ"Ղ(IWY _xJ;Cph5CΚ[Kk:ݛ9?o8d.%ʁ>pmZGr`v fH2Ck\+cDUU8[Ė;VMПy}(`uv! *k/Pd)fpk@~A&x'F-M3ʾt j#)TvtK8h hʼnX `CX}BUS65` :|R{b!!yyIԇf3n o}sk[2svHW}@F3GC%;Z/*JQPD.ńLѭlꂃǾOD[˄ɣ?eB̩ưUH=HO.l^\:G eVgE,jVZ FįGR*Y~}?0EuLlQV]٧|xFX 77rbU^w4/N&.4~sHi`v||#M'$Tle<,OCM)B=>R:K؞qxF19 \BD,=eH| yl/Ҁ3z)LGd˦p. 3]\)ѝLRl,+A=$X)It2;L")8>9}rUg]_jUs4Ma/BYd1*|_>NJg+*,O8V`Ǜ0jy~|Λsz ଢr֎+hKy?mL2NEp:EpV!f"Qw'XMePcTJ(7Rj?}U%LmN+C%( <i7i)ё |dlpQ#X=wZĵ֯r.u&1xv{J[ ;wd<2UZ™N.}_d{W6LճUHipVPݻ p٫'b16*(?}p" Q+,dY[mNTNϫ|X Tt^~vDV\.JOzĂn2+GfF"aV;L,_EبȽsϳ_)%BZSyWqNE1: j;t\M~XyOcƽݧjfKr6Tjػ[ot#*Oi'šb46 U)8N/ꌄh9gݼot+y_fsǫ cNIꉰ&z]ϓp6WQnj0f ͋@ w9eܪ[0RnuQ1;a(̉WM{t;]ţmi@&lPZxߗ櫈.Zg\gw[BGTF#QƏy\>C&j}n0L8eخ̍zveTmP x6x@DJ 4ag)x?S=@{uxi,nu7=rDe oXsd̛Jx'zЋ1hhNGƮzl[%pyLq"}AA {iЋR/&lrQu,4 eL O#Dž+Rq Dr.rnVܲ 5=|Əj͑8:˅q_/M waT =_%cL33WTR8+vtz&ScMt:4H`͢ Ӝ̚(l6mN & [^r٦M'a_)WMew>rKr 2_>DL ϾɈo6JѸ DzG5+"\U2f> gT&Vw)&(R@ \nr8@> 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 1840 /Length2 11964 /Length3 0 /Length 13108 /Filter /FlateDecode >> stream xڍP-' 2wܝ\.[>罪{kfպ"S`37Jۃ]ؘYJlVVfVVvD**M-o1"6dU&ijdȻ8ll<vVV;$M@%f=H%aryMGOw df(X^34@@ A+hlbld)LpXԁ@'79&v*cFhZk[8[ 6:^4*@_Ɗ0 p{ [,@@" #l O&i15klrpqfvQ"a^,6]' rݓ寓ۻ E:hA@9ɿM^Ee@+++'zY^k"  "d0Zwy X_g 矧enm(khi2U?:qq{7' bwU,Xʁ-|}}c)ۿ-@{߱r~?O.Gی/!iW[?մ?j;3:J[_S_;4Vu, \̬Z,- TwqXYGYf67D.ٛa\''ODAbx90]^],8Qn./E `,E`8,ѫ?FL#>?5b X$,__  |%b/7d{ |k/k_y8 pr*_[_Wڮ~CWb*NyИ:9^DyG@3{3Z1Bw Y}t:&e.GM[>])ҟާmpjO>FKS8CO4E|~:h@AS;b޻x4 V-p+ =W0jż ,*0͙#ua":ws;7B*Ȁ-[=akR3>%>1 4Qł V4C 傤ND;lc&K݌TE78gOD-'j@`.GH;L>%9B}lirR]֢/ 'ŏSfފ 'Yx6OTdr1RcaQJQNfX|ش{6p5)<ò,E-i+x\U ZM؋D>k1!ИQ&(xSdU0 D>wvTPš]6NzJ c*T5^kwK_HŰk_ "'km_ݸ~IX"ӼQ&ȳ_`#V*g̯eN4p6o6n{5<"J8r'=ZYlDKV9WiOn>gps2{.a1ۣrUT$n)_x| m?(T@rçOEc|ܪM6ƾI?X3Dn.ۏͥdK+UMLÙH/VxV4 bDʹQy:ƮlₙyA9/b2[X'0uأzt f#QVkô31>݁V?߉ʅ0~BebٓP:]֑嬶CYi|[ ShT-6< 6[9MO-)AnL|m]ˬqwD =w.ϫn0G>!nC:GLp}2Anw)E- XNNBjo4 }]uT&ņ32: K1f< h\Zg͕)ӂ>({>u#A~lȇ ;ը4ǴY'H2}Ծ0tI&n*G8 V3qloO6e!)Px@ |Q̅gm!ojD*#{_㵸&Pu 1,e,\hTZBtXvd9^J4?I?'t0KdA᳞:m=}qDaңiHLcbq˛MőCԣ*ԣTS.siz)uZVn=|FtscYCh cJq+OI*_]$wXy*hi"3 j0? }H9m8Fy8jĹLWPd lh=*?8 t 6TqKA\B<]ROP/@J,o&Hz6["ۍ/?]rpW?:g̝꽋͑vgD/3,5'vEIz݀ѽӪQ!b\9&$}G0T7UȦ(^iB~_, Py D}EIrk92"9k~Q^~\8X/MQo 3ԗ;=r E4t{u)jvB(*;Erj97L$eR?c\s4YJGߝbxp9g9ZJ */P e Yb5m8xxMM& OC(@r5.ـ%|2 }/$Lbf?gOzWj=;ʮzGTD^T(pCĮ*JsI~끖d T8WBH#YS& Xeh[pfNm:l(b`± &PpbqX%Й-G`J?Im /.r\䗐I=2I{F6`B6Kc ~N\dS "9qX$ tDidS`{k.@Tî@(mbI1C |ϖĕ@Ȃܾݾ[Sz\Fo(K@J!Jx|J`gCv4R3;ۡkjA 'N?p @+R c  9(@EX,/30TXcZ0J+OovaQydk?BN bAhƮd\ fo2Uߛ DAK}xKj ilV3*\KhL U[[]&KX^.CG^ J!U ߐ5#97XԧCPH:$b.V5^['R\ Ǝ{\@B;F:!&%slYF,tU]X}S}k+{ 5`^F|[#HcȾ ,s~gQ3̾QT3 FET5=Y},$.|oWW'Z7Uޠ1ϸ+oK*KqLˋ2pCd%A8JfU ^Jz FH p;Jֱ=^{X| (cVGG܄L1Q,ch"ltZL&'l<2K)bfa$%BeZ>.r.;2-A;lu$uNv\kNlOX㮶nfQw6ܘa`Z:׸{5R|U*[va 2(\d0H^"4?X 'KiD Oh9׉ʹx5%zO- 9G3VI)-;D.a.+MVvr96CfW\.I|ʙ˽cr9B@ڱ7'*ck{ 2Zb,oDl,$x׿ c}˧/o<6]qhޜ-8梇t{_DV BD(y2q?jjYqUE#wP[;L{q|9yFyyy9=b&yHgĻtԛ"e{#;5v Q_XQ,/zs~Pd-W঺C)S󼻯GZo*^%?m֢SnCxt!/tԷY4h~Jab163fቡr4dQ.ܘ{3F/MJmawG~^]ٵk#3kt^-/ :ŭt/L1350ҭ\M:Ϣos:,R#iy34MG^bW3 MU|w#a 6'8 g)OX|f[cj}-.u/sRܓ[Z{BbWtm%u]I seHLٕUo#運 U]64)F;u|4m>茾`BgM>6sR>Ӯ^[:JQB W`Bu_Xƣ؁{R%Fw7GnrwP-HjW9us'WO6ΩV͙ơy&媵~Ta#¨M2:)"P9{M?Jn߬'SFY@PwAQQ=SE&%@ܩxy fs/V W4V ٨X6;Y=cO L1z%?fhg‚8;a|ޥj't^(B[s.𥉘SDz:G 38ci-{쾀1([T96KBrl=GR)Wg-hR?'ȸgk[Q5tbO퍐_d%j %I[:+ DCl􏪅DFj 'Ty-ZJnv7HuDaX^O7lzW*RqkμJ7!{_~Ƭ⨭4 glsxv6[E+eΞ2-w*T!+GJ2)&x,&ڔu?1qMmQ#G_1+hEbHs0Wr{ׄ䔟0N/3A8*& (*T6T瓵Xm}ݡTlb!<\"lVɍo]e]-O N|K&_ ]0Zva7#N,g!.B.4iQo_tHToZjY_vlU`//[*1ցuHzL:6Z.^p\; o/nF6sS&)~=f_9V.!D,qldHˠ&TWYmNEl6v@U+PCo!+_P,L.rAî_!SE k {NAG h URE,'7٠ Ũ8e+*pe{LZ"ʥ. oDq,Hvet<ggX*"fY6Yr s6Jqt$T_ɢƒjUkQmAO|ջe9[LNQDd!AJB>cϣM@j/g GrSJX6HkHiSr=rEX2uy<ur Ɖ?$߂T5?!iӴrj(ˣ̓JKoՈ8r˜*OO};F^{eZCRxeOy~>„fx}")s pF.X*I ^Jxld|)wNose9PcN][ KxK^ 4R=  PLE$ePJ>q"4VxKw:M?3"עUG"9F1 0񎰠X.̗T SYxd]C3{V~`,+T;5&ҭ%l\Ĉ`%W262;Cb򒊀GbHH97QYkytYs' eC(\9j܁Ѓ }IzWK,YWhA81WIDK:[m͙ ՗vձiX-M +X~YI@h[G7)vH\AWՓ)^;4A!6~kP:_9wv%h(!HdPO~1QDv3< fr_i0Ų]h71(85 d?caX-jI is6a^s$ĴFOnuyu*Z >ԕ+ej&kD:-Z9<+}.]=26zv$lI6x-bz2Δh8r?3xvkƺ=rjbOqEXc'Rl=+O;}m`l*b$rdyKh Z147%D@h϶b$}j4!%'_ѿVzb] ̤v?>̒OHJi 1{Qf-FF bu) 5;T> ,@d#ڳu?!Tq: NP?ur"A\\[(/qB{zl@_P̧;lztJdOUځgx^PKx05~in1j%SJ+Br3BӅwcM0T_aWOz3oqt0>%u._Bxr6-< 0L~G,$mjI6}0b$f%_ER%_|a`k01]m |+uR)(MQO f0J;Pn)@ҷLI7!L2wt\wHʓ0Ehuf9Z-^=>R[ɾ]%jgDvW"!3|}LL=1ltt (ءx`\Tm|(6̈́Z0}9cdy;"zEՇI:T^֯5^rM/-ϑxtQJ]HQ7 b;088H (.FRgS h^ȣfIsIn0riG]Ž<%ɜ|6+4%۪ʴ-WUVKldSœ\ jOHy#WLcr'oG ~RiJʪ@U 4okFz ~G0W)zw)]Mn7:Ov>CEǘ| mK%t*G7vbj-?<]s~3)GX4TWAF)xmT7jӽ9vtĊau4cv^{0AF2oJp gPD*b`\4z ꇧfId:$30bT!q^PiN-zնjd?r5tPb?jMxխ8Z咟 4YhO3],͊55Ιg@Q/;2OzbV=|rfS<]>Ҥ9(Cun.y :|2ikĔ3Y;̈y;$ɴx(B(c,V˜hzn=& DDN (ZnV2po_Rˎ݁ .L>uPB7i̘|0U8tfB"_.o!ɠ6\ ¼8t){v:0K֊0s#)KB‚X٠C0+ffffTc3UnY_ j+v!?n֤dz}<>"GOuP6``r"zZS ,!::봕R_4j7Hx`2E범I+.!{G$o@O! Ӵ8 v1-=:ADvC؅> 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 << /Producer (pdfTeX-1.40.20) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20210916083325+02'00') /ModDate (D:20210916083325+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian) kpathsea version 6.3.1) >> endobj 2 0 obj << /Type /ObjStm /N 73 /First 571 /Length 3246 /Filter /FlateDecode >> stream x[ms9_PWFRu !K BB ,8,ܯ=3$q*%M[z,cYf2Ϙ?̈́`BY&$#4=Lka)͜s Ḵ 4S2)BL0V)o!ˠ$$04x;oyǴcRg؁7o)iRت=QǮ k5Jb t)LZL2YU=K]A') ̡k!wD`џl[ dAYlڲfR`3()ao<y,#ʈ$H;ߓ,$DLM"F,u>V : D;$ %!Yv_a=xlXP'?c F3d{FtF%Za1٠݃Yv/FweQD4=mCKqpĮUZ[$6hÌ=mWh92mTqJǢu*jGXwBE!Ӹ; ȩFР -R7-eB:! cfZ-]:W>V7*>Ԧɲ}ZY\ٲ{0ͳ yj*/FR'QRZ}?TmcjETUʾ\M&i.}D_)'.A&>"PeD"3b,)h^čjG=0[hOT'hK%;d< }!J\Y\ %ct_[E [g5Rmd5ƫYiQ%]wfq{*Rju 5rLg2RLO-lKOiK[Al Tj{Vld-LawĦQ3eNY=< 5 NLE>ijy%|*?S'#zL#O(' xoEOm)RBEG5X W1:dWiڑ,(T &:-Hv+<1Z+y8=!}E[FJ' vEh'j1QR`+WTaa(f(B\Rv2nu%SAW2W|VC],#qՎ6*E]JjI'R:LnbH%m%Y.{.BV@H85 FB"xO^K!c}Җqa R4V![%8"Lӿ+L5jGzXE Fx,)ZI5&AU'?RڊZV$8E&͢X) XqU&đtP:~%.ܔ$PM36(g<[:iR*eYRF@LWvS?TA*Ggdz{|y'0'h:N*!Z?c3_s~/VLKW~7|VLư/o<WyW>6@~4}y]v #X`nn|?% b <07Q<$SJ%O ڠ tbT# Vnl[h5tvUhx[F)HW`[ E.G^~ti61c/Ee1.n^8"Dũgh۝UCΫã.tz}VŹ%O:T*fsU]_nM^ N޿$]tlPn(lMS!prc%Rۨ-9|tV2t<Ψma?xaUo^pg UKz 7?a)?gV\.2+QB<GxBGbLKo9éjz*G(|KqkV7YKgLg( q^G'חYYsOkWW;R2 jgXo mx`s zW/JMV{_NJndli o/d53SN~sWpw?Z~KQvl͂)ۭ9[pu®deޖ5ouinW-kޖ5Vwll^5[WvnWw-{ Un55gSݨxPi _s6uE`o-kΦ^l7dVҍkn/ryϲt.nv=Z%2, f)VLr]jUN͒/npe}efLܸn57UPt5gtyZ+Wt|5VBySa*i0 ~P\i{[qd7Nbsk\[[h)1Y']m7P < -o3/beqv;g9W.U>IאT kc 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 [ ] /Length 245 /Filter /FlateDecode >> stream x%ѹ6QBLIBSL! XK!W)4רuz7N4҆wkg]3F0 pdTT@ ehfA t,鳭؆-؄}Xu؃v(NYuAR eI/A? 0D01LȢ7)zM kZ5#rלT>ע|$}GDk pPS}ū[ endstream endobj startxref 153254 %%EOF e1071/inst/doc/svmdoc.pdf0000644000175100001440000101224014120562464014541 0ustar hornikusers%PDF-1.5 % 15 0 obj << /Length 2808 /Filter /FlateDecode >> stream xڵYIsWrpB7sHlȞx*U3HZ HsJm(JJ6z}F,(xu=@4 oe*le26 D{Ԥa&8I^ vM]oJxML. W.4Zij8E)|؟x)Uk&RHy5Pp֏tᮂV{ rFc){=-pj xt>ED<fGyx7IӰ\e'NMsS Ҫ#x4۠"-ONS?YU8U&] '+ew=+.nO "x^xCqˊ;1Qʤٱ 0VBebeoJ[xL'D?l'^0c\EКXy#B5>%q@PīL6Fљ PXcUƱJ8y}/Ɠb"${%bZ czxJfy4 fN4BUx%<&Jf"BS4)Md-J6\#}"GqR}?e刬4zl{Ehcco,x'Hg#7% J;ơk.ߐ}DW0J{F!DiF2l+n#ݷBd G^G*L^f+̸o;~@9u"un`Y&o<dΑѺ;Lc[tؽ^ ʖ{{>H(;?F,!ktٰE+]Cџ+'Q1x@L"B硹ވ`T"k':]>b)aoyq8R(<uIK5:v@ Ǥ, 8@>W6g;̤(L/,?0ϛȫp`O1 C Ve~cäjHi&mH佶0 0<,bi$ -'䞨(6E_V7#l TR1.-T侟=ٷke+f'7H2 -箤熲U.偳Q ơ![uCũ+{* Rv] C} ]@{w`^Di mPD!iu~@ t!ΏB9',8r>oޯnh&.ʘP37"bR`EYk4Yb͂ox1ˣo_,7rS249GCUJSaTRl?3&hF.yVɥ 5Z`r%aXVGZ5nu+ByXs9 vsIkΫ1 mi;Kkg!נ#ǴK:no;ZP9o`g#:8%6-l#p}ۙ&x@b tjN`>kab4u8WEcwgW@(yS I}Ns',` :Y/T)/JcHЭ5 xGՕJ\96|[,Н@/s>.[X +r=xaj]O^ tSqG|4p"$ȒN(ǥ<!>u9ؒd'mW];SH?8^3Z:U&0_O2g53DX GWjsӰ'6 T8_Zb/y?@,~wNՄ17YJG߻sϼ=)릕 L/[_( }?CرKRKγ}ϋԌ21^m.GQWr7o|/ȏleWo6mfdc"efE{U~{|}E3 endstream endobj 45 0 obj << /Length 2137 /Filter /FlateDecode >> stream xڝXK6ϯ`DU|OnT.v)DYׁׄ3:,B9Gf񊌊vh=F'T2[+Rշ>بE!We0QLШ|k t+ ij' ATi~|F +K e?Ih-VPW.-a9d1Mu3|e"qtE@G=,5}3ȕP;5I{Z:ǟt1<ry *6l*:#(%띯k]p #K3'z`'Ok^t&Lg("D 2KѮ)YN͡}' n[+ϫQ( 9Sa@#  _aJ.Mt/"N'^RV3"gf%!:>XZO(@\Zy (|/A\XY\&bk^fqKQw^ @OVa&+2wAi=s!%8#7ΠXN=ͯxvZ<4;l/:PYXszS9 S*"=)N i" bɾjnS2IM~47g7ֿc. ķ+t?x5C>~2'u`e XMwj'z,'.ss< #|&&ЌW# u<2v`G,l}1&e4CN=D$eF֔i~$FiqRit^$ǞLEQkq^IQ<:ce⒢5W!ANGȳxrfMc#ˌo/ik`7jsǾ6xr֢Um^oĹEdoC|n@,FCRpR 76ݤ|"JwY4xP}1fa;k,3*yQ۝ZmQ3 sg3U Qc 8T^=QDFF~i̘I"O'\hQI VNxȔKP6ϙ|h ,P6v<׋K羍NXTsB;4nӴaoBF^8J5ʷca+޿I sɽ?H[7V£l5rbE2~-_)4j.O'>Vr~v&|rjfrk`?0D]DQ*/plUB\e [AȾ|15gAN[I:nKܒېGCZW~+}T#oD`2yxnf%2s endstream endobj 40 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpVUyL5P/Rbuild8e334242753c/e1071/vignettes/svm.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 47 0 R /BBox [0 0 486 481] /Resources << /ProcSet [ /PDF /Text ] /Font << /R6 48 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 53 0 obj << /Length 2316 /Filter /FlateDecode >> stream xڵYKs7WC*]oU]ي/Ye0"$GQ/`0Jte@ hC7g҃wWohV"5n=LrmfNUdja6ǻ޾M6QIYy lO}?~۷y%VEb/¤<;9{|3H%+-TpXpL\{XCacll>wNbe &x[o4J>&ﲦIڣ2mbA]+=<2dc';P77X9tl圮x̶Xv;!5Rv5{qډB0 Ye8+g~"nWݲ4_Ͽk KqTرT6żi=ԡ݀pk vCn~PɌZ1VuNc Xg OcH=rt1߮8*WPΫ*X.&\a/k4E5@0=;BS%ß]>/o~ Bz¯ !{C,OA'5<>BB_XXv}/ bMK+p&ɚ藝KWDp28qm%?G&@I)0AVSYeK6Uz~ȣa"Aɒɽgu w{& Ź|.\WBS8s5xj W 0?x#*+9=v"k%[^,7@ Q iʅKXL_yDնۜgdz.LKYTpQd~X >o ԗ5`سd3v;~Ua*=-lv~YDIzNCP*?>8ꋢQ_+0{[8=ܵ<tm;]ٵ%TIJa;#8[]ϔn]7tPWjNlƇOw|=Ǩ8/?To$ϤLX+yA&bP(=PÇ (~}IxK-pj &h ѡa?$&qsw7˦a414<8?MA81O@W]_WE7]Mrdr,dPh%ut pD7^`HIwdUֵeR"cSv(]!&MTEnJ5{mqyA]LnG7c۳^w.(Uj2oTcB opiᕴ^mKwM%+־Šo=2:Q+%D7ujBûnϣBu\Ns/^Ty~KVцګK; Tꅿ<,^vݙYgJĬ jiIk֕/D(-M! pwM, endstream endobj 63 0 obj << /Length 1709 /Filter /FlateDecode >> stream xXo6_!t/2P(Xt:lE5Aר?2ibGe'A!PLR}*yR$?+k:4*R綐IU\:OQVJ~7p <+xṁg̽na^\15,:!X@[~et1d̈́ɳcKx\e2myi_&RO;-:옸eI[D*A1.DxʨвȭI&A/a^}xb_ÿ27FQSE{ 8cpa<-G {@@w6̼yt~nyHPX!N8̑$8{ɺ[u?9C$1̳*b$?:0,g*Q-M^W&/d /mj*QJea`Lޟ:>ͥ*-l Õ珛Q&+ 2QL5%[-dR2}QGd)'rI.dQU!ںMfhaŅ΍ߦ*)44&E/'XnPGw,{J۴Qⱦi68JS`Y DBR2W ժ q;TLK2f1ӲteEy%>רvsźuIgwOc q?1ϒ,iٕ=3q}<11qt{nZ$JW5Sj<*ms]<eZ֌k̮%jE S!n? X>PYLzC$U~7)=a4mBηkGpS]/.Fb_6Kp2fݍSv$-I5/+~KKƕDHƐOg[n6[jdOaЃnnm/8]Oi4x!w ~SE NZԡܣ;gZ(t$糡<2L`2ʊƇ N*T eDدG.q/v;Hs-}uW9P͊޿(apBfgT.`G qCo(Av|W$䄏>L]t=4>q/C!Hk}άD@JJ8T$μ&#`:ڧDsS՝OE5Jlq(σ[Ad#nseBaasDwJu WŻM4BA|xjΛف+Wqm $G]C^Tyt,7rL/BokJ7vnbB|]W EWŎ\z147X`=9 9K ;F_4ZV ii ?4>[>>e '~nCts&۲QoO"Z3 s0w-#]4(xMnL\y%l}>2jga/7*뒁\ pHxYM endstream endobj 71 0 obj << /Length 2151 /Filter /FlateDecode >> stream xY[o6~ϯY^D.@; 4>(츳r(wnVd@ECZ'D'ߝhy?==yHj2e^Zbfqq޺ D-iȾذk,]YȔH²b,U=Ág; 'Sj,1J~#FX+-(H$VI,p!쨫haS(h-i|SG yHx[Z3œIb'*_<1Ǧ;ETHv$6eh92om_ ۳56k?49Xɲ)2sa]5}:U^jya[/zȁUnCNCh=oMZ7Q*(|25.r~r^B <0s3dҮj&',di{E4.}4Y$.-nUZ,`RO7\pޞ6_D|ܗv*w~`6 (#jgkq?dMHeJRJ(;TN:  2E^6qLL 8%xeҸl !Eysy+g(H=<`-YC;W(1N0)ZEG EzM>xjTvCG1^K`u=I_Љ'zR?Ǫ,kpž@ᦊ|cpc[ $yG@> 8ae^Ekhڠٴ3CĮ. ψ9X( J%P]_(Z1"qHȁZʙޕ.RĠJ՞߉Zׇ~%J-pО2IQ0|_`]0 h-4b-ҳߚ{Wl%l֗k%$.D1F* D2B"qo5_,TI40F`upR] ZqSؐ]nA90E;'^]ڋ}AK$*b>,G&o]ˋFW;fGI 5.Dtlsϕ"Èxq>usqa .oDaYt4>Aghn62iwk4}ACVVXhV(ejM$%o[rrl1N R.ꬖc7sj>졲> ̂|YʮD$-+("ش5|L12ewG^[ 65;K(+/jjnwXg\옉!+X 䮁OY_諝f0ŃjcTG1`[\Xeŋ]k\^wY\QˑGWWSV9GBB_7p9 endstream endobj 78 0 obj << /Length 2935 /Filter /FlateDecode >> stream xZs۸ЭLEN{Hi;L^6{%Q"^QW3{ !=`@|'-&w1ە8}y}uۉT8a rn&]u˺~BY4{|py1h n wZ)ҕGpYigM8)-zt;ĉ-3^ 'aJl~6Wv{nN,,'s),Yr,{ cݔEfDZm]NͽWLw/)h]~AEžJ"**u m A]$#IR"Q³LC.D\Ͱg=W0^Ռ6c4 L Z"v<.cX\vgf;(Rd-E>9C;bϻ؏(7e&T1G:lZAFlӐ'{,[[~w^sZ`i!̩$T噹^ {D'ٗ)js@ypt]Ѐ*T~~æi<>pPglϚYOq& t1]1`=ůӣ7F) Vwcdd:>xQ*lY r&ԱA٧Ew}{I7;_lÈz{ /8xbqvUz4OBh0ILG7wg^iR{Y'dPuad"Nzӯ3%بɕ%~rVΑqyP "4CɃ)8mhkd>f?6v/ep'_hL<|j,lFyN@]Vw``;=*mQmbb*\%9ONs/$X^x}fb"'ʙ)XVc,6W*&KU躚<tUkɻq5xةTd50"z>;i^~_xMFf?M$ LFajx״B9O?9~ZNCYD˺"#{LE)mF+"9(ԞUDU 7Z$@;M$ b:g*$%Pn/gR3 }V8*EԜ1 n%BJM*J AQ琓lب!> 1cP 8cO"VQp5ԹC+sT@؇,gP 9}cw YFzuComvU6TӅCl7pe,}%9fإVO݆ePq IC6>mWTkAujH 'YvBc ]9-'$NV. =GfRzrV`fG~۸IQjX{6u7H]jnGЦT*'auI@t؃1BHKawllZ|ңRMY%]$@ +/Ѫų_b*B0$οJO_ .Ā]mg endstream endobj 89 0 obj << /Length 1979 /Filter /FlateDecode >> stream xZn7+8iVqI͈ldm#Ɏ%קې5= 3X+eqY{s E[_pNZ5\9~sGE=X>#1t k;4|8E21궞daEp;PEijhBA4oY( (Ёp)ӛWodqF_(PŷjMEG/kwuX-zؘzM_[[O֮iZjO\MQ&^2+za[ŌUiQ(BG ^h;AqB L_jI~ "4cHaMjrW:zKkWƦ6ՀghYjp>$0h`4 a|kߎەB$FRPޡ K#(nU7h;gF)g8pZGphfHk'w@Xw6_P]6AU :X2h-J!mwOp+hle/v r;2leƮ:D - Wkįc)a,KbA!Gj&9'9RiS.,DۄE,?9,"\YΡw:VQ]d5~(9>Et6Y)ӣ35Mg*)tg1ޔ ` F+%FG;AMr[)opؤ8z^j#KI5iX- :T \ "lGKƳH {s,_[[ UBRMݡ3i*VITVPLsb+ܼ5Qm]UHg-ߖ|쌂f'G?x,\jc3*+\@4)|:TJ$6'3e3*.#QHSvπe-OMy{~<;')9{W7y^ &?ITb'o%ي22FU?@qc M'I|!L"cwH^W)%I˂F \; lnEn_k JeI1.&zs{{7C'lnLK.RM6%M}nzV.]ro+׎j;j* [x5TlՏ' rwuLoxjϫ[rk >``3mbh{82[!dfh@y?ӫ)vOШOEd!eHבSbHl<m"qƶQƥ3)Lh=#v̏sr֤ \(!1Ok}n^Gy|d45.G.֨xkta]?s}o\l,ϓV=w\OsJ4/G2hFu4/ɤ½12~ه|t'8b BP'p]x!3ꦵY |jt! KA ]N endstream endobj 103 0 obj << /Length 2121 /Filter /FlateDecode >> stream xXKoﯘA^v7nDױk+a ΁p֐pz5#J0rAbOwUu=*2^lwBlkbidYT)ngawoa!K}@ITԕA' /(qf4wNsÜND~NgI {^.sƠ3A9|N_41L> &@rd;5 ȶ* (F ǡX/qQt@֋WQ$^wpEl܅z%dwbv}E@Ie8gOqrYT{d43 )'l?B7M&0g'r`$P.M m-*K'{_s|r H` T2.^VˍN1xO(9 ͨ3id%ܷ2J-@2<:51u$ώvH|g{'5d]e g>2JKhZ=P.ZM^ ?@6  By @$5wL_a0zYu3lCŭUILSFF23C$A~ 7-YpV?YŏۂC,L?z+&Qcy:n_BsGv⟺&Œ'??6-%? >u>F3y\hՏwѷ?Y ,%poj %=l]qt?{΃g{Rxq3|\w Oǽ߭FOY_= 茡AT4VTm? ^R!ܳI2 e2i^ZK%JnD֓:xrF9GR͖X`5\/>ڂGJ Rp:*w7'-MZP{$5!J?S[!%Buwfd ou)=#Oqm xx9J=*~ohjL3W^ f@+s3*7;;/cxxA57 G}mN }Wk|lx= #5RA5*'pC“,^;I2@j0{wNeIziB5q#cQ>2djvh)53mb\mrG0/WF!>_PFyqF9, חpՒFHBFa9\E;6/[R R,6cE7u~<_i&(@o&}7`$5 )fN@ʤ$G[₳a-ڜn$Q}R,ŏ}Ƚm HWuS/G$ #RbLG@ P==f:"a"^ŭDVÇ*cpvO]tKgՙ>t}^% b]6c.7m7ȩ3k)ِHN%kdxvPt?:v02To @jg>cXygI^ (/Pӿ-8{g^n`Na4iL,wwm endstream endobj 121 0 obj << /Length 135 /Filter /FlateDecode >> stream x3631Q0P0U0R02S02VH1*22PA#CDr.'~PKW4K)YwQ6T0tQ`H``(`   ~$~K  dE@Yb..WO@.gC' endstream endobj 128 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 2 0 obj << /Type /ObjStm /N 100 /First 829 /Length 3811 /Filter /FlateDecode >> stream x[Y~G Bz> #lE;1d9@q). |_rsH``YS]]wZeWުI**fU^UUQ*kgɎW6'lR6;Sb1'JMP׬ Qwv,%1:Ek½WJ<> Ȋ@qAE" bR>X'Z\KUʧjT$WKP $~`GjBp^=!$p* J"Z[IegS<9ky*^V KE Џzܔ-{!4 S@lجg,aۭ( ʭ4Vx2yk1UaTy )4bgC( ^QP - P 46 YG>B# 2ЗRIF\I KZQ0s]Os4<[(ď܈FgI:9;0 -Kwbq/Ge'iBu/Չ1VݫTxKzCPh2[OꇋLz|2|3=?c aymMV/L mwUdu >i׵ibrSmIpca:-$FlI9DS7v*Q5:_u'ۇ#F w?Cb0ϾPػ% kеfa{鏧B wHٻ] fxuI#"t<߯חw݇d5JOϮCwЯr|9]w\_ .ndxDhm~TWҝhÆ졾BIbQhp\6º3}}Zfem䟡oB.mDJ6٬lmVB:7+1mVE7"lc)|+};q}yp-QqB#3r:V꣗␐Edן gWR}||v6?_֫rvVF(Qگ(<ƫ|zt= BB\2=立l|Z̟8%na yb*a\!!r[{K/Y|[1 -ngZ4 3= V[%GYKl%)&J+M扊Qg滋x9r˟&,3BЁ7|rͿ莏J-֤\a%X."mp[%⯏tMt>;ީHJ/0ǖ W[ߜ$VEr{=܄ ׌U;q7Y BFBbzw2;@#3H1"D\R[oaQCf!bw l7=ez(ks6j(\gQeDH Prz* 7C\ÞQUIFyt$`:zϤcıUɈ6 ȩC9|9| R!8n\`Xt*? r=Lՙz7:;HYV~ {/ɡTXUa@Zs-9Zsvsl۟ۚG柈 hP{lʍ ߰#&psf]ywPވx(-Y=,Cuo C p8 QO4_-hyu(Ŕ>WbI۫#QJh W(xt,uA3?e(C!!^^4^%bsyM4^Np,X:Y)cRq^֙a?8O/w_#r/]ش;&cn +퐷Pykk8m38R];'jv> CozS6#>X{9Hֲ9n͟ j qCyw?6vZF[\ӡӾ2 t]az{o;;mBR x:m l endstream endobj 138 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍN1 @\IMKxb-E;}Z'l ^aMƃѐ"2)ch \1P0V gQ9]=l1UN똢 ڜg7^nC?_Up[ ;@6D!^I> stream xڍP\k.%! $K ,];\oս5U3i}w  1P֙ "'`ddgdd'#S9[Ó@v2q9Dl.&;77## F S=@O&bg2p~O?J*!# glyhbd P3=+%=79?- lP:]?  jrKbgf A&@[w[S#=9@EJ`X/Z߽03'ldbbgcod5qYzgwgZFNvFF k#w?ąF]#ى dG yﲘ ~ G{=:Y+[;7["L]lA.@)ѿMÉ6FFFv&t7`#=O |fE}@fx/'#W o#x&&)` 4] 4 #>{L?>y{/S;[k<_uq9% 9*NXE cfc01x0FiW6c׿w,y(r]F6F/QoMHO5dк8/oS _K+lgmuRFk dkn&A@SE_\@\*:&F{_,} TSؙٚ`l#GG##~Gl/M49z[;w{q>3;G?Γ /`q8 6?O `GQ|b0(X j A\?]gbgeA&_?`/?eo;;w6fWe'ٻ;_wy8 pI~˿;M_?m=Q5qqt|J/ h0gglY~_-F37MJE D=3pV(iuyKFp먥&5A Nyr FxP/|8<:U]o+Ni\Nd|{uʗFBvv D),OFohع8S mNflTKu篽3-qD 7`W哎tX"y} Szb?kKLNT2͇@M'pVS~CݻNGѩTQӤfby;~twIޣC_meaH\I § n/㑋ӹSCX hO`|]0" %G~ -@qaV\55@׾5oJb\=ͣ'~dT!efrhz i^4m$ڛo!xge9b2nK<#g8ۥ,R\05fM˹˦WdSU|J*8w-,RvE{ Q3j@iT!î5rҷ *3o;hFP%8ܫ4><,*&/2 J"*'^zoW n=8,\up"k^>;/ţaE4q@w66L4i&8|H1b2J#՝[ZVSi`?Ρ.Jig ԹBL)0$U+` Q³)=Pj"Ǣ>3=v/w˔9IC4LBsA/5%S~gdA|"^~sB Ky9lg5a $r_Ve41'cEY5`)&gvi\1A pWo naBدaj١E뱱3AKWIf{Bױ 'S^co`<p0<=( .|K=h-Ȃgr϶[yTa{c!9Z6 y SUkыQϻK^y1Cb~sNM{Y; mc vxW%_V3e~|mUZ\Չj˿P7 ȕ_M`ȍfpRHrͷͶE9s[޲zJ~Y_VCp.O`y!ֹȩ[sk.YS=@5kTIݏ!&Bp(cf^|IZ+cA7|_Yf'8h0"D`[)<'A"Ff28NLM F"q1v5^deX]B|TgDC56%Eqb/z]-=ѡM@SɝeU_O)ĢA@.( ̙U?!mq9k M/%ǗA++@K cMH6Ή$*0VR3p%ݧ ݱ GEsALg}w$i,?޸$ я{Bhpԉ".%x \۬q!&58[K𑁁Dfѯ4"I&wP* #^Ĕ}b` p?u8pf'{sOV˝MѺDV nREUQ ]g=)E% R'" zgp]02fEX) ]jW ]tS{laYD=5b!T~*9&Wh )]N!],¿NƨWۿ8<>FIL+RJ~kVxQe*@MCas v+Opo0h(wrj}hjMq˭Y1r}|u t̟mxžR3Pj: cTܟm(O9$7L~ThrѺ sQ $s yQt"ш-^%9DS ǯi'ۙ\@m<]6y9`WBaPXnԌ iVWԀ=T=^ρ@҃ʋA1SS=~2+AOͣ{~@M#h\,}K qݏa$5cb~ptľnw٨فn d' ϨwjM-kK0c! O:(b9pQ|z_94i$ct1t~ 8w:*EmTAB ^w77FC*\SZ,\^o )c-<_0m;ŪV lKȳ:gѽԀ iLX!闗?oj krM~)Cr×h2&u]d<*&_bfdԬ >!V!Od\Ps(FdJUX=s%2iҫ˛N .蝎C%,^\dyXaR 5 .ӻ$.Lmm/]p(Y{F LY OnX9 EBѕ'su{ZmrUBNS_b G%bN$".B޻.?Z]3@L+yΌۧ=Tg T%zqq-|LeTͥ\r7 ~0FkT"Kh>OZny$=z#|38)V#: V?ͱT4`.=΋`Red/;7&`q|36 7G:R nx ׷y4(6؈9͗sas=O&8y,6^Κj/|U{%&v>T/M^On e,oۙyeBw\r zDžc;U y3|\[ќYd="&8I/.u~]s{{F7V}MA}z*Ņeɚyq%GXj $sUoe>ڷ!$F >Xk}9&H0ZXV޹тfW $Y Ս,77}([&0x}أLiҍ iܮIZYeZu)ӥh&L|mf';͟ۅxuB[{B+q_1jm h~D 5l|00GN*G[ fb8~4)K!$l?Y E1Se+U!O] [t!Dǜ $u3r/3ys$LcƦ_=jGlmP@ Z{ީKBILr@ 5=5$1 &Wb&YK $<&V{A:6}IK\n{ҔjN2&n~ϨKY5Q&P4s|l.t7eX5zD޶j8;?x@GJjtPxUT38lucL'%1P Zr~myĊB)9XaPt%?Gǻ[VR. AOȪӛژ6&x 2id x0^z6tuh:M;,D߸)]| Q\ȥCHbKg>^ !S2;Vst 0M'أ8y:üˢ e\=6w2_B9XO!LzEw_F7cp7+I!Y>#,XP,1?i^ <9J|w CTΝ XAx XY3PUZN1e0S'QmTCS|- i‚ћѰ?(LXAlKzWu?.-m^3O:(_{mx9nd% "g'uW mt>WZf_6Nǀ3uD̍S18T}JGU A1ot>G9#laJx Bǿ5 ;x]M1e?6f-fse?t(w#^ĻA *۠j-6NsX}=IXtGJpffGXVGXf+謍l%\kE_$s {Y2T) ~@Yܶs$rpH%l~9li= @})ү&KkZPHarG]%`~ϫy 1Ꮉ<V8ٍ+8J?!1PV<D~B*˃!%b;~OԸ{/64'PgMiR~vw,1ĄʂD9"<(F~E#Al2OHpe^ʩvr Xۋa2aboM;yIQ-5,Q#b;2RNlcv/oG:)nx/Xmmq?|1(W <)Ja_$ ^3[?reH5JPCUde:DN8u ҵ3?\ .X3oAjl_yz7{][x4wLI %鋈8q]Jgع݉rH#|B4|7e$;V2 ֎wW:ֆ@5ZxN+䊵黃$Z|*C(Yvk"B GberZL5o?B4_Q&B;ĊHٹq䤆 r&R27ZBJj/I{0< WgnjRLgKn$[e%=/dAA6yQcqj#d O C76#Nם~DX&qv/PI`-k=ĞVM,-2馝/).*u{K.4{.e|J.I2Хs?3`w(H۶{?6q"xEIe0n9@ ?A4 _ m౉'ZQI )[ћf Vַ:79w Ɲ苞x?$5? sLv>dV}/?q?x e+5>$"O:Zz :jUBw&90)YbwpRS^>`N rnzc>l؀~_z31uֽ 'N}#BNqoab&jڃ'&0?䧀$G`30SRcFY f솕^e֡;U6Z}Y:9ʫ?d&wpVOLc?9~?lw.1\ w*hKQ,y&)tR=f)8 |$p4TJ3eku_~Wl;O>*f'q$XYꟚ:G=|Bu÷xK#^^є٭/r#P7a@5$Iqs<07IߖX,N)wi.z ,z@,"i("3::X }uCzܓ.NL\-s)\[6yq'g,P/rhTޯ\b`\7h-v] r@c(oq ZT?J8<)i712/ qAmYF$q'ߕݱA) ʁm-:=o)Y?9x<Kޢfe:?e}W؋IR 'B oQ^pQ"AyKCazv]yz+B`؀V%#[չ$qu}_V .k9@1V؊P539`>:(x:L1/EO{#.8jT.FX23bZljzft̥:B5{;I'>@%ZTYb F֊jnTT Z)`n:SZBѨe}& '//Z>C̕+:k9cעצ&LgAi~Ú"CuZmⰬ!oc 'CkݍE;..‡xaUe&D,QVC2@9ľi-i}ڵSs.5/q_lף%x#\wbʕSGඦDRft'Np>"fkeȨ T'09BR| $B$ %U: ZIFF0-"# 46hOB*^s0! 6WJN/d!xk9eUh<.vtGng|`^W`|,J )Iq)8/K_PL9j9W52$=/:σ~⍛ Y@ACE&| 95&qAM8,fwEib5"H BKMzjdg:]eD~RDՀ?{XGu⸦.:8ut={$MFM5֣K exz]73}(y"d=}Uกu/D{N,\NW q"9׹[ӭ 8zːWhxĄm 2| Ty~IFvJ~YBe80cKDrŨyL~ۘm5Y޷4-pvpm/Nwmsbm!g}; iS\}v(3.Io/AB]Nq\݉/jJCv_ Oyhr/P{tOZ3l4#-ɌZ 9TXrpj]Ǜ_ק?ڐ|sE ^-'J*q-ڏ"TC _fР*}9!y2MP!L<\Ƈ?kٜ%cңVEd>fb}`52v-Ʒ `5-J, I/#PׅuY`َh"Sa'{LO#-7̡Y^2%`$Ǚ(K DL(OTV'.VsJ$"}r'TWKZԼEzy|# M*] .0y7UlZ!(oz k `Y̧k ea"~#ߋNH1ƒ6%WyMrs6ܔ[fY kxMa)d-Q#c՞5Ppd0cv4yAra7ףcs.-[&_>_pٲb6&^aISB8 0o #F| %bKrr0|?_ qp=!LT32~B  @+@FQ{Md rY`*WdYq4sSy`3S:{j ZQg7U'<(_`OL;\03aGvB-Ʌ5*GqZ#l N\ipރgOW01n2ɂ:LFӵ`K&홒r aɢȽcTuhtŜ`C|o|_yۓ>Xq:IW-u5dҤrƱDsW2gLd;;w`ovdGc?37aS6(^@W5#,A\llo'*AU;31P/q;ϻ16/enQ#vO/i˜L%2yE5l{;`8z[f K KYpk,4AiM_LV/}CÛ);x ;aO|}i5Dt.i8mRa*||?U{Ø>X(JWfq0F/"F\;ww0N5hyzM'G%RV?Oxl2b+`fNQ?o @si"^l0ШHF]KD`:??Ksj狵˚`a9xV2a$B&^!IH6V׍SQk|iZT+{zDm}&KpG&q1>:s9= /JyX' +)D2t_w ֡|Jy_xO:YϧC0Q䎚>nwC|~0ughg;JFfZyu|LӐQٷ6op4MKaΠb{[:v M ~aA#ʊ׫̂)0bυA6vUͰ7Z@ K>cA ͳ,*K.ui9eb(!T_ i4pYZro.4HWE?@lɸ%TJ0) '+zQA7Y hfKu,=%jI-:%ZY*N/TEɘoFG DT/')K}Ê7>k䝭)f>js9T\<Ŧ+oUpGY0ru|pd_㧀Ay~Lw̠fiq!Y`0gaMڞ0; wZlYÚƂk1BF.3w{ "\9b$:A CHvZc $v_J$gzBńWq.*p]uP,cpv`~[,iOl#_޾&J-^%&̧fƟ)-8JЋOCHxH1%Ka}- >E!Z60AVoF 0{Q+@}f_Ejps@#'lB㔺0YCzr{CROZG[bCw DvSG޲ʏ22E"%hơBG9NPl~˧0Y6٘&q*5t lȈF\1~gJ4ߠ=sY\2#bqZ,(ʎ(w[%Ky/ҷw1DbٱZ*j|/oeZF*ASeޱHDWz}AplDq_jB l_46wӻsmYԘs"Is "a3s?'[ع>z4ieύ^Ea#XDnֲL%ܺIo1ƚetu xtmqwvl-D\o+i(m_v[#ƾ*kjUN~ݴCJu6%ߠ/d~Fy1Mc9R2k+_6R+ >X,A9B ğ> stream xڍT6Lw H )-  00tH4H7HIwHwJ t_߷Y7g:هZ]Mb8ظ9ҪR\NNvNNn zzm0^uC! aO: q(x\|B\BnNN@  zi'lm{hgtA@G*frxhhA, `88ف.+ h\@P7%w516` Z+; <) G'WGKxr عo߁''`^˩<`o tO?rSb;\]{e-! G dPӽ{r=\;G?wN:`gWߘ'ƿu '''? yXpNc~ zj=ax@0` d vw'5/iP~\߿f q7ψ9 $Yn_F))'t8@u WOOnsaw,5sA݈Ӈ\X;[;_\WBvzVW bo6Ei$u`9R .u~/=q~Zl\c{. 剓L[4a  x ?,p;B`O.|V( p84~H\O[p(p_ZBO{CO#y@ ,B8ȶ&J̝mgLt~G j2Seƻ5d`7,"սasjhKFiN+C^ tr6m]{go;f%gW<+yҥJ>e̻)h(3$4(06 4g_/e?R)ų`Exs\ϼ])v$#5 @<62%^xΫ0jMt.?vk^x#fа(pϴ]0lk#UX {Y҇5Br K#j^qKώx4#1#SL'F3 B:/\e RM8˻~)hg 3w`*" Tzi*@Agh]6ic9;m*&O]5i'*i@ǝ~ PtKY4aIv5*g4%I4M 7< #WTS Eׂ6T՗ r2򴺭nv&vYreyt,jT74hx% b4eY3aG݅'w_av`aKmpkQR?"s3|5#ҏk iS)H1Lн :7"ɒ*,K\aM.{Sږ_x cFtkZpQQ9S5MTmiW[i[tޑϾ&%Ox='4o/y_qKX/׹2딫 P+/a;*F؍>g^=B:I]ؚw[YFdPJs7=#`qC7t|/ Ytd#hTs_1bװmTn3oH\yYT0WtʝA˜|foVC"Q3ll0!&S%d_M(LBӋᄺ"[ N\_FBE %9\γ^[9|!*\URѯ4ؾ82!"U=`J*YM;JdZV_V,IGC;/3i<8/mh\ %}6hf1-eYƻn]0f4;ٮ7y>l %oqɨ~T%[em+i< Cɰerþۉ3ۺ <͛] C&'.o;v$-Z)D,KN(jI+4Z"VD!evR!,O [El`i p,Elm_!; 'eO>ea*6[~p 7][ F;ltO6Ϭ }OѦ,A|9uȨGc3m=6 |7(l8ۃpOo-<_[(9JlVҿdQp+-r'疨/{/o0[~L4^ͷA7R`_'GKnar3F6vՐ xHT(H''(}j/4܊y޶>]:(d2̍PENFuwW^sD6,5A>g#֭jD2U84 5lKonbPFlwބ=oeh$N\^BC{D[[ #7 ~;}UL$Jet{P3mZUb4APi&ϦƓzNwXk?TJfxN9 aҳtQ=1NSFNT2zSS&kɈEE(`l7P!zr*y"*:~=n]08x3. UQ_?|j2hǞMU-\|30SH~I V ׯ44Ta?KJiLVNb 6M3J10fJXC5`T6G.Zel/ӬPJ.}UyFAȿ ;KnguJG!2&TŶWMPm|uk(uduBagMxAI2L^\vmGu`^+`n=kÉ1S#=ذ@0ps4V=ͮ&'tt#Vd$`sk6|Ij$Ԩ]b:`?j\I 켐t&k2;91)@o4X̀Ԍ h| .$k|e>"" o=!hv"I bnO q5GUo]`~)ˆy"Di`RF¹Ww?"S֜Y {zz+z>>@46߷>3%b.26"a*<>%pA+8(-b!?scME>-HK0kc% dY(WxE1Xj;|'\7&:V}vÛ YbE| |6Wg޻iEđ,n rR:R"ݚ(|0gˈSAdEe/|G2 y'jxb«8Ea9 {e,1#R lXϳҸOC&C);fZ9vcZ Tf M]dX?Jr“jD~ 6Dee[D2rRMB`u#:$FTq.+Z1C4б׊`{3a̞};][6j6fq1F[^7Ǭvo{G^ü .\^gL N8ֿx70Yͻ7ia~,kTyj[˳w"ML "Ewu@x㮚F^0^ݼ$e˖`+FB$2[YL45s\T1w>BַB"՗'KArT9@=y\!E"K'zuyoH~m[`r= t66m0Cc}N!wM$жØVy)'A*YTOF[Mݷ+H,6졄ԃEu>,#gN,Gfs/){ګ>J%ԞLၜep:4UJ=+Ky/}J>PWE1HaT>_kdFPW{u#ôݺLڅ[U93w&Kmul)g79wgRHJ"Sr7 q ݶIA/= t-E m6)b$XK ?G_F!"Y,j'4`+QMnw܏QyBۢ_N~"[q]x>6pgOW;{g EEmK34 cBҹcalˬռ.=onFs5|Kf0伱!9G:ZKN/3ԛ$6}ԃH?ҽa,3b5;k.P\`}FYlpʢqG$O?=sjBaGyX?\pRy7:UB20e&KFgn#eю|0 SF&- .Y康̲$kC$fzJAMqĞ]az) U>%TÙ{%V F'E8z>%@Əlț>:&R\TS3N/d?Ѽ*3Ӗe ˊoxYߘ`C0B4@ :=0:\V 0_o˯Wx@^;247T;"+&6V,ғhJ$طÏ/9||nl?^k[ <߬ .@/WNGǘgp*;ϼ.>@Id}FlhEْ^xlKΪ]L>z2[s$/hDI=znKaK'xb'rJd qnKw\)jV@j٩\)#cܯd*hΐ ԳuR]i)o\.%夌FC[+dQu ظ5 {ih5ܗ;ZcاMY%a G E-{FhcS@񛏳MٯtOz/fjunX+8GۍJou+xwe*Pa| od`'pVivZ; |Z7gD\DkھLB"hB]rV>V s:!? rryV\y&|i -R=jw2DMՂ̚UBecC{+po[ eH:7h1#.ѹdX"o}^b6`ACN &Dv|Qe.=-oo:5:i٦q(nq/j0#rug0_7ǜKhlU'UliQ|N5[Zf#C#S#(e4^ΧS>]ϟ6\6RP@|>6{8g!1}I3{+9CG0蚌R #dcJU9.?=dj0tAL:Pe82:CդI!YD8=D\UcpAR}NIoQeZʱoBy]C!v֬ɕbEIBwfSV*޳_X(CJ? W=-Ĉ6@w332J5ngO\|.斬W߬1u8K}MoV錑BW`)! %cаc1nBieRҙ|FKQ.Zwݚ?bq.?%hk(z8)7wkƓ 9$;P$~q0'tJჟN ަg0#jڐ ̦#GƠq xNhdR;7hG0/vw.odI"~nGT|wܰBo4XFuA· Uƚrx2zhI\ {LraWu ?L&<$ah] r3bVWWN`wth·bO!ÅbdKTCVU#BB3 .4'PT .>ꇆq/+|t`\QpͻQ&1h<c#GĨdqǟuaΡ<`M LYlwfKWPPwT+1r5*zdlg~$g'id>M=z{ܭt!sH%*Tw*x&Ms::VS}+;~qHAG -ݵ0(LtȺӻ}T2))5 V92\j mem -E t.5p'ul?{ʩ8))<<i[Lkgu;1d١l-*٫i/Yg/|VI2<2]U xgk" H絥؀F3ʩb 5gLC}8 lYmq<Xd539m(9eTͼuJW~m2"nIE,yҌg@nRqH7ƛJɘaƢ gLl߻ؗ7 [wi{*!D-G{1+u-;,f"W(?7E&Y6}\AxQ}C:U&ObI %Pw3l< a"faXGڑ3RdLšJ5{"Zy\U3CWA:Y-<poB*\5 PjwR8񕮮guRSZZ C䙷i#HST&DޘSΚ|$ DW`_wh?I[i䉟k./ƞ(ӷذLڶ!dP10V z'ȥ2J 2gs{*'~L崅0VdJssͪj&zI@lA?ӟo& endstream endobj 147 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 149 0 obj << /Length1 1668 /Length2 9186 /Length3 0 /Length 10281 /Filter /FlateDecode >> stream xڍP.LBp&X[Р0` .wwN @p<8 =gW[S|OvWK7,f0S &TVggqq`iB61!NP1$! M $* 6vN;;?D@ 5(`v' :I#x `F;??/q[# (  +%n/lXa"W(q8@[l!ƊAд:x3!G  sz q38OWC$+I`u9vV;` ٹC,P@UFg~A6Nx j2}$Q: #=vWN`G=܉ jG4,mg& 0~'up`vAP;3m9y8&l8q@hCp6?i?C0<@.ߎ# vv B,vd4Cďw`Qaf0;vJH,n6;y@пXy;sw>^jvK m#T`҅Q7,WoE266$ [_G:@ vKՁ3zux4 ;+ןv b-͟v g_1Qll{2kQ@N+c1q]f{8y GG;7qM ndC={a J6x@ſFrl-A[@߈7zCf;/XA>onO NG9{y/= Ƙj/\Y6FP/u9XF=ƫo2KefeT$.3fNsPlYPFO?? m@I(rAPkG5yC{+=a BPJk{Uq9F~ SWY?l?E%R+ ^aĺV /wStD)oɥVj/fx>5̘xYrl~k!$<Dcvf|f> '\R k Eɮ[g$y@fX_ut-Q.Mץ_3xd,3Mp%[6k.6srb@+pu?{zp瞴J9TFEDz.x\~TGJzڮ{U* =mVfGT%;mQĬMakݡgef*O{a.~׻w O(j,xr{0EfDT}lن48=[_5A7FUp-Y3'T؎,rژ8QM6\,_3}ӂ$]J՘fP\;i5 z}FZ xVI510>5RKș!|FL^Nާjv8m즭 /V˨"wz`}z6]^K gɖ$o>ң&g16n1zl7D;dEu݅XӬ  ~f/}͸r4 pg׮]i_{>YIm x>#r5`nQģ|1o:R}?Ak`sDg|jKk¿4t*YsT3RBS2s-C?=ÔwC1t3 W/EDͭpMXL4`Ú(;opCsMԼkvͱxƪ`>7 /ҝ>qX%54ѵc}h ZfUH–7Fʼs_$ 'j*Ux(Q?5FAƌVD챠5~=ʾ3,1rE1Ʃ[Mؘp>4PiSFA5o93> Ɏy_>Ix/Af*`(hAb1勋|Slw0guʻyLu.ެ/y@͟q z۩H<%ފlUD#_"x}؎%bC{mE\ctw~EU"<]aMN3%|Pa-a ٶoΰ\W!9*@J9]]xgJ3Q/Ag()8WE(io5,&x%٦gȽ *!rDKnn2>z?n q8m"&[A_}un;_5˲R_\ClCVD"ғ55/u{ڕ[/sb!6ךrviއ[ qpX'Ո!0e}̣oQ>4^vJ].ȏ(7&dgT#W;PfƜa%ջ_NXDw=o`WyWsVoUW%hSB= k~2kPP>yr/AҌ<Ӣ902#]QI^CiE*Jۗ$ ]ruy4M"#/]sUyoCifsDc^HVlQ>Laω$^n`mq2XteHmEOxg,<0pO='hL=QA)K;1ֳ<}Xi<$~ďٳn࿦q% @+`z;G[q&hMByFU H*mMb*%5G]'p|2PJ3=}(@:A[n]Gwd-k4Jl;H[cs]sZyS~%1@ KY[43=VJvUy GQL`B8{Mp&]1 cƌ)'8VHb*!ã 4Hf}e2G؝y L0bOR%jX𭛿4f&Z|QX[29iVn;)Te3xXq'~g+1{3٬UEz=Ňu,~k1]|?\PG*mv/A+J'3?NZ z2s1 :r;O(SR/PHV RPN%YW'g*}^(C;I oiGx"Oҥ2rQ/9Q4Z6:7w)?GXx[(+6h}Ѻ2g:s)dM5& wX"8mľU B7lfZA|յy`kvXwh!CȾ;!̒']wvz'[ ;>рL\bW^؋L7yZ]2ݨrn6Pm8]ȃ[:ҏă6h&C!efPK pܽuDs㐬$ @޳ 251018fG[+R -`1ҍ8Mm땟n[8[E>Rts*Xj /(Oێ53Cʖ7$)#VzaX[ @!'RٚSZ7mrT*>dd9{ Fh DL\ m Uddi kbDɗaHYCɳI.m gVQY 7YZ 8*ZjDm>Հ  .N_BwXI}1B q w7 exXHýHk dG~V>H%~YĖcN,ebϺ ֻO'NYF;U1Evg< F5;<+WbvlHZoLJ&{%!O{o63Ou#t*H Nkυ=t:Bz}A*\+fc|9޴O|' N =4۳:?L⭠Ztu[J :4c۽o8I*h BSwzѫ0bwZ~+HяH>z5Mfk0l{,zR3e RHc1֓K,i;\tEE(2W)$X{5OU*W1,؏HQsУ$؇c*Trv>QߎOBcؕ|<+qDH[|#"X6nXM_8ciƑ5xqwJ򽑤DjVcI1aC9b[ ,Cq+hѸ={QT1s|57TŠWdiiO h9ig"n?rPM%qZ|}=h&{',+ls"S1;'C1vaDޔ_+jk|#]Lhu#`euu ˟m)~ep;XݎFvCc,Ak#ɚeGt4)`78 [+.~{tu2$SMc]!UxNs_ާu2:ST8)5I.EMQi# UkŬX7^ rd.ZRBiw _c~,m~CAI%|GTF%lCڋ~6g=@ B2JHj|ERP; Yv;><75agbkhu e45S)XpjPщVUJeox2 pD,j|оãb%1'$sC KB Swٶ:4D/WF|y.(ujaaUдtk#1DE BlO?H10N^1ȍ_ 86h>N2uN{_`fcϻ1.G)|ʒ|+;J]׸N<ea"jO/3)&XDdtX%}@U/b -xIc,fJeYG&9~Lsx F6H5x~P歃&/yVnuiF$umۧ\q FEK˕P 4nY&a b.!;sˈvHܽfe1{ݻJ $i^l]~^+xs|#Au?6D.ڸ 4$_ΑZhSߦG{)%PDLjDwGmt-JiFt-2vaBم"iT}z0e^b"V9Xć{I \Ĝ^_1i]`R)sh~W;[g^vYq"9U%yO,]"ki^o6>͕G{030TJ-ǘcՏ_a{ DtdƻX.ipV%;Òv >2Q=OSIt7 vJ.#*r4=nC_8 8%%Q"vl4=4TF-Dʰ`5%\4eļl^l񫔛;zNku|; &Y^2'fʌ ԟlD>K0 "Д;ԉd%.%צfo[ mF] r`Kt$Ŋ_Kor6e'S*` )*aSPxhc2;C$܇p;$=a)6fqEuJ| ˀdž71Ǎ_~f߶ZCInX ]OqgF㲥ɩu2~uKJH&qqPˉҍ]KF,hOktw%mrs׼|svlj?Fxy*gNPWqq`F? v1IV\C!;0YIQZťb`^7ZR W$K'TkSZ[x+.lvd,c@ֳ&zY6LFI[VX_^\ cbܶ`7rqI{yE=e{+h"]qF-ȯ5 x2̶?7'@,jS>ƐF>y2]&Xv7z(,2ℊ*{ͭԍdy~`2|dP`Z0-6W#Xؽ px争[tuJGĩoX1 rd+6-# xToh8c/xRHX#KjZt\s|[0J? 7MkMcRvʞ"O ~W@'DK>n/2lvǽ;8o p3hZQAN `;YY/q0ܯO^}zh=}gжKQFBYWi>ǥyKGq+Gky01{>XN V -e^;dE}dSX>1Oū.A]#@i- @vITJAZ:4z!é3JӃ_hL{ٸ㮝ԥW"*+ɯH.ZZJ W؇6Z 7qAz,|nL/\EͲ+jR\nX{;Rq#Dk%Uh(6IսJ3._vt}a` gJ9*ହ6nmc79t0璳Ux43>-}Fo@T`$16͐ḫ!W mK?P@ Bm s)ʗYm!t?'8ys=fՂC/X JV͈לF͢|E2ZClq~d'#g;_4y퍄SqepYnf(٭RjdZ:E+[[δ+D\˹oAqf÷M#c8n&!eIԶe .} <eFOiۻ,pkCqhxyU<7=݊P+**0\cth{q+(r|0ʂ-:q%GRwMaWmE Ŕߌsqj5.JIxWK fv{Z7JyvS: +i"Dd=x  a-zulDUTy-B*;gyT20(X//¤M/Cﹱ]K9`gl'\&foͺ[L4?yh3g.~OG(QHW *o޵~ۻB>أߪ?;D'77tON="U:*S|"?vU4jJ7y#"r[$fG4؄!zː{? M໯? _n; q;uf"\!X:2Z)Ÿ9HsHĞb9i7ϺmS'/;Il<^}f>9V ][;yl'ѵƷҌ JH4*ռ݋bd&`kM=Pu96L˪hKz_KCFפ*'Sf'\MF.txyϵ{]:]S;P!TUց7\g,.0Q~(­~ hGPz›Z_nXA ">馡-\dnll B xYdE hmQN%!bY݆6Ԛfuc [8j0ؓ//s]L[v <-X 9Ҩ6aV}YidN"ٟ݂&QF#s)gmīe5%f{&Fk,8qd y_~<5F(C I8+Lb*TC0hlV]'r=6)êk*^>REmHMRЙi^R)k<#[>zh;f 8g6ڍ*\ i4bu>걌"ICI(xd yHO89ME=H==-{Yy<7:Sn ֨I_R7&iSoT^=#q=+S*n#QZqM#7_෢%$F"zn-=i1I_,# W_u]k^L&`ͱ9-q+: y` i,k(bL%U  endstream endobj 151 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 153 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 157 0 obj << /Length1 1854 /Length2 12192 /Length3 0 /Length 13345 /Filter /FlateDecode >> stream xڍPڶ-&7n][4܃Kp 5n-}UUW=昺֘"WVc17Iڃ]X|1UV6 !QQ[؂6#Qi|rsč]YW[+;h7v2(0d g$*1{O'+ K2@kJ`f3 br25],AvoMmjV JAŁݝΙBnb P9@f?(ہ ni] x3Zo`38@MF,#2'$lljjo` [̭lA%IyfF1Gc[gxc7c+[c7?;7H{|o}8 v|+F:m?4>]֘?^ KBNNoK iiޔ?ĺ.F؝ioR`jO+{ɩ >:+hF$ecuGZxWk|x[Jϓavi/DIIԅ}}4m[!e]yД <WT䐟gb4KM ù0"cy]bN&0 ǰyl{U9RB_c=L]Z469ej{H뵧ztta@M5GKH#)zM:Ѯ<#lUvC悻ęQ)UɖSw!N>\7 N [OQg17l6‹f$AmUxN>1"3w.5vCosvei?Խ?lfGhB$pXӖ+@ >("%+#QyPn2]fa;]rWy2g}JR" [0Yy2 ڗ[ ךMУ9ƝOw+ޡnavLM!d9jPF}G6'^$.g2"\w'T#_4!E5WzVDʴYVǃEUă~r|ՂL@:@ _WDc3Xܶ8Fa; 3NwCT?P+tF^ MfNٵ,)*bO2%RIO%Ĺw_^M'6 FKmf,3`uٖ6sߑli\elv(Piٝ&0F:ĻwN1$-K DT5А3&m-sK0ΖF\oTB.́, 6Y7`(gƒơrf#mB7N8;8)_ZAS\cln<=u+ǹâӶG']^%zxܸr#p :pmK1|^OBS)2.nvjraif4eivήp {?%I|&WC+"PuɩbǓ RQA wNl!9|VG5NjQ ^K[w ڎ#N=$il]^pm-|"~Mz=Ld=kJPc8KSzid7>͝ÅhmEB E4>BYxFQ$'Lxa. ҮKvXh WwWn)cܾ "rUd\EI  W\4WlQhsѹ8Ut{i%Ȓ;E ~꼔H87(~k0.?gf^D Tn%N5NG+1wbZJyrOw``szgB7)VtIM,Í#)IM$,7A`X%6QqA6mh{:81'O ۩h0Qu n 2u8!uf8\W`}o{_=}t ѻ%m{͊ f1R|=!|-Ǿ׉y~qTXd9%+29CР-w6ޓFΥeL4-0Y~xX#<ɌS29?"<.{w?_jP f(фA|8%ג.4 UQfpk Ӷ,,)5LQ'21☒zS;m3lcNbg)~׏UMe('SLqI NK{G_-JY9aZLT+S%}TNțy65>6_l6/>(@DA$$: %!&Q(rւztT0Մ ;"gW34-k~J 0<`UZ@Jd_gs9V"&#;]*/ZS1E![xsBꀏĝ@Ljba&qȋ7.L2ߗa-%vcɑ]k! OG̐_WtY&_۽/ES< RVtLp7H|$w}˂[\5mη3q?|1kٓrN-!(dAp"6hxOҟx>ѓ(U\`p$wݐ@0mRl=maq=·rDZa^tw 2HW_u),`ܣ[4o%Y(1H𺛨A9{o-d47fYA}Yx*\07uJ'kXI"bEy.?gml'ʑ*1)m [p hxLz6 .H]vU̽Z INL("&'Z x $=ؓ$6bjω8kv!l{Z&D܊+j9@I#Kg-S@=֤E\zb8Ͷ꒫l zI_"2 !eؖ&ST"~?DI7!Y"3ǂ+\Ȉ},^jAus'n?p3@3RkE7 @7)(@IT$'50\PmZ 0Ouʕ),*=|)1Qy'%Q)L齆'1~?ߕR;3"1{T2.xXH['{\*T^qeTnVwsgp+|CV Vlq A!j$ɤEwU{Yn7N3s@j>lI1 `vk)[:?%O%+b$m af-#Ԁy)Yzӹ.Ρǐ}wbtpz/[ݵ`/}V NaèH =Opq:|P>Ri7ҙ-F+⤑^GZwMg=O uWi#Z)Ez ;d $9b$;)bRL4WxzKp@iM,*F(^`锆E)C)ew*bpsxJ!ܙ?J)+ʍ۬0YC9 Ao ZE^> ;2 ;!\}UҲT9'ܘܫ"/SY4 Q…v dECC[yJS4pX"ӆB[ u t1-9#|G{I6a."+&3+%!#\~$*f,oH9g :kƷaoN.<Lojq-ggcV*Ƴ66ʫ#g<>]g\֔"_Q]šLNURhY.Aأ0 /dUټ (*Ns Y?UM5ndu8]e<:/G ݺF_8JzF}ȣ S"Ѓv+/*m^`^gڽr~EtSަÖ~S&B3קSr k!5] j$m0jy-¡>(PȐO9϶oeL4 ԈD_hXߔ0 {t[H,}}c՞1#6 e]&Rcn%\҂q)͠SrRCa #M@q2tI,V;f[GDгm[?Y.}fT7Q|s-.n?\ukm/h;^->J'5.0D;\-kĉkH!3aS}E݋qa*r&VJS͇LBLl=JpTTݴt3kSK!J@&> L FdXgr39ipgÂ8=KqacE~$kHF$e2zŒNLN8H /*a)VTpB4Ĵp}9b6b@uIB2"89iY^W@ٛ{]u0>w%Wz;4Өϯs}<5l_0 &/.~g^3e1 SwF% |6'/P\/rX5 L4밍["IǠ489\b`B$lgk5CxKXloVqy!֭(´hA6/W4~wA<%Cfbi\dwRu]W4ZMDO;ރ/9+"^vTѓ~u,>?e&%{hjU݄ `]$bZǕjj)AV|D rzMmp|npt8!5Yj6΁_GfK*C!^g($)GV>fv0K?sRsPoInL9jL/>6'|XPy_5IaIn$!9;-5* G8?do'KӵdZLGN0=\>mK.EU+tD] Yp /a5'^AŞ#,f۲];Or\?I0Jhs}+_~}hMcMَу/h ?⏝\w @P|*"K$M2%X%lՐTw)6g?_GtB!F EXm(IfW̪a@MRhV t1%=S .%N^q (/vZ {zϫJֶe**̏'JTkC|ly ӗ+q>)}+C"KK4ޣ ~@؃S8z_moN3FR;0P0WNϼܠò6`Tv"]#@b+>< r6`# tg/tQj$"46),@ZQL|X+Muqz"*);3:qA~} Vk|1MhCcІuř(!_$fń0{ &FI8dxpwlۂ˜߇#89}$;\ av%bNOj}g\ou\Z\(qfT!soRʕ %-؎YW')*[Mg-t!Ä@ +7EKT4=-m;2`lsrl.abޏrljͭ'_!=[OK+ ª|@i/1L WMqF8++U 07Wn(s ͆fm=ᦸ2W?PgA:Dd5tN>zWL8pK lz{w4%;z^֓ .հ?}v,y;=5Ir֣[=V [[>~GȵiUP[T:Hj4 Fx'Q\"cCc!Q_5c2*\kwx9r!C2}b,VQ{V2Զ)ol7Xj/oT*I4hi$4{E gV|Z2hdi[yD Аp\U \2b0xu@&Q&$NcQ1NmUR렍52'kCJPKF`ڶhAZ]Al*͗ݹ)+TJ)4P7dzD5WA{,hՅ^)PyBy3: X,L 4;uލC`<զW8nRJ+Q1ߡ*QNGȴJi,h'~+~QQ{źZx|SQrҠyrj|K-}́35? s cUHU4ZZ?tUlӈ|OVjVq47|.;3qk_a,B|ܩ)!I{Ef`-%d+[58R}-LYf5o!U\~7,&2F[]0̩amoQѠ%_~6ba޸G#3Vz߽ˀU[ky>iBՅ`|\ w:ءO=Εjm-ŇyL;p6g:POiS ai~SJGG6: J~9.kV2 [5D;BO/Κ~!OZ,~LĩCBéчDHsFv*d:P灊Q&0xSY* 1$6`whfF7mszFm gy$V-kJ%O{{CVHT ;,E'*ǶH)pHjKwhۋxx h$Ieoiցl+wXNP2Q~m^}!+OiBRCW>u<6> Z ei(i_Vďٗߣ\`ng?H F(V4*mJl\Ɖ❖ex{zcM ZI _yUcf`-vVZ*F$j76!, ` ܙNTO?:5h<G}Qcktnj9HFֺS1r(Ne2[9<&;\}u]W\פ]gϭ=:hq}.ܛ§Nė-*B4fD$uo` -è?OZ_G#}JSXـ{hD #)Rp?.Z.ϬJ2|~,;2ɺU5:;` n/;E͆q10t;nZ}^04 =חnyh8y Ԕ]R(A[VcX+YIIwa s>8Q;pOŌh#»ɀ )6v!>.%GdCQMa2" MK}iUWN&S1}A~L)0V4 BB_{>oacD6#XJڅXj;A *gqYY va`Xs Pg`@`}Ba9|œOg~Dɸ-g'e]gtt="モ W/UH嶴MD!GPy]q# .$ۿ#FN-,(#,ZtMG?R+eLJ4-W2I`0>5G^9HlHofrlŪA#q٬FǬ#@cr_!#NՃcτ, 9r 82KY-!/`k_i(7N--x#<˴r\b_wM0_Ił-6qb⦒WW4Ұx:~U&ht|x-Z8s" wfDmg}vH2=jԢ3NRB]vqAP]*^q(˯ܑ)Poa+Aej<*x<0:NH(?~KP+ -FZ.1~6aI o~OOm]M-Nҧc"^ܩW,$r>,ҍz #\~'݈yoJwNɫ\meΨLZr=/~(&C9&XvUuz:ҤzӌW3QyvU^Vp I[2v:R Ɩa#0Oz_Nݡne0]h)E>!BA DnT?i;_\:@fkܒÁ5ͽ8萴g&aGUg ihtk~v$"_֖ʱ?wv'Q6 .gL&|52V".ߝ>-aIF <ӸZ=M/0ubc?#(t$:p* (7WĄw>q?$jQ|_kDr'6(0ۓ2ەߕN5}bG$9e8㉣ys}pU!~gAyжà[Kܱ]-VP0l#[K Viq56m?^Tq_M?/^W8UaMs=۴eDZe=_6G^c_?;X<\7!b]u';]EIaWk_"Y_~`uxLj>RCׇHV8Mk@j͛8ػ;d:`.E~D玂tU]tո}goˈuTܔ{_W@c#/&`\K?=GY?c ^2Iפr:#<ڭBxC?BQentNP-X!PVٿ:ɠ߷L|48XQ/@0<3!XYvII`~Ll5E^fsEQSW>4{z._` @9{L( }p?,o :r0Xw%Oi>OCc/$X3/M$O&֙yΆG՛7SuUEseB%aBcܞ~G@̨AO@ӲM(b9]{&+h+_m , mkL]H;O^zvl]v!y\z1֣5e^{q8@7 (cWjΰyP{EӨ AqJXC͡y Qaufc $x#ap{ \x\<6e2gBu>ZwLkGt/` O0ˬd<;vjFX>KL):7Ň\\EETŠ~lRw8Ӽr1@w,Ds"  $Ha> 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 161 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 163 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 165 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 167 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 169 0 obj << /Length1 1534 /Length2 7038 /Length3 0 /Length 8069 /Filter /FlateDecode >> stream xڍx4־ Z!zE:`3D{ !z D'ABA&y{}k֚g?{~Yʤg+ H^>$@Q\@A_8KqЃ"/׼p AyeC uxA?UMPDzZPS-f?DP5x+ۃ<A C`GB7ʋ5抡0o7.(wuMB=%%{uXO7=^;7@1S-2Qg9r܊82Hx14R+eRo NK4Eɨ4 ҆)R 4^z)\(Ve0SEa؉-LnqQ mwBdAv;?U[Z3OC6khqh>g,\ ]k!OSTWvy֙0D` cfhX1t\6}}61cLﶽ9AS̄uK}.r1Gb¥,l\Dr&&φbuJYI,M1',iKFɇU?W+txtx(%dƭ{ڤ{ hX8Uk S)׻ 3a'b kE !d$}9o9.2oe΄l>{Km1D7u0͞~TUr9 VӚ,ҡ~"ruކֱ奔vnαj%)RVv(D &~IWqRTKٱo&~ɾ%x't:5e*?|V?銾G6=߱6U nNJ5^8n#)1O[b|u#e+~ '@7CM>Mԉ nHoqZ~۞<~-c+ƨU sB/u10+k@yJ?N$<"q@{)&KZe> 1d]M<ԬIbRbŏ$YS޷_r8T#V3~Z~0HJ% #Ltf*__)dm@c<єQx&ߔ(Q(=*9UQc\53r𮏁bRf35ᬜ-OnWy+=\mH1`2_Jlz%Ud; OtE-]Fidq B}(P0%ybi]>>@UQ5<̗i1k\4q@ovɟs#Ivk>D~I YMXZwy]E(>w;kD/kuhr|(^\gw#~pc+ׄ $5e?/lBV9Ⱦo4$0z}cbwpW!)k!ǻI%Vb ́[d'ZgX[bA0b'dA|I1Pn'ͽXH_䯻\¸VE/)69aV /? 8.*n(LKin7ZY  t5%X,=^-<m (l>_mj] jS0$Km|OcaL~x#'RvFn$qB(kB>J/)R\Xރ.JMS 2ʜ85p_ k0 8t7K h1qAQIq:,x#DΏFk!:RsV %<'#\5/\;pyƯ^|Pχ)i[`]]̻ױ W Eba \"b"eXn1Tpb!:f;/C'j;Ot/!# [}2ѿ߈e+7rh.K(]Ͷ{`(6W?YD2s/J/4J\kjƻ)(Uo0zĽLUf xѾdVJS/TyƇ9 n2A)}4wzʯk9>Ǟp1R Gz3ɯ=;2]y\kZil4)n@N` .;4M03~Ve8qG捺2HrSV& 5O?(A+o,O$>YmgBf=(-7}i= y3"AzX^y_*?ss;ˇ4r!Q :vUߒDG_v} X4(Gc;P>l/i 7~ڞτUlS|U`09r"\q?Eﱵ,fIz["2#&' 5/&Oƈ֦[bJS9R֞,ouݥ{YZa!~,?h#&'xYI:٣2nhK {Dykuxp[܀[vg2fLo2!_F&` M2Ϙ(^=sO@ǛWV=W>ti.{ |A*nI}EjXy2&< +7y&~8,FIur$`ie4aϽj 0a]hGn^s?I3Ww^|q7G}rź~&d&Q t*suN@Aio!ü,εgdܵ_  =S'HVl. MwxF1Z67lz#dcǙYpb-_Oyvl+^Oܩi%w:vCE;#Li8LJ ~;-gO=zT1moIzds?K4bnYBNo/xY)!|)?l5gؤy{afɕz;wմL] @6usyǖwNtX&X '$"ܛGcV\V(l#{7uM qo,8ʋy~hΉYyu[`˘GR8=垶v^KS$ǐ[kG!V- &_#=^] WzyU?nTj|ܩ9]5c#pd^@hi󴚥\%^r$=$?&醹@zfp`oİt5!Sʹ,5SYSlvr5V!bU%=G:͖mꣶ{8'Ffqwpfe$\ݱF}++ ,hwlg 6" ~bUJ#X:Cxk = !k>=\1 ,О]]LN>&iJ-ENØEslSncn\Y2ކlQi,K#Ҥoݤ4Ňzj#e룹1zt#i=aWgw/F#ĐH" o)M'wgӉ R/9?7I}_5;IW#?MYԘ(~ν? fy0aXZT=_PXIXUw-Iںkz&c UC;G_c%(\z:mc&y˒Ԑ(jxaAq=uJdE:d a>[S(ݥTX7BgIu'=S9.>ܲ#[" f$:y^\$7^DEoY 3h:`V W%fA̬CAvJlz+E޼YܱQs(r⏈Dz$dN*;Ȍ,Cc eه]10We%Ucf/Q?4x"ppYZ$"}@K%kn@!,x 8h}?$2XYwϹLʯ"&_Il1rJW01wt.`[.KPS7"[],ȭcKߺ]x0>벏MB٥W#{3 -w1Ozqo>w >$>@W7XN4RkVʕj}&@,`ED[ѴoMjPE~Np4q z zz.iQR]>\(ehxĒbV+޹=ɜs !"J~5[- o"ܫL&vC{STQhn>i%XtE#}l━LkBqSc69yJ8ܙoG|^ca[߾ۑTWR*fi(b6~-m_90W?ym.{%jBWIAUc>cIX^ȣol|jq7u}fZ|hԶ} EɴyL@H`\`]Sޓm;ro|€080䡿X/\Uq&C1JZ8'朐Kv &Dʁg638sy_&7.|$6o&{?s4ucxYϼX ˷?joQR^jl/ݳU\?Pfl`4ix5+}!.r_53`7^2$MrW); yc{ל;/hO aE.jlj4G|dV:;[y &3$ڔ2Nr0 ɇRe67DO#toN s3jٮW&ɒH3̩r/ޜȋGU3 dnXuo; 7jQ"@`N!5۷Za=j4*BSYWtN2Kj'ȲVWl_6\ŷ'N=.V'6ZӳZ_8g*Z`[Z42>ݡAe caɹtB̠Ncih z Nlp'Fq}GWh]ѣu-tW:)r-;j,UAZbWP |ۚYO#NzKidx1Ys(&j7\Bg4n|^.!wR)Ntm͗V͍pT\iën`r,vT{5:K LquCT9|'}st 4#i3T_hٞC$ M+k*ɈE G3~[8 c]SQ(ٱ(h6]5<#@Ho˺Xa0}.kPS>VzG$Cj'URVEF)_Tz"cmo840aZ?j8f%8rs㶛9$:E1]Vt غ9秊,S5ૹ }Oz`U/mzr2!>ճ ^[*r9LH\.[]8Za5)[0rt-G)FN_>,ˆ1,b2ra=?/:F?%7Rzg?>jU!=vk Sҍ;Us86= =ѝt>P`\lV1bZӈ c!n64"iHgB0׉Ӎdd.C^vKڃo>; xf\WGz0IחYE}=0´AQRV{B1S*93C99yQ,ݢ#RZpGgi&s/DaY)iU #?5Al}K;MusN@|'uTBno*OI|T,{iu7L 1ސƚO\-LEm%+RM%O Y/k&?uK 8<^hzl4Szc&v[31aHC-ӌ[bqmX8G6?;Cࢳ endstream endobj 171 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ڍ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 175 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 177 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 179 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 181 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 137 0 obj << /Type /ObjStm /N 58 /First 495 /Length 2875 /Filter /FlateDecode >> stream xڭZmSۺ_4dLBy) t9szݕĖ1%)&dIYI3 H#ɉb1ڸ-h(x#`iX0GD3 Ixh"(h ǎ yNˆ(D$! NA%-* D)N"%""@$"آ\AgOB "1SsHew"*P(0qQtS*0GD( @Ds:`'VDA4T8PF5M0b1 1ebՍ"Ԙ,c>A@\+L˂@8QoP FOӕ,?J2lfw߮E҄XTE nN2KwC+! #-cS;*\FsE{`0fp4Q(PUӭ#l`úfU/.ԁFu]yΩ{Ç9K=ȦEwbcءg߅c;<| X2wkw7>n!~b>HrlO D{MaK?)y^9xĕMz_rK OCKel)E Q5w9C{C2O۷8q2ӫy&0 Xm]`40hlOmDo-B]X l12j9 p!U\ ^Su:ꪲE)˱9m4dmQYo%`Ίl". }sU={,%)ip@ϽxvT${/xvqB`~La"ݡ_AQ9cTtzLOL%_ A6Φ&>tHGts6J4c:SlӜ' K%3 Dy!/ݝ6 90K X,j`@Ubn/>{V FqmVT *6 h)RBV5)_L&qf4u&v]ߞ]GmvЎ/>$g⭶AT_x<6RYBL3:!%4QJq0hMи9=rh4 Rf`ۿtcmRO)JijQүmD6_n?]}>.ۢ2g/kuu)Mm;{|b9b-K_OS<gcuEKSHyY4c'S{J@{K@$0a0N Wrj,xӿߋ$GʁBV$wc}Yq#l1$uh$K<#6"/ǧ.V/r4x&zeZǯsIi2 ruR~"%H׿>ݳP*1Ud^hEU\*.5ErOhrw]0]ʖdfWq["7ݏhJ`^W0EMF$ʍZ[q5 T:gV]-UMum nȡvM7ޓ٧ps?jݞb:LTXjbu,#Jq>H"',gAz6%RpĐZ.D6Nyb1d/2mi&{MJr#91+@ v`xhq]<'+?9&01bxg޹vI:]uP6"epς"ĄæD^B6 LoT5Y6/֪.7!JyYtE:HlVp#5Xx~\I?s\62r_qxWw3mȖ% ۈoVb/xr;[bIrX3Frdko9ㅻ}紟z6|qW"CU<}LPewK;Ļ|53{ZpVo4ݑ b 5W Mn!q i0]>3֗\n.ݿCK_<^TW~K`N_nXYI6_IzEb6yCw[ =B/6]/W-ׯo|鍨{n|ē.QTU:-v{ on? FE.oawB8<el.d?xƓaC:\̝7Kg)XgRju;²jjTWp-k٩m0kJ݂]J˓+-oE|Kѵ W/όH ^ѾM`Yՠڵ]UK,⻱=)#ko%ّ %"-ʧ,|D]ف3Olb8gÎ51:([mi/yyQ!'~%kY'E:m endstream endobj 194 0 obj << /Type /XRef /Index [0 195] /Size 195 /W [1 3 1] /Root 192 0 R /Info 193 0 R /ID [ ] /Length 493 /Filter /FlateDecode >> stream x%9SQne@T6QEQAqGGܑT 4!Le`ej䟰$3J=.܃!,sSV 3"-iH:ח!#SSV{AZ*yjVzI}=5+ /xjQS^i]YO=ڔhS򠧢SiOJ=TR.%O2$, \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/svmdoc.Rnw0000655000175100001440000004340313475431256014552 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 sensitive 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-\mathbf{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/NEWS.Rd0000655000175100001440000004150214120557636013062 0ustar hornikusers\name{NEWS} \title{News for Package \pkg{e1071}} \newcommand{\cpkg}{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}} \section{Changes in version 1.7-9}{ \itemize{ \item Remove configure code testing for gcc 2.96. } } \section{Changes in version 1.7-8}{ \itemize{ \item Bugfixes in \code{gknn()}: wrong behavior in case of tied k-nearest neighbors (for \code{use_all=TRUE}), and also in case of an overall class tie. } } \section{Changes in version 1.7-7}{ \itemize{ \item Bugfix in examples of \code{cshell()} } } \section{Changes in version 1.7-6}{ \itemize{ \item Bugfix in \code{scale_data_frame()} - now calls \code{scale()} if x is not a data frame. } } \section{Changes in version 1.7-5}{ \itemize{ \item NaiveBayes: better handling od character and logical features \item Added: \code{gknn()} for generalized k-Nearest Neighbours (using arbitrary proximity measures) \item Added: \code{scale_data_frame()} for scaling the numeric columns of a data frame. } } \section{Changes in version 1.7-4}{ \itemize{ \item Bug fix: "inverse" argument for class.weights argument in \code{svm.default()} did not work } } \section{Changes in version 1.7-2}{ \itemize{ \item Change license to GPL-2 OR GPL-3 \item add coef() method for SVMs with linear kernel } } \section{Changes in version 1.7-1}{ \itemize{ \item add warning in \code{predict.naiveBayes()} if the variable type (numeric/factor) does not match for training and new data. \item Fix bug in tune when parameter space is sampled \item Fix formula interface for NaiveBayes to account for variable removal } } \section{Changes in version 1.7-0}{ \itemize{ \item Bug fix in \code{lca()} \item The \code{class.weights} argument of \code{svm()} now accepts \code{"inverse"}, setting the weights inversely proportional to the class distribution \item \code{predict.naiveBayes} now fixes the factor levels of \code{newdata} to be identical with the training data. \item{libsvm updated to version 3.23} } } \section{Changes in version 1.6-8}{ \itemize{ \item add and use native symbols for C-code \item \code{naiveBayes()} now supports logical variables } } \section{Changes in version 1.6-7}{ \itemize{ \item fix some bug in handling weights in \code{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()}) } }