From 902c558da996a7624a6a150e227f43f3146975ec Mon Sep 17 00:00:00 2001
From: Mauricio Zambrano-Bigiarini <hzambran@users.noreply.github.com>
Date: Thu, 25 Oct 2012 15:56:22 +0000
Subject: [PATCH] 'hydroPSO' function: argument 'method' now allows
 'canonical'. 'fn' argument now can be function or character

---
 DESCRIPTION     |  4 ++--
 NEWS            | 15 ++++++++++-----
 R/PSO_v2012.R   | 41 ++++++++++++++++++++++++++---------------
 man/hydroPSO.Rd | 30 ++++++++++++++++--------------
 4 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index 5235674..5d69d48 100755
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,8 +1,8 @@
 Package: hydroPSO
 Type: Package
 Title: Model-Independent Particle Swarm Optimisation for Environmental Models
-Version: 0.1-58-13
-Date: 2012-10-22
+Version: 0.1-58-14
+Date: 2012-10-25
 Authors@R: c(person("Mauricio", "Zambrano-Bigiarini", email="mzb.devel@gmail.com", role=c("aut","cre")), person("Rodrigo", "Rojas", email="Rodrigo.RojasMujica@gmail.com", role=c("ctb")) )
 Maintainer: Mauricio Zambrano-Bigiarini <mzb.devel@gmail.com>
 Description: This package implements a state-of-the-art version of the Particle Swarm Optimisation (PSO) algorithm (SPSO-2011 and SPSO-2007 capable), with a special focus on the calibration of environmental models. hydroPSO is model-independent, allowing the user to easily interface any model code with the calibration engine (PSO). It includes a series of controlling options and PSO variants to fine-tune the performance of the calibration engine to different calibration problems. An advanced sensitivity analysis function together with user-friendly plotting summaries facilitate the interpretation and assessment of the calibration results. Bugs reports/comments/questions are very welcomed.
diff --git a/NEWS b/NEWS
index 845223d..a761308 100755
--- a/NEWS
+++ b/NEWS
@@ -8,22 +8,26 @@ NEWS/ChangeLog for hydroPSO
                                * new confinement of the velocity ( V[t+1] = -0.5 * V[t], when x[t+1] > x_max | x[t+1] < x_min )
                                * optional normalisation of parameter values
         
+                            -) 'fn' argument now can be any R function or a character. In the latter case, it can be "hydromod" or the name of name 
+                               valid R function. In previous versions of 'hydroPSO' only a character type was accepted.
                             -) now it handles models with sub-daily time step and with sub-daily observations (thanks to Olda Rakovec !)
                             -) new output file 'BestModel_out.txt', with the model outputs corresponding to the best parameter set. 
                                Only available when 'fn.name=="hydromod"'
                             -) new 'normalise' parameter for the 'control' variable, in order to improve the performance when the search space is not 
                                a hypercube
-                            -) argument 'method' now allows the following 2 new values: 'spso2007' and 'spso2011', which set the values of the PSO 
-                               engine to the ones of the SPSO 2007 and SPSO 2011, respectively. 
+                            -) argument 'method' now allows the following 3 new values: 'spso2007', 'spso2011' and 'canonical', which set the values of the PSO 
+                               engine to the ones of the SPSO 2007, SPSO 2011 and the canonical one, respectively. 
                             -) argument 'method'. The old (default) value 'pso' was replaced by the new (default) value 'spso2011'
-                            -) argument 'Vini.type' now allows the following 2 new values: 'random2011' and 'lhs2011', which set the initial velocity 
-                               values for the particles to random values according to the equation specified in the SPSO 2011, with a uniform 
-                               distribution or with a Latin-hypercube sampling, respectively.
+                            -) argument 'Vini.type' now allows 2 new values for setting the initial velocity of the particles according to the equation 
+                               specified in the SPSO 2011: 'random2011' and 'lhs2011', which use a uniform distribution or with a Latin-hypercube 
+                               sampling, respectively.
                             -) argument 'Vini.type'. The old values 'random' and 'lhs' were replaced by 'random2007' and 'lhs2007', in order to make 
                                clear that it follows the equation described in SPSO 2007.
                             -) argument 'Vini.type', when missing its value depends on the value of the 'method' argument:
                                method == 'spso2007' => Vini.type='random2007' 
                                method != 'spso2007' => Vini.type='random2011'
+                            -) argument 'Xini.type', now its default value is 'random' instead of 'lhs', in order to make it compatible with the default
+                               value for 'method' (method='spso2011')
                             -) argument 'npart', when missing its value depends on the value of the 'method' argument:
                                method == 'spso2007' => npart=10+2*[sqrt(n)] 
                                method != 'spso2007' => npart=40
