Salome HOME
Documentation update and method improvement
authorJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Wed, 4 Oct 2023 14:10:51 +0000 (16:10 +0200)
committerJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Wed, 4 Oct 2023 14:10:51 +0000 (16:10 +0200)
15 files changed:
doc/en/bibliography.rst
doc/en/ref_algorithm_MeasurementsOptimalPositioningTask.rst
doc/en/snippets/Residus.rst
doc/en/snippets/SingularValues.rst [new file with mode: 0644]
doc/en/snippets/Variant_MOP.rst
doc/fr/bibliography.rst
doc/fr/ref_algorithm_MeasurementsOptimalPositioningTask.rst
doc/fr/snippets/Residus.rst
doc/fr/snippets/SingularValues.rst [new file with mode: 0644]
doc/fr/snippets/Variant_MOP.rst
src/daComposant/daAlgorithms/Atoms/ecwdeim.py [new file with mode: 0644]
src/daComposant/daAlgorithms/Atoms/ecweim.py
src/daComposant/daAlgorithms/InterpolationByReducedModelTask.py
src/daComposant/daAlgorithms/MeasurementsOptimalPositioningTask.py
src/daComposant/daCore/BasicObjects.py

index 17551edcdb4648a66abd0c90a05cd05dfcc3c92f..f672e6f5d56432aaad4f0e1ab40e78d4d4dd0fbd 100644 (file)
@@ -55,6 +55,8 @@ exhaustive bibliography.
 
 .. [Chakraborty08] Chakraborty U.K., *Advances in differential evolution*, Studies in computational intelligence, Vol.143, Springer, 2008
 
+.. [Chaturantabut10] Chaturantabut S., Sorensen D.C., *Nonlinear model reduction via discrete empirical interpolation*, SIMA Journal of Scientific Computing, 32(5), pp.2737-2764, 2010
+
 .. [Cohn98] Cohn S. E., Da Silva A., Guo J., Sienkiewicz M., Lamich D., *Assessing the effects of data selection with the DAO Physical-space Statistical Analysis System*, Monthly Weather Review, 126, pp.2913–2926, 1998
 
 .. [Courtier94] Courtier P., Thépaut J.-N., Hollingsworth A., *A strategy for operational implementation of 4D-Var, using an incremental approach*, Quarterly Journal of the Royal Meteorological Society, 120(519), pp.1367–1387, 1994
index 4979d64b327e174871f7c4d13956f18559cdd833..cc02459a72292778d563fc1a7817aff02ff3756a 100644 (file)
@@ -54,9 +54,12 @@ returns the complete field(s) for a given set of parameters :math:`\mathbf{x}`,
 or of an explicit observation of the complete field(s) :math:`\mathbf{y}`.
 
 To determine the optimum positioning of measurements, an Empirical
-Interpolation Method (EIM [Barrault04]_) is used, which establishes a reduced
-model of type Reduced Order Model (ROM), with (variant "*lcEIM*") or without
-(variant "*EIM*") positioning constraints.
+Interpolation Method (EIM [Barrault04]_) or Discrete Empirical Interpolation
+Method (DEIM [Chaturantabut10]_) is used, which establishes a reduced model of
+type Reduced Order Model (ROM), with (variant "*lcEIM*" or "*lcDEIM*") or
+without (variant "*EIM*" or "*DEIM*") positioning constraints. For performance,
+we recommend using the variant "*lcEIM*" or "*EIM*" when the dimension of the
+full fields space is large.
 
 There are two ways to use this algorithm:
 
@@ -88,8 +91,8 @@ it can grow quickly to be quite large.
     **General scheme for using the algorithm**
 
 It is possible to exclude a priori potential positions for measurement
-positioning, using the analysis variant "*lcEIM*" for a constrained positioning
-search.
+positioning, using the analysis variant "*lcEIM*" or "*lcDEIM*" for a
+constrained positioning search.
 
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo02.rst
@@ -142,6 +145,7 @@ StoreSupplementaryCalculations
   "OptimalPoints",
   "ReducedBasis",
   "Residus",
