R/sESOM4BMUs.R

Defines functions sESOM4BMUs

Documented in sESOM4BMUs

sESOM4BMUs =function(BMUs,Data,esom,toroid,CurrentRadius, ComputeInR = FALSE, Parallel=TRUE) {
    #esom=sESOM4BMUs(bmpos,Data, esom, toroid=TRUE, CurrentRadius)=F
    #simplified ESOM Algorithmus for BestMatchingUnits
    # INPUT
    # BMUs[1:Lines,1:Columns]               BestMAtchingUnits generated by ProjectedPoints2Grid()
    # Data[1:n,1:d]                         array of data: n cases in rows, d variables in columns
    # esom[1:Lines,1:Columns,1:weights]     wts in array form, see ListAsEsomNeurons()
    # toroid                                TRUE/FALSE - topology of points
    # CurrentRadius                         number betweeen 1 to x
    # OPTIONAL
    # ComputeInR                                  =T: Rcode, =F Cpp Code
    
    # OUTPUT
    # esom[1:Lines,1:Columns,1:weights]      abgeaenderte wts
    
    # author: MT 07/2015, based on getUmatrix4BMUs()
    #1.Editor MT 06/2016
    NumberOfDataSamples <- dim(Data)[1] # number of inputvectors
    
    if (NumberOfDataSamples != nrow(BMUs))
      stop(
        paste(
          'NumberOfDataSamples',
          NumberOfDataSamples,
          'does not equal to Number of Best Matching units',
          nrow(BMUs)
        )
      )
    # pos= 1:NumberOfDataSamples
    pos <-
      sample(1:NumberOfDataSamples, NumberOfDataSamples) # permutation of 1:n
    newData <- Data[pos, ]
    BMUnew = BMUs[pos, ]
    if (is.vector(newData)) {
      newData <- as.matrix(newData) # 1 x d-matrix instead of vector
    }
    # Initialisierungen werden aus der For-Schleife herausgestellt
    k <- dim(esom)[1] #Lines
    m <- dim(esom)[2] #Columns
    NumberOfweights <- dim(esom)[3]
    #meshgrid
    aux <- array(0, c(k, m, 2))
    for (i in 1:k) {
      aux[i, , 1] <- i
    }
    for (j in 1:m) {
      aux[, j, 2] <- j  # Indexarray
    }
    # meshgrid generiert
    neigharray <- array(0, c(k, m, NumberOfweights))
    
    #GetBestMatch Initialisierungen
    difference <- esom
    if (!ComputeInR) {

      if(Parallel){
        esomAngepasst=trainstepC2(esom,aux-1, newData, BMUnew-1,k, m, NumberOfweights, CurrentRadius,toroid)
      }else{
        esomAngepasst = trainstepC(esom, aux - 1, newData, BMUnew - 1, k, m, CurrentRadius, toroid)
      }
    } else{
      for (p in 1:NumberOfDataSamples) {
        ## Begin One Learnstep for one inputvector (1 Datenzeile)
        DataSample = newData[p, ]
        
        ##Keine BestMatchSuche
        bmpos = BMUnew[p, ]
        
        # toroid map: different distances
        # example: on a toroid 5 x 4-grid the distance between the points (3,4) and (1,1) is sqrt(8)
        
        if (toroid) {
          OutputDistances <-
            0.5 * sqrt((k - abs(2 * abs(
              aux[, , 1] - bmpos[1]
            ) - k)) ^ 2 + (m - abs(2 * abs(
              aux[, , 2] - bmpos[2]
            ) - m)) ^ 2)
        } else{
          OutputDistances <-
            sqrt((aux[, , 1] - bmpos[1]) ^ 2 + (aux[, , 2] - bmpos[2]) ^ 2)
        } #end if toroid
        
        #Bestimme Nachbahrschaftsfunktion innerhalb Radius
        #  neighborfunction='kreis'
        neighmatrix = 1 - OutputDistances ^ 2 / (pi * CurrentRadius ^ 2)
        neighmatrix[neighmatrix < 0] = 0
        neigharray = array(neighmatrix, c(k, m, NumberOfweights)) #Bringe auf gleiche Dimension wie esom und inputdiff
        
        #Das muesste auch vektoriesierbar sein, momentan klappts aber nur als for schleife
        #Injeder Dimension der inputdiff matrize wirdein Wert des Datenvekotr abgezogen
        #dadurch wird defakto von jedem gewicht der datenvektor komplett abgezogen
        #das dunktioniert, weil R automatisch den Wert auf die korrekte Matrizengroesse vergroessert
        
        # inputdiff <- esom
        # #Das muesste auch vektoriesierbar sein, momentan klappts aber nur als for schleife
        # for (w in 1:NumberOfweights) {
        #   #neigharray[,,w] <- neighmatrix #Nachbahrschaftsmatrix ist fuer alle Gewichtsvektoren konstant
        #   inputdiff[,,w] <- inputdiff[,,w]-DataSample[w]
        # } #end for 1:NumberOfweights
        
        # #CurrentLearnrate is always 1
        inputdiff = Delta3DWeightsC(esom * 1, DataSample) #MT: Ohne Multiplikation mit 1 ist esom==inputdiff, kA wieso
        esom <- esom - 1 * neigharray * inputdiff
        ## End One Learnstep for one inputvector (1 Datenzeilen)
        
        # Hold BMUs
        #for (i in c(1:NumberOfDataSamples)) {
        #  esom[BMUs[i, 1], BMUs[i, 2], ] = Data[i, ]
        #} # end for hold bmus
        esomAngepasst = esom
      } #end for 1:NumberOfDataSamples
    }
    return(esomAngepasst)
  }
Mthrun/DatabionicSwarm documentation built on Nov. 2, 2023, 6:51 a.m.