# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
__doc__ = """
- Standard Particle Swarm Optimization
+ Canonical Particle Swarm Optimization
"""
__author__ = "Jean-Philippe ARGAUD"
import numpy, logging, copy
-from daCore.NumericObjects import ApplyBounds, ForceNumericBounds
+from daCore.NumericObjects import ApplyBounds, VariablesAndIncrementsBounds
from numpy.random import uniform as rand
# ==============================================================================
def ecwnpso(selfA, Xb, Y, HO, R, B):
- #
- if ("BoxBounds" in selfA._parameters) and isinstance(selfA._parameters["BoxBounds"], (list, tuple)) and (len(selfA._parameters["BoxBounds"]) > 0):
- BoxBounds = selfA._parameters["BoxBounds"]
- logging.debug("%s Prise en compte des bornes d'incréments de paramètres effectuée"%(selfA._name,))
- else:
- raise ValueError("Particle Swarm Optimization requires bounds on all variables increments to be truly given (BoxBounds).")
- BoxBounds = numpy.array(BoxBounds)
- if numpy.isnan(BoxBounds).any():
- raise ValueError("Particle Swarm Optimization requires bounds on all variables increments to be truly given (BoxBounds), \"None\" is not allowed. The actual increments bounds are:\n%s"%BoxBounds)
- #
- selfA._parameters["Bounds"] = ForceNumericBounds( selfA._parameters["Bounds"] )
#
Hm = HO["Direct"].appliedTo
#
#
Xini = selfA._parameters["InitializationPoint"]
#
+ Bounds, BoxBounds = VariablesAndIncrementsBounds(
+ selfA._parameters["Bounds"],
+ selfA._parameters["BoxBounds"],
+ Xini,
+ selfA._name,
+ )
+ #
def CostFunction(x, QualityMeasure="AugmentedWeightedLeastSquares"):
_X = numpy.asarray( x ).reshape((-1,1))
_HX = numpy.asarray( Hm( _X ) ).reshape((-1,1))
#
# Initialisation de l'essaim
# --------------------------
- LimitStep = Xini.reshape((-1,1)) + BoxBounds
- __dx = __vc * numpy.abs(BoxBounds[:,1]-BoxBounds[:,0])
- LimitSpeed = numpy.vstack((-__dx,__dx)).T
+ LimitPlace = Bounds
+ LimitSpeed = 0.5 * BoxBounds # "1/2*([Xmin,Xmax]-Xini)"
#
NumberOfFunctionEvaluations = 1
JXini, JbXini, JoXini = CostFunction(Xini,selfA._parameters["QualityCriterion"])
#
Swarm = numpy.zeros((__nbI,3,__nbP)) # 3 car (x,v,xbest)
for __p in range(__nbP) :
- Swarm[:,0,__p] = rand( low=LimitStep[__p,0], high=LimitStep[__p,1], size=__nbI) # Position
+ Swarm[:,0,__p] = rand( low=LimitPlace[__p,0], high=LimitPlace[__p,1], size=__nbI) # Position
Swarm[:,1,__p] = rand( low=LimitSpeed[__p,0], high=LimitSpeed[__p,1], size=__nbI) # Velocity
logging.debug("%s Initialisation of the swarm with %i insects of size %i "%(selfA._name,Swarm.shape[0],Swarm.shape[2]))
#
Swarm[__i,1,:] = ApplyBounds( __velins, LimitSpeed )
# Position
__velins = Swarm[__i,0,:] + Swarm[__i,1,:]
- Swarm[__i,0,:] = ApplyBounds( __velins, selfA._parameters["Bounds"] )
+ Swarm[__i,0,:] = ApplyBounds( __velins, LimitPlace )
#
NumberOfFunctionEvaluations += 1
JTest, JbTest, JoTest = CostFunction(Swarm[__i,0,:],selfA._parameters["QualityCriterion"])
__author__ = "Jean-Philippe ARGAUD"
import numpy, logging, copy
+from daCore.NumericObjects import VariablesAndIncrementsBounds
from numpy.random import uniform as rand
# ==============================================================================
def ecwopso(selfA, Xb, Y, HO, R, B):
#
- if ("BoxBounds" in selfA._parameters) and isinstance(selfA._parameters["BoxBounds"], (list, tuple)) and (len(selfA._parameters["BoxBounds"]) > 0):
- BoxBounds = selfA._parameters["BoxBounds"]
- logging.debug("%s Prise en compte des bornes d'incréments de paramètres effectuée"%(selfA._name,))
- else:
- raise ValueError("Particle Swarm Optimization requires bounds on all variables increments to be truly given (BoxBounds).")
- BoxBounds = numpy.array(BoxBounds)
- if numpy.isnan(BoxBounds).any():
- raise ValueError("Particle Swarm Optimization requires bounds on all variables increments to be truly given (BoxBounds), \"None\" is not allowed. The actual increments bounds are:\n%s"%BoxBounds)
- #
Hm = HO["Direct"].appliedTo
#
BI = B.getI()
#
Xini = selfA._parameters["InitializationPoint"]
#
+ Bounds, BoxBounds = VariablesAndIncrementsBounds(
+ selfA._parameters["Bounds"],
+ selfA._parameters["BoxBounds"],
+ Xini,
+ selfA._name,
+ )
+ #
def CostFunction(x, QualityMeasure="AugmentedWeightedLeastSquares"):
_X = numpy.asarray( x ).reshape((-1,1))
_HX = numpy.asarray( Hm( _X ) ).reshape((-1,1))
#
# Initialisation de l'essaim
# --------------------------
- LimitStep = Xini.reshape((-1,1)) + BoxBounds
- __dx = __vc * numpy.abs(BoxBounds[:,1]-BoxBounds[:,0])
- LimitSpeed = numpy.vstack((-__dx,__dx)).T
+ LimitPlace = Bounds
+ LimitSpeed = 0.5 * BoxBounds # "1/2*([Xmin,Xmax]-Xini)"
#
NumberOfFunctionEvaluations = 1
JXini, JbXini, JoXini = CostFunction(Xini,selfA._parameters["QualityCriterion"])
#
Swarm = numpy.zeros((__nbI,3,__nbP)) # 3 car (x,v,xbest)
for __p in range(__nbP) :
- Swarm[:,0,__p] = rand( low=LimitStep[__p,0], high=LimitStep[__p,1], size=__nbI) # Position
+ Swarm[:,0,__p] = rand( low=LimitPlace[__p,0], high=LimitPlace[__p,1], size=__nbI) # Position
Swarm[:,1,__p] = rand( low=LimitSpeed[__p,0], high=LimitSpeed[__p,1], size=__nbI) # Velocity
logging.debug("%s Initialisation of the swarm with %i insects of size %i "%(selfA._name,Swarm.shape[0],Swarm.shape[2]))
#
__Dict.pop('Algorithm','')
__Dict.pop('Parameters','')
if 'SetSeed' in __Dict:__Dict['SetSeed'] = int(__Dict['SetSeed'])
+ if 'Bounds' in __Dict and type(__Dict['Bounds']) is str:
+ __Dict['Bounds'] = eval(__Dict['Bounds'])
if 'BoxBounds' in __Dict and type(__Dict['BoxBounds']) is str:
__Dict['BoxBounds'] = eval(__Dict['BoxBounds'])
if len(__Dict) > 0:
#
return __Vector
+# ==============================================================================
+def VariablesAndIncrementsBounds( __Bounds, __BoxBounds, __Xini, __Name, __Multiplier = 1. ):
+ __Bounds = ForceNumericBounds( __Bounds )
+ __BoxBounds = ForceNumericBounds( __BoxBounds )
+ if __Bounds is None and __BoxBounds is None:
+ raise ValueError("Algorithm %s requires bounds on all variables (by Bounds), or on all variables increments (by BoxBounds), or both, to be explicitly given."%(__Name,))
+ elif __Bounds is None and __BoxBounds is not None:
+ __Bounds = __BoxBounds
+ logging.debug("%s Définition des bornes de paramètres à partir des bornes d'incréments courantes"%(__Name,))
+ elif __Bounds is not None and __BoxBounds is None:
+ __BoxBounds = __Multiplier * (__Bounds - __Xini.reshape((-1,1))) # "M * [Xmin,Xmax]-Xini"
+ logging.debug("%s Définition des bornes d'incréments de paramètres à partir des bornes courantes"%(__Name,))
+ return __Bounds, __BoxBounds
+
# ==============================================================================
def Apply3DVarRecentringOnEnsemble( __EnXn, __EnXf, __Ynpu, __HO, __R, __B, __SuppPars ):
"Recentre l'ensemble Xn autour de l'analyse 3DVAR"