@@ -53,6 +57,7 @@ NEWS/ChangeLog for hydroPSO
                                following changes in default values:
                                               ver <= 0.1-58   ->    ver >= 0.1-59
                             -) npart        : 10+2*[sqrt(n)]  ->   40
+                            -) Xini.type    : 'lhs'           ->  'random'
                             -) Vini.type    : 'lhs2007'       ->  'random2011'
                             -) boundary.wall: 'reflecting'    ->  'absorbing2011'
                             
diff --git a/R/PSO_v2012.R b/R/PSO_v2012.R
index 34f810a..0bbcc59 100755
--- a/R/PSO_v2012.R
+++ b/R/PSO_v2012.R
@@ -190,7 +190,7 @@ alea.sphere <- function(G, radius) {
 
 compute.CF <- function(c1, c2) {
     psi <- c1 + c2  # psi >= 4
-    CF <- 2 / abs( 2 - psi - sqrt(psi^2 - 4*psi) )
+    return( 2 / abs( 2 - psi - sqrt(psi^2 - 4*psi) ) )
 } # 'compute.CF' end
 
 
@@ -1291,7 +1291,7 @@ hydromod.eval <- function(part, Particles, iter, npart, maxit,
 #          15-Jan-2012 ; 23-Jan-2012 ; 30-Jan-2012 ; 23-Feb-2012 ; 23-Mar-2012 #
 #          14-Jun-2012 ; 15-Jun-2012 ; 03-Jul-2012 ; 06-Jul-2012               #
 #          11-Jul-2012 ; 17-Jul-2012 ; 18-Jul-2012 ; 13-Sep-2012; 14-Sep-2012  #
-#          17-Sep-2012 ; 23-Sep-2012 ; 15-Oct-2012                             #                          
+#          17-Sep-2012 ; 23-Sep-2012 ; 15-Oct-2012 ; 25-Oct-2012               #                          
 ################################################################################
 # 'lower'           : minimum possible value for each parameter
 # 'upper'           : maximum possible value for each parameter
@@ -1514,7 +1514,7 @@ hydroPSO <- function(
                     par, 
                     fn="hydromod",  
                     ...,
-                    method=c("spso2011", "spso2007", "ipso", "fips", "wfips"),
+                    method=c("spso2011", "spso2007", "ipso", "fips", "wfips", "canonical"),
                     lower=-Inf,
                     upper=Inf,                
                     control=list(),
@@ -1536,15 +1536,21 @@ hydroPSO <- function(
 
     if (missing(fn)) {
       stop("Missing argument: 'fn' must be provided")
-    } else {
-	fn.name <- fn
-	fn      <- match.fun(fn)
-      } # ELSE end 
+    } else 
+        if ( is.character(fn) | is.function(fn) )  {
+          if (is.character(fn)) {
+            fn.name <- fn
+	    fn      <- match.fun(fn)
+	  } else if (is.function(fn)) {
+	      fn.name <- as.character(expression(fn))
+	      fn      <- fn
+	    } # ELSE end
+        } else stop("Missing argument: 'class(fn)' must be in c('function', 'character')")
 
     method <- match.arg(method)       
 
     if (length(lower) != length(upper) )
-      stop( paste( "Invalid argument: 'length(lower) != length(upper) (", length(lower), "!=", length(upper), ")'", sep="" ) )
+      stop( "Invalid argument: 'length(lower) != length(upper) (", length(lower), "!=", length(upper), ")'" )
 
     if (!is.null(n)) {
        if (length(lower) != n)
@@ -1573,7 +1579,7 @@ hydroPSO <- function(
 
 	    abstol= NULL,    
 	    reltol=sqrt(.Machine$double.eps),             
-	    Xini.type=c("lhs", "random"),  
+	    Xini.type=c("random", "lhs"),  
 	    Vini.type=c(NA, "random2011", "lhs2011", "random2007", "lhs2007",  "zero"), 
 	    best.update=c("sync", "async"),
 	    random.update=TRUE,
@@ -1607,7 +1613,8 @@ hydroPSO <- function(
     best.update   <- match.arg(control[["best.update"]], con[["best.update"]]) 
     boundary.wall <- match.arg(control[["boundary.wall"]], con[["boundary.wall"]]) 
     boundary.wall <- ifelse(is.na(boundary.wall), 
-                            ifelse(method=="spso2007", "absorbing2007", "absorbing2011"),
+                            ifelse(method %in% c("spso2007", "canonical"), 
+                                   "absorbing2007", "absorbing2011"),
                             boundary.wall)
     topology      <- match.arg(control[["topology"]], con[["topology"]]) 
     IW.type       <- match.arg(control[["IW.type"]], con[["IW.type"]])
@@ -1634,12 +1641,16 @@ hydroPSO <- function(
                                 con[["npart"]] )                                 
     maxit             <- con[["maxit"]] 
     maxfn             <- con[["maxfn"]] 
-    c1                <- con[["c1"]] 
-    c2                <- con[["c2"]] 
-    use.IW            <- as.logical(con[["use.IW"]])
+    #c1                <- con[["c1"]] 
+    c1                <- ifelse(method!="canonical", con[["c1"]], 2.05)
+    #c2                <- con[["c2"]] 
+    c2                <- ifelse(method!="canonical", con[["c2"]], 2.05)
+    #use.IW            <- as.logical(con[["use.IW"]])
+    use.IW            <- ifelse(method!="canonical", as.logical(con[["use.IW"]]), FALSE)
     IW.w              <- con[["IW.w"]]
     IW.exp            <- con[["IW.exp"]]
-    use.CF            <- con[["use.CF"]] 
+    #use.CF            <- con[["use.CF"]] 
+    use.CF            <- ifelse(method!="canonical", as.logical(con[["use.CF"]]), TRUE)
     lambda            <- con[["lambda"]]  
     abstol            <- con[["abstol"]]     
     reltol            <- con[["reltol"]]             
@@ -1735,7 +1746,7 @@ hydroPSO <- function(
 	} # ELSE end
 
       if ( length(model.FUN.args)==0 ) {
-	warning( "[ 'model.FUN.args' is an empty list. Are you sure your model does not have any argument(s) ? ]" )
+	warning( "['model.FUN.args' is an empty list. Are you sure your model does not have any argument(s) ?]" )
       } else {
 	  model.FUN.argsDefaults <- formals(model.FUN)
 	  model.FUN.args         <- modifyList(model.FUN.argsDefaults, model.FUN.args) 
diff --git a/man/hydroPSO.Rd b/man/hydroPSO.Rd
index 90b6fc7..b75ea6e 100755
--- a/man/hydroPSO.Rd
+++ b/man/hydroPSO.Rd
@@ -14,7 +14,8 @@ Enhanced Particle Swarm Optimisation algorithm
 Particle Swarm Optimisation algorithm to calibrate environmental models. It implements a state-of-the-art Particle Swarm Optimisation (PSO) algorithm (SPSO-2011 and SPSO-2007 capable), with several fine-tuning options and PSO variants available to customise the PSO engine to different calibration problems.
 }
 \usage{
-hydroPSO(par, fn= "hydromod", ..., method=c("spso2011", "spso2007", "ipso", "fips", "wfips"),
+hydroPSO(par, fn= "hydromod", ..., 
+         method=c("spso2011", "spso2007", "ipso", "fips", "wfips", "canonical"),
          lower=-Inf, upper=Inf, control=list(), 
          model.FUN=NULL, model.FUN.args=list() )
 }
@@ -34,16 +35,15 @@ OPTIONAL. Only used when \code{fn!='hydromod'}. \cr
 further arguments to be passed to \code{fn}.
 }
   \item{method}{
-character, variant of the PSO algorithm to be used. Valid values are in \code{c('spso2011', 'spso2007', 'ipso', 'fips', 'wfips')}: \cr
-f
+character, variant of the PSO algorithm to be used. By default \code{method='spso2011'}, while valid values are in \code{c('spso2011', 'spso2007', 'ipso', 'fips', 'wfips', 'canonical')}: \cr
+
 \kbd{spso2011}: At each iteration particles are attracted to its own best-known \sQuote{personal} and to the best-known position in its \sQuote{local} neighbourhood, which depens on the value of \code{topology}. In addition, values of the PSO engine are set to the values defined in the Standard PSO 2011 (SPSO 2011, see Clerc 2012) \cr
 \kbd{spso2007}: As in \code{method='spso2011'}, but with values of the PSO engine set to the values defined in the Standard PSO 2007 (SPSO 2007, see Clerc 2012)
 \kbd{ipso}: at each iteration particles in the swarm are rearranged in descending order according to their goodness-of-fit and the best \code{ngbest} particles are used to modify particles' position and velocity (see Zhao, 2006). Each particle is connected to a neighbourhood of particles depending on the \code{topology} value \cr
 \kbd{fips}: at each iteration ALL particles contribute to modify the particles' position and velocity (see Mendes et al., 2004). Each particle is connected to a neighbourhood of particles depending on the \code{topology} value \cr
 \kbd{wfips}: same implementation as \kbd{fips} method, but the contribution of each particle is weighted according to their goodness-of-fit value (see Mendes et al., 2004) \cr
-By default \code{method=pso}
-
-
+\kbd{canonical}: It corresponds to the first formulation of the PSO algorithm, and it is included here for educational and comparative purposes only, due to several limitations described in literature. See Kennedy 2006 \cr
+At each iteration particles are attracted to its own best-known \sQuote{personal} and to the best-known position in all the swarm (\sQuote{global}). The following \code{control} arguments are set when this methos is selected: (i) \code{topology='gbest'}, (ii) \code{Xini.type='random'}, (iii) \code{Vini.type='random2007'}, (iv) \code{use.CF=TRUE}, (v) \code{c1=2.05}, (vi) \code{c2=2.05}, (vii) \code{boundary.wall='absorbing2007'}, (viii) \code{lambda=1.0}
 }
   \item{lower}{
 numeric, lower boundary for each parameter \cr
@@ -351,14 +351,6 @@ integer code where \code{0} indicates that the algorithm terminated by reaching
 }
 }
 \references{
-\cite{Kennedy, J. and R. Eberhart. Particle Swarm Optimization. in proceedings IEEE international conference on Neural networks. pages 1942-1948. 1995. doi: 10.1109/ICNN.1995.488968}
-        
-\cite{Kennedy, J.; Mendes, R.. Population structure and particle swarm performance. Evolutionary Computation, 2002. CEC '02. Proceedings of the 2002 Congress on , vol.2, no., pp.1671-1676, 2002. doi: 10.1109/CEC.2002.1004493}
-
-\cite{Kennedy, J.; Mendes, R.; , Neighborhood topologies in fully-informed and best-of-neighborhood particle swarms. Soft Computing in Industrial Applications, 2003. SMCia/03. Proceedings of the 2003 IEEE International Workshop on , vol., no., pp. 45- 50, 23-25 June 2003. doi: 10.1109/SMCIA.2003.1231342}
-
-\cite{Kennedy, J.; Small worlds and mega-minds: effects of neighborhood topology on particle swarm performance. Evolutionary Computation, 1999. CEC 99. Proceedings of the 1999 Congress on , vol.3, no., pp.3 vol. (xxxvii+2348), 1999. doi: 10.1109/CEC.1999.785509}
-     
 \cite{Clerc, M. Standard Particle Swarm. 2012. (SPSO-2007, SPSO-2011). \url{clerc.maurice.free.fr/pso/SPSO_descriptions.pdf}. Last visited [24-Sep-2012]}
 
 \cite{Clerc, M. From Theory to Practice in Particle Swarm Optimization, Handbook of Swarm Intelligence, Springer Berlin Heidelberg, 3-36, Eds: Panigrahi, Bijaya Ketan, Shi, Yuhui, Lim, Meng-Hiot, Hiot, Lim Meng, and Ong, Yew Soon, 2010, doi: 10.1007/978-3-642-17390-5_1}
@@ -377,6 +369,16 @@ integer code where \code{0} indicates that the algorithm terminated by reaching
 
 \cite{Huang, T.; Mohan, A.S.; , A hybrid boundary condition for robust particle swarm optimization. Antennas and Wireless Propagation Letters, IEEE , vol.4, no., pp. 112-117, 2005. doi: 10.1109/LAWP.2005.846166}
 
+\cite{Kennedy, J. and R. Eberhart. Particle Swarm Optimization. in proceedings IEEE international conference on Neural networks. pages 1942-1948. 1995. doi: 10.1109/ICNN.1995.488968}
+        
+\cite{Kennedy, J.; Small worlds and mega-minds: effects of neighborhood topology on particle swarm performance. Evolutionary Computation, 1999. CEC 99. Proceedings of the 1999 Congress on , vol.3, no., pp.3 vol. (xxxvii+2348), 1999. doi: 10.1109/CEC.1999.785509}
+
+\cite{Kennedy, J.; Mendes, R.. Population structure and particle swarm performance. Evolutionary Computation, 2002. CEC '02. Proceedings of the 2002 Congress on , vol.2, no., pp.1671-1676, 2002. doi: 10.1109/CEC.2002.1004493}
+
+\cite{Kennedy, J.; Mendes, R.; , Neighborhood topologies in fully-informed and best-of-neighborhood particle swarms. Soft Computing in Industrial Applications, 2003. SMCia/03. Proceedings of the 2003 IEEE International Workshop on , vol., no., pp. 45- 50, 23-25 June 2003. doi: 10.1109/SMCIA.2003.1231342}
+
+\cite{Kennedy, J. 2006. Swarm intelligence, in Handbook of Nature-Inspired and Innovative Computing, edited by A. Zomaya, pp. 187-219, Springer US, DOI:10.1007/0-387-27705-6_6}
+
 \cite{Liu, B. and L. Wang, Y.-H. Jin, F. Tang, and D.-X. Huang. Improved particle swarm optimization combined with chaos. Chaos, Solitons \& Fractals, vol. 25, no. 5, pp.1261-1271, Sep. 2005. doi:10.1016/j.chaos.2004.11.095}
 
 \cite{Mendes, R.; Kennedy, J.; Neves, J. The fully informed particle swarm: simpler, maybe better. Evolutionary Computation, IEEE Transactions on , vol.8, no.3, pp. 204-210, June 2004. doi: 10.1109/TEVC.2004.826074}
-- 
GitLab