+  "SingularValues",
   ].
 
   Example :
@@ -169,6 +173,8 @@ StoreSupplementaryCalculations
 
 .. include:: snippets/Residus.rst
 
+.. include:: snippets/SingularValues.rst
+
 .. ------------------------------------ ..
 .. _section_ref_algorithm_MeasurementsOptimalPositioningTask_examples:
 
@@ -205,5 +211,6 @@ StoreSupplementaryCalculations
 .. include:: snippets/Header2Algo07.rst
 
 - [Barrault04]_
+- [Chaturantabut10]_
 - [Gong18]_
 - [Quarteroni16]_
index e727a3d04d875d10cdb5ea14859e163818873748..aa86ca794cf780d37cf72eca7465730add51615e 100644 (file)
@@ -5,4 +5,4 @@ Residus
   of the particular residue checked during the running of the algorithm.
 
   Example :
-  ``rs = ADD.get("Residus")[:]``
+  ``rs = ADD.get("Residus")[-1]``
diff --git a/doc/en/snippets/SingularValues.rst b/doc/en/snippets/SingularValues.rst
new file mode 100644 (file)
index 0000000..1101946
--- /dev/null
@@ -0,0 +1,9 @@
+.. index:: single: SingularValues
+
+SingularValues
+  *List of real value series*. Each element is a series, containing the
+  singular values obtained through a SVD decomposition of a collection of full
+  state vectors.
+
+  Example :
+  ``sv = ADD.get("SingularValues")[-1]``
index a8def457928ef2f22d1f0179f1b8bfe85548316b..cf15a3ff00a15429e31e6d4e2a25004fa3f293ac 100644 (file)
@@ -1,15 +1,24 @@
 .. index::
     single: Variant
+    pair: Variant ; EIM
+    pair: Variant ; DEIM
+    pair: Variant ; lcEIM
+    pair: Variant ; lcDEIM
     pair: Variant ; PositioningByEIM
+    pair: Variant ; PositioningByDEIM
     pair: Variant ; PositioningBylcEIM
+    pair: Variant ; PositioningBylcDEIM
 
 Variant
   *Predefined name*.  This key allows to choose one of the possible variants
   for the optimal positioning search. The default variant is the constrained by
-  excluded locations "PositioningBylcEIM", and the possible choices are
-  "PositioningByEIM" (using the original EIM algorithm),
-  "PositioningBylcEIM" (using the constrained by excluded locations EIM, named "Location Constrained EIM").
+  excluded locations "lcEIM" or "PositioningBylcEIM", and the possible choices
+  are "EIM" or "PositioningByEIM" (using the original EIM algorithm), "lcEIM"
+  or "PositioningBylcEIM" (using the constrained by excluded locations EIM,
+  named "Location Constrained EIM"), "DEIM" or "PositioningByDEIM" (using the
+  original DEIM algorithm), "lcDEIM" or "PositioningBylcDEIM" (using the
+  constrained by excluded locations DEIM, named "Location Constrained DEIM").
   It is highly recommended to keep the default value.
 
   Example :
-  ``{"Variant":"PositioningBylcEIM"}``
+  ``{"Variant":"lcEIM"}``
index 8b2cf92dc0b8bcf4d62e9fda5780d3a3e618b2dd..dc6f0d151b974768705a395229d9f1f7aeb49b48 100644 (file)
@@ -55,6 +55,8 @@ néanmoins d'intention de constituer une bibliographie exhaustive.
 
 .. [Chakraborty08] Chakraborty U.K., *Advances in differential evolution*, Studies in computational intelligence, Vol.143, Springer, 2008
 
+.. [Chaturantabut10] Chaturantabut S., Sorensen D.C., *Nonlinear model reduction via discrete empirical interpolation*, SIMA Journal of Scientific Computing, 32(5), pp.2737-2764, 2010
+
 .. [Cohn98] Cohn S. E., Da Silva A., Guo J., Sienkiewicz M., Lamich D., *Assessing the effects of data selection with the DAO Physical-space Statistical Analysis System*, Monthly Weather Review, 126, pp.2913–2926, 1998
 
 .. [Courtier94] Courtier P., Thépaut J.-N., Hollingsworth A., *A strategy for operational implementation of 4D-Var, using an incremental approach*, Quarterly Journal of the Royal Meteorological Society, 120(519), pp.1367–1387, 1994
