From b815cc63c6c8deabd18a3f5c210a2a088883eb50 Mon Sep 17 00:00:00 2001
From: Mauricio Zambrano-Bigiarini <hzambran@users.noreply.github.com>
Date: Wed, 19 Sep 2012 16:37:59 +0000
Subject: [PATCH] new internal function: 'alea.sphere'. Function
 'compute.veloc' partially implement 'G-X' (SPSO2011)

---
 NEWS          |   2 +-
 R/PSO_v2012.R | 180 ++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 140 insertions(+), 42 deletions(-)

diff --git a/NEWS b/NEWS
index f3c9c48..c79adcf 100755
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
 NEWS/ChangeLog for hydroPSO
 --------------------------
-0.1-58	(under-development)
+0.1-59	(under-development & not working yet)
         o 'hydroPSO'      : -) towards SPSO 2011 capable...
         
                             -) argument 'method' now allows the following 2 new values: 'spso2007' and 'spso2011', which set the values of the PSO 
diff --git a/R/PSO_v2012.R b/R/PSO_v2012.R
index 3346f46..73284b5 100755
--- a/R/PSO_v2012.R
+++ b/R/PSO_v2012.R
@@ -35,7 +35,7 @@ Random.Bounded.Matrix <- function(npart, x.MinMax) {
 	
   return(X)
 	
-} # 'Random.Bounded.Matrix2' end
+} # 'Random.Bounded.Matrix' end
 #Random.Bounded.Matrix(10, X.MinMax)
 
 
@@ -81,6 +81,95 @@ rLHS <- function(n, ranges) {
 } # 'rLHS' end
 
 
+################################################################################
+#                                    enorm                                     #
+################################################################################
+# Author : Mauricio Zambrano-Bigiarini                                         #
+################################################################################
+# Created: 19-Sep-2012                                                         #
+# Updates:                                                                     #
+################################################################################
+# Purpose  : Computes the Euclidean norm of a vector                           #
+################################################################################
+# Output   : single numeric value with the euclidean norm of 'x'               #
+################################################################################
+enorm <- function(x) sqrt( sum(x*x) )
+
+
+################################################################################
+#                                alea.normal                                   #
+################################################################################
+# Author : Mauricio Zambrano-Bigiarini                                         #
+#          Based on the Matlab function developed by Maurice Clerc (May 2011), #
+#          and available on:                                                   #
+#          http://www.particleswarm.info/SPSO2011_matlab.zip                   #
+################################################################################
+# Created: 19-Sep-2012                                                         #
+# Updates:                                                                     #
+################################################################################
+# Purpose  : It uses the polar form of the Box-Muller transformation to obtain #
+#            a pseudo-random number from a Gaussian distribution               #
+################################################################################
+# Output   : single numeric value with a pseudo-random number from a Gaussian  #
+#            distribution with mean='mean' and standard deviation ='sd'        #
+################################################################################
+alea.normal <- function(mean=0, sd=1) {
+
+  w <- 2  
+  while (w >= 1) {
+     x1 <- 2 * runif(1) - 1
+     x2 <- 2 * runif(1) - 1
+     w  <- x1*x1 + x2*x2   
+  } # 'WHILE' end   
+  w  <- sqrt( -2*log(w) / w )
+  y1 <- x1*w  
+  if ( runif(1) < 0.5 ) y1 <- -y1  
+  y1 <- y1 * sd + mean 
+   
+  return(y1)
+
+} # 'alea.normal' end
+
+
+################################################################################
+#                                alea.sphere                                   #
+################################################################################
+# Author : Mauricio Zambrano-Bigiarini                                         #
+#          Based on the Matlab function developed by Maurice Clerc (May 2011), #
+#          and available on:                                                   #
+#          http://www.particleswarm.info/SPSO2011_matlab.zip                   #
+################################################################################
+# Created: 19-Sep-2012                                                         #
+# Updates:                                                                     #
+################################################################################
+# Purpose  : It generates a random point inside the hypersphere around G with  #
+#            radius = r                                                        #
+################################################################################
+# Output   : numeric vector with the location of a random point inside the     #
+#            hypersphere around G with radius = r                              #
+################################################################################
+alea.sphere <- function(G, radius) {
+
+  # dimension of 'G' (number of parameters)
+  n <- length(G)
+  
+  # Step 1. Direction
+  l <- 0
+  x <- replicate( n, alea.normal(mean=0, sd=1) )
+  l <- sqrt( sum(x*x) )
+  
+  # Step 2. Random Radius
+  r <- runif(1)
+  
+  x <- r * radius * x / l
+  
+  # Centering the random point at 'G'
+  x <- x + G
+  
+  return(x)
+
+} # 'alea.sphere' end
+
 
 ################################################################################
 #                               compute.CF Function                            #
