[Yasomi-commits] r45 - in trunk/yasomi: . R inst/doc man src tests

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Apr 30 19:02:39 CEST 2011


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  <Fabrice dot Rossi at apiacoa dot org>
 
+	* 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(x<R+1,1-x/(R+1),0)
     if(is.matrix(x)) {
         matrix(pre,ncol=ncol(x),nrow=nrow(x))
     } else {
@@ -22,6 +20,10 @@
     }
 }
 
+kernel.zeroone <- function(R,x) {
+    ifelse(x<=R,1,0)
+}
+
 bmu.R <- function(prototypes,data,weights) {
     distances <- dist(prototypes,data)
     clusters <- apply(distances,2,which.min)
@@ -46,14 +48,15 @@
 }
 
 batchsom.R <- function(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,
-                             assignment = c("single", "heskes"),
-                             cut = 1e-07,
-                             verbose=FALSE,keepdata=TRUE,...) {
+                       weights,
+                       mode = c("continuous","stepwise"),
+                       min.radius, max.radius, steps,
+                       decrease = c("power", "linear"), max.iter,
+                       kernel = c("gaussian", "linear", "zeroone"),
+                       normalised,
+                       assignment = c("single", "heskes"),
+                       cut = 1e-07,
+                       verbose=FALSE,keepdata=TRUE,...) {
     ## process parameters and perform a few sanity checks
     if(class(somgrid)!="somgrid") {
         stop("'somgrid' is not of somgrid class")
@@ -67,7 +70,7 @@
     if(control$mode=="continuous") {
         stop("continuous annealing mode is unsupported in batchsom.R")
     }
-    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)) {

Modified: trunk/yasomi/R/som.R
===================================================================
--- trunk/yasomi/R/som.R	2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/som.R	2011-04-30 17:02:38 UTC (rev 45)
@@ -125,7 +125,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,...) {
@@ -139,7 +140,7 @@
     the.call[[1]] <- batchsom.control
     control <- eval(the.call,envir = parent.frame())
     control$assignment.int <- switch(control$assignment,"single"=0,"heskes"=1)
-    control$kernel.int <- switch(control$kernel,"gaussian"=0,"linear"=1)
+    control$kernel.int <- switch(control$kernel,"gaussian"=0,"linear"=1,"zeroone"=2)
     if(!missing(weights)) {
         if(length(weights)!=nrow(data)) {
             stop("'weights' and 'data' have different dimensions")
@@ -336,7 +337,7 @@
     cat("       grid: ",object$somgrid$topo," grid of size ",
         object$somgrid$xdim,"x",object$somgrid$ydim," with diameter ",
         object$somgrid$diam,"\n",sep="")
-    cat("     kernel: ",object$control$kernel,
+    cat("     kernel:",object$control$kernel,
         if(!object$control$normalised) {" not normalised"} else {" normalised"},
         "\n",sep="")
     cat(" assignment:",object$control$assignment,"\n")

Modified: trunk/yasomi/R/tune.R
===================================================================
--- trunk/yasomi/R/tune.R	2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/tune.R	2011-04-30 17:02:38 UTC (rev 45)
@@ -14,7 +14,8 @@
          innernradii=innernradii,
          maxiter=maxiter,
          annealing=match.arg(annealing,c("power","linear"),several.ok = TRUE),
-         kernel=match.arg(kernel,c("gaussian","linear"),several.ok = TRUE),
+         kernel=match.arg(kernel,c("gaussian","linear", "zeroone"),
+         several.ok = TRUE),
          criterion=criterion)
 }
 

Modified: trunk/yasomi/TODO
===================================================================
--- trunk/yasomi/TODO	2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/TODO	2011-04-30 17:02:38 UTC (rev 45)
@@ -21,6 +21,7 @@
   - possibly in predict.* (for the error calculation)
 - fix the border "problem" in plot.somgrid
 - do we need a final assigment in the continuous annealing case?
+- neighborhood kernels are not documented
 
 + Long term R goals:
   - move to S4 classes

Added: trunk/yasomi/inst/doc/grids.Rnw
===================================================================
--- trunk/yasomi/inst/doc/grids.Rnw	                        (rev 0)
+++ trunk/yasomi/inst/doc/grids.Rnw	2011-04-30 17:02:38 UTC (rev 45)
@@ -0,0 +1,102 @@
+%% -*- ispell-dictionary: "british" -*-
+% \VignetteIndexEntry{Prior structures and neighbourhoods in YASOMI}
+% \VignetteDepends{e1071, proxy, colorspace}
+% \VignetteKeyword{Self Organising Map}
+% \VignetteKeyword{Self Organizing Map}
+% \VignetteKeyword{Neighbourhoods}
+% \VignetteKeyword{Neighborhoods}
+% \VignetteKeyword{Clustering}
+
+\documentclass[a4paper]{article}
+\usepackage{amsmath}
+
+\begin{document}
+\title{Prior structures and neighbourhoods in YASOMI}
+\author{Fabrice Rossi}
+
+\SweaveOpts{width=7,height=5}
+
+\maketitle
+
+\section{Prior structures}
+
+\section{Neighbourhoods}
+Self Organising Map fitting is based on a form of annealing implemented by a
+shrinking neighbour influence in the prior structure: when the prototype
+associated to cell $i$ (in the prior structure) is updated, then all other
+prototypes are updated similarly but with an update magnitude that decreases
+with the distance between cell $i$ and the cell of the updated prototype. For
+instance, in the stochastic SOM, the update of prototype $j$ at step $t$ is
+given by 
+\[
+p^{(t)}_j=p^{(t-1)}_j+\varepsilon^{(t)}N^{(t)}(i,j)\left(x^{(t)}-p^{(t-1)}_i\right),
+\]
+where $x^{(t)}$ is the data point considered at step $t$, $i$ is the best
+matching unit for this data point, $\varepsilon^{(t)}$ the learning rate and
+$N^{(t)}(i,j)$ the neighbouring influence between cells $i$ and $j$. 
+
+The classical form for $N^{(t)}(i,j)$ is 
+\[
+N^{(t)}(i,j)=K(R^{(t)},d_p(i,j)),
+\]
+where $d_p$ is a distance between units in the prior structure (see previous
+Section for details, $R^{(t)}$ is a radius of influence, which decreases
+during the fitting process, and $K(R,.)$ is a so-called \emph{kernel function}
+which maps $[0,\infty[$ to $[0,1]$. $K(R,.)$ should be decreasing from $1$ to
+$0$ at a speed specified by $R$. 
+
+To make the last assumption precise, yasomi uses the following conventions:
+\begin{enumerate}
+\item $K(R,.)$ is decreasing;
+\item $K(R,0)=1$;
+\item $K(R,R+1)\leq 0.01$.
+\end{enumerate}
+There are currently three kernel included in yasomi:
+\begin{description}
+\item[zero one] this kernel has binary outputs, that is
+  $K_{01}(R,.)\in\{0,1\}$. The $R$ parameter gives the radius of influence of the
+  kernel which is simply defined as follows:
+\[
+K_{01}(R,d)=
+\begin{cases}
+0 & \text{if $d>R$},\\
+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<R+1$}.
+\end{cases}
+\]
+\item[gaussian] this kernel is a smooth version of the linear kernel and uses
+  the same convention that $R+1$ is the end of influence. The kernel is given
+  by 
+\[
+K_{gaussian}(R,d)=\exp^{b\frac{d^2}{(R+1)^2}},
+\]
+with $b=\ln(0.01)$. 
+\end{description}
+Figure \ref{fig:kernels} shows the behaviour of the three kernels for $R=2$. 
+
+\begin{figure}[htbp]
+  \begin{center}
+<<echo=FALSE,fig=TRUE>>= 
+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)))



More information about the Yasomi-commits mailing list