1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2021 EDF R&D
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22 "Verification du fonctionnement correct d'entrees en mono ou multi-fonctions"
27 from adao import adaoBuilder
29 # ==============================================================================
31 def ElementaryFunction01( InputArgument ):
33 Exemple de fonction non-lineaire et non-carree
35 L'argument en entree est un vecteur au sens mathematique, c'est-a-dire
36 une suite ordonnee de valeurs reelles. Au sens informatique, c'est tout
37 objet qui peut se transformer en une serie continue unidimensionnelle de
38 valeurs reelles. L'argument en sortie est un vecteur Numpy 1D.
41 if isinstance( InputArgument, (numpy.ndarray, numpy.matrix, list, tuple) ) or type(InputArgument).__name__ in ('generator','range'):
42 _subX = numpy.ravel(InputArgument)
44 raise ValueError("ElementaryFunction01 unkown input type: %s"%(type(InputArgument).__name__,))
47 _OutputArgument.extend( (-1 + _subX).tolist() )
48 _OutputArgument.extend( numpy.cos(_subX/2).tolist() )
49 _OutputArgument.extend( numpy.exp((3.14 * _subX)).tolist() )
51 return numpy.ravel( _OutputArgument )
53 def MultiFonction01( xSerie ):
55 Exemple de multi-fonction
57 Pour une liste ordonnee de vecteurs en entree, renvoie en sortie la liste
58 correspondante de valeurs de la fonction en argument
60 if not (isinstance( xSerie, (list, tuple) ) or type(xSerie).__name__ in ('generator','range')):
61 raise ValueError("MultiFonction01 unkown input type: %s"%(type(xSerie),))
65 _ySerie.append( ElementaryFunction01( _subX ) )
69 # ==============================================================================
70 class Test_Adao(unittest.TestCase):
73 Verification du fonctionnement identique pour les algorithmes temporels
74 en utilisant une fonction non-lineaire et non-carree
76 print("\n "+self.test1.__doc__.strip()+"\n")
79 #~ for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
80 for algo in ("ExtendedKalmanFilter", "KalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
82 msg = "Algorithme en test en MonoFonction : %s"%algo
83 print(msg+"\n"+"-"*len(msg))
85 adaopy = adaoBuilder.New()
86 adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
87 adaopy.setBackground (Vector = [0,1,2])
88 adaopy.setBackgroundError (ScalarSparseMatrix = 1.)
89 adaopy.setObservation (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
90 adaopy.setObservationError (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
91 adaopy.setObservationOperator(OneFunction = ElementaryFunction01)
92 adaopy.setEvolutionError (ScalarSparseMatrix = 1.)
93 adaopy.setEvolutionModel (Matrix = "1 0 0;0 1 0;0 0 1")
94 adaopy.setObserver("Analysis",Template="ValuePrinter")
96 Xa["Mono/"+algo] = adaopy.get("Analysis")[-1]
99 #~ for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
100 for algo in ("ExtendedKalmanFilter", "KalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
102 msg = "Algorithme en test en MultiFonction : %s"%algo
103 print(msg+"\n"+"-"*len(msg))
105 adaopy = adaoBuilder.New()
106 adaopy.setAlgorithmParameters(Algorithm=algo, Parameters={"EpsilonMinimumExponent":-10, "SetSeed":1000})
107 adaopy.setBackground (Vector = [0,1,2])
108 adaopy.setBackgroundError (ScalarSparseMatrix = 1.)
109 adaopy.setObservation (Vector = [0.5,1.5,2.5,0.5,1.5,2.5,0.5,1.5,2.5])
110 adaopy.setObservationError (DiagonalSparseMatrix = "1 1 1 1 1 1 1 1 1")
111 adaopy.setObservationOperator(OneFunction = MultiFonction01, InputFunctionAsMulti = True)
112 adaopy.setEvolutionError (ScalarSparseMatrix = 1.)
113 adaopy.setEvolutionModel (Matrix = "1 0 0;0 1 0;0 0 1")
114 adaopy.setObserver("Analysis",Template="ValuePrinter")
116 Xa["Multi/"+algo] = adaopy.get("Analysis")[-1]
120 msg = "Tests des ecarts attendus :"
121 print(msg+"\n"+"="*len(msg))
122 #~ for algo in ("ExtendedKalmanFilter", "KalmanFilter", "EnsembleKalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
123 for algo in ("ExtendedKalmanFilter", "KalmanFilter", "UnscentedKalmanFilter", "4DVAR"):
124 verify_similarity_of_algo_results(("Multi/"+algo, "Mono/"+algo), Xa, 1.e-20)
125 print(" Les resultats obtenus sont corrects.")
130 # ==============================================================================
131 def almost_equal_vectors(v1, v2, precision = 1.e-15, msg = ""):
132 """Comparaison de deux vecteurs"""
133 print(" Difference maximale %s: %.2e"%(msg, max(abs(v2 - v1))))
134 return max(abs(v2 - v1)) < precision
136 def verify_similarity_of_algo_results(serie = [], Xa = {}, precision = 1.e-15):
137 print(" Comparaisons :")
140 if algo1 is algo2: break
141 assert almost_equal_vectors( Xa[algo1], Xa[algo2], precision, "entre %s et %s "%(algo1, algo2) )
142 print(" Algorithmes dont les resultats sont similaires a %.0e : %s\n"%(precision, serie,))
145 #===============================================================================
146 if __name__ == "__main__":
147 print("\nAUTODIAGNOSTIC\n==============")
148 sys.stderr = sys.stdout
149 unittest.main(verbosity=2)