From: Jean-Philippe ARGAUD Date: Fri, 4 Jan 2019 18:06:59 +0000 (+0100) Subject: Adding multi-functions input capabilities (7) X-Git-Tag: V9_3_0.1-prealpha1~16 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3cfbeab1a6f9659a21c210f98fa976f1f334647e;p=modules%2Fadao.git Adding multi-functions input capabilities (7) --- diff --git a/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py b/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py index 597eadc..c7ab08e 100644 --- a/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py +++ b/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py @@ -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 ) diff --git a/src/daComposant/daAlgorithms/KalmanFilter.py b/src/daComposant/daAlgorithms/KalmanFilter.py index 9e6fe0a..2f06348 100644 --- a/src/daComposant/daAlgorithms/KalmanFilter.py +++ b/src/daComposant/daAlgorithms/KalmanFilter.py @@ -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 ) diff --git a/src/daComposant/daCore/BasicObjects.py b/src/daComposant/daCore/BasicObjects.py index 4b596f2..c62b486 100644 --- a/src/daComposant/daCore/BasicObjects.py +++ b/src/daComposant/daCore/BasicObjects.py @@ -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]: diff --git a/test/CTestTestfileInstall.cmake.in b/test/CTestTestfileInstall.cmake.in index 57be46a..9a62457 100644 --- a/test/CTestTestfileInstall.cmake.in +++ b/test/CTestTestfileInstall.cmake.in @@ -34,4 +34,5 @@ SUBDIRS( test6711 test6901 test6902 + test6903 ) diff --git a/test/Makefile.am b/test/Makefile.am index 40a054c..7eca54e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 index 0000000..56ec8ac --- /dev/null +++ b/test/test6903/CTestTestfile.cmake @@ -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 index 0000000..a3efca6 --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_A.py @@ -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 index 0000000..19e8739 --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_B.py @@ -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 index 0000000..ef208eb --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_C.py @@ -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 index 0000000..cb03c86 --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_D.py @@ -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 index 0000000..503d99f --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_E.py @@ -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 index 0000000..f8afb07 --- /dev/null +++ b/test/test6903/Verification_des_mono_et_multi_fonctions_F.py @@ -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()