]> SALOME platform Git repositories - modules/adao.git/commitdiff
Salome HOME
Adding multi-functions input capabilities (7)
authorJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Fri, 4 Jan 2019 18:06:59 +0000 (19:06 +0100)
committerJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Fri, 4 Jan 2019 18:06:59 +0000 (19:06 +0100)
12 files changed:
src/daComposant/daAlgorithms/ExtendedKalmanFilter.py
src/daComposant/daAlgorithms/KalmanFilter.py
src/daComposant/daCore/BasicObjects.py
test/CTestTestfileInstall.cmake.in
test/Makefile.am
test/test6903/CTestTestfile.cmake [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_A.py [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_B.py [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_C.py [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_D.py [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_E.py [new file with mode: 0644]
test/test6903/Verification_des_mono_et_multi_fonctions_F.py [new file with mode: 0644]

index 597eadc90320efb7bc2db0b3067c085ee8131769..c7ab08eb7a6a7cb1c04d128180599da3f10c125d 100644 (file)
@@ -171,10 +171,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 if Cm is not None and Un is not None: # Attention : si Cm est aussi dans H, doublon !
                     d = d - Cm * Un
             #
-            _A = R + Ht * Pn_predicted * Ha
+            _A = R + numpy.dot(Ht, Pn_predicted * Ha)
             _u = numpy.linalg.solve( _A , d )
             Xn = Xn_predicted + Pn_predicted * Ha * _u
-            Kn = Pn_predicted * Ha * (R + Ht * Pn_predicted * Ha).I
+            Kn = Pn_predicted * Ha * (R + numpy.dot(Ht, Pn_predicted * Ha)).I
             Pn = Pn_predicted - Kn * Ht * Pn_predicted
             #
             self.StoredVariables["Analysis"].store( Xn.A1 )
index 9e6fe0a069bdaf1b459af0f4e78c30aa9ba46dfb..2f06348c127fcd09fb2fbd862a01bff237b20837 100644 (file)
@@ -147,10 +147,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 if Cm is not None and Un is not None: # Attention : si Cm est aussi dans H, doublon !
                     d = d - Cm * Un
             #
-            _A = R + Ht * Pn_predicted * Ha
+            _A = R + numpy.dot(Ht, Pn_predicted * Ha)
             _u = numpy.linalg.solve( _A , d )
             Xn = Xn_predicted + Pn_predicted * Ha * _u
-            Kn = Pn_predicted * Ha * (R + Ht * Pn_predicted * Ha).I
+            Kn = Pn_predicted * Ha * (R + numpy.dot(Ht, Pn_predicted * Ha)).I
             Pn = Pn_predicted - Kn * Ht * Pn_predicted
             #
             self.StoredVariables["Analysis"].store( Xn.A1 )
index 4b596f23ac37086af8487941c2449c718aa16598..c62b486446b4aa9ebd224388c9bf38505a96cff0 100644 (file)
@@ -65,7 +65,7 @@ class CacheManager(object):
         __alc = False
         __HxV = None
         for i in range(min(len(self.__listOPCV),self.__lenghtOR)-1,-1,-1):
-            if xValue.size != self.__listOPCV[i][0].size:
+            if not hasattr(xValue, 'size') or (xValue.size != self.__listOPCV[i][0].size):
                 # logging.debug("CM Différence de la taille %s de X et de celle %s du point %i déjà calculé", xValue.shape,i,self.__listOPCP[i].shape)
                 continue
             if numpy.linalg.norm(numpy.ravel(xValue) - self.__listOPCV[i][0]) < self.__tolerBP * self.__listOPCV[i][2]:
index 57be46a4e87641d702e0e74e51c4c9fac8905ea0..9a62457e78b94d985384c14d6355dc0c40af17b4 100644 (file)
@@ -34,4 +34,5 @@ SUBDIRS(
     test6711
     test6901
     test6902
+    test6903
     )
index 40a054cf37e7c9e53ad1c242c907df16fb643174..7eca54e390b08f5be3f2b955f8b9bdd04b9c5b5c 100644 (file)
@@ -21,7 +21,7 @@
 
 include $(top_srcdir)/adm_local/make_common_starter.am
 
-EXTRA_DIST = test1001 test1002 test6701 test6702 test6703 test6901 test6902 CTestTestfileInstall.cmake.in
+EXTRA_DIST = test1001 test1002 test6701 test6702 test6703 test6901 test6902 test6903 CTestTestfileInstall.cmake.in
 
 DIR = $(top_srcdir)/test/
 
@@ -37,6 +37,7 @@ install-data-local:
        cp -R $(DIR)test6711 $(SALOMETESTDIR)
        cp -R $(DIR)test6901 $(SALOMETESTDIR)
        cp -R $(DIR)test6902 $(SALOMETESTDIR)
+       cp -R $(DIR)test6903 $(SALOMETESTDIR)
        cp    $(DIR)CTestTestfileInstall.cmake.in $(SALOMETESTDIR)/CTestTestfile.cmake
 
 uninstall-local:
@@ -49,4 +50,5 @@ uninstall-local:
        rm -rf $(SALOMETESTDIR)/test6711
        rm -rf $(SALOMETESTDIR)/test6901
        rm -rf $(SALOMETESTDIR)/test6902
+       rm -rf $(SALOMETESTDIR)/test6903
        rm     $(SALOMETESTDIR)/CTestTestfile.cmake
diff --git a/test/test6903/CTestTestfile.cmake b/test/test6903/CTestTestfile.cmake
new file mode 100644 (file)
index 0000000..56ec8ac
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2008-2018 EDF R&D
+#
+# This file is part of SALOME ADAO module
+#
+# 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, or (at your option) any later version.
+#
+# 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
+#
+
+SET(TEST_NAMES
+  Verification_des_mono_et_multi_fonctions_A
+  Verification_des_mono_et_multi_fonctions_B
+  Verification_des_mono_et_multi_fonctions_C
+  Verification_des_mono_et_multi_fonctions_D
+  Verification_des_mono_et_multi_fonctions_E
+  Verification_des_mono_et_multi_fonctions_F
+  )
+
+FOREACH(tfile ${TEST_NAMES})
+  SET(TEST_NAME ADAO_${tfile})
+  ADD_TEST(${TEST_NAME} python ${tfile}.py)
+  #ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+  SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+ENDFOREACH()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_A.py b/test/test6903/Verification_des_mono_et_multi_fonctions_A.py
new file mode 100644 (file)
index 0000000..a3efca6
--- /dev/null
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+M = numpy.matrix("1 0 0;0 2 0;0 0 3")
+def MonoFonction( x ):
+    return M * numpy.asmatrix(numpy.ravel( x )).T
+
+def MultiFonction( xserie ):
+    _mulHX = []
+    for _subX in xserie:
+        _mulHX.append( M * numpy.asmatrix(numpy.ravel( _subX )).T )
+    return _mulHX
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes non-temporels
+    en utilisant une fonction lineaire et carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "Bounds":[[-1,10.],[-1,10.],[-1,10.]]})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1")
+        adaopy.setObservationOperator(OneFunction = MonoFonction)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "Bounds":[[-1,10.],[-1,10.],[-1,10.]]})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1")
+        adaopy.setObservationOperator(OneFunction = MultiFonction, InputAsMF = True)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_B.py b/test/test6903/Verification_des_mono_et_multi_fonctions_B.py
new file mode 100644 (file)
index 0000000..19e8739
--- /dev/null
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+M = numpy.matrix("1 0 0;0 2 0;0 0 3")
+def MonoFonction( x ):
+    return M * numpy.asmatrix(numpy.ravel( x )).T
+
+def MultiFonction( xserie ):
+    _mulHX = []
+    for _subX in xserie:
+        _mulHX.append( M * numpy.asmatrix(numpy.ravel( _subX )).T )
+    return _mulHX
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes temporels
+    en utilisant une fonction lineaire et carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1")
+        adaopy.setObservationOperator(OneFunction = MonoFonction)
+        adaopy.setEvolutionError     (ScalarSparseMatrix = 1.)
+        adaopy.setEvolutionModel     (Matrix = "1 0 0;0 1 0;0 0 1")
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1")
+        adaopy.setObservationOperator(OneFunction = MultiFonction, InputAsMF = True)
+        adaopy.setEvolutionError     (ScalarSparseMatrix = 1.)
+        adaopy.setEvolutionModel     (Matrix = "1 0 0;0 1 0;0 0 1")
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_C.py b/test/test6903/Verification_des_mono_et_multi_fonctions_C.py
new file mode 100644 (file)
index 0000000..ef208eb
--- /dev/null
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+M = numpy.matrix("1 0 0;0 2 0;0 0 3")
+def MonoFonction( x ):
+    return M * numpy.asmatrix(numpy.ravel( x )).T
+
+def MultiFonction( xserie ):
+    _mulHX = []
+    for _subX in xserie:
+        _mulHX.append( M * numpy.asmatrix(numpy.ravel( _subX )).T )
+    return _mulHX
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes autres
+    en utilisant une fonction lineaire et carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression", ):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"BoxBounds":3*[[-1,3]], "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 2 3")
+        adaopy.setObservationOperator(OneFunction = MonoFonction)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression", ):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"BoxBounds":3*[[-1,3]], "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 2 3")
+        adaopy.setObservationOperator(OneFunction = MultiFonction, InputAsMF = True)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_D.py b/test/test6903/Verification_des_mono_et_multi_fonctions_D.py
new file mode 100644 (file)
index 0000000..cb03c86
--- /dev/null
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+def ElementaryFunction01( InputArgument ):
+    """
+    Exemple de fonction non-lineaire et non-carree
+
+    L'argument en entree est un vecteur au sens mathematique, c'est-a-dire
+    une suite ordonnee de valeurs reelles. Au sens informatique, c'est tout
+    objet qui peut se transformer en une serie continue unidimensionnelle de
+    valeurs reelles. L'argument en sortie est un vecteur Numpy 1D.
+    """
+    #
+    if isinstance( InputArgument, (numpy.ndarray, numpy.matrix, list, tuple) ) or type(InputArgument).__name__ in ('generator','range'):
+        _subX = numpy.ravel(InputArgument)
+    else:
+        raise ValueError("ElementaryFunction01 unkown input type: %s"%(type(InputArgument).__name__,))
+    #
+    _OutputArgument = []
+    _OutputArgument.extend( (-1 + _subX).tolist() )
+    _OutputArgument.extend( numpy.cos(_subX/2).tolist() )
+    _OutputArgument.extend( numpy.exp((3.14 * _subX)).tolist() )
+    #
+    return numpy.ravel( _OutputArgument )
+
+def MultiFonction01( xSerie ):
+    """
+    Exemple de multi-fonction
+
+    Pour une liste ordonnee de vecteurs en entree, renvoie en sortie la liste
+    correspondante de valeurs de la fonction en argument
+    """
+    if not (isinstance( xSerie, (list, tuple) ) or type(xSerie).__name__ in ('generator','range')):
+        raise ValueError("MultiFonction01 unkown input type: %s"%(type(xSerie),))
+    #
+    _ySerie = []
+    for _subX in xSerie:
+        _ySerie.append( ElementaryFunction01( _subX ) )
+    #
+    return _ySerie
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes non-temporels
+    en utilisant une fonction non-lineaire et non-carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "Bounds":[[-1,10.],[-1,10.],[-1,10.]]})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = ElementaryFunction01)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "Bounds":[[-1,10.],[-1,10.],[-1,10.]]})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = MultiFonction01, InputAsMF = True)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("3DVAR", "Blue", "ExtendedBlue", "NonLinearLeastSquares", "DerivativeFreeOptimization"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_E.py b/test/test6903/Verification_des_mono_et_multi_fonctions_E.py
new file mode 100644 (file)
index 0000000..503d99f
--- /dev/null
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+def ElementaryFunction01( InputArgument ):
+    """
+    Exemple de fonction non-lineaire et non-carree
+
+    L'argument en entree est un vecteur au sens mathematique, c'est-a-dire
+    une suite ordonnee de valeurs reelles. Au sens informatique, c'est tout
+    objet qui peut se transformer en une serie continue unidimensionnelle de
+    valeurs reelles. L'argument en sortie est un vecteur Numpy 1D.
+    """
+    #
+    if isinstance( InputArgument, (numpy.ndarray, numpy.matrix, list, tuple) ) or type(InputArgument).__name__ in ('generator','range'):
+        _subX = numpy.ravel(InputArgument)
+    else:
+        raise ValueError("ElementaryFunction01 unkown input type: %s"%(type(InputArgument).__name__,))
+    #
+    _OutputArgument = []
+    _OutputArgument.extend( (-1 + _subX).tolist() )
+    _OutputArgument.extend( numpy.cos(_subX/2).tolist() )
+    _OutputArgument.extend( numpy.exp((3.14 * _subX)).tolist() )
+    #
+    return numpy.ravel( _OutputArgument )
+
+def MultiFonction01( xSerie ):
+    """
+    Exemple de multi-fonction
+
+    Pour une liste ordonnee de vecteurs en entree, renvoie en sortie la liste
+    correspondante de valeurs de la fonction en argument
+    """
+    if not (isinstance( xSerie, (list, tuple) ) or type(xSerie).__name__ in ('generator','range')):
+        raise ValueError("MultiFonction01 unkown input type: %s"%(type(xSerie),))
+    #
+    _ySerie = []
+    for _subX in xSerie:
+        _ySerie.append( ElementaryFunction01( _subX ) )
+    #
+    return _ySerie
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes temporels
+    en utilisant une fonction non-lineaire et non-carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = ElementaryFunction01)
+        adaopy.setEvolutionError     (ScalarSparseMatrix = 1.)
+        adaopy.setEvolutionModel     (Matrix = "1 0 0;0 1 0;0 0 1")
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = MultiFonction01, InputAsMF = True)
+        adaopy.setEvolutionError     (ScalarSparseMatrix = 1.)
+        adaopy.setEvolutionModel     (Matrix = "1 0 0;0 1 0;0 0 1")
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()
diff --git a/test/test6903/Verification_des_mono_et_multi_fonctions_F.py b/test/test6903/Verification_des_mono_et_multi_fonctions_F.py
new file mode 100644 (file)
index 0000000..f8afb07
--- /dev/null
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2018 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
+"Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
+
+# ==============================================================================
+import numpy, sys
+from adao import adaoBuilder
+
+def ElementaryFunction01( InputArgument ):
+    """
+    Exemple de fonction non-lineaire et non-carree
+
+    L'argument en entree est un vecteur au sens mathematique, c'est-a-dire
+    une suite ordonnee de valeurs reelles. Au sens informatique, c'est tout
+    objet qui peut se transformer en une serie continue unidimensionnelle de
+    valeurs reelles. L'argument en sortie est un vecteur Numpy 1D.
+    """
+    #
+    if isinstance( InputArgument, (numpy.ndarray, numpy.matrix, list, tuple) ) or type(InputArgument).__name__ in ('generator','range'):
+        _subX = numpy.ravel(InputArgument)
+    else:
+        raise ValueError("ElementaryFunction01 unkown input type: %s"%(type(InputArgument).__name__,))
+    #
+    _OutputArgument = []
+    _OutputArgument.extend( (-1 + _subX).tolist() )
+    _OutputArgument.extend( numpy.cos(_subX/2).tolist() )
+    _OutputArgument.extend( numpy.exp((3.14 * _subX)).tolist() )
+    #
+    return numpy.ravel( _OutputArgument )
+
+def MultiFonction01( xSerie ):
+    """
+    Exemple de multi-fonction
+
+    Pour une liste ordonnee de vecteurs en entree, renvoie en sortie la liste
+    correspondante de valeurs de la fonction en argument
+    """
+    if not (isinstance( xSerie, (list, tuple) ) or type(xSerie).__name__ in ('generator','range')):
+        raise ValueError("MultiFonction01 unkown input type: %s"%(type(xSerie),))
+    #
+    _ySerie = []
+    for _subX in xSerie:
+        _ySerie.append( ElementaryFunction01( _subX ) )
+    #
+    return _ySerie
+
+# ==============================================================================
+def test1():
+    """
+    Verification du fonctionnement identique pour les algorithmes autres
+    en utilisant une fonction non-lineaire et non-carree
+    """
+    print(test1.__doc__)
+    Xa = {}
+    #
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression", ):
+        print("")
+        msg = "Algorithme en test en MonoFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"BoxBounds":3*[[-1,3]], "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = ElementaryFunction01)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression", ):
+        print("")
+        msg = "Algorithme en test en MultiFonction : %s"%algo
+        print(msg+"\n"+"-"*len(msg))
+        #
+        adaopy = adaoBuilder.New()
+        adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"BoxBounds":3*[[-1,3]], "SetSeed":1000})
+        adaopy.setBackground         (Vector = [0,1,2])
+        adaopy.setBackgroundError    (ScalarSparseMatrix = 1.)
+        adaopy.setObservation        (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
+        adaopy.setObservationError   (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
+        adaopy.setObservationOperator(OneFunction = MultiFonction01, InputAsMF = True)
+        adaopy.setObserver("Analysis",Template="ValuePrinter")
+        adaopy.execute()
+        Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
+        del adaopy
+    #
+    print("")
+    msg = "Tests des ecarts attendus :"
+    print(msg+"\n"+"="*len(msg))
+    for algo in ("ParticleSwarmOptimization", "QuantileRegression"):
+        verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
+    print("  Les resultats obtenus sont corrects.")
+    print("")
+    #
+    return 0
+
+# ==============================================================================
+def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
+    """Comparaison de deux vecteurs"""
+    print("    Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
+    return max(abs(v2 - v1)) < precision
+
+def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
+    print("  Comparaisons :")
+    for algo1 in serie:
+        for algo2 in serie:
+            if algo1 is algo2: break
+            assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
+    print("  Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
+    sys.stdout.flush()
+
+#===============================================================================
+if __name__ == "__main__":
+    print('\nAUTODIAGNOSTIC\n')
+    test1()