From noreply at r-forge.r-project.org Sat Apr 30 14:27:33 2011 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 30 Apr 2011 14:27:33 +0200 (CEST) Subject: [Yasomi-commits] r44 - in trunk/yasomi: . src Message-ID: <20110430122733.9AAB89D02F@r-forge.r-project.org> Author: frossi Date: 2011-04-30 14:27:33 +0200 (Sat, 30 Apr 2011) New Revision: 44 Modified: trunk/yasomi/ChangeLog trunk/yasomi/src/bmu.c trunk/yasomi/src/bmu.h trunk/yasomi/src/neighborhood.c trunk/yasomi/src/neighborhood.h Log: Added new C functions for a finer grain calculation of best matching units and of neighborhood functions (building blocks for stochastic SOM). Modified: trunk/yasomi/ChangeLog =================================================================== --- trunk/yasomi/ChangeLog 2011-03-06 11:06:20 UTC (rev 43) +++ trunk/yasomi/ChangeLog 2011-04-30 12:27:33 UTC (rev 44) @@ -1,6 +1,16 @@ +2011-04-30 Fabrice Rossi + + * src/neighborhood.c (neighborhood_single): new function that computes the neighborhood values around a single unit rather than around all units. + + * src/neighborhood.h: header of the new function (see above). + + * src/bmu.c (bmu_single_full_data): new function that computes the bmu for a vector given the full data. + + * src/bmu.h: header of the new function (see above). + 2010-10-22 Fabrice Rossi - * man/sominit.pca.dist.Rd: added the weight parameters to the documention. + * man/sominit.pca.dist.Rd: added the weight parameters to the documention. * demo/som-iris.R: fixed a parameter misspecification @@ -12,7 +22,7 @@ 2009-08-03 Fabrice Rossi - * R/som.R (sominit.pca.default): first implementation of the weighted version of the PCA. Based on princomp, to be revised. + * R/som.R (sominit.pca.default): first implementation of the weighted version of the PCA. Based on princomp, to be revised. * inst/doc/kernel.Rnw: started to work on this vignette @@ -22,7 +32,7 @@ * R/kmeans.R (prototypes.random): the "cluster" method takes now into account the weights - * man/sominit.random.Rd: modified to reflect the new rule for weighting values in random convex combinations. + * man/sominit.random.Rd: modified to reflect the new rule for weighting values in random convex combinations. * R/kmeans.R (convex.prototypes.random): the "random" method takes now into account the weights @@ -53,7 +63,7 @@ * DESCRIPTION (Suggests): colorspace is used in the vignettes - * inst/doc/introduction.Rnw: added hierarchical clustering of the + * inst/doc/introduction.Rnw: added hierarchical clustering of the results. * R/graphics.R (hitMap): use with.grid instead of with.cells for consistency @@ -129,7 +139,7 @@ * NAMESPACE: new function - * R/generic.R (batchkmeans): new generic function for kmeans + * R/generic.R (batchkmeans): new generic function for kmeans * R/kmeans.R (batchkmeans.default): new file: kmeans implementations @@ -500,7 +510,7 @@ * R/relational.R (predict.relationalsom): prediction for relational som (new function) - * R/quality.R (error.quantisation.som): generic version when no new data is used. + * R/quality.R (error.quantisation.som): generic version when no new data is used. (error.quantisation.somnum): numerical version (error.quantisation.relationalsom): relational version @@ -890,5 +900,5 @@ * demo/som-iris.R: updated this demo to use the distance.grid function - * R/som.R (somPCAInit): fixed a small bug in the eigenvector attribution + * R/som.R (somPCAInit): fixed a small bug in the eigenvector attribution Modified: trunk/yasomi/src/bmu.c =================================================================== --- trunk/yasomi/src/bmu.c 2011-03-06 11:06:20 UTC (rev 43) +++ trunk/yasomi/src/bmu.c 2011-04-30 12:27:33 UTC (rev 44) @@ -169,3 +169,29 @@ } +void bmu_single_full_data(double *proto,int *nproto,double *data,int *ndata, + int *dim,int *indiv,int *winner,double *error) { + double bestDist,dist,tmp; + int i=*indiv,j,k; + int bestSoFar; + int dataSize=*ndata,protoSize=*nproto,dimension=*dim; + + bestDist = R_PosInf; + bestSoFar = -1; + /* loop on prototypes */ + for(j = 0; j < protoSize; j++) { + dist = 0; + /* loop on dimensions */ + for(k = 0; k < dimension; k++) { + tmp = data[i + k * dataSize] - proto[j + k * protoSize]; + dist += tmp * tmp; + } + if(dist < bestDist) { + bestDist = dist; + bestSoFar = j; + } + } + *winner = bestSoFar; + *error = bestDist; +} + Modified: trunk/yasomi/src/bmu.h =================================================================== --- trunk/yasomi/src/bmu.h 2011-03-06 11:06:20 UTC (rev 43) +++ trunk/yasomi/src/bmu.h 2011-04-30 12:27:33 UTC (rev 44) @@ -18,5 +18,8 @@ void bmu_single(double *proto,int *nproto,double *one_data,int *dim, int *winner,double *error); +void bmu_single_full_data(double *proto,int *nproto,double *data,int *ndata, + int *dim,int *indiv,int *winner,double *error); + #endif /* !YASOMI_BMU_H */ Modified: trunk/yasomi/src/neighborhood.c =================================================================== --- trunk/yasomi/src/neighborhood.c 2011-03-06 11:06:20 UTC (rev 43) +++ trunk/yasomi/src/neighborhood.c 2011-04-30 12:27:33 UTC (rev 44) @@ -45,3 +45,40 @@ } } } + +void neighborhood_single(double *distances,double *nv,int *nbUnit, + double *radius,int *kernelType,int *isNormalized) +{ + int i; + double tmp; + kernel_type eKernelType = (kernel_type) *kernelType; + int nb=*nbUnit; + double theRadius=*radius; + + switch(eKernelType) { + case gaussian: + /* Gaussian kernel */ + theRadius /= 3; + for(i = 0 ; i < nb; i++) { + tmp = distances[i]/theRadius; + nv[i] = exp (-0.5*tmp*tmp); + } + break; + case linear: + /* Linear kernel */ + for(i = 0 ; i < nb; i++) { + tmp = distances[i]; + nv[i] = tmp < theRadius ? (1-tmp/theRadius) : 0; + } + break; + } + if(*isNormalized) { + tmp = 0; + for(i = 0 ; i < nb; i++) { + tmp += nv[i]; + } + for(i = 0 ; i < nb; i++) { + nv[i] /= tmp; + } + } +} Modified: trunk/yasomi/src/neighborhood.h =================================================================== --- trunk/yasomi/src/neighborhood.h 2011-03-06 11:06:20 UTC (rev 43) +++ trunk/yasomi/src/neighborhood.h 2011-04-30 12:27:33 UTC (rev 44) @@ -9,4 +9,7 @@ void neighborhood(double *distances,double *nv,int nbUnit,double radius, int kernelType,int isNormalized); +void neighborhood_single(double *distances,double *nv,int *nbUnit, + double *radius,int *kernelType,int *isNormalized); + #endif /* !YASOMI_NEIGHBORHOOD_H */ From noreply at r-forge.r-project.org Sat Apr 30 19:02:39 2011 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sat, 30 Apr 2011 19:02:39 +0200 (CEST) Subject: [Yasomi-commits] r45 - in trunk/yasomi: . R inst/doc man src tests Message-ID: <20110430170239.65C219D02B@r-forge.r-project.org> Author: frossi Date: 2011-04-30 19:02:38 +0200 (Sat, 30 Apr 2011) New Revision: 45 Added: trunk/yasomi/inst/doc/grids.Rnw Modified: trunk/yasomi/ChangeLog trunk/yasomi/R/annealing.R trunk/yasomi/R/generic.R trunk/yasomi/R/kernel.R trunk/yasomi/R/relational.R trunk/yasomi/R/slow-versions.R trunk/yasomi/R/som.R trunk/yasomi/R/tune.R trunk/yasomi/TODO trunk/yasomi/man/batchsom.Rd trunk/yasomi/man/batchsom.default.Rd trunk/yasomi/man/batchsom.dist.Rd trunk/yasomi/man/batchsom.kernelmatrix.Rd trunk/yasomi/man/som.tunecontrol.Rd trunk/yasomi/src/neighborhood.c trunk/yasomi/src/neighborhood.h trunk/yasomi/src/som.c trunk/yasomi/tests/kernel.R trunk/yasomi/tests/relational.R Log: Added a new neighbourhood kernel (zero one) and harmonized radius definition. Added supported for the kernel everywhere. Started to documented kernels and grids. Modified: trunk/yasomi/ChangeLog =================================================================== --- trunk/yasomi/ChangeLog 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/ChangeLog 2011-04-30 17:02:38 UTC (rev 45) @@ -1,5 +1,53 @@ 2011-04-30 Fabrice Rossi + * R/annealing.R (radius.exp): modified to accomodate for min.radius=0 + + * src/som.c: added the new kernel. + + * tests/relational.R: added cut=0. + + * tests/kernel.R: added cut=0. + + * man/batchsom.Rd: added the new kernel. + + * man/batchsom.kernelmatrix.Rd: added the new kernel. + + * man/batchsom.dist.Rd: added the new kernel. + + * man/batchsom.default.Rd: added the new kernel. + + * man/som.tunecontrol.Rd: added the new kernel. + + * R/tune.R (som.tunecontrol): added the new kernel. + + * R/stochastic.R (ssom.default.R): added the new kernel. + (ssom.default): ditto. + + * R/som.R (batchsom.default): added the new kernel. + + * R/relational.R (batchsom.dist): added the new kernel. + + * R/kernel.R (batchsom.kernelmatrix): added the new kernel. + + * R/generic.R (batchsom): added the new kernel. + (batchsom.control): ditto. + + * R/annealing.R (batchsom.control.default): added support for the zero one kernel and fix default min.radius to accomodate the revised kernel formulae. + + * R/slow-versions.R (neighborhood): transmits now the radius to kernel functions. + (kernel.gaussian): rewritten to reflect the vignette. + (kernel.linear): rewritten to reflect the vignette. + (kernel.zeroone): new kernel. + (batchsom.R): added support for the new zero one kernel. + + * inst/doc/grids.Rnw: new vignette about structures and neighbourhoods + + * src/neighborhood.c (neighborhood): fixed formulas and added the new kernel. + (neighborhood_single): ditto. + + * src/neighborhood.h (enum): added a new kernel type (zero one) + (GAUSSIAN_COEFF): normalisation constant for the gaussian kernel + * src/neighborhood.c (neighborhood_single): new function that computes the neighborhood values around a single unit rather than around all units. * src/neighborhood.h: header of the new function (see above). Modified: trunk/yasomi/R/annealing.R =================================================================== --- trunk/yasomi/R/annealing.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/R/annealing.R 2011-04-30 17:02:38 UTC (rev 45) @@ -1,5 +1,5 @@ radius.exp <- function(min,max,steps) { - max*(min/max)^(seq(0,1,length.out=steps)) + max*((min+1)/max)^(seq(0,1,length.out=steps))-1 } radius.lin <- function(min,max,steps) { @@ -10,26 +10,26 @@ mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07,...) { mode <- match.arg(mode,c("continuous","stepwise")) decrease <- match.arg(decrease,c("power","linear")) - kernel <- match.arg(kernel,c("gaussian","linear")) + kernel <- match.arg(kernel,c("gaussian","linear","zeroone")) assignment <- match.arg(assignment,c("single", "heskes")) if(missing(max.radius)) { max.radius <- 2/3*somgrid$diam+1 } if(missing(min.radius)) { - min.radius <- switch(kernel,"gaussian"=0.5,"linear"=1) + min.radius <- 0 } if(max.radius<=min.radius) { stop("max.radius must be larger than min.radius") } - if(min.radius<=0) { - stop("min.radius must be positive") + if(min.radius<0) { + stop("min.radius must be non negative") } if(missing(steps)) { steps <- switch(mode, Modified: trunk/yasomi/R/generic.R =================================================================== --- trunk/yasomi/R/generic.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/R/generic.R 2011-04-30 17:02:38 UTC (rev 45) @@ -26,7 +26,7 @@ mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose=FALSE,keepdata=TRUE,...) { @@ -46,7 +46,7 @@ mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07,...) { Modified: trunk/yasomi/R/kernel.R =================================================================== --- trunk/yasomi/R/kernel.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/R/kernel.R 2011-04-30 17:02:38 UTC (rev 45) @@ -365,7 +365,8 @@ mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), + normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose=FALSE,keepdata=TRUE,...) { @@ -379,7 +380,7 @@ } the.call[[1]] <- batchsom.control control <- eval(the.call,envir = parent.frame()) - control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear) + control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear,"zeroone"=kernel.zeroone) if(!missing(weights)) { if(length(weights)!=nrow(data)) { stop("'weights' and 'data' have different dimensions") Modified: trunk/yasomi/R/relational.R =================================================================== --- trunk/yasomi/R/relational.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/R/relational.R 2011-04-30 17:02:38 UTC (rev 45) @@ -410,7 +410,8 @@ mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), + normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose=FALSE,keepdata=TRUE,...) { @@ -425,7 +426,7 @@ # the.call[[1]] <- as.name("batchsom.control") the.call[[1]] <- batchsom.control control <- eval(the.call,envir = parent.frame()) - control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear) + control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear,"zeroone"=kernel.zeroone) if(!missing(weights)) { if(length(weights)!=nrow(data)) { stop("'weights' and 'data' have different dimensions") Modified: trunk/yasomi/R/slow-versions.R =================================================================== --- trunk/yasomi/R/slow-versions.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/R/slow-versions.R 2011-04-30 17:02:38 UTC (rev 45) @@ -1,5 +1,5 @@ -neighborhood <- function(somgrid,T,kernel,normalised=TRUE) { - raw <- kernel(somgrid$dist/T) +neighborhood <- function(somgrid,R,kernel,normalised=TRUE) { + raw <- kernel(R,somgrid$dist) if(normalised) { sweep(raw,1,rowSums(raw),"/") } else { @@ -7,14 +7,12 @@ } } -kernel.gaussian <- function(x) { - exp(-(3*x)^2/2) +kernel.gaussian <- function(R,x) { + exp(-4.605170185988090914009*(x/(R+1))^2) } -kernel.linear <- function(x) { - pre <- sapply(x,function(x) { - if(x<1) {1-x} else {0} - }) +kernel.linear <- function(R,x) { + pre <- ifelse(xR$},\\ +1 & \text{if $d\leq R$}. +\end{cases} +\] +\item[linear] this kernel replaces the strong one to zero jump of the previous + kernel by a linear decrease. In this case, $R+1$ gives the end of influence + of the kernel. It is defined has follows: +\[ +K_{lin}(R,d)= +\begin{cases} +0 & \text{if $d\geq R+1$},\\ +1-\frac{d}{R+1} & \text{if $d>= +distances <- seq(0,5,length.out=101) +R <- 2 +b <- log(0.01) +plot(distances,ifelse(distances<=R,1,0),type="l",lwd=2,main="R=2",ylab="kernel function") +lines(distances,ifelse(distances<=R+1,1-distances/(R+1),0),col="red",lwd=2) +lines(distances,exp(b*(distances/(R+1))^2),col="blue",lwd=2) +legend("topright",legend=c("zero one","linear","gaussian"),lwd=2,col=c("black","red","blue")) +@ +\end{center} + +\caption{Three kernel functions computed for $R=2$} +\label{fig:kernels} +\end{figure} +\end{document} Modified: trunk/yasomi/man/batchsom.Rd =================================================================== --- trunk/yasomi/man/batchsom.Rd 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/man/batchsom.Rd 2011-04-30 17:02:38 UTC (rev 45) @@ -8,7 +8,7 @@ batchsom(data, somgrid, init=c("pca","random"), prototypes, weights, mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose = FALSE, keepdata = TRUE, \dots) } @@ -39,8 +39,8 @@ } } \item{min.radius}{the minimum neighbourhood influence radius. If - missing, the value depends on the one of \code{kernel} but ensures - in practice a local learning only (see details)} + missing, the value might depend on the one of \code{kernel} but ensures + in practice a local learning only (currently defaults to one)} \item{max.radius}{the maximal neighbourhood influence radius. If missing two third of the prior structure diameter plus one} \item{steps}{the number of radii to use during annealing} Modified: trunk/yasomi/man/batchsom.default.Rd =================================================================== --- trunk/yasomi/man/batchsom.default.Rd 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/man/batchsom.default.Rd 2011-04-30 17:02:38 UTC (rev 45) @@ -10,7 +10,7 @@ prototypes,weights, mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose = FALSE, keepdata = TRUE, \dots) } @@ -42,8 +42,8 @@ } } \item{min.radius}{the minimum neighbourhood influence radius. If - missing, the value depends on the one of \code{kernel} but ensures - in practice a local learning only (see details)} + missing, the value might depend on the one of \code{kernel} but ensures + in practice a local learning only (currently defaults to one)} \item{max.radius}{the maximal neighbourhood influence radius. If missing two third of the prior structure diameter plus one} \item{steps}{the number of radii to use during annealing} Modified: trunk/yasomi/man/batchsom.dist.Rd =================================================================== --- trunk/yasomi/man/batchsom.dist.Rd 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/man/batchsom.dist.Rd 2011-04-30 17:02:38 UTC (rev 45) @@ -10,7 +10,7 @@ prototypes,weights, mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose = FALSE, keepdata = TRUE, \dots) } @@ -46,8 +46,8 @@ } } \item{min.radius}{the minimum neighbourhood influence radius. If - missing, the value depends on the one of \code{kernel} but ensures - in practice a local learning only (see details)} + missing, the value might depend on the one of \code{kernel} but ensures + in practice a local learning only (currently defaults to one)} \item{max.radius}{the maximal neighbourhood influence radius. If missing two third of the prior structure diameter plus one} \item{steps}{the number of radii to use during annealing} Modified: trunk/yasomi/man/batchsom.kernelmatrix.Rd =================================================================== --- trunk/yasomi/man/batchsom.kernelmatrix.Rd 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/man/batchsom.kernelmatrix.Rd 2011-04-30 17:02:38 UTC (rev 45) @@ -10,7 +10,7 @@ prototypes,weights, mode = c("continuous","stepwise"), min.radius, max.radius, steps, decrease = c("power", "linear"), max.iter, - kernel = c("gaussian", "linear"), normalised, + kernel = c("gaussian", "linear", "zeroone"), normalised, assignment = c("single", "heskes"), cut = 1e-07, verbose = FALSE, keepdata = TRUE, \dots) } @@ -45,8 +45,8 @@ } } \item{min.radius}{the minimum neighbourhood influence radius. If - missing, the value depends on the one of \code{kernel} but ensures - in practice a local learning only (see details)} + missing, the value might depend on the one of \code{kernel} but ensures + in practice a local learning only (currently defaults to one)} \item{max.radius}{the maximal neighbourhood influence radius. If missing two third of the prior structure diameter plus one} \item{steps}{the number of radii to use during annealing} Modified: trunk/yasomi/man/som.tunecontrol.Rd =================================================================== --- trunk/yasomi/man/som.tunecontrol.Rd 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/man/som.tunecontrol.Rd 2011-04-30 17:02:38 UTC (rev 45) @@ -34,7 +34,8 @@ fitting (see \code{\link{batchsom}})} \item{annealing}{annealing scheme with valid values \code{"power"} (exponential like annealing) and \code{"linear"} (linear scheme)} - \item{kernel}{kernel chosen between \code{"gaussian"} and \code{"linear"}} + \item{kernel}{kernel chosen between \code{"gaussian"}, \code{"linear"} + and \code{"zeroone"}} \item{criterion}{an error criterion, i.e., a function that evaluate the quality of a fitted som on a dataset} } Modified: trunk/yasomi/src/neighborhood.c =================================================================== --- trunk/yasomi/src/neighborhood.c 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/src/neighborhood.c 2011-04-30 17:02:38 UTC (rev 45) @@ -4,7 +4,7 @@ /* Neighborhood function calculation. The kernel functions are defined such that neighborhood(x,y) is approximatly zero when the distance between x and - y is higher than the radius parameter. + y is higher or equal to the radius parameter plus one. When normalized, a row major approach is used to preserve memory locality. */ void neighborhood(double *distances,double *nv,int nbUnit,double radius, @@ -18,19 +18,25 @@ switch(eKernelType) { case gaussian: /* Gaussian kernel */ - radius /= 3; for(i = 0 ; i < size; i++) { - tmp = distances[i]/radius; - nv[i] = exp (-0.5*tmp*tmp); + tmp = distances[i]/(radius+1); + nv[i] = exp (GAUSSIAN_COEFF*tmp*tmp); } break; case linear: /* Linear kernel */ for(i = 0 ; i < size; i++) { tmp = distances[i]; - nv[i] = tmp < radius ? (1-tmp/radius) : 0; + nv[i] = tmp < radius + 1 ? (1-tmp/(radius+1)) : 0; } break; + case zeroone: + /* Zero one kernel */ + for(i = 0 ; i < size; i++) { + tmp = distances[i]; + nv[i] = tmp <= radius ? 1 : 0; + } + break; } if(isNormalized) { for(i = 0 ; i < nbUnit; i++) { @@ -58,19 +64,25 @@ switch(eKernelType) { case gaussian: /* Gaussian kernel */ - theRadius /= 3; for(i = 0 ; i < nb; i++) { - tmp = distances[i]/theRadius; - nv[i] = exp (-0.5*tmp*tmp); + tmp = distances[i]/(theRadius+1); + nv[i] = exp (GAUSSIAN_COEFF*tmp*tmp); } break; case linear: /* Linear kernel */ for(i = 0 ; i < nb; i++) { tmp = distances[i]; - nv[i] = tmp < theRadius ? (1-tmp/theRadius) : 0; + nv[i] = tmp < theRadius + 1 ? (1-tmp/(theRadius+1)) : 0; } break; + case zeroone: + /* Zero one kernel */ + for(i = 0 ; i < nb; i++) { + tmp = distances[i]; + nv[i] = tmp <= theRadius ? 1 : 0; + } + break; } if(*isNormalized) { tmp = 0; Modified: trunk/yasomi/src/neighborhood.h =================================================================== --- trunk/yasomi/src/neighborhood.h 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/src/neighborhood.h 2011-04-30 17:02:38 UTC (rev 45) @@ -3,9 +3,12 @@ typedef enum { gaussian = 0, - linear = 1 + linear = 1, + zeroone = 2 } kernel_type; +#define GAUSSIAN_COEFF -4.605170185988090914009 + void neighborhood(double *distances,double *nv,int nbUnit,double radius, int kernelType,int isNormalized); Modified: trunk/yasomi/src/som.c =================================================================== --- trunk/yasomi/src/som.c 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/src/som.c 2011-04-30 17:02:38 UTC (rev 45) @@ -69,6 +69,9 @@ case 1: Rprintf(" linear kernel"); break; + case 2: + Rprintf(" zero one kernel"); + break; } switch(assignmentRule) { case 0: @@ -217,6 +220,9 @@ case 1: Rprintf(" linear kernel"); break; + case 2: + Rprintf(" zero one kernel"); + break; } switch(assignmentRule) { case 0: @@ -387,6 +393,9 @@ case 1: Rprintf(" linear kernel"); break; + case 2: + Rprintf(" zero one kernel"); + break; } switch(assignmentRule) { case 0: Modified: trunk/yasomi/tests/kernel.R =================================================================== --- trunk/yasomi/tests/kernel.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/tests/kernel.R 2011-04-30 17:02:38 UTC (rev 45) @@ -25,9 +25,9 @@ kprototypes.final <- ksom$prototypes%*%X ## and now the same thing for the standard vector SOM - +## cut=0 is needed as the kernel SOM does not provide the cutting feature som <- batchsom(X,sg,prototypes=prototypes.init,verbose=TRUE, - max.radius=radius.max,steps=nb.radii,mode=mode) + max.radius=radius.max,steps=nb.radii,mode=mode,cut=0) stopifnot(all.equal(error.kaskilagus(som),error.kaskilagus(ksom))) stopifnot(all.equal(error.quantisation(som),error.quantisation(ksom))) Modified: trunk/yasomi/tests/relational.R =================================================================== --- trunk/yasomi/tests/relational.R 2011-04-30 12:27:33 UTC (rev 44) +++ trunk/yasomi/tests/relational.R 2011-04-30 17:02:38 UTC (rev 45) @@ -25,9 +25,9 @@ rprototypes.final <- rsom$prototypes%*%X ## and now the same thing for the standard vector SOM - +## cut=0 is needed as the dissimilarity SOM does not provide the cutting feature som <- batchsom(X,sg,prototypes=prototypes.init,verbose=TRUE, - max.radius=radius.max,steps=nb.radii,mode=mode) + max.radius=radius.max,steps=nb.radii,mode=mode,cut=0) stopifnot(all.equal(error.kaskilagus(som),error.kaskilagus(rsom))) stopifnot(all.equal(error.quantisation(som),error.quantisation(rsom)))