+ self.__name = str(name)
+ self.__check = bool(toBeChecked)
+ #
+ self.__V = None
+ self.__T = None
+ self.__is_vector = False
+ self.__is_series = False
+ #
+ if asScript is not None:
+ __Vector, __Series = None, None
+ if asPersistentVector:
+ __Series = ImportFromScript(asScript).getvalue( self.__name )
+ else:
+ __Vector = ImportFromScript(asScript).getvalue( self.__name )
+ elif asDataFile is not None:
+ __Vector, __Series = None, None
+ if asPersistentVector:
+ if colNames is not None:
+ __Series = ImportFromFile(asDataFile).getvalue( colNames )[1]
+ else:
+ __Series = ImportFromFile(asDataFile).getvalue( [self.__name,] )[1]
+ if bool(colMajor) and not ImportFromFile(asDataFile).getformat() == "application/numpy.npz":
+ __Series = numpy.transpose(__Series)
+ elif not bool(colMajor) and ImportFromFile(asDataFile).getformat() == "application/numpy.npz":
+ __Series = numpy.transpose(__Series)
+ else:
+ if colNames is not None:
+ __Vector = ImportFromFile(asDataFile).getvalue( colNames )[1]
+ else:
+ __Vector = ImportFromFile(asDataFile).getvalue( [self.__name,] )[1]
+ if bool(colMajor):
+ __Vector = numpy.ravel(__Vector, order = "F")
+ else:
+ __Vector = numpy.ravel(__Vector, order = "C")
+ else:
+ __Vector, __Series = asVector, asPersistentVector
+ #
+ if __Vector is not None:
+ self.__is_vector = True
+ self.__V = numpy.matrix( numpy.asmatrix(__Vector).A1, numpy.float ).T
+ self.shape = self.__V.shape
+ self.size = self.__V.size
+ elif __Series is not None:
+ self.__is_series = True
+ if isinstance(__Series, (tuple, list, numpy.ndarray, numpy.matrix, str)):
+ self.__V = Persistence.OneVector(self.__name, basetype=numpy.matrix)
+ if isinstance(__Series, str): __Series = eval(__Series)
+ for member in __Series:
+ self.__V.store( numpy.matrix( numpy.asmatrix(member).A1, numpy.float ).T )
+ else:
+ self.__V = __Series
+ if isinstance(self.__V.shape, (tuple, list)):
+ self.shape = self.__V.shape
+ else:
+ self.shape = self.__V.shape()
+ if len(self.shape) == 1:
+ self.shape = (self.shape[0],1)
+ self.size = self.shape[0] * self.shape[1]
+ else:
+ raise ValueError("The %s object is improperly defined, it requires at minima either a vector, a list/tuple of vectors or a persistent object. Please check your vector input."%self.__name)
+ #
+ if scheduledBy is not None:
+ self.__T = scheduledBy
+
+ def getO(self, withScheduler=False):
+ if withScheduler:
+ return self.__V, self.__T
+ elif self.__T is None:
+ return self.__V
+ else:
+ return self.__V
+
+ def isvector(self):
+ "Vérification du type interne"
+ return self.__is_vector
+
+ def isseries(self):
+ "Vérification du type interne"
+ return self.__is_series
+
+ def __repr__(self):
+ "x.__repr__() <==> repr(x)"
+ return repr(self.__V)
+
+ def __str__(self):
+ "x.__str__() <==> str(x)"
+ return str(self.__V)
+
+# ==============================================================================
+class Covariance(object):
+ """
+ Classe générale d'interface de type covariance
+ """
+ def __init__(self,
+ name = "GenericCovariance",
+ asCovariance = None,
+ asEyeByScalar = None,
+ asEyeByVector = None,
+ asCovObject = None,
+ asScript = None,
+ toBeChecked = False,
+ ):
+ """
+ Permet de définir une covariance :
+ - asCovariance : entrée des données, comme une matrice compatible avec
+ le constructeur de numpy.matrix
+ - asEyeByScalar : entrée des données comme un seul scalaire de variance,
+ multiplicatif d'une matrice de corrélation identité, aucune matrice
+ n'étant donc explicitement à donner
+ - asEyeByVector : entrée des données comme un seul vecteur de variance,
+ à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
+ n'étant donc explicitement à donner
+ - asCovObject : entrée des données comme un objet python, qui a les
+ methodes obligatoires "getT", "getI", "diag", "trace", "__add__",
+ "__sub__", "__neg__", "__mul__", "__rmul__" et facultatives "shape",
+ "size", "cholesky", "choleskyI", "asfullmatrix", "__repr__", "__str__"
+ - toBeChecked : booléen indiquant si le caractère SDP de la matrice
+ pleine doit être vérifié
+ """
+ self.__name = str(name)
+ self.__check = bool(toBeChecked)
+ #
+ self.__C = None
+ self.__is_scalar = False
+ self.__is_vector = False
+ self.__is_matrix = False
+ self.__is_object = False
+ #
+ if asScript is not None:
+ __Matrix, __Scalar, __Vector, __Object = None, None, None, None
+ if asEyeByScalar:
+ __Scalar = ImportFromScript(asScript).getvalue( self.__name )
+ elif asEyeByVector:
+ __Vector = ImportFromScript(asScript).getvalue( self.__name )
+ elif asCovObject:
+ __Object = ImportFromScript(asScript).getvalue( self.__name )
+ else:
+ __Matrix = ImportFromScript(asScript).getvalue( self.__name )
+ else:
+ __Matrix, __Scalar, __Vector, __Object = asCovariance, asEyeByScalar, asEyeByVector, asCovObject
+ #
+ if __Scalar is not None:
+ if numpy.matrix(__Scalar).size != 1:
+ raise ValueError(' The diagonal multiplier given to define a sparse matrix is not a unique scalar value.\n Its actual measured size is %i. Please check your scalar input.'%numpy.matrix(__Scalar).size)
+ self.__is_scalar = True
+ self.__C = numpy.abs( float(__Scalar) )
+ self.shape = (0,0)
+ self.size = 0
+ elif __Vector is not None:
+ self.__is_vector = True
+ self.__C = numpy.abs( numpy.array( numpy.ravel( numpy.matrix(__Vector, float ) ) ) )
+ self.shape = (self.__C.size,self.__C.size)
+ self.size = self.__C.size**2
+ elif __Matrix is not None:
+ self.__is_matrix = True
+ self.__C = numpy.matrix( __Matrix, float )
+ self.shape = self.__C.shape
+ self.size = self.__C.size
+ elif __Object is not None:
+ self.__is_object = True
+ self.__C = __Object
+ for at in ("getT","getI","diag","trace","__add__","__sub__","__neg__","__mul__","__rmul__"):
+ if not hasattr(self.__C,at):
+ raise ValueError("The matrix given for %s as an object has no attribute \"%s\". Please check your object input."%(self.__name,at))
+ if hasattr(self.__C,"shape"):
+ self.shape = self.__C.shape
+ else:
+ self.shape = (0,0)
+ if hasattr(self.__C,"size"):
+ self.size = self.__C.size
+ else:
+ self.size = 0
+ else:
+ pass
+ # raise ValueError("The %s covariance matrix has to be specified either as a matrix, a vector for its diagonal or a scalar multiplying an identity matrix."%self.__name)
+ #
+ self.__validate()
+
+ def __validate(self):
+ "Validation"
+ if self.__C is None:
+ raise UnboundLocalError("%s covariance matrix value has not been set!"%(self.__name,))
+ if self.ismatrix() and min(self.shape) != max(self.shape):
+ raise ValueError("The given matrix for %s is not a square one, its shape is %s. Please check your matrix input."%(self.__name,self.shape))
+ if self.isobject() and min(self.shape) != max(self.shape):
+ raise ValueError("The matrix given for \"%s\" is not a square one, its shape is %s. Please check your object input."%(self.__name,self.shape))
+ if self.isscalar() and self.__C <= 0:
+ raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your scalar input %s."%(self.__name,self.__C))
+ if self.isvector() and (self.__C <= 0).any():
+ raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your vector input."%(self.__name,))
+ if self.ismatrix() and (self.__check or logging.getLogger().level < logging.WARNING):
+ try:
+ L = numpy.linalg.cholesky( self.__C )
+ except:
+ raise ValueError("The %s covariance matrix is not symmetric positive-definite. Please check your matrix input."%(self.__name,))
+ if self.isobject() and (self.__check or logging.getLogger().level < logging.WARNING):
+ try:
+ L = self.__C.cholesky()
+ except:
+ raise ValueError("The %s covariance object is not symmetric positive-definite. Please check your matrix input."%(self.__name,))
+
+ def isscalar(self):
+ "Vérification du type interne"
+ return self.__is_scalar
+
+ def isvector(self):
+ "Vérification du type interne"
+ return self.__is_vector
+
+ def ismatrix(self):
+ "Vérification du type interne"
+ return self.__is_matrix
+
+ def isobject(self):
+ "Vérification du type interne"
+ return self.__is_object
+
+ def getI(self):
+ "Inversion"
+ if self.ismatrix():
+ return Covariance(self.__name+"I", asCovariance = self.__C.I )
+ elif self.isvector():
+ return Covariance(self.__name+"I", asEyeByVector = 1. / self.__C )
+ elif self.isscalar():
+ return Covariance(self.__name+"I", asEyeByScalar = 1. / self.__C )
+ elif self.isobject():
+ return Covariance(self.__name+"I", asCovObject = self.__C.getI() )
+ else:
+ return None # Indispensable
+
+ def getT(self):
+ "Transposition"
+ if self.ismatrix():
+ return Covariance(self.__name+"T", asCovariance = self.__C.T )
+ elif self.isvector():
+ return Covariance(self.__name+"T", asEyeByVector = self.__C )
+ elif self.isscalar():
+ return Covariance(self.__name+"T", asEyeByScalar = self.__C )
+ elif self.isobject():
+ return Covariance(self.__name+"T", asCovObject = self.__C.getT() )
+
+ def cholesky(self):
+ "Décomposition de Cholesky"
+ if self.ismatrix():
+ return Covariance(self.__name+"C", asCovariance = numpy.linalg.cholesky(self.__C) )
+ elif self.isvector():
+ return Covariance(self.__name+"C", asEyeByVector = numpy.sqrt( self.__C ) )
+ elif self.isscalar():
+ return Covariance(self.__name+"C", asEyeByScalar = numpy.sqrt( self.__C ) )
+ elif self.isobject() and hasattr(self.__C,"cholesky"):
+ return Covariance(self.__name+"C", asCovObject = self.__C.cholesky() )
+
+ def choleskyI(self):
+ "Inversion de la décomposition de Cholesky"
+ if self.ismatrix():
+ return Covariance(self.__name+"H", asCovariance = numpy.linalg.cholesky(self.__C).I )
+ elif self.isvector():
+ return Covariance(self.__name+"H", asEyeByVector = 1.0 / numpy.sqrt( self.__C ) )
+ elif self.isscalar():
+ return Covariance(self.__name+"H", asEyeByScalar = 1.0 / numpy.sqrt( self.__C ) )
+ elif self.isobject() and hasattr(self.__C,"choleskyI"):
+ return Covariance(self.__name+"H", asCovObject = self.__C.choleskyI() )
+
+ def diag(self, msize=None):
+ "Diagonale de la matrice"
+ if self.ismatrix():
+ return numpy.diag(self.__C)
+ elif self.isvector():
+ return self.__C
+ elif self.isscalar():
+ if msize is None:
+ raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
+ else:
+ return self.__C * numpy.ones(int(msize))
+ elif self.isobject():
+ return self.__C.diag()
+
+ def asfullmatrix(self, msize=None):
+ "Matrice pleine"
+ if self.ismatrix():
+ return self.__C
+ elif self.isvector():
+ return numpy.matrix( numpy.diag(self.__C), float )
+ elif self.isscalar():
+ if msize is None:
+ raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
+ else:
+ return numpy.matrix( self.__C * numpy.eye(int(msize)), float )
+ elif self.isobject() and hasattr(self.__C,"asfullmatrix"):
+ return self.__C.asfullmatrix()
+
+ def trace(self, msize=None):
+ "Trace de la matrice"
+ if self.ismatrix():
+ return numpy.trace(self.__C)
+ elif self.isvector():
+ return float(numpy.sum(self.__C))
+ elif self.isscalar():
+ if msize is None:
+ raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
+ else:
+ return self.__C * int(msize)
+ elif self.isobject():
+ return self.__C.trace()
+
+ def getO(self):
+ return self
+
+ def __repr__(self):
+ "x.__repr__() <==> repr(x)"
+ return repr(self.__C)
+
+ def __str__(self):
+ "x.__str__() <==> str(x)"
+ return str(self.__C)
+
+ def __add__(self, other):
+ "x.__add__(y) <==> x+y"
+ if self.ismatrix() or self.isobject():
+ return self.__C + numpy.asmatrix(other)
+ elif self.isvector() or self.isscalar():
+ _A = numpy.asarray(other)
+ _A.reshape(_A.size)[::_A.shape[1]+1] += self.__C
+ return numpy.asmatrix(_A)
+
+ def __radd__(self, other):
+ "x.__radd__(y) <==> y+x"
+ raise NotImplementedError("%s covariance matrix __radd__ method not available for %s type!"%(self.__name,type(other)))
+
+ def __sub__(self, other):
+ "x.__sub__(y) <==> x-y"
+ if self.ismatrix() or self.isobject():
+ return self.__C - numpy.asmatrix(other)
+ elif self.isvector() or self.isscalar():
+ _A = numpy.asarray(other)
+ _A.reshape(_A.size)[::_A.shape[1]+1] = self.__C - _A.reshape(_A.size)[::_A.shape[1]+1]
+ return numpy.asmatrix(_A)
+
+ def __rsub__(self, other):
+ "x.__rsub__(y) <==> y-x"
+ raise NotImplementedError("%s covariance matrix __rsub__ method not available for %s type!"%(self.__name,type(other)))
+
+ def __neg__(self):
+ "x.__neg__() <==> -x"
+ return - self.__C
+
+ def __mul__(self, other):
+ "x.__mul__(y) <==> x*y"
+ if self.ismatrix() and isinstance(other, (int, numpy.matrix, float)):
+ return self.__C * other
+ elif self.ismatrix() and isinstance(other, (list, numpy.ndarray, tuple)):
+ if numpy.ravel(other).size == self.shape[1]: # Vecteur
+ return self.__C * numpy.asmatrix(numpy.ravel(other)).T
+ elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice
+ return self.__C * numpy.asmatrix(other)
+ else:
+ raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.asmatrix(other).shape,self.__name))
+ elif self.isvector() and isinstance(other, (list, numpy.matrix, numpy.ndarray, tuple)):
+ if numpy.ravel(other).size == self.shape[1]: # Vecteur
+ return numpy.asmatrix(self.__C * numpy.ravel(other)).T
+ elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice
+ return numpy.asmatrix((self.__C * (numpy.asarray(other).transpose())).transpose())
+ else:
+ raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.ravel(other).shape,self.__name))
+ elif self.isscalar() and isinstance(other,numpy.matrix):
+ return self.__C * other
+ elif self.isscalar() and isinstance(other, (list, numpy.ndarray, tuple)):
+ if len(numpy.asarray(other).shape) == 1 or numpy.asarray(other).shape[1] == 1 or numpy.asarray(other).shape[0] == 1:
+ return self.__C * numpy.asmatrix(numpy.ravel(other)).T
+ else:
+ return self.__C * numpy.asmatrix(other)
+ elif self.isobject():
+ return self.__C.__mul__(other)
+ else:
+ raise NotImplementedError("%s covariance matrix __mul__ method not available for %s type!"%(self.__name,type(other)))
+
+ def __rmul__(self, other):
+ "x.__rmul__(y) <==> y*x"
+ if self.ismatrix() and isinstance(other, (int, numpy.matrix, float)):
+ return other * self.__C
+ elif self.ismatrix() and isinstance(other, (list, numpy.ndarray, tuple)):
+ if numpy.ravel(other).size == self.shape[1]: # Vecteur
+ return numpy.asmatrix(numpy.ravel(other)) * self.__C
+ elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice
+ return numpy.asmatrix(other) * self.__C
+ else:
+ raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(numpy.asmatrix(other).shape,self.shape,self.__name))
+ elif self.isvector() and isinstance(other,numpy.matrix):
+ if numpy.ravel(other).size == self.shape[0]: # Vecteur
+ return numpy.asmatrix(numpy.ravel(other) * self.__C)
+ elif numpy.asmatrix(other).shape[1] == self.shape[0]: # Matrice
+ return numpy.asmatrix(numpy.array(other) * self.__C)
+ else:
+ raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(numpy.ravel(other).shape,self.shape,self.__name))
+ elif self.isscalar() and isinstance(other,numpy.matrix):
+ return other * self.__C
+ elif self.isobject():
+ return self.__C.__rmul__(other)
+ else:
+ raise NotImplementedError("%s covariance matrix __rmul__ method not available for %s type!"%(self.__name,type(other)))
+
+ def __len__(self):
+ "x.__len__() <==> len(x)"
+ return self.shape[0]
+
+# ==============================================================================
+class ObserverF(object):
+ """
+ Creation d'une fonction d'observateur a partir de son texte
+ """
+ def __init__(self, corps=""):
+ self.__corps = corps
+ def func(self,var,info):
+ "Fonction d'observation"
+ exec(self.__corps)
+ def getfunc(self):
+ "Restitution du pointeur de fonction dans l'objet"
+ return self.func
+
+# ==============================================================================
+class CaseLogger(object):
+ """
+ Conservation des commandes de creation d'un cas
+ """
+ def __init__(self, __name="", __objname="case", __addViewers=None, __addLoaders=None):
+ self.__name = str(__name)
+ self.__objname = str(__objname)
+ self.__logSerie = []
+ self.__switchoff = False
+ self.__viewers = {
+ "TUI" :Interfaces._TUIViewer,
+ "SCD" :Interfaces._SCDViewer,
+ "YACS":Interfaces._YACSViewer,
+ }
+ self.__loaders = {
+ "TUI" :Interfaces._TUIViewer,
+ "COM" :Interfaces._COMViewer,
+ }
+ if __addViewers is not None:
+ self.__viewers.update(dict(__addViewers))
+ if __addLoaders is not None:
+ self.__loaders.update(dict(__addLoaders))
+
+ def register(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
+ "Enregistrement d'une commande individuelle"
+ if __command is not None and __keys is not None and __local is not None and not self.__switchoff:
+ if "self" in __keys: __keys.remove("self")
+ self.__logSerie.append( (str(__command), __keys, __local, __pre, __switchoff) )
+ if __switchoff:
+ self.__switchoff = True
+ if not __switchoff:
+ self.__switchoff = False
+
+ def dump(self, __filename=None, __format="TUI", __upa=""):
+ "Restitution normalisée des commandes"
+ if __format in self.__viewers:
+ __formater = self.__viewers[__format](self.__name, self.__objname, self.__logSerie)
+ else:
+ raise ValueError("Dumping as \"%s\" is not available"%__format)
+ return __formater.dump(__filename, __upa)
+
+ def load(self, __filename=None, __content=None, __object=None, __format="TUI"):
+ "Chargement normalisé des commandes"
+ if __format in self.__loaders:
+ __formater = self.__loaders[__format]()
+ else:
+ raise ValueError("Loading as \"%s\" is not available"%__format)
+ return __formater.load(__filename, __content, __object)
+
+# ==============================================================================
+def MultiFonction( __xserie, _extraArguments = None, _sFunction = lambda x: x ):
+ """
+ Pour une liste ordonnée de vecteurs en entrée, renvoie en sortie la liste
+ correspondante de valeurs de la fonction en argument
+ """
+ # Vérifications et définitions initiales
+ if not PlatformInfo.isIterable( __xserie ):
+ raise TypeError("MultiFonction not iterable unkown input type: %s"%(type(__xserie),))
+ #
+ # Calculs effectifs
+ __multiHX = []
+ if _extraArguments is None:
+ for __xvalue in __xserie:
+ __multiHX.append( _sFunction( __xvalue ) )
+ elif _extraArguments is not None and isinstance(_extraArguments, (list, tuple, map)):
+ for __xvalue in __xserie:
+ __multiHX.append( _sFunction( __xvalue, *_extraArguments ) )
+ elif _extraArguments is not None and isinstance(_extraArguments, dict):
+ for __xvalue in __xserie:
+ __multiHX.append( _sFunction( __xvalue, **_extraArguments ) )
+ else:
+ raise TypeError("MultiFonction extra arguments unkown input type: %s"%(type(_extraArguments),))
+ #
+ return __multiHX
+
+# ==============================================================================
+def CostFunction3D(_x,
+ _Hm = None, # Pour simuler Hm(x) : HO["Direct"].appliedTo
+ _HmX = None, # Simulation déjà faite de Hm(x)
+ _arg = None, # Arguments supplementaires pour Hm, sous la forme d'un tuple
+ _BI = None,
+ _RI = None,
+ _Xb = None,
+ _Y = None,
+ _SIV = False, # A résorber pour la 8.0
+ _SSC = [], # self._parameters["StoreSupplementaryCalculations"]
+ _nPS = 0, # nbPreviousSteps
+ _QM = "DA", # QualityMeasure
+ _SSV = {}, # Entrée et/ou sortie : self.StoredVariables
+ _fRt = False, # Restitue ou pas la sortie étendue
+ _sSc = True, # Stocke ou pas les SSC
+ ):
+ """
+ Fonction-coût générale utile pour les algorithmes statiques/3D : 3DVAR, BLUE
+ et dérivés, Kalman et dérivés, LeastSquares, SamplingTest, PSO, SA, Tabu,
+ DFO, QuantileRegression
+ """
+ if not _sSc:
+ _SIV = False
+ _SSC = {}
+ else:
+ for k in ["CostFunctionJ",
+ "CostFunctionJb",
+ "CostFunctionJo",
+ "CurrentOptimum",
+ "CurrentState",
+ "IndexOfOptimum",
+ "SimulatedObservationAtCurrentOptimum",
+ "SimulatedObservationAtCurrentState",
+ ]:
+ if k not in _SSV:
+ _SSV[k] = []
+ if hasattr(_SSV[k],"store"):
+ _SSV[k].append = _SSV[k].store # Pour utiliser "append" au lieu de "store"
+ #
+ _X = numpy.asmatrix(numpy.ravel( _x )).T
+ if _SIV or "CurrentState" in _SSC or "CurrentOptimum" in _SSC:
+ _SSV["CurrentState"].append( _X )
+ #
+ if _HmX is not None:
+ _HX = _HmX
+ else:
+ if _Hm is None:
+ raise ValueError("COSTFUNCTION3D Operator has to be defined.")
+ if _arg is None:
+ _HX = _Hm( _X )
+ else:
+ _HX = _Hm( _X, *_arg )
+ _HX = numpy.asmatrix(numpy.ravel( _HX )).T
+ #
+ if "SimulatedObservationAtCurrentState" in _SSC or \
+ "SimulatedObservationAtCurrentOptimum" in _SSC:
+ _SSV["SimulatedObservationAtCurrentState"].append( _HX )
+ #
+ if numpy.any(numpy.isnan(_HX)):
+ Jb, Jo, J = numpy.nan, numpy.nan, numpy.nan
+ else:
+ _Y = numpy.asmatrix(numpy.ravel( _Y )).T
+ if _QM in ["AugmentedWeightedLeastSquares", "AWLS", "AugmentedPonderatedLeastSquares", "APLS", "DA"]:
+ if _BI is None or _RI is None:
+ raise ValueError("Background and Observation error covariance matrix has to be properly defined!")
+ _Xb = numpy.asmatrix(numpy.ravel( _Xb )).T
+ Jb = 0.5 * (_X - _Xb).T * _BI * (_X - _Xb)
+ Jo = 0.5 * (_Y - _HX).T * _RI * (_Y - _HX)
+ elif _QM in ["WeightedLeastSquares", "WLS", "PonderatedLeastSquares", "PLS"]:
+ if _RI is None:
+ raise ValueError("Observation error covariance matrix has to be properly defined!")
+ Jb = 0.
+ Jo = 0.5 * (_Y - _HX).T * _RI * (_Y - _HX)
+ elif _QM in ["LeastSquares", "LS", "L2"]:
+ Jb = 0.
+ Jo = 0.5 * (_Y - _HX).T * (_Y - _HX)
+ elif _QM in ["AbsoluteValue", "L1"]:
+ Jb = 0.
+ Jo = numpy.sum( numpy.abs(_Y - _HX) )
+ elif _QM in ["MaximumError", "ME"]:
+ Jb = 0.
+ Jo = numpy.max( numpy.abs(_Y - _HX) )
+ elif _QM in ["QR", "Null"]:
+ Jb = 0.
+ Jo = 0.
+ else:
+ raise ValueError("Unknown asked quality measure!")
+ #
+ J = float( Jb ) + float( Jo )
+ #
+ if _sSc:
+ _SSV["CostFunctionJb"].append( Jb )
+ _SSV["CostFunctionJo"].append( Jo )
+ _SSV["CostFunctionJ" ].append( J )
+ #
+ if "IndexOfOptimum" in _SSC or \
+ "CurrentOptimum" in _SSC or \
+ "SimulatedObservationAtCurrentOptimum" in _SSC:
+ IndexMin = numpy.argmin( _SSV["CostFunctionJ"][_nPS:] ) + _nPS
+ if "IndexOfOptimum" in _SSC:
+ _SSV["IndexOfOptimum"].append( IndexMin )
+ if "CurrentOptimum" in _SSC:
+ _SSV["CurrentOptimum"].append( _SSV["CurrentState"][IndexMin] )
+ if "SimulatedObservationAtCurrentOptimum" in _SSC:
+ _SSV["SimulatedObservationAtCurrentOptimum"].append( _SSV["SimulatedObservationAtCurrentState"][IndexMin] )
+ #
+ if _fRt:
+ return _SSV
+ else:
+ if _QM in ["QR"]: # Pour le QuantileRegression
+ return _HX
+ else:
+ return J