index 629da6b0a7fb68af1260225d5965290e4cfed945..9ee7b935b7fc66be3854bf49000d25903d36646c 100644 (file)
@@ -55,9 +55,13 @@ un jeu de paramètres donné :math:`\mathbf{x}`, ou d'une observation explicite
 du (ou des) champ(s) complet(s) :math:`\mathbf{y}`.
 
 Pour établir la position optimale de mesures, on utilise une méthode de type
-Empirical Interpolation Method (EIM [Barrault04]_), qui établit un modèle
-réduit de type Reduced Order Model (ROM), avec contraintes (variant "*lcEIM*")
-ou sans contraintes (variant "*EIM*") de positionnement.
+Empirical Interpolation Method (EIM [Barrault04]_) ou Discrete Empirical
+Interpolation Method (DEIM [Chaturantabut10]_), qui établit un modèle réduit de
+type Reduced Order Model (ROM), avec contraintes (variante "*lcEIM*" ou
+"*lcDEIM*") ou sans contraintes (variante "*EIM*" ou "*DEIM*") de
+positionnement. Pour la performance, il est recommandé d'utiliser la variante
+"*lcEIM*" ou "*EIM*" lorsque la dimension de l'espace des champs complets est
+grande.
 
 Il y a deux manières d'utiliser cet algorithme:
 
@@ -90,8 +94,8 @@ d'atteindre, elle peut rapidement devenir importante.
     **Schéma général d'utilisation de l'algorithme**
 
 Il est possible d'exclure a priori des positions potentielles pour le
-positionnement des mesures, en utilisant le variant "*lcEIM*" d'analyse pour
-une recherche de positionnement contraint.
+positionnement des mesures, en utilisant le variant "*lcEIM*" ou "*lcDEIM*"
+d'analyse pour une recherche de positionnement contraint.
 
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo02.rst
@@ -144,6 +148,7 @@ StoreSupplementaryCalculations
   "OptimalPoints",
   "ReducedBasis",
   "Residus",
+  "SingularValues",
   ].
 
   Exemple :
@@ -171,6 +176,8 @@ StoreSupplementaryCalculations
 
 .. include:: snippets/Residus.rst
 
+.. include:: snippets/SingularValues.rst
+
 .. ------------------------------------ ..
 .. _section_ref_algorithm_MeasurementsOptimalPositioningTask_examples:
 
@@ -207,5 +214,6 @@ StoreSupplementaryCalculations
 .. include:: snippets/Header2Algo07.rst
 
 - [Barrault04]_
+- [Chaturantabut10]_
 - [Gong18]_
 - [Quarteroni16]_
index 6b189031f1d046130adf903a9e539e1f16f59d11..8389ae16dadcaea9f73dbc535cc214b4ff2944e7 100644 (file)
@@ -6,4 +6,4 @@ Residus
   l'algorithme.
 
   Exemple :
-  ``rs = ADD.get("Residus")[:]``
+  ``rs = ADD.get("Residus")[-1]``
diff --git a/doc/fr/snippets/SingularValues.rst b/doc/fr/snippets/SingularValues.rst
new file mode 100644 (file)
index 0000000..5c0c851
--- /dev/null
@@ -0,0 +1,9 @@
+.. index:: single: SingularValues
+
+SingularValues
+  *Liste de série de valeurs réelles*. Chaque élément est une série, contenant
+  les valeurs singulières obtenues par une décomposition SVD d'un ensemble de
+  vecteurs d'états complets.
+
+  Exemple :
+  ``sv = ADD.get("SingularValues")[-1]``
index 72279fd708a81dc5a882430ae11c1247ecc4bc9f..a18bd5dc49ca2ae97a96e1d1979f1aab8c0b0e7b 100644 (file)
@@ -1,16 +1,25 @@
 .. index::
     single: Variant