@@ -131,6 +220,7 @@ compute.CF <- function(c1, c2) {
 ################################################################################
 # Created: 2008                                                                #
 # Updates: Oct-2011 ; Nov-2011                                                 #
+#          19-Sep-2012                                                         #
 ################################################################################
 compute.veloc <- function(x, v, w, c1, c2, CF, Pbest, part.index, gbest, 
                           topology, method, MinMax, neighs.index, 
@@ -145,59 +235,67 @@ compute.veloc <- function(x, v, w, c1, c2, CF, Pbest, part.index, gbest,
   r1 <- runif(n, min=0, max=1)
   r2 <- runif(n, min=0, max=1)
   
-  if ( method=="spso2007" ) {
+  if ( method=="spso2011" ) {
+  
+     # Gi - Xi:
+     ifelse( part.index != localBest.pos,
+             gx <- r1*(c1/3)*(pbest-x) + r2*(c2/3)*(localBest-x),
+             gx <- r1*(c1/2)*(pbest-x)
+           )
+  
+  } else if ( method=="spso2007" ) {
   
-    ifelse(part.index != localBest.pos,  
-           vn <- CF * ( w*v + r1*c1*(pbest-x) + r2*c2*(localBest-x) ),
-           vn <- CF * ( w*v + r1*c1*(pbest-x) ) )
+           ifelse(part.index != localBest.pos,  
+                  vn <- CF * ( w*v + r1*c1*(pbest-x) + r2*c2*(localBest-x) ),
+                  vn <- CF * ( w*v + r1*c1*(pbest-x) ) )
     
-  } else if ( method=="ipso" ) {
+         } else if ( method=="ipso" ) {
   
-        # number of best particles that have to be considered      
-        nngbest <- length(ngbest.fit)
+               # number of best particles that have to be considered      
+               nngbest <- length(ngbest.fit)
   
-        R2 <-  matrix(rep(r2,nngbest), nrow=nngbest, byrow=TRUE)
+               R2 <-  matrix(rep(r2,nngbest), nrow=nngbest, byrow=TRUE)
         
-        # computing the c2 values for each one of the best particles,
-        # weighted according to their fitness value
-        ifelse(MinMax == "min", c2i <- c2 * ( (1/ngbest.fit)/sum(1/ngbest.fit) ), 
-                                c2i <- c2 * ( ngbest.fit/sum(ngbest.fit) )
-              ) 
+               # computing the c2 values for each one of the best particles,
+               # weighted according to their fitness value
+               ifelse(MinMax == "min", c2i <- c2 * ( (1/ngbest.fit)/sum(1/ngbest.fit) ), 
+                                       c2i <- c2 * ( ngbest.fit/sum(ngbest.fit) )
+                     ) 
               
-        # transforming 'x' into a matrix, with the same values in each row, in 
-        # order to be able to substract 'x' from 'ngest'
-        X <- matrix(rep(x, nngbest), ncol=n, byrow=TRUE)
+               # transforming 'x' into a matrix, with the same values in each row, in 
+               # order to be able to substract 'x' from 'ngest'
+               X <- matrix(rep(x, nngbest), ncol=n, byrow=TRUE)
         
-        # computing the velocity
-        vn <- CF * ( w*v + r1*c1*(pbest-x) + colSums(R2*c2i*(ngbest-X) ) )  
+               # computing the velocity
+               vn <- CF * ( w*v + r1*c1*(pbest-x) + colSums(R2*c2i*(ngbest-X) ) )  
            
-     } else if ( method=="fips" ) {
+           } else if ( method=="fips" ) {
               
-              neighs.index <- neighs.index[!is.na(neighs.index)] # only for topology=='random' 
-              N   <- length(neighs.index)              
-              X   <- matrix(rep(x,N), nrow=N, byrow=TRUE)
-              P   <- Pbest[neighs.index, ]
-              phi <- c1 + c2
-              r   <- runif(N, min=0, max=phi)
+                     neighs.index <- neighs.index[!is.na(neighs.index)] # only for topology=='random' 
+                     N   <- length(neighs.index)              
+                     X   <- matrix(rep(x,N), nrow=N, byrow=TRUE)
+                     P   <- Pbest[neighs.index, ]
+                     phi <- c1 + c2
+                     r   <- runif(N, min=0, max=phi)
                  
-              vn  <-  CF * ( w*v + (1/N)*colSums( r*(P-X) ) )
+                     vn  <-  CF * ( w*v + (1/N)*colSums( r*(P-X) ) )
               
                
-            } else if ( method=="wfips" ) {
+                   } else if ( method=="wfips" ) {
             
-                neighs.index <- neighs.index[!is.na(neighs.index)] # only for topology=='random' 
-                N    <- length(neighs.index)              
-                X    <- matrix(rep(x,N), nrow=N, byrow=TRUE)
-                P    <- Pbest[neighs.index, ]
-                pfit <- lpbest.fit[neighs.index]
-                phi  <- c1 + c2
-                r    <- runif(N, min=0, max=phi)
-                ifelse(MinMax == "min", wght <- (1/lpbest.fit)/sum(1/lpbest.fit), 
-                                        wght <- lpbest.fit/sum(lpbest.fit) 
-                      ) 
+                       neighs.index <- neighs.index[!is.na(neighs.index)] # only for topology=='random' 
+                       N    <- length(neighs.index)              
+                       X    <- matrix(rep(x,N), nrow=N, byrow=TRUE)
+                       P    <- Pbest[neighs.index, ]
+                       pfit <- lpbest.fit[neighs.index]
+                       phi  <- c1 + c2
+                       r    <- runif(N, min=0, max=phi)
+                       ifelse(MinMax == "min", wght <- (1/lpbest.fit)/sum(1/lpbest.fit), 
+                                               wght <- lpbest.fit/sum(lpbest.fit) 
+                             ) 
                    
-                vn  <-  CF * ( w*v + (1/N) * colSums( wght*r*(P-X) ) )	  
-              } # ELSE end
+                       vn  <-  CF * ( w*v + (1/N) * colSums( wght*r*(P-X) ) )	  
+                     } # ELSE end
   
   return(vn)
   
@@ -2355,7 +2453,7 @@ hydroPSO <- function(
 				method=method,                                    
 				MinMax=MinMax,                             # topology="ipso" | method="wfips"
 				neighs.index=X.neighbours[j, ],            # method in c("fips", "wfips")
-				localBest=X.best.part[LocalBest.pos[j], ], # topology="lbest"
+				localBest=X.best.part[LocalBest.pos[j], ], # topology=c("random", "lbest")
 				localBest.pos=LocalBest.pos[j],            # topology=c("random", "lbest")
 				ngbest.fit=ngbest.fit,                     # topology="ipso"
 				ngbest=X.best.part[ngbest.pos, ],          # topology="ipso"
-- 
GitLab