Concept = None, # Premier argument
Algorithm = None,
AppliedInXb = None,
- AvoidRC = True,
Checked = False,
ColMajor = False,
ColNames = None,
ObjectMatrix = None,
OneFunction = None,
Parameters = None,
+ PerformanceProfile = None,
ScalarSparseMatrix = None,
Scheduler = None,
Script = None,
self.setObservationOperator(
Matrix, OneFunction, ThreeFunctions, AppliedInXb,
Parameters, Script, ExtraArguments,
- Stored, AvoidRC, InputFunctionAsMulti, Checked )
+ Stored, PerformanceProfile, InputFunctionAsMulti, Checked )
elif Concept in ("EvolutionModel", "ControlModel"):
commande = getattr(self,"set"+Concept)
commande(
Matrix, OneFunction, ThreeFunctions,
Parameters, Script, Scheduler, ExtraArguments,
- Stored, AvoidRC, InputFunctionAsMulti, Checked )
+ Stored, PerformanceProfile, InputFunctionAsMulti, Checked )
else:
raise ValueError("the variable named '%s' is not allowed."%str(Concept))
except Exception as e:
Script = None,
ExtraArguments = None,
Stored = False,
- AvoidRC = True,
+ PerformanceProfile = None,
InputFunctionAsMulti = False,
Checked = False):
"Definition d'un concept de calcul"
asDict = Parameters,
appliedInX = AppliedInXb,
extraArguments = ExtraArguments,
- avoidRC = AvoidRC,
+ performancePrf = PerformanceProfile,
inputAsMF = InputFunctionAsMulti,
scheduledBy = None,
toBeChecked = Checked,
Scheduler = None,
ExtraArguments = None,
Stored = False,
- AvoidRC = True,
+ PerformanceProfile = None,
InputFunctionAsMulti = False,
Checked = False):
"Definition d'un concept de calcul"
asDict = Parameters,
appliedInX = None,
extraArguments = ExtraArguments,
- avoidRC = AvoidRC,
+ performancePrf = PerformanceProfile,
inputAsMF = InputFunctionAsMulti,
scheduledBy = Scheduler,
toBeChecked = Checked,
Scheduler = None,
ExtraArguments = None,
Stored = False,
- AvoidRC = True,
+ PerformanceProfile = None,
InputFunctionAsMulti = False,
Checked = False):
"Definition d'un concept de calcul"
asDict = Parameters,
appliedInX = None,
extraArguments = ExtraArguments,
- avoidRC = AvoidRC,
+ performancePrf = PerformanceProfile,
inputAsMF = InputFunctionAsMulti,
scheduledBy = Scheduler,
toBeChecked = Checked,
fromMethod = None,
fromMatrix = None,
avoidingRedundancy = True,
+ reducingMemoryUse = False,
inputAsMultiFunction = False,
enableMultiProcess = False,
extraArguments = None,
- fromMethod : argument de type fonction Python
- fromMatrix : argument adapté au constructeur numpy.matrix
- avoidingRedundancy : booléen évitant (ou pas) les calculs redondants
+ - reducingMemoryUse : booléen forçant (ou pas) des calculs moins
+ gourmands en mémoire
- inputAsMultiFunction : booléen indiquant une fonction explicitement
définie (ou pas) en multi-fonction
- extraArguments : arguments supplémentaires passés à la fonction de
"""
self.__name = str(name)
self.__NbCallsAsMatrix, self.__NbCallsAsMethod, self.__NbCallsOfCached = 0, 0, 0
- self.__AvoidRC = bool( avoidingRedundancy )
+ self.__reduceM = bool( reducingMemoryUse )
+ self.__avoidRC = bool( avoidingRedundancy )
self.__inputAsMF = bool( inputAsMultiFunction )
self.__mpEnabled = bool( enableMultiProcess )
self.__extraArgs = extraArguments
def enableAvoidingRedundancy(self):
"Active le cache"
- if self.__AvoidRC:
+ if self.__avoidRC:
Operator.CM.enable()
else:
Operator.CM.disable()
_HxValue = []
for i in range(len(_HValue)):
_HxValue.append( numpy.asmatrix( numpy.ravel( _HValue[i] ) ).T )
- if self.__AvoidRC:
+ if self.__avoidRC:
Operator.CM.storeValueInX(_xValue[i],_HxValue[-1],self.__name)
else:
_HxValue = []
_xserie = []
_hindex = []
for i, xv in enumerate(_xValue):
- if self.__AvoidRC:
+ if self.__avoidRC:
__alreadyCalculated, __HxV = Operator.CM.wasCalculatedIn(xv,self.__name)
else:
__alreadyCalculated = False
_xv = _xserie.pop(0)
_hv = _hserie.pop(0)
_HxValue[i] = _hv
- if self.__AvoidRC:
+ if self.__avoidRC:
Operator.CM.storeValueInX(_xv,_hv,self.__name)
#
if returnSerieAsArrayMatrix:
asDict = None, # Parameters
appliedInX = None,
extraArguments = None,
- avoidRC = True,
+ performancePrf = None,
inputAsMF = False,# Fonction(s) as Multi-Functions
scheduledBy = None,
toBeChecked = False,
__Parameters["EnableMultiProcessingInEvaluation"] = False
if "withIncrement" in __Parameters: # Temporaire
__Parameters["DifferentialIncrement"] = __Parameters["withIncrement"]
+ # Le défaut est équivalent à "ReducedOverallRequirements"
+ __reduceM, __avoidRC = True, True
+ if performancePrf is not None:
+ if performancePrf == "ReducedAmountOfCalculation":
+ __reduceM, __avoidRC = False, True
+ elif performancePrf == "ReducedMemoryFootprint":
+ __reduceM, __avoidRC = True, False
+ elif performancePrf == "NoSavings":
+ __reduceM, __avoidRC = False, False
#
if asScript is not None:
__Matrix, __Function = None, None
if "CenteredFiniteDifference" not in __Function: __Function["CenteredFiniteDifference"] = False
if "DifferentialIncrement" not in __Function: __Function["DifferentialIncrement"] = 0.01
if "withdX" not in __Function: __Function["withdX"] = None
- if "withAvoidingRedundancy" not in __Function: __Function["withAvoidingRedundancy"] = avoidRC
+ if "withReducingMemoryUse" not in __Function: __Function["withReducingMemoryUse"] = __reduceM
+ if "withAvoidingRedundancy" not in __Function: __Function["withAvoidingRedundancy"] = __avoidRC
if "withToleranceInRedundancy" not in __Function: __Function["withToleranceInRedundancy"] = 1.e-18
if "withLenghtOfRedundancy" not in __Function: __Function["withLenghtOfRedundancy"] = -1
if "NumberOfProcesses" not in __Function: __Function["NumberOfProcesses"] = None
increment = __Function["DifferentialIncrement"],
dX = __Function["withdX"],
extraArguments = self.__extraArgs,
+ reducingMemoryUse = __Function["withReducingMemoryUse"],
avoidingRedundancy = __Function["withAvoidingRedundancy"],
toleranceInRedundancy = __Function["withToleranceInRedundancy"],
lenghtOfRedundancy = __Function["withLenghtOfRedundancy"],
mpWorkers = __Function["NumberOfProcesses"],
mfEnabled = __Function["withmfEnabled"],
)
- self.__FO["Direct"] = Operator( name = self.__name, fromMethod = FDA.DirectOperator, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
- self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMethod = FDA.TangentOperator, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
- self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMethod = FDA.AdjointOperator, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
+ self.__FO["Direct"] = Operator( name = self.__name, fromMethod = FDA.DirectOperator, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
+ self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMethod = FDA.TangentOperator, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
+ self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMethod = FDA.AdjointOperator, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
elif isinstance(__Function, dict) and \
("Direct" in __Function) and ("Tangent" in __Function) and ("Adjoint" in __Function) and \
(__Function["Direct"] is not None) and (__Function["Tangent"] is not None) and (__Function["Adjoint"] is not None):
- self.__FO["Direct"] = Operator( name = self.__name, fromMethod = __Function["Direct"], avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
- self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMethod = __Function["Tangent"], avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
- self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMethod = __Function["Adjoint"], avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
+ self.__FO["Direct"] = Operator( name = self.__name, fromMethod = __Function["Direct"], reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
+ self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMethod = __Function["Tangent"], reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
+ self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMethod = __Function["Adjoint"], reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, extraArguments = self.__extraArgs )
elif asMatrix is not None:
__matrice = numpy.matrix( __Matrix, numpy.float )
- self.__FO["Direct"] = Operator( name = self.__name, fromMatrix = __matrice, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
- self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMatrix = __matrice, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF )
- self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMatrix = __matrice.T, avoidingRedundancy = avoidRC, inputAsMultiFunction = inputAsMF )
+ self.__FO["Direct"] = Operator( name = self.__name, fromMatrix = __matrice, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF, enableMultiProcess = __Parameters["EnableMultiProcessingInEvaluation"] )
+ self.__FO["Tangent"] = Operator( name = self.__name+"Tangent", fromMatrix = __matrice, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF )
+ self.__FO["Adjoint"] = Operator( name = self.__name+"Adjoint", fromMatrix = __matrice.T, reducingMemoryUse = __reduceM, avoidingRedundancy = __avoidRC, inputAsMultiFunction = inputAsMF )
del __matrice
else:
raise ValueError("The %s object is improperly defined or undefined, it requires at minima either a matrix, a Direct operator for approximate derivatives or a Tangent/Adjoint operators pair. Please check your operator input."%self.__name)
self._parameters[k] = self.setParameterValue(k)
else:
pass
- logging.debug("%s %s : %s", self._name, self.__required_parameters[k]["message"], self._parameters[k])
+ if hasattr(self._parameters[k],"__len__") and len(self._parameters[k]) > 100:
+ logging.debug("%s %s de longueur %s", self._name, self.__required_parameters[k]["message"], len(self._parameters[k]))
+ else:
+ logging.debug("%s %s : %s", self._name, self.__required_parameters[k]["message"], self._parameters[k])
def _setInternalState(self, key=None, value=None, fromDico={}, reset=False):
"""
if k == "ColMajor" and not __v: continue
if k == "InputFunctionAsMulti" and not __v: continue
if k == "nextStep" and not __v: continue
- if k == "AvoidRC" and __v: continue
+ if k == "PerformanceProfile" and __v: continue
if k == "noDetails": continue
if isinstance(__v,Persistence.Persistence): __v = __v.values()
if callable(__v): __text = self._missing%__v.__name__+__text
elif __k in ('Stored', 'Checked', 'ColMajor', 'InputFunctionAsMulti', 'nextStep'):
if bool(__v):
__text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
- elif __k in ('AvoidRC', 'noDetails'):
+ elif __k in ('PerformanceProfile', 'noDetails'):
if not bool(__v):
__text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
else:
if k == "ColMajor" and not __v: continue
if k == "InputFunctionAsMulti" and not __v: continue
if k == "nextStep" and not __v: continue
- if k == "AvoidRC" and __v: continue
+ if k == "PerformanceProfile" and __v: continue
if k == "noDetails": continue
if k == "Concept": continue
if k == "self": continue
increment = 0.01,
dX = None,
extraArguments = None,
+ reducingMemoryUse = False,
avoidingRedundancy = True,
toleranceInRedundancy = 1.e-18,
lenghtOfRedundancy = -1,
):
self.__name = str(name)
self.__extraArgs = extraArguments
+ #
if mpEnabled:
try:
import multiprocessing
self.__mpWorkers = None
logging.debug("FDA Calculs en multiprocessing : %s (nombre de processus : %s)"%(self.__mpEnabled,self.__mpWorkers))
#
- if mfEnabled:
- self.__mfEnabled = True
- else:
- self.__mfEnabled = False
+ self.__mfEnabled = bool(mfEnabled)
logging.debug("FDA Calculs en multifonctions : %s"%(self.__mfEnabled,))
#
+ self.__rmEnabled = bool(reducingMemoryUse)
+ logging.debug("FDA Calculs avec réduction mémoire : %s"%(self.__rmEnabled,))
+ #
if avoidingRedundancy:
self.__avoidRC = True
self.__tolerBP = float(toleranceInRedundancy)
self.__listJPIN = [] # Jacobian Previous Calculated Increment Norms
else:
self.__avoidRC = False
+ logging.debug("FDA Calculs avec réduction des doublons : %s"%self.__avoidRC)
+ if self.__avoidRC:
+ logging.debug("FDA Tolérance de détermination des doublons : %.2e"%self.__tolerBP)
#
if self.__mpEnabled:
if isinstance(Function,types.FunctionType):
self.__dX = None
else:
self.__dX = numpy.ravel( dX )
- logging.debug("FDA Reduction des doublons de calcul : %s"%self.__avoidRC)
- if self.__avoidRC:
- logging.debug("FDA Tolerance de determination des doublons : %.2e"%self.__tolerBP)
# ---------------------------------------------------------
def __doublon__(self, e, l, n, v=None):
break
return __ac, __iac
+ # ---------------------------------------------------------
+ def __listdotwith__(self, __LMatrix, __dotWith = None, __dotTWith = None):
+ "Produit incrémental d'une matrice liste de colonnes avec un vecteur"
+ if not isinstance(__LMatrix, (list,tuple)):
+ raise TypeError("Columnwise list matrix has not the proper type: %s"%type(__LMatrix))
+ if __dotWith is not None:
+ __Idwx = numpy.ravel( __dotWith )
+ assert len(__LMatrix) == __Idwx.size, "Incorrect size of elements"
+ __Produit = numpy.zeros(__LMatrix[0].size)
+ for i, col in enumerate(__LMatrix):
+ __Produit += float(__Idwx[i]) * col
+ return __Produit
+ elif __dotTWith is not None:
+ _Idwy = numpy.ravel( __dotTWith ).T
+ assert __LMatrix[0].size == _Idwy.size, "Incorrect size of elements"
+ __Produit = numpy.zeros(len(__LMatrix))
+ for i, col in enumerate(__LMatrix):
+ __Produit[i] = float( _Idwy @ col)
+ return __Produit
+ else:
+ __Produit = None
+ return __Produit
+
# ---------------------------------------------------------
def DirectOperator(self, X, **extraArgs ):
"""
return _HX
# ---------------------------------------------------------
- def TangentMatrix(self, X ):
+ def TangentMatrix(self, X, dotWith = None, dotTWith = None ):
"""
Calcul de l'opérateur tangent comme la Jacobienne par différences finies,
c'est-à-dire le gradient de H en X. On utilise des différences finies
if __alreadyCalculated:
logging.debug("FDA Calcul Jacobienne (par récupération du doublon %i)"%__i)
_Jacobienne = self.__listJPCR[__i]
+ logging.debug("FDA Fin du calcul de la Jacobienne")
+ if dotWith is not None:
+ return numpy.dot(_Jacobienne, numpy.ravel( dotWith ))
+ elif dotTWith is not None:
+ return numpy.dot(_Jacobienne.T, numpy.ravel( dotTWith ))
else:
logging.debug("FDA Calcul Jacobienne (explicite)")
if self.__centeredDF:
_HX_plus_dXi = self.DirectOperator( _X_plus_dXi )
#
_Jacobienne.append( numpy.ravel(( _HX_plus_dXi - _HX ) / _dXi) )
- #
#
- _Jacobienne = numpy.transpose( numpy.vstack( _Jacobienne ) )
- if self.__avoidRC:
- if self.__lenghtRJ < 0: self.__lenghtRJ = 2 * _X.size
- while len(self.__listJPCP) > self.__lenghtRJ:
- self.__listJPCP.pop(0)
- self.__listJPCI.pop(0)
- self.__listJPCR.pop(0)
- self.__listJPPN.pop(0)
- self.__listJPIN.pop(0)
- self.__listJPCP.append( copy.copy(_X) )
- self.__listJPCI.append( copy.copy(_dX) )
- self.__listJPCR.append( copy.copy(_Jacobienne) )
- self.__listJPPN.append( numpy.linalg.norm(_X) )
- self.__listJPIN.append( numpy.linalg.norm(_Jacobienne) )
- #
- logging.debug("FDA Fin du calcul de la Jacobienne")
+ if (dotWith is not None) or (dotTWith is not None):
+ __Produit = self.__listdotwith__(_Jacobienne, dotWith, dotTWith)
+ else:
+ __Produit = None
+ if __Produit is None or self.__avoidRC:
+ _Jacobienne = numpy.transpose( numpy.vstack( _Jacobienne ) )
+ if self.__avoidRC:
+ if self.__lenghtRJ < 0: self.__lenghtRJ = 2 * _X.size
+ while len(self.__listJPCP) > self.__lenghtRJ:
+ self.__listJPCP.pop(0)
+ self.__listJPCI.pop(0)
+ self.__listJPCR.pop(0)
+ self.__listJPPN.pop(0)
+ self.__listJPIN.pop(0)
+ self.__listJPCP.append( copy.copy(_X) )
+ self.__listJPCI.append( copy.copy(_dX) )
+ self.__listJPCR.append( copy.copy(_Jacobienne) )
+ self.__listJPPN.append( numpy.linalg.norm(_X) )
+ self.__listJPIN.append( numpy.linalg.norm(_Jacobienne) )
+ logging.debug("FDA Fin du calcul de la Jacobienne")
+ if __Produit is not None:
+ return __Produit
#
return _Jacobienne
ne doivent pas être données ici à la fonction utilisateur.
"""
if self.__mfEnabled:
- assert len(paire) == 1, "Incorrect lenght of arguments"
+ assert len(paire) == 1, "Incorrect length of arguments"
_paire = paire[0]
assert len(_paire) == 2, "Incorrect number of arguments"
else:
assert len(paire) == 2, "Incorrect number of arguments"
_paire = paire
X, dX = _paire
- _Jacobienne = self.TangentMatrix( X )
if dX is None or len(dX) == 0:
#
# Calcul de la forme matricielle si le second argument est None
# -------------------------------------------------------------
+ _Jacobienne = self.TangentMatrix( X )
if self.__mfEnabled: return [_Jacobienne,]
else: return _Jacobienne
else:
#
# Calcul de la valeur linéarisée de H en X appliqué à dX
# ------------------------------------------------------
- _dX = numpy.ravel( dX )
- _HtX = numpy.dot(_Jacobienne, _dX)
+ _HtX = self.TangentMatrix( X, dotWith = dX )
if self.__mfEnabled: return [_HtX,]
else: return _HtX
ne doivent pas être données ici à la fonction utilisateur.
"""
if self.__mfEnabled:
- assert len(paire) == 1, "Incorrect lenght of arguments"
+ assert len(paire) == 1, "Incorrect length of arguments"
_paire = paire[0]
assert len(_paire) == 2, "Incorrect number of arguments"
else:
assert len(paire) == 2, "Incorrect number of arguments"
_paire = paire
X, Y = _paire
- _JacobienneT = self.TangentMatrix( X ).T
if Y is None or len(Y) == 0:
#
# Calcul de la forme matricielle si le second argument est None
# -------------------------------------------------------------
+ _JacobienneT = self.TangentMatrix( X ).T
if self.__mfEnabled: return [_JacobienneT,]
else: return _JacobienneT
else:
#
# Calcul de la valeur de l'adjoint en X appliqué à Y
# --------------------------------------------------
- _Y = numpy.ravel( Y )
- _HaY = numpy.dot(_JacobienneT, _Y)
+ _HaY = self.TangentMatrix( X, dotTWith = Y )
if self.__mfEnabled: return [_HaY,]
else: return _HaY