+    pair: Variant ; EIM
+    pair: Variant ; DEIM
+    pair: Variant ; lcEIM
+    pair: Variant ; lcDEIM
     pair: Variant ; PositioningByEIM
+    pair: Variant ; PositioningByDEIM
     pair: Variant ; PositioningBylcEIM
+    pair: Variant ; PositioningBylcDEIM
 
 Variant
   *Nom prédéfini*. Cette clé permet de choisir l'une des variantes possibles
   pour la recherche du positionnement optimal. La variante par défaut est la
-  version contrainte par des positions exclues "PositioningBylcEIM", et les
-  choix possibles sont
-  "PositioningByEIM" (utilisant l'algorithme EIM original),
-  "PositioningBylcEIM" (utilisant l'algorithme EIM contraint par des positions exclues, nommé "Location Constrained EIM").
-  Il est fortement recommandé de conserver la valeur par défaut.
+  version contrainte par des positions exclues "lcEIM" ou "PositioningBylcEIM",
+  et les choix possibles sont "EIM" ou "PositioningByEIM" (utilisant
+  l'algorithme EIM original), "lcEIM" ou "PositioningBylcEIM" (utilisant
+  l'algorithme EIM contraint par des positions exclues, nommé "Location
+  Constrained EIM"), "DEIM" ou "PositioningByDEIM" (utilisant l'algorithme DEIM
+  original), "lcDEIM" ou "PositioningBylcDEIM" (utilisant l'algorithme DEIM
+  contraint par des positions exclues, nommé "Location Constrained DEIM"). Il
+  est fortement recommandé de conserver la valeur par défaut.
 
   Exemple :
-  ``{"Variant":"PositioningBylcEIM"}``
+  ``{"Variant":"lcEIM"}``
diff --git a/src/daComposant/daAlgorithms/Atoms/ecwdeim.py b/src/daComposant/daAlgorithms/Atoms/ecwdeim.py
new file mode 100644 (file)
index 0000000..cb79f6f
--- /dev/null
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2023 EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
+
+__doc__ = """
+    Empirical Interpolation Method DEIM & lcDEIM
+"""
+__author__ = "Jean-Philippe ARGAUD"
+
+import numpy, scipy, logging
+import daCore.Persistence
+from daCore.NumericObjects import FindIndexesFromNames
+
+# ==============================================================================
+def DEIM_offline(selfA, EOS = None, Verbose = False):
+    """
+    Établissement de la base
+    """
+    #
+    # Initialisations
+    # ---------------
+    if isinstance(EOS, (numpy.ndarray, numpy.matrix)):
+        __EOS = numpy.asarray(EOS)
+    elif isinstance(EOS, (list, tuple, daCore.Persistence.Persistence)):
+        __EOS = numpy.stack([numpy.ravel(_sn) for _sn in EOS], axis=1)
+        # __EOS = numpy.asarray(EOS).T
+    else:
+        raise ValueError("EnsembleOfSnapshots has to be an array/matrix (each column being a vector) or a list/tuple (each element being a vector).")
+    __dimS, __nbmS = __EOS.shape
+    logging.debug("%s Building a RB using a collection of %i snapshots of individual size of %i"%(selfA._name,__nbmS,__dimS))
+    #
+    if selfA._parameters["Variant"] in ["DEIM", "PositioningByDEIM"]:
+        __LcCsts = False
+    else:
+        __LcCsts = True
+    if __LcCsts and "ExcludeLocations" in selfA._parameters:
+        __ExcludedMagicPoints = selfA._parameters["ExcludeLocations"]
+    else:
+        __ExcludedMagicPoints = ()
+    if __LcCsts and "NameOfLocations" in selfA._parameters:
+        if isinstance(selfA._parameters["NameOfLocations"], (list, numpy.ndarray, tuple)) and len(selfA._parameters["NameOfLocations"]) == __dimS:
+            __NameOfLocations = selfA._parameters["NameOfLocations"]
+        else:
+            __NameOfLocations = ()
+    else:
+        __NameOfLocations = ()
+    if __LcCsts and len(__ExcludedMagicPoints) > 0:
+        __ExcludedMagicPoints = FindIndexesFromNames( __NameOfLocations, __ExcludedMagicPoints )
+        __ExcludedMagicPoints = numpy.ravel(numpy.asarray(__ExcludedMagicPoints, dtype=int))
+        __IncludedMagicPoints = numpy.setdiff1d(
+            numpy.arange(__EOS.shape[0]),
+            __ExcludedMagicPoints,
+            assume_unique = True,
+            )
+    else:
+        __IncludedMagicPoints = []
+    #
+    if "MaximumNumberOfLocations" in selfA._parameters and "MaximumRBSize" in selfA._parameters:
+        selfA._parameters["MaximumRBSize"] = min(selfA._parameters["MaximumNumberOfLocations"],selfA._parameters["MaximumRBSize"])
+    elif "MaximumNumberOfLocations" in selfA._parameters:
+        selfA._parameters["MaximumRBSize"] = selfA._parameters["MaximumNumberOfLocations"]
+    elif "MaximumRBSize" in selfA._parameters:
+        pass
+    else:
+        selfA._parameters["MaximumRBSize"] = __nbmS
+    __maxM   = min(selfA._parameters["MaximumRBSize"], __dimS, __nbmS)
+    if "ErrorNormTolerance" in selfA._parameters:
+        selfA._parameters["EpsilonEIM"] = selfA._parameters["ErrorNormTolerance"]
+    else:
+        selfA._parameters["EpsilonEIM"] = 1.e-2
+    #
+    __U, __vs, _ = scipy.linalg.svd( __EOS )
+    __rhoM = numpy.compress(__vs > selfA._parameters["EpsilonEIM"], __U, axis=1)
+    __lVs, __svdM = __rhoM.shape
+    assert __lVs == __dimS, "Différence entre lVs et dim(EOS)"
+    __qivs = (1. - __vs[:__svdM].cumsum()/__vs.sum())
+    __maxM   = min(__maxM,__svdM)
+    #
+    if __LcCsts and len(__IncludedMagicPoints) > 0:
+        __im = numpy.argmax( numpy.abs(
+            numpy.take(__rhoM[:,0], __IncludedMagicPoints, mode='clip')
+            ))
+    else:
+        __im = numpy.argmax( numpy.abs(
+            __rhoM[:,0]
+            ))
+    #
+    __mu     = [None,] # Convention
+    __I      = [__im,]
+    __Q      = __rhoM[:,0].reshape((-1,1))
+    __errors = []
+    #
+    __M      = 1 # Car le premier est déjà construit
+    __errors.append(__qivs[0])
+    #
+    # Boucle
+    # ------
+    while __M < __maxM:
+        #
+        __restrictedQi = __Q[__I,:]
+        if __M > 1:
+            __Qi_inv = numpy.linalg.inv(__restrictedQi)
+        else:
+            __Qi_inv = 1. / __restrictedQi
+        #
+        __restrictedrhoMi = __rhoM[__I,__M].reshape((-1,1))
+        #
+        if __M > 1:
+            __interpolator = numpy.dot(__Q,numpy.dot(__Qi_inv,__restrictedrhoMi))
+        else:
+            __interpolator = numpy.outer(__Q,numpy.outer(__Qi_inv,__restrictedrhoMi))
+        #
+        __residuM = __rhoM[:,__M].reshape((-1,1)) - __interpolator
+        #
+        if __LcCsts and len(__IncludedMagicPoints) > 0:
+            __im = numpy.argmax( numpy.abs(
+                numpy.take(__residuM, __IncludedMagicPoints, mode='clip')
+                ))
+        else:
+            __im = numpy.argmax( numpy.abs(
+                __residuM
+                ))
+        __Q = numpy.column_stack((__Q, __rhoM[:,__M]))
+        __I.append(__im)
+        #
+        __errors.append(__qivs[__M])
+        __mu.append(None) # Convention
+        #
+        __M = __M + 1
+    #
+    #--------------------------
+    if __errors[-1] < selfA._parameters["EpsilonEIM"]:
+        logging.debug("%s %s (%.1e)"%(selfA._name,"The convergence is obtained when reaching the required EIM tolerance",selfA._parameters["EpsilonEIM"]))
+    if __M >= __maxM:
+        logging.debug("%s %s (%i)"%(selfA._name,"The convergence is obtained when reaching the maximum number of RB dimension",__maxM))
+    logging.debug("%s The RB of size %i has been correctly build"%(selfA._name,__Q.shape[1]))
+    logging.debug("%s There are %i points that have been excluded from the potential optimal points"%(selfA._name,len(__ExcludedMagicPoints)))
+    if hasattr(selfA, "StoredVariables"):
+        selfA.StoredVariables["OptimalPoints"].store( __I )
+        if selfA._toStore("ReducedBasis"):
+            selfA.StoredVariables["ReducedBasis"].store( __Q )
+        if selfA._toStore("Residus"):
+            selfA.StoredVariables["Residus"].store( __errors )
+        if selfA._toStore("ExcludedPoints"):
+            selfA.StoredVariables["ExcludedPoints"].store( __ExcludedMagicPoints )
+        if selfA._toStore("SingularValues"):
+            selfA.StoredVariables["SingularValues"].store( __vs )
+    #
+    return __mu, __I, __Q, __errors
+
+# ==============================================================================
+# DEIM_online == EIM_online
+# ==============================================================================
+if __name__ == "__main__":
+    print('\n AUTODIAGNOSTIC\n')
index 4236143bab51c4a480253fd8b97c12456fdff861..aab8f9ce6408e3d4a42dfc7830e0bdd5633bd704 100644 (file)
@@ -139,7 +139,6 @@ def EIM_offline(selfA, EOS = None, Verbose = False):
         #
         __restrictedEOSi = __EOS[__I,:]
         #
-        __interpolator = numpy.empty(__EOS.shape)
         if __M > 1:
             __interpolator = numpy.dot(__Q,numpy.dot(__Qi_inv,__restrictedEOSi))
         else:
@@ -152,7 +151,7 @@ def EIM_offline(selfA, EOS = None, Verbose = False):
         __residuM = __dataForNextIter[:,__muM]
     #
     #--------------------------
-    if __eM < selfA._parameters["EpsilonEIM"]:
+    if __errors[-1] < selfA._parameters["EpsilonEIM"]:
         logging.debug("%s %s (%.1e)"%(selfA._name,"The convergence is obtained when reaching the required EIM tolerance",selfA._parameters["EpsilonEIM"]))
     if __M >= __maxM:
         logging.debug("%s %s (%i)"%(selfA._name,"The convergence is obtained when reaching the maximum number of RB dimension",__maxM))
index 98fe7ebf0817fb97813cc484644770f0a50b16f6..fc256881187e67a8e7e1a3808612e7ddea32e486 100644 (file)
 
 import numpy
 from daCore import BasicObjects
-from daAlgorithms.Atoms import ecweim, eosg
+from daAlgorithms.Atoms import ecweim
 
 # ==============================================================================
 class ElementaryAlgorithm(BasicObjects.Algorithm):
     def __init__(self):
-        # ModelInterpolationByROM
-        # ModelEvaluationByReducedInterpolation
-        # MeasuresInterpolationByReducedModel
-        #
         BasicObjects.Algorithm.__init__(self, "INTERPOLATIONBYREDUCEDMODEL")
         self.defineRequiredParameter(
             name     = "ReducedBasis",
index d015b64ec3d55b9c525e4ea71d1d240fa263fc37..2e08abeb50d878ab07f2f924135eb8f3295989d1 100644 (file)
@@ -22,7 +22,7 @@
 
 import numpy
 from daCore import BasicObjects
-from daAlgorithms.Atoms import ecweim, eosg
+from daAlgorithms.Atoms import ecweim, ecwdeim, eosg
 
 # ==============================================================================
 class ElementaryAlgorithm(BasicObjects.Algorithm):
@@ -30,12 +30,14 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
         BasicObjects.Algorithm.__init__(self, "MEASUREMENTSOPTIMALPOSITIONING")
         self.defineRequiredParameter(
             name     = "Variant",
-            default  = "PositioningBylcEIM",
+            default  = "lcEIM",
             typecast = str,
             message  = "Variant ou formulation de la méthode",
             listval  = [
-                "EIM",   "PositioningByEIM",
-                "lcEIM", "PositioningBylcEIM",
+                "EIM",    "PositioningByEIM",
+                "lcEIM",  "PositioningBylcEIM",
+                "DEIM",   "PositioningByDEIM",
+                "lcDEIM", "PositioningBylcDEIM",
                 ],
             )
         self.defineRequiredParameter(
@@ -119,6 +121,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 "OptimalPoints",
                 "ReducedBasis",
                 "Residus",
+                "SingularValues",
                 ]
             )
         self.defineRequiredParameter(
@@ -160,6 +163,27 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 raise ValueError("Snapshots or Operator have to be given in order to launch the analysis")
         #
         #--------------------------
+        elif self._parameters["Variant"] in ["lcDEIM", "PositioningBylcDEIM"]:
+            if len(self._parameters["EnsembleOfSnapshots"]) > 0:
+                if self._toStore("EnsembleOfSimulations"):
+                    self.StoredVariables["EnsembleOfSimulations"].store( self._parameters["EnsembleOfSnapshots"] )
+                ecwdeim.DEIM_offline(self, self._parameters["EnsembleOfSnapshots"])
+            elif isinstance(HO, dict):
+                ecwdeim.DEIM_offline(self, eosg.eosg(self, Xb, HO))
+            else:
+                raise ValueError("Snapshots or Operator have to be given in order to launch the analysis")
+        #
+        elif self._parameters["Variant"] in ["DEIM", "PositioningByDEIM"]:
+            if len(self._parameters["EnsembleOfSnapshots"]) > 0:
+                if self._toStore("EnsembleOfSimulations"):
+                    self.StoredVariables["EnsembleOfSimulations"].store( self._parameters["EnsembleOfSnapshots"] )
+                ecwdeim.DEIM_offline(self, self._parameters["EnsembleOfSnapshots"])
+            elif isinstance(HO, dict):
+                ecwdeim.DEIM_offline(self, eosg.eosg(self, Xb, HO))
+            else:
+                raise ValueError("Snapshots or Operator have to be given in order to launch the analysis")
+        #
+        #--------------------------
         else:
             raise ValueError("Error in Variant name: %s"%self._parameters["Variant"])
         #
index 6904e183ce6e8643059505b6bc01df207aea35b2..276f87a88c51d27acaf61354baf1f0562e6a9b72 100644 (file)
@@ -736,6 +736,7 @@ class Algorithm(object):
             - SimulatedObservationAtCurrentState : l'état observé H(X) à l'état courant
             - SimulatedObservationAtOptimum : l'état observé H(Xa) à l'optimum
             - SimulationQuantiles : états observés H(X) pour les quantiles demandés
+            - SingularValues : valeurs singulières provenant d'une décomposition SVD
         On peut rajouter des variables à stocker dans l'initialisation de
         l'algorithme élémentaire qui va hériter de cette classe
         """
@@ -811,6 +812,7 @@ class Algorithm(object):
         self.StoredVariables["SimulatedObservationAtCurrentState"]   = Persistence.OneVector(name = "SimulatedObservationAtCurrentState")
         self.StoredVariables["SimulatedObservationAtOptimum"]        = Persistence.OneVector(name = "SimulatedObservationAtOptimum")
         self.StoredVariables["SimulationQuantiles"]                  = Persistence.OneMatrix(name = "SimulationQuantiles")
+        self.StoredVariables["SingularValues"]                       = Persistence.OneVector(name = "SingularValues")
         #
         for k in self.StoredVariables:
             self.__canonical_stored_name[k.lower()] = k