From: Jean-Philippe ARGAUD Date: Sun, 18 Jan 2015 20:08:34 +0000 (+0100) Subject: Documentation corrections and improvements for outputs X-Git-Tag: V7_5_1rc1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=694dd096ef2980296e38feb14d4c108997d1c2fb;p=modules%2Fadao.git Documentation corrections and improvements for outputs --- diff --git a/doc/en/bibliography.rst b/doc/en/bibliography.rst index f6b2ed6..c154313 100644 --- a/doc/en/bibliography.rst +++ b/doc/en/bibliography.rst @@ -29,9 +29,9 @@ Bibliography .. [Argaud09] Argaud J.-P., Bouriquet B., Hunt J., *Data Assimilation from Operational and Industrial Applications to Complex Systems*, Mathematics Today, pp.150-152, October 2009 -.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/newsevents/training/rcourse_notes/pdf_files/Assim_concepts.pdf +.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/sites/default/files/Data%20assimilation%20concepts%20and%20methods.pdf -.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2004-2008, http://cerea.enpc.fr/HomePages/bocquet/assim.pdf +.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2014, http://cerea.enpc.fr/HomePages/bocquet/Doc/assim-mb.pdf .. [Buchinsky98] Buchinsky M., *Recent Advances in Quantile Regression Models: A Practical Guidline for Empirical Research*, Journal of Human Resources, 33(1), pp.88-126, 1998 diff --git a/doc/en/examples.rst b/doc/en/examples.rst index 4b4c8b0..c215ac7 100644 --- a/doc/en/examples.rst +++ b/doc/en/examples.rst @@ -636,4 +636,4 @@ The state at the first step is the randomly generated background state available in the "*YACS Container Log*" window, obtained through the right click menu of the "*proc*" window in the YACS executed scheme. -.. [#] For more information on YACS, see the *YACS module User's Guide* available in the main "*Help*" menu of SALOME platform. +.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform. diff --git a/doc/en/license.rst b/doc/en/license.rst index 2aa91be..637bae5 100644 --- a/doc/en/license.rst +++ b/doc/en/license.rst @@ -55,7 +55,7 @@ GPL), as stated here and in the source files:: See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com In addition, we expect that all publications describing work using this -software, or all commercial products using it, quote at least one of the +software, or all commercial or not products using it, quote at least one of the references given below: * *ADAO, a SALOME module for Data Assimilation and Optimization*, diff --git a/doc/en/ref_algorithm_3DVAR.rst b/doc/en/ref_algorithm_3DVAR.rst index 22ae3b4..b7d4170 100644 --- a/doc/en/ref_algorithm_3DVAR.rst +++ b/doc/en/ref_algorithm_3DVAR.rst @@ -300,6 +300,18 @@ The conditional outputs of the algorithm are the following: Example : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *List of vectors*. Each element is a vector corresponding to the observed state which realize the required quantile, in the same order than the diff --git a/doc/en/ref_algorithm_Blue.rst b/doc/en/ref_algorithm_Blue.rst index 169ddd6..59defa9 100644 --- a/doc/en/ref_algorithm_Blue.rst +++ b/doc/en/ref_algorithm_Blue.rst @@ -246,6 +246,18 @@ The conditional outputs of the algorithm are the following: Example : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *List of vectors*. Each element is a vector corresponding to the observed state which realize the required quantile, in the same order than the diff --git a/doc/en/ref_algorithm_ExtendedBlue.rst b/doc/en/ref_algorithm_ExtendedBlue.rst index 1ceb984..76b1ce5 100644 --- a/doc/en/ref_algorithm_ExtendedBlue.rst +++ b/doc/en/ref_algorithm_ExtendedBlue.rst @@ -251,6 +251,18 @@ The conditional outputs of the algorithm are the following: Example : ``sQuantiles = ADD.get("SimulationQuantiles")[:]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + See also ++++++++ diff --git a/doc/en/ref_algorithm_LinearLeastSquares.rst b/doc/en/ref_algorithm_LinearLeastSquares.rst index b6049da..b287b71 100644 --- a/doc/en/ref_algorithm_LinearLeastSquares.rst +++ b/doc/en/ref_algorithm_LinearLeastSquares.rst @@ -155,6 +155,12 @@ The conditional outputs of the algorithm are the following: Example : ``oma = ADD.get("OMA")[-1]`` + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + See also ++++++++ diff --git a/doc/en/ref_algorithm_NonLinearLeastSquares.rst b/doc/en/ref_algorithm_NonLinearLeastSquares.rst index 52aa00a..06d062f 100644 --- a/doc/en/ref_algorithm_NonLinearLeastSquares.rst +++ b/doc/en/ref_algorithm_NonLinearLeastSquares.rst @@ -242,6 +242,12 @@ The conditional outputs of the algorithm are the following: Example : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + See also ++++++++ diff --git a/doc/en/ref_algorithm_ParticleSwarmOptimization.rst b/doc/en/ref_algorithm_ParticleSwarmOptimization.rst index 5ebca5c..c951355 100644 --- a/doc/en/ref_algorithm_ParticleSwarmOptimization.rst +++ b/doc/en/ref_algorithm_ParticleSwarmOptimization.rst @@ -240,6 +240,18 @@ The conditional outputs of the algorithm are the following: Example : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + See also ++++++++ diff --git a/doc/en/ref_algorithm_QuantileRegression.rst b/doc/en/ref_algorithm_QuantileRegression.rst index 3abc14c..c1f83a0 100644 --- a/doc/en/ref_algorithm_QuantileRegression.rst +++ b/doc/en/ref_algorithm_QuantileRegression.rst @@ -195,6 +195,18 @@ The conditional outputs of the algorithm are the following: Example : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + See also ++++++++ diff --git a/doc/en/ref_output_variables.rst b/doc/en/ref_output_variables.rst index f27b735..edc1aa4 100644 --- a/doc/en/ref_output_variables.rst +++ b/doc/en/ref_output_variables.rst @@ -26,12 +26,14 @@ Variables and informations available at the output -------------------------------------------------- -How to obtain information available at the output -+++++++++++++++++++++++++++++++++++++++++++++++++ +How to obtain the information available at the output ++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. index:: single: UserPostAnalysis .. index:: single: algoResults +.. index:: single: getResults .. index:: single: get +.. index:: single: ADD At the output, after executing data assimilation, optimization or checking study, there are variables and information originating from the calculation. The @@ -46,10 +48,10 @@ output port "*algoResults*" of the calculation block): #. In the case where the user defines the post-processing in his ADAO case, it uses an external script file or commands in the field type "*String*" or "*Template*". The script it provides has a fixed variable "*ADD*" in the namespace. #. In the case where the user defines the post-processing in its YACS scheme by a Python node located after the block of calculation, it should add a input port of type "*pyobj*" named for example "*Study*", graphically connected to the output port "*algoResults*" of the calculation block. The Python post-processing node must then start with ``ADD = Study.getResults()``. - -In all cases, the post-processing of the user has in the namespace a variable -whose name is "*ADD*", and whose only available method is named ``get``. The -arguments of this method are an output information name, as described in the +Templates are given hereafter as :ref:`subsection_r_o_v_Template`. In all cases, +the post-processing of the user has in the namespace a variable whose name is +"*ADD*", and whose only available method is named ``get``. The arguments of this +method are an output information name, as described in the :ref:`subsection_r_o_v_Inventaire`. For example, to have the optimal state after a data assimilation or optimization @@ -62,6 +64,72 @@ input variables that are by nature only a unique specimen, the value itself). One can then request a particular item in the list by the standard list commands (especially ``[-1]`` for the last, and ``[:]`` for all items). +.. _subsection_r_o_v_Template: + +Examples of Python scripts to obtain or treat the outputs ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. index:: single: Template +.. index:: single: AnalysisPrinter +.. index:: single: AnalysisSaver +.. index:: single: AnalysisPrinterAndSaver + +These examples present Python commands or scripts which allow to obtain or to +treat the ouput of an algorithm run. To help the user, they are directly +available in the user interface, when building the ADAO case in EFICAS, in the +"*Template*" type fields. In an equivalent way, these commands can be integrated +in an external user script (and inserted in the ADAO case by a "*Script*" type +input) or can exist as a string, including line feeds (and inserted in the ADAO +case by a "*String*" type input). Lot of variants can be build from these +simple examples, the main objective beeing to help the user to elaborate the +exact procedure he needs in output. + +The first example (named "*AnalysisPrinter*" in the inputs of type +"*Template*") consists in printing, in the standard log output, the value of the +analysis or the optimal state, noted as :math:`\mathbf{x}^a` in the section +:ref:`section_theory`. It is realized by the commands:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + print 'Analysis:',xa" + +The ``numpy.ravel`` function is here to be sure that the ``xa`` variable will +contain a real unidimensional vector, whatever the previoux computing choices +are. + +A second example (named "*AnalysisSaver*" in the inputs of type "*Template*") +consists in saving on file the value of the analysis or the optimal state +:math:`\mathbf{x}^a`. It is realized by the commands:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + f='/tmp/analysis.txt' + print 'Analysis saved in "%s"'%f + numpy.savetxt(f,xa)" + +The chosen recording file is a text one named ``/tmp/analysis.txt``. + +It is easy to combine these two examples by building a third one (named +"*AnalysisPrinterAndSaver*" in the inputs of type "*Template*"). It consists in +simultaneously printing in the standard log output and in saving on file the +value of :math:`\mathbf{x}^a`. It is realized by the commands:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + print 'Analysis:',xa + f='/tmp/analysis.txt' + print 'Analysis saved in "%s"'%f + numpy.savetxt(f,xa) + +To facilitate these examples extension for user needs, we recall that all the +SALOME functions are available at the same level than these commands. The user +can for example request for graphical representation with the PARAVIS [#]_ or +other modules, for computating operations driven by YACS [#]_ or an another +module, etc. + +Other usage examples are also given for :ref:`section_u_step4` of the +:ref:`section_using` section, or in part :ref:`section_examples`. + Cross compliance of the information available at the output +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -223,9 +291,25 @@ of availability. They are the following, in alphabetical order: Example : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *List of vectors*. Each element is a vector of observation simulated from + the background :math:`\mathbf{x}^b`. + + Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *List of vectors*. Each element is a vector of observation simulated from + the analysis or optimal state :math:`\mathbf{x}^a`. + + Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *List of vectors*. Each element is a vector corresponding to the observed state which realize the required quantile, in the same order than the quantiles required by the user. Example : ``sQuantiles = ADD.get("SimulationQuantiles")[:]`` + +.. [#] For more information on PARAVIS, see the *PARAVIS module* and its integrated help available from the main menu *Help* of the SALOME platform. + +.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform. diff --git a/doc/en/using.rst b/doc/en/using.rst index 629b860..bfbfe2d 100644 --- a/doc/en/using.rst +++ b/doc/en/using.rst @@ -70,6 +70,8 @@ SALOME or not. Each step will be detailed in the next section. +.. _section_u_step1: + STEP 1: Activate the ADAO module and use the editor GUI ------------------------------------------------------- @@ -96,6 +98,8 @@ create a new ADAO case, and you will see: .. centered:: **The EFICAS editor for cases definition in module ADAO** +.. _section_u_step2: + STEP 2: Build and modify the ADAO case, and save it --------------------------------------------------- @@ -137,6 +141,8 @@ used for JDC EFICAS files. This will generate a pair of files describing the ADAO case, with the same base name, the first one being completed by a "*.comm*" extension and the second one by a "*.py*" extension [#]_. +.. _section_u_step3: + STEP 3: Export the ADAO case as a YACS scheme --------------------------------------------- @@ -159,6 +165,8 @@ same directory and with the same base name as the ADAO saved case, only changing its extension to "*.xml*". Be careful, *if the XML file name already exist, the file will be overwritten without prompting for replacing the XML file*. +.. _section_u_step4: + STEP 4: Supplement and modify the YACS scheme, and save it ---------------------------------------------------------- @@ -177,9 +185,11 @@ evaluation of the results has to be done in the physical context of the simulation used by the data assimilation procedure. The post-processing can be provided through the "*UserPostAnalysis*" ADAO keyword as a script or a string, by templates, or can be build as YACS nodes. These two ways of building the -post-processing can use all the SALOME possibilities. +post-processing can use all the SALOME possibilities. See the part describing +:ref:`section_ref_output_variables`, or the help for each algorithm, for the +full description of these elements. -In details, the YACS scheme has an "*algoResults*" output port of the +In practice, the YACS scheme has an "*algoResults*" output port of the computation bloc, which gives access to an object of type "*pyobj*" named hereafter "*ADD*", containing all the calculation results. These results can be obtained by retrieving the named variables stored along the calculation. The @@ -206,6 +216,8 @@ Such method can be used to print results, or to convert these ones to structures that can be used in the native or external SALOME post-processing. A simple example is given in the section :ref:`section_examples`. +.. _section_u_step5: + STEP 5: Execute the YACS case and obtain the results ---------------------------------------------------- @@ -237,10 +249,10 @@ shown in the "*YACS Container Log*". The execution can also be done using a shell script, as described in the section :ref:`section_advanced`. -.. [#] For more information on EFICAS, see the *EFICAS module* available in SALOME platform. +.. [#] For more information on EFICAS, see the *EFICAS module* and its integrated help available from the main menu *Help* of the SALOME platform. .. [#] The use of physical simulation code in the data assimilation elementary operators is illustrated or described in the following main parts. -.. [#] For more information on YACS, see the *YACS module User's Guide* available in the main "*Help*" menu of SALOME platform. +.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform. .. [#] This intermediary python file can also be used as described in the section :ref:`section_advanced`. diff --git a/doc/fr/bibliography.rst b/doc/fr/bibliography.rst index f3b2a44..1757095 100644 --- a/doc/fr/bibliography.rst +++ b/doc/fr/bibliography.rst @@ -29,9 +29,9 @@ Bibliographie .. [Argaud09] Argaud J.-P., Bouriquet B., Hunt J., *Data Assimilation from Operational and Industrial Applications to Complex Systems*, Mathematics Today, pp.150-152, October 2009 -.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/newsevents/training/rcourse_notes/pdf_files/Assim_concepts.pdf +.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/sites/default/files/Data%20assimilation%20concepts%20and%20methods.pdf -.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2004-2008, http://cerea.enpc.fr/HomePages/bocquet/assim.pdf +.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2014, http://cerea.enpc.fr/HomePages/bocquet/Doc/assim-mb.pdf .. [Buchinsky98] Buchinsky M., *Recent Advances in Quantile Regression Models: A Practical Guidline for Empirical Research*, Journal of Human Resources, 33(1), pp.88-126, 1998 diff --git a/doc/fr/examples.rst b/doc/fr/examples.rst index 64f0a44..7207efb 100644 --- a/doc/fr/examples.rst +++ b/doc/fr/examples.rst @@ -671,4 +671,4 @@ al disponibles dans la fenêtre "*fenêtre de sortie de YACS*", que l'on obtient par clic droit sur la fenêtre "*proc*" du schéma YACS exécuté. -.. [#] Pour de plus amples informations sur YACS, voir le *Guide utilisateur du module YACS* disponible dans le menu principal *Aide* de l'environnement SALOME. +.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME. diff --git a/doc/fr/license.rst b/doc/fr/license.rst index 640f824..6def81d 100644 --- a/doc/fr/license.rst +++ b/doc/fr/license.rst @@ -55,8 +55,8 @@ tel qu'il est d See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com En outre, nous souhaitons que toute publication décrivant des travaux utilisant -ce module, ou tout produit commercial l'utilisant, cite au moins l'une des -références ci-dessous : +ce module, ou tout produit commercial ou non l'utilisant, cite au moins l'une +des références ci-dessous : * *ADAO, a SALOME module for Data Assimilation and Optimization*, http://www.salome-platform.org/ diff --git a/doc/fr/ref_algorithm_3DVAR.rst b/doc/fr/ref_algorithm_3DVAR.rst index 387b31a..c83abf1 100644 --- a/doc/fr/ref_algorithm_3DVAR.rst +++ b/doc/fr/ref_algorithm_3DVAR.rst @@ -309,6 +309,18 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état observé qui réalise le quantile demandé, dans le même ordre que les diff --git a/doc/fr/ref_algorithm_Blue.rst b/doc/fr/ref_algorithm_Blue.rst index 53219ba..9b520ff 100644 --- a/doc/fr/ref_algorithm_Blue.rst +++ b/doc/fr/ref_algorithm_Blue.rst @@ -251,6 +251,18 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état observé qui réalise le quantile demandé, dans le même ordre que les diff --git a/doc/fr/ref_algorithm_ExtendedBlue.rst b/doc/fr/ref_algorithm_ExtendedBlue.rst index d06696f..dfbee64 100644 --- a/doc/fr/ref_algorithm_ExtendedBlue.rst +++ b/doc/fr/ref_algorithm_ExtendedBlue.rst @@ -248,6 +248,18 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état observé qui réalise le quantile demandé, dans le même ordre que les diff --git a/doc/fr/ref_algorithm_LinearLeastSquares.rst b/doc/fr/ref_algorithm_LinearLeastSquares.rst index c817a5e..efee489 100644 --- a/doc/fr/ref_algorithm_LinearLeastSquares.rst +++ b/doc/fr/ref_algorithm_LinearLeastSquares.rst @@ -160,6 +160,12 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``oma = ADD.get("OMA")[-1]`` + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + Voir aussi ++++++++++ diff --git a/doc/fr/ref_algorithm_NonLinearLeastSquares.rst b/doc/fr/ref_algorithm_NonLinearLeastSquares.rst index 6b9a817..542ad2b 100644 --- a/doc/fr/ref_algorithm_NonLinearLeastSquares.rst +++ b/doc/fr/ref_algorithm_NonLinearLeastSquares.rst @@ -253,6 +253,12 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + Voir aussi ++++++++++ diff --git a/doc/fr/ref_algorithm_ParticleSwarmOptimization.rst b/doc/fr/ref_algorithm_ParticleSwarmOptimization.rst index b5ebfd6..ffc989f 100644 --- a/doc/fr/ref_algorithm_ParticleSwarmOptimization.rst +++ b/doc/fr/ref_algorithm_ParticleSwarmOptimization.rst @@ -247,6 +247,18 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + Voir aussi ++++++++++ diff --git a/doc/fr/ref_algorithm_QuantileRegression.rst b/doc/fr/ref_algorithm_QuantileRegression.rst index 4cc7d2b..9a1b4d0 100644 --- a/doc/fr/ref_algorithm_QuantileRegression.rst +++ b/doc/fr/ref_algorithm_QuantileRegression.rst @@ -200,6 +200,18 @@ Les sorties conditionnelles de l'algorithme sont les suivantes: Exemple : ``omb = ADD.get("OMB")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + Voir aussi ++++++++++ diff --git a/doc/fr/ref_output_variables.rst b/doc/fr/ref_output_variables.rst index a8760d8..d31383f 100644 --- a/doc/fr/ref_output_variables.rst +++ b/doc/fr/ref_output_variables.rst @@ -26,17 +26,19 @@ Variables et informations disponibles en sortie ----------------------------------------------- -Comment obtenir des informations disponibles en sortie +Comment obtenir les informations disponibles en sortie ++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. index:: single: UserPostAnalysis .. index:: single: algoResults +.. index:: single: getResults .. index:: single: get +.. index:: single: ADD En sortie, après exécution d'une assimilation de données, d'une optimisation ou d'une vérification, on dispose de variables et d'informations issues du calcul. L'obtention de ces informations se fait ensuite de manière standardisée -à l'aide de l'étape de post-processing du calcul. +à l'aide de l'étape de post-processing du calcul. L'étape est aisément identifiée par l'utilisateur dans son cas ADAO de définition (par la mot-clé "*UserPostAnalysis*") ou dans son schéma YACS @@ -46,10 +48,12 @@ graphiquement au port de sortie "*algoResults*" du bloc de calcul): #. Dans le cas où l'utilisateur définit le post-processing dans son cas ADAO, il utilise un fichier script externe ou des commandes dans le champ de type "*String*" ou "*Template*". Le script qu'il fournit dispose d'une variable fixe "*ADD*" dans l'espace de noms. #. Dans le cas où l'utilisateur définit le post-processing dans son schéma YACS par un noeud Python situé après le bloc de calcul, il doit ajouter un port d'entrée de type "*pyobj*" nommé par exemple "*Study*", relié graphiquement au port de sortie "*algoResults*" du bloc de calcul. Le noeud Python de post-processing doit ensuite débuter par ``ADD = Study.getResults()``. -Dans tous les cas, le post-processing de l'utilisateur dispose dans l'espace de -noms d'une variable dont le nom est "*ADD*", et dont l'unique méthode utilisable -est nommée ``get``. Les arguments de cette méthode sont un nom d'information de -sortie, comme décrit dans l':ref:`subsection_r_o_v_Inventaire`. +Des patrons (ou "templates") sont donnés ci-après en +:ref:`subsection_r_o_v_Template`. Dans tous les cas, le post-processing de +l'utilisateur dispose dans l'espace de noms d'une variable dont le nom est +"*ADD*", et dont l'unique méthode utilisable est nommée ``get``. Les arguments +de cette méthode sont un nom d'information de sortie, comme décrit dans +l':ref:`subsection_r_o_v_Inventaire`. Par exemple, pour avoir l'état optimal après un calcul d'assimilation de données ou d'optimisation, on utilise l'appel suivant:: @@ -62,6 +66,74 @@ valeur elle-m les commandes standards de liste (en particulier ``[-1]`` pour le dernier, et ``[:]`` pour tous les éléments). +.. _subsection_r_o_v_Template: + +Exemples de scripts Python pour obtenir ou traiter les sorties +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. index:: single: Template +.. index:: single: AnalysisPrinter +.. index:: single: AnalysisSaver +.. index:: single: AnalysisPrinterAndSaver + +Ces exemples présentent des commandes ou scripts Python qui permettent d'obtenir +ou de traiter les sorties d'une exécution d'algorithme. Pour aider l'utilisateur, +ils sont directement disponibles dans l'interface, à la construction du cas ADAO +dans EFICAS, dans les champs de type "*Template*". De manière équivalente, ces +commandes peuvent être contenues dans un script utilisateur externe (et insérées +dans le cas ADAO par l'entrée de type "*Script*") ou contenues dans une chaîne +de caractères, y compris les retour à la ligne (et insérées dans le cas ADAO par +l'entrée de type "*String*"). De nombreuses variantes peuvent être imaginées à +partir de ces exemples simples, l'objectif étant surtout d'aider l'utilisateur à +effectuer le traitement exact dont il a besoin en sortie. + +Le premier exemple (appelé "*AnalysisPrinter*" dans les entrées de type +"*Template*") consiste à afficher, dans la sortie standard d'exécution, la +valeur de l'analyse ou de l'état optimal, noté :math:`\mathbf{x}^a` dans la +partie :ref:`section_theory`. Cela se réalise par les commandes:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + print 'Analysis:',xa" + +La fonction ``numpy.ravel`` assure simplement que la variable ``xa`` contienne +un vrai vecteur unidimensionnel, quels que soient les choix informatiques +précédents. + +Un second exemple (appelé "*AnalysisSaver*" dans les entrées de type +"*Template*") consiste à enregistrer sur fichier la valeur de l'analyse ou de +l'état optimal :math:`\mathbf{x}^a`. Cela se réalise par les commandes:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + f='/tmp/analysis.txt' + print 'Analysis saved in "%s"'%f + numpy.savetxt(f,xa)" + +Le fichier d'enregistrement choisi est un fichier texte ``/tmp/analysis.txt``. + +Il est aisé de combiner ces deux exemples pour en construire un troisième +(appelé "*AnalysisPrinterAndSaver*" dans les entrées de type "*Template*"). Il +consiste à simultanément afficher dans la sortie standard d'exécution et à +enregistrer sur fichier la valeur de :math:`\mathbf{x}^a`. Cela se réalise par +les commandes:: + + import numpy + xa=numpy.ravel(ADD.get('Analysis')[-1]) + print 'Analysis:',xa + f='/tmp/analysis.txt' + print 'Analysis saved in "%s"'%f + numpy.savetxt(f,xa) + +Pour faciliter l'extension de ces exemples selon les besoins utilisateurs, on +rappelle que l'ensemble des fonctions de SALOME sont disponibles au même niveau +que ces commandes. L'utilisateur peut en particulier requérir des actions de +représentation graphique avec le module PARAVIS [#]_ ou d'autres modules, des +actions de calcul pilotés par YACS [#]_ ou un autre module, etc. + +D'autres exemples d'utilisation sont aussi donnés en :ref:`section_u_step4` de +la partie :ref:`section_using`, ou en partie :ref:`section_examples`. + Conditionnalité des informations disponibles en sortie ++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -228,9 +300,25 @@ alphab Exemple : ``so2 = ADD.get("SigmaObs")[-1]`` + SimulatedObservationAtBackground + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'ébauche :math:`\mathbf{x}^b`. + + Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]`` + + SimulatedObservationAtOptimum + *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à + partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`. + + Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]`` + SimulationQuantiles *Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état observé qui réalise le quantile demandé, dans le même ordre que les quantiles requis par l'utilisateur. Exemple : ``sQuantiles = ADD.get("SimulationQuantiles")[:]`` + +.. [#] Pour de plus amples informations sur PARAVIS, voir le *module PARAVIS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME. + +.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME. diff --git a/doc/fr/using.rst b/doc/fr/using.rst index 78153c6..1c4cbf8 100644 --- a/doc/fr/using.rst +++ b/doc/fr/using.rst @@ -72,6 +72,8 @@ suivantes:** Chaque étape est détaillée dans la section suivante. +.. _section_u_step1: + ÉTAPE 1 : Activer le module ADAO et utiliser l'interface graphique d'édition (GUI) ---------------------------------------------------------------------------------- @@ -99,6 +101,8 @@ le menu principal "*ADAO*") pour cr .. centered:: **L'éditeur EFICAS pour la définition des cas dans le module ADAO** +.. _section_u_step2: + ÉTAPE 2 : Créer et modifier le cas ADAO, et l'enregistrer --------------------------------------------------------- @@ -144,6 +148,8 @@ JDC d'EFICAS. Cette action va g ADAO, avec le même nom de base, le premier présentant une extension "*.comm*" et le second une extension "*.py*" [#]_. +.. _section_u_step3: + ÉTAPE 3 : Exporter le cas ADAO comme un schéma YACS --------------------------------------------------- @@ -168,6 +174,8 @@ changeant simplement son extension en "*.xml*". Attention, *si le nom de fichier XML existe déjà, le fichier est écrasé sans avertissement sur le remplacement du fichier XML*. +.. _section_u_step4: + ÉTAPE 4 : Compléter et modifier le schéma YACS, et l'enregistrer ---------------------------------------------------------------- @@ -187,10 +195,12 @@ post-processing peut d'ADAO sous la forme d'un fichier de script ou d'une chaîne de caractères, par des patrons ("templates"), ou peut être construit comme des noeuds YACS. Ces deux manières de construire le post-processing peuvent utiliser toutes les -capacités de SALOME. +capacités de SALOME. On se reportera à la partie traitant des +:ref:`section_ref_output_variables`, ou à l'aide de chaque algorithme, pour la +description complète de ces éléments. -Dans le détail, le schéma YACS dispose d'un port de sortie "*algoResults*" dans -le bloc de calcul, qui donne accès à un objet de type "*pyobj*" nommé ci-aprés +En pratique, le schéma YACS dispose d'un port de sortie "*algoResults*" dans le +bloc de calcul, qui donne accès à un objet de type "*pyobj*" nommé ci-aprés "*ADD*", qui contient tous les résultats de calcul. Ces résultats peuvent être obtenus en récupérant les variables nommées stockées au cours des calculs. L'information principale est la variable "*Analysis*", qui peut être obtenue par @@ -217,6 +227,8 @@ convertir dans des structures qui peuvent natif ou externe à SALOME. Un exemple simple est disponible dans la section :ref:`section_examples`. +.. _section_u_step5: + ÉTAPE 5 : Exécuter le schéma YACS et obtenir les résultats ---------------------------------------------------------- @@ -250,10 +262,10 @@ pr L'exécution peut aussi être conduite en utilisant un script de commandes shell, comme décrit dans la section :ref:`section_advanced`. -.. [#] Pour de plus amples informations sur EFICAS, voir le *module EFICAS* et son aide disponible dans l'environnement SALOME. +.. [#] Pour de plus amples informations sur EFICAS, voir le *module EFICAS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME. .. [#] L'utilisation du code de simulation physique dans les opérateurs de base de l'assimilation de données est illustrée ou décrite dans les parties principales qui suivent. -.. [#] Pour de plus amples informations sur YACS, voir le *Guide utilisateur du module YACS* disponible dans le menu principal *Aide* de l'environnement SALOME. +.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME. .. [#] Ce fichier python intermédiaire peut aussi être utilisé comme décrit dans la section :ref:`section_advanced`. diff --git a/src/daComposant/daAlgorithms/3DVAR.py b/src/daComposant/daAlgorithms/3DVAR.py index ec409c6..3e27be3 100644 --- a/src/daComposant/daAlgorithms/3DVAR.py +++ b/src/daComposant/daAlgorithms/3DVAR.py @@ -72,7 +72,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"] + listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"] ) self.defineRequiredParameter( name = "Quantiles", @@ -263,9 +263,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # self.StoredVariables["Analysis"].store( Xa.A1 ) # - if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ - "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ - "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: + if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: HXa = Hm(Xa) # # Calcul de la covariance d'analyse @@ -337,6 +338,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if YQ is None: YQ = YfQ[:,indice] else: YQ = numpy.hstack((YQ,YfQ[:,indice])) self.StoredVariables["SimulationQuantiles"].store( YQ ) + if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/Blue.py b/src/daComposant/daAlgorithms/Blue.py index b446fe1..d3d0567 100644 --- a/src/daComposant/daAlgorithms/Blue.py +++ b/src/daComposant/daAlgorithms/Blue.py @@ -39,7 +39,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"] + listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"] ) self.defineRequiredParameter( name = "Quantiles", @@ -127,10 +127,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # Calcul de la fonction coût # -------------------------- if self._parameters["StoreInternalVariables"] or \ - "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ - "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ - "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \ - "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: + "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ + "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: HXa = Hm * Xa oma = Y - HXa if self._parameters["StoreInternalVariables"] or \ @@ -145,7 +146,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # Calcul de la covariance d'analyse # --------------------------------- if "APosterioriCovariance" in self._parameters["StoreSupplementaryCalculations"] or \ - "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: + "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: A = B - K * Hm * B if min(A.shape) != max(A.shape): raise ValueError("The %s a posteriori covariance matrix A is of shape %s, despites it has to be a squared matrix. There is an error in the observation operator, please check it."%(self._name,str(A.shape))) @@ -199,6 +200,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if YQ is None: YQ = YfQ[:,indice] else: YQ = numpy.hstack((YQ,YfQ[:,indice])) self.StoredVariables["SimulationQuantiles"].store( YQ ) + if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/ExtendedBlue.py b/src/daComposant/daAlgorithms/ExtendedBlue.py index deb55b6..aaa8534 100644 --- a/src/daComposant/daAlgorithms/ExtendedBlue.py +++ b/src/daComposant/daAlgorithms/ExtendedBlue.py @@ -39,7 +39,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"] + listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"] ) self.defineRequiredParameter( name = "Quantiles", @@ -128,10 +128,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # Calcul de la fonction coût # -------------------------- if self._parameters["StoreInternalVariables"] or \ - "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ - "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ - "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \ - "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: + "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \ + "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]: HXa = numpy.matrix(numpy.ravel( H( Xa ) )).T oma = Y - HXa if self._parameters["StoreInternalVariables"] or \ @@ -205,6 +206,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if YQ is None: YQ = YfQ[:,indice] else: YQ = numpy.hstack((YQ,YfQ[:,indice])) self.StoredVariables["SimulationQuantiles"].store( YQ ) + if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/LinearLeastSquares.py b/src/daComposant/daAlgorithms/LinearLeastSquares.py index 33d05e5..20931ad 100644 --- a/src/daComposant/daAlgorithms/LinearLeastSquares.py +++ b/src/daComposant/daAlgorithms/LinearLeastSquares.py @@ -39,7 +39,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["OMA"] + listval = ["OMA", "SimulatedObservationAtOptimum"] ) def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None): @@ -66,8 +66,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # # Calcul de la fonction coût # -------------------------- - if self._parameters["StoreInternalVariables"] or "OMA" in self._parameters["StoreSupplementaryCalculations"]: - oma = Y - Hm * Xa + if self._parameters["StoreInternalVariables"] or \ + "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + HXa = Hm * Xa + oma = Y - HXa if self._parameters["StoreInternalVariables"]: Jb = 0. Jo = 0.5 * oma.T * RI * oma @@ -80,6 +83,8 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # --------------------------------------- if "OMA" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["OMA"].store( numpy.ravel(oma) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/NonLinearLeastSquares.py b/src/daComposant/daAlgorithms/NonLinearLeastSquares.py index 53a90aa..b593773 100644 --- a/src/daComposant/daAlgorithms/NonLinearLeastSquares.py +++ b/src/daComposant/daAlgorithms/NonLinearLeastSquares.py @@ -72,7 +72,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["BMA", "OMA", "OMB", "Innovation"] + listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtOptimum"] ) def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None): @@ -98,8 +98,8 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if self._parameters.has_key("Minimizer") == "TNC": self.setParameterValue("StoreInternalVariables",True) # - # Opérateur d'observation - # ----------------------- + # Opérateurs + # ---------- Hm = HO["Direct"].appliedTo Ha = HO["Adjoint"].appliedInXTo # @@ -273,6 +273,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # self.StoredVariables["Analysis"].store( Xa.A1 ) # + if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + HXa = Hm(Xa) + # + # # Calculs et/ou stockages supplémentaires # --------------------------------------- if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: @@ -280,9 +285,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if "BMA" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["BMA"].store( numpy.ravel(Xb) - numpy.ravel(Xa) ) if "OMA" in self._parameters["StoreSupplementaryCalculations"]: - self.StoredVariables["OMA"].store( numpy.ravel(Y) - numpy.ravel(Hm(Xa)) ) + self.StoredVariables["OMA"].store( numpy.ravel(Y) - numpy.ravel(HXa) ) if "OMB" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["OMB"].store( numpy.ravel(d) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/ParticleSwarmOptimization.py b/src/daComposant/daAlgorithms/ParticleSwarmOptimization.py index 53c75d4..ccf148f 100644 --- a/src/daComposant/daAlgorithms/ParticleSwarmOptimization.py +++ b/src/daComposant/daAlgorithms/ParticleSwarmOptimization.py @@ -84,7 +84,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["BMA", "OMA", "OMB", "Innovation"] + listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"] ) def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None): @@ -230,18 +230,29 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # self.StoredVariables["Analysis"].store( Xa.A1 ) # + if "Innovation" in self._parameters["StoreSupplementaryCalculations"] or \ + "OMB" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + HXb = Hm(Xb) + d = Y - HXb + if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + HXa = Hm(Xa) + # # Calculs et/ou stockages supplémentaires # --------------------------------------- - if "Innovation" in self._parameters["StoreSupplementaryCalculations"] or "OMB" in self._parameters["StoreSupplementaryCalculations"]: - d = Y - Hm(Xb) if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["Innovation"].store( numpy.ravel(d) ) if "BMA" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["BMA"].store( numpy.ravel(Xb - Xa) ) if "OMA" in self._parameters["StoreSupplementaryCalculations"]: - self.StoredVariables["OMA"].store( numpy.ravel(Y - Hm(Xa)) ) + self.StoredVariables["OMA"].store( numpy.ravel(Y - HXa) ) if "OMB" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["OMB"].store( numpy.ravel(d) ) + if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daAlgorithms/QuantileRegression.py b/src/daComposant/daAlgorithms/QuantileRegression.py index effa8ed..ce51631 100644 --- a/src/daComposant/daAlgorithms/QuantileRegression.py +++ b/src/daComposant/daAlgorithms/QuantileRegression.py @@ -67,7 +67,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = [], typecast = tuple, message = "Liste de calculs supplémentaires à stocker et/ou effectuer", - listval = ["BMA", "OMA", "OMB", "Innovation"] + listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"] ) def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None): @@ -156,6 +156,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # self.StoredVariables["Analysis"].store( Xa.A1 ) # + if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \ + "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + HXa = Hm(Xa) + # # Calculs et/ou stockages supplémentaires # --------------------------------------- if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: @@ -163,9 +167,13 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if "BMA" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["BMA"].store( numpy.ravel(Xb - Xa) ) if "OMA" in self._parameters["StoreSupplementaryCalculations"]: - self.StoredVariables["OMA"].store( numpy.ravel(Y - Hm(Xa)) ) + self.StoredVariables["OMA"].store( numpy.ravel(Y - HXa) ) if "OMB" in self._parameters["StoreSupplementaryCalculations"]: self.StoredVariables["OMB"].store( numpy.ravel(d) ) + if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) ) + if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) ) # self._post_run(HO) return 0 diff --git a/src/daComposant/daCore/AssimilationStudy.py b/src/daComposant/daCore/AssimilationStudy.py index 87888d3..b0f79e2 100644 --- a/src/daComposant/daCore/AssimilationStudy.py +++ b/src/daComposant/daCore/AssimilationStudy.py @@ -137,6 +137,7 @@ class AssimilationStudy: asCovariance = None, asEyeByScalar = None, asEyeByVector = None, + asCovObject = None, toBeStored = False, ): """ @@ -149,6 +150,8 @@ class AssimilationStudy: - asEyeByVector : entrée des données comme un seul vecteur de variance, à mettre sur la diagonale d'une matrice de corrélation, aucune matrice n'étant donc explicitement à donner + - asCovObject : entrée des données comme un objet ayant des méthodes + particulieres de type matriciel - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour être rendue disponible au même titre que les variables de calcul """ @@ -157,6 +160,7 @@ class AssimilationStudy: asCovariance = asCovariance, asEyeByScalar = asEyeByScalar, asEyeByVector = asEyeByVector, + asCovObject = asCovObject, ) if toBeStored: self.__StoredInputs["BackgroundError"] = self.__B @@ -201,6 +205,7 @@ class AssimilationStudy: asCovariance = None, asEyeByScalar = None, asEyeByVector = None, + asCovObject = None, toBeStored = False, ): """ @@ -213,6 +218,8 @@ class AssimilationStudy: - asEyeByVector : entrée des données comme un seul vecteur de variance, à mettre sur la diagonale d'une matrice de corrélation, aucune matrice n'étant donc explicitement à donner + - asCovObject : entrée des données comme un objet ayant des méthodes + particulieres de type matriciel - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour être rendue disponible au même titre que les variables de calcul """ @@ -221,6 +228,7 @@ class AssimilationStudy: asCovariance = asCovariance, asEyeByScalar = asEyeByScalar, asEyeByVector = asEyeByVector, + asCovObject = asCovObject, ) if toBeStored: self.__StoredInputs["ObservationError"] = self.__R @@ -425,6 +433,7 @@ class AssimilationStudy: asCovariance = None, asEyeByScalar = None, asEyeByVector = None, + asCovObject = None, toBeStored = False, ): """ @@ -437,6 +446,8 @@ class AssimilationStudy: - asEyeByVector : entrée des données comme un seul vecteur de variance, à mettre sur la diagonale d'une matrice de corrélation, aucune matrice n'étant donc explicitement à donner + - asCovObject : entrée des données comme un objet ayant des méthodes + particulieres de type matriciel - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour être rendue disponible au même titre que les variables de calcul """ @@ -445,6 +456,7 @@ class AssimilationStudy: asCovariance = asCovariance, asEyeByScalar = asEyeByScalar, asEyeByVector = asEyeByVector, + asCovObject = asCovObject, ) if toBeStored: self.__StoredInputs["EvolutionError"] = self.__Q diff --git a/src/daComposant/daCore/BasicObjects.py b/src/daComposant/daCore/BasicObjects.py index 5eef798..f63821d 100644 --- a/src/daComposant/daCore/BasicObjects.py +++ b/src/daComposant/daCore/BasicObjects.py @@ -261,6 +261,8 @@ class Algorithm: - GradientOfCostFunctionJo : gradient de la partie observations de la fonction-cout - CurrentState : état courant lors d'itérations - Analysis : l'analyse Xa + - SimulatedObservationAtBackground : l'état observé H(Xb) à l'ébauche + - SimulatedObservationAtOptimum : l'état observé H(Xa) à l'optimum - ObservedState : l'état observé H(X) - Innovation : l'innovation : d = Y - H(X) - SigmaObs2 : indicateur de correction optimale des erreurs d'observation @@ -281,24 +283,26 @@ class Algorithm: self.__required_parameters = {} self.StoredVariables = {} # - self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ") - self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb") - self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo") - self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ") - self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb") - self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo") - self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState") - self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis") - self.StoredVariables["ObservedState"] = Persistence.OneVector(name = "ObservedState") - self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation") - self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2") - self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2") - self.StoredVariables["MahalanobisConsistency"] = Persistence.OneScalar(name = "MahalanobisConsistency") - self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA") - self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB") - self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA") - self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance") - self.StoredVariables["SimulationQuantiles"] = Persistence.OneMatrix(name = "SimulationQuantiles") + self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ") + self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb") + self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo") + self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ") + self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb") + self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo") + self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState") + self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis") + self.StoredVariables["SimulatedObservationAtBackground"] = Persistence.OneVector(name = "SimulatedObservationAtBackground") + self.StoredVariables["SimulatedObservationAtOptimum"] = Persistence.OneVector(name = "SimulatedObservationAtOptimum") + self.StoredVariables["ObservedState"] = Persistence.OneVector(name = "ObservedState") + self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation") + self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2") + self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2") + self.StoredVariables["MahalanobisConsistency"] = Persistence.OneScalar(name = "MahalanobisConsistency") + self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA") + self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB") + self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA") + self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance") + self.StoredVariables["SimulationQuantiles"] = Persistence.OneMatrix(name = "SimulationQuantiles") def _pre_run(self): logging.debug("%s Lancement"%self._name) @@ -462,6 +466,7 @@ class Covariance: asCovariance = None, asEyeByScalar = None, asEyeByVector = None, + asCovObject = None, ): """ Permet de définir une covariance : @@ -473,28 +478,47 @@ class Covariance: - asEyeByVector : entrée des données comme un seul vecteur de variance, à mettre sur la diagonale d'une matrice de corrélation, aucune matrice n'étant donc explicitement à donner + - asCovObject : entrée des données comme un objet python, qui a les + methodes obligatoires "getT", "getI", "diag", "trace", "__add__", + "__sub__", "__neg__", "__mul__", "__rmul__" et facultatives "shape", + "size", "cholesky", "choleskyI", "asfullmatrix", "__repr__", "__str__" """ self.__name = str(name) # - self.__B = None + self.__C = None self.__is_scalar = False self.__is_vector = False self.__is_matrix = False + self.__is_object = False if asEyeByScalar is not None: self.__is_scalar = True - self.__B = numpy.abs( float(asEyeByScalar) ) + self.__C = numpy.abs( float(asEyeByScalar) ) self.shape = (0,0) self.size = 0 elif asEyeByVector is not None: self.__is_vector = True - self.__B = numpy.abs( numpy.array( numpy.ravel( asEyeByVector ), float ) ) - self.shape = (self.__B.size,self.__B.size) - self.size = self.__B.size**2 + self.__C = numpy.abs( numpy.array( numpy.ravel( asEyeByVector ), float ) ) + self.shape = (self.__C.size,self.__C.size) + self.size = self.__C.size**2 elif asCovariance is not None: self.__is_matrix = True - self.__B = numpy.matrix( asCovariance, float ) - self.shape = self.__B.shape - self.size = self.__B.size + self.__C = numpy.matrix( asCovariance, float ) + self.shape = self.__C.shape + self.size = self.__C.size + elif asCovObject is not None: + self.__is_object = True + self.__C = asCovObject + for at in ("getT","getI","diag","trace","__add__","__sub__","__neg__","__mul__","__rmul__"): + if not hasattr(self.__C,at): + raise ValueError("The matrix given for %s as an object has no attribute \"%s\". Please check your object input."%(self.__name,at)) + if hasattr(self.__C,"shape"): + self.shape = self.__C.shape + else: + self.shape = (0,0) + if hasattr(self.__C,"size"): + self.size = self.__C.size + else: + self.size = 0 else: pass # raise ValueError("The %s covariance matrix has to be specified either as a matrix, a vector for its diagonal or a scalar multiplying an identity matrix."%self.__name) @@ -504,13 +528,15 @@ class Covariance: def __validate(self): if self.ismatrix() and min(self.shape) != max(self.shape): raise ValueError("The given matrix for %s is not a square one, its shape is %s. Please check your matrix input."%(self.__name,self.shape)) - if self.isscalar() and self.__B <= 0: - raise ValueError("The %s covariance matrix is not positive-definite. Please check your scalar input %s."%(self.__name,self.__B_scalar)) - if self.isvector() and (self.__B <= 0).any(): - raise ValueError("The %s covariance matrix is not positive-definite. Please check your vector input."%(self.__name,)) + if self.isobject() and min(self.shape) != max(self.shape): + raise ValueError("The matrix given for \"%s\" is not a square one, its shape is %s. Please check your object input."%(self.__name,self.shape)) + if self.isscalar() and self.__C <= 0: + raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your scalar input %s."%(self.__name,self.__C)) + if self.isvector() and (self.__C <= 0).any(): + raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your vector input."%(self.__name,)) if self.ismatrix() and logging.getLogger().level < logging.WARNING: # La verification n'a lieu qu'en debug try: - L = numpy.linalg.cholesky( self.__B ) + L = numpy.linalg.cholesky( self.__C ) except: raise ValueError("The %s covariance matrix is not symmetric positive-definite. Please check your matrix input."%(self.__name,)) @@ -523,114 +549,131 @@ class Covariance: def ismatrix(self): return self.__is_matrix + def isobject(self): + return self.__is_object + def getI(self): if self.ismatrix(): - return Covariance(self.__name+"I", asCovariance = self.__B.I ) + return Covariance(self.__name+"I", asCovariance = self.__C.I ) elif self.isvector(): - return Covariance(self.__name+"I", asEyeByVector = 1. / self.__B ) + return Covariance(self.__name+"I", asEyeByVector = 1. / self.__C ) elif self.isscalar(): - return Covariance(self.__name+"I", asEyeByScalar = 1. / self.__B ) + return Covariance(self.__name+"I", asEyeByScalar = 1. / self.__C ) + elif self.isobject(): + return Covariance(self.__name+"I", asCovObject = self.__C.getI() ) else: - return None + return None # Indispensable def getT(self): if self.ismatrix(): - return Covariance(self.__name+"T", asCovariance = self.__B.T ) + return Covariance(self.__name+"T", asCovariance = self.__C.T ) elif self.isvector(): - return Covariance(self.__name+"T", asEyeByVector = self.__B ) + return Covariance(self.__name+"T", asEyeByVector = self.__C ) elif self.isscalar(): - return Covariance(self.__name+"T", asEyeByScalar = self.__B ) + return Covariance(self.__name+"T", asEyeByScalar = self.__C ) + elif self.isobject(): + return Covariance(self.__name+"T", asCovObject = self.__C.getT() ) def cholesky(self): if self.ismatrix(): - return Covariance(self.__name+"C", asCovariance = numpy.linalg.cholesky(self.__B) ) + return Covariance(self.__name+"C", asCovariance = numpy.linalg.cholesky(self.__C) ) elif self.isvector(): - return Covariance(self.__name+"C", asEyeByVector = numpy.sqrt( self.__B ) ) + return Covariance(self.__name+"C", asEyeByVector = numpy.sqrt( self.__C ) ) elif self.isscalar(): - return Covariance(self.__name+"C", asEyeByScalar = numpy.sqrt( self.__B ) ) + return Covariance(self.__name+"C", asEyeByScalar = numpy.sqrt( self.__C ) ) + elif self.isobject() and hasattr(self.__C,"cholesky"): + return Covariance(self.__name+"C", asCovObject = self.__C.cholesky() ) def choleskyI(self): if self.ismatrix(): - return Covariance(self.__name+"H", asCovariance = numpy.linalg.cholesky(self.__B).I ) + return Covariance(self.__name+"H", asCovariance = numpy.linalg.cholesky(self.__C).I ) elif self.isvector(): - return Covariance(self.__name+"H", asEyeByVector = 1.0 / numpy.sqrt( self.__B ) ) + return Covariance(self.__name+"H", asEyeByVector = 1.0 / numpy.sqrt( self.__C ) ) elif self.isscalar(): - return Covariance(self.__name+"H", asEyeByScalar = 1.0 / numpy.sqrt( self.__B ) ) + return Covariance(self.__name+"H", asEyeByScalar = 1.0 / numpy.sqrt( self.__C ) ) + elif self.isobject() and hasattr(self.__C,"choleskyI"): + return Covariance(self.__name+"H", asCovObject = self.__C.choleskyI() ) def diag(self, msize=None): if self.ismatrix(): - return numpy.diag(self.__B) + return numpy.diag(self.__C) elif self.isvector(): - return self.__B + return self.__C elif self.isscalar(): if msize is None: raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,)) else: - return self.__B * numpy.ones(int(msize)) + return self.__C * numpy.ones(int(msize)) + elif self.isobject(): + return self.__C.diag() def asfullmatrix(self, msize=None): if self.ismatrix(): - return self.__B + return self.__C elif self.isvector(): - return numpy.matrix( numpy.diag(self.__B), float ) + return numpy.matrix( numpy.diag(self.__C), float ) elif self.isscalar(): if msize is None: raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,)) else: - return numpy.matrix( self.__B * numpy.eye(int(msize)), float ) + return numpy.matrix( self.__C * numpy.eye(int(msize)), float ) + elif self.isobject() and hasattr(self.__C,"asfullmatrix"): + return self.__C.asfullmatrix() def trace(self, msize=None): if self.ismatrix(): - return numpy.trace(self.__B) + return numpy.trace(self.__C) elif self.isvector(): - return float(numpy.sum(self.__B)) + return float(numpy.sum(self.__C)) elif self.isscalar(): if msize is None: raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,)) else: - return self.__B * int(msize) + return self.__C * int(msize) + elif self.isobject(): + return self.__C.trace() def __repr__(self): - return repr(self.__B) + return repr(self.__C) def __str__(self): - return str(self.__B) + return str(self.__C) def __add__(self, other): - if self.ismatrix(): - return self.__B + numpy.asmatrix(other) + if self.ismatrix() or self.isobject(): + return self.__C + numpy.asmatrix(other) elif self.isvector() or self.isscalar(): _A = numpy.asarray(other) - _A.reshape(_A.size)[::_A.shape[1]+1] += self.__B + _A.reshape(_A.size)[::_A.shape[1]+1] += self.__C return numpy.asmatrix(_A) def __radd__(self, other): raise NotImplementedError("%s covariance matrix __radd__ method not available for %s type!"%(self.__name,type(other))) def __sub__(self, other): - if self.ismatrix(): - return self.__B - numpy.asmatrix(other) + if self.ismatrix() or self.isobject(): + return self.__C - numpy.asmatrix(other) elif self.isvector() or self.isscalar(): _A = numpy.asarray(other) - _A.reshape(_A.size)[::_A.shape[1]+1] = self.__B - _A.reshape(_A.size)[::_A.shape[1]+1] + _A.reshape(_A.size)[::_A.shape[1]+1] = self.__C - _A.reshape(_A.size)[::_A.shape[1]+1] return numpy.asmatrix(_A) def __rsub__(self, other): raise NotImplementedError("%s covariance matrix __rsub__ method not available for %s type!"%(self.__name,type(other))) def __neg__(self): - return - self.__B + return - self.__C def __mul__(self, other): if self.ismatrix() and isinstance(other,numpy.matrix): - return self.__B * other + return self.__C * other elif self.ismatrix() and (isinstance(other,numpy.ndarray) \ or isinstance(other,list) \ or isinstance(other,tuple)): if numpy.ravel(other).size == self.shape[1]: # Vecteur - return self.__B * numpy.asmatrix(numpy.ravel(other)).T + return self.__C * numpy.asmatrix(numpy.ravel(other)).T elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice - return self.__B * numpy.asmatrix(other) + return self.__C * numpy.asmatrix(other) else: raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.asmatrix(other).shape,self.__name)) elif self.isvector() and (isinstance(other,numpy.matrix) \ @@ -638,35 +681,39 @@ class Covariance: or isinstance(other,list) \ or isinstance(other,tuple)): if numpy.ravel(other).size == self.shape[1]: # Vecteur - return numpy.asmatrix(self.__B * numpy.ravel(other)).T + return numpy.asmatrix(self.__C * numpy.ravel(other)).T elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice - return numpy.asmatrix((self.__B * (numpy.asarray(other).transpose())).transpose()) + return numpy.asmatrix((self.__C * (numpy.asarray(other).transpose())).transpose()) else: raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.ravel(other).shape,self.__name)) elif self.isscalar() and isinstance(other,numpy.matrix): - return self.__B * other + return self.__C * other elif self.isscalar() and (isinstance(other,numpy.ndarray) \ or isinstance(other,list) \ or isinstance(other,tuple)): if len(numpy.asarray(other).shape) == 1 or numpy.asarray(other).shape[1] == 1 or numpy.asarray(other).shape[0] == 1: - return self.__B * numpy.asmatrix(numpy.ravel(other)).T + return self.__C * numpy.asmatrix(numpy.ravel(other)).T else: - return self.__B * numpy.asmatrix(other) + return self.__C * numpy.asmatrix(other) + elif self.isobject(): + return self.__C.__mul__(other) else: raise NotImplementedError("%s covariance matrix __mul__ method not available for %s type!"%(self.__name,type(other))) def __rmul__(self, other): if self.ismatrix() and isinstance(other,numpy.matrix): - return other * self.__B + return other * self.__C elif self.isvector() and isinstance(other,numpy.matrix): if numpy.ravel(other).size == self.shape[0]: # Vecteur - return numpy.asmatrix(numpy.ravel(other) * self.__B) + return numpy.asmatrix(numpy.ravel(other) * self.__C) elif numpy.asmatrix(other).shape[1] == self.shape[0]: # Matrice - return numpy.asmatrix(numpy.array(other) * self.__B) + return numpy.asmatrix(numpy.array(other) * self.__C) else: raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.ravel(other).shape,self.__name)) elif self.isscalar() and isinstance(other,numpy.matrix): - return other * self.__B + return other * self.__C + elif self.isobject(): + return self.__C.__rmul__(other) else: raise NotImplementedError("%s covariance matrix __rmul__ method not available for %s type!"%(self.__name,type(other))) diff --git a/src/daComposant/daCore/Persistence.py b/src/daComposant/daCore/Persistence.py index 76feef2..d642d47 100644 --- a/src/daComposant/daCore/Persistence.py +++ b/src/daComposant/daCore/Persistence.py @@ -640,10 +640,10 @@ class Persistence: # ============================================================================== class OneScalar(Persistence): """ - Classe définissant le stockage d'une valeur unique réelle (float) par pas - + Classe définissant le stockage d'une valeur unique réelle (float) par pas. + Le type de base peut être changé par la méthode "basetype", mais il faut que - le nouveau type de base soit compatible avec les types par éléments de + le nouveau type de base soit compatible avec les types par éléments de numpy. On peut même utiliser cette classe pour stocker des vecteurs/listes ou des matrices comme dans les classes suivantes, mais c'est déconseillé pour conserver une signification claire des noms. @@ -653,26 +653,24 @@ class OneScalar(Persistence): class OneVector(Persistence): """ - Classe définissant le stockage d'une liste (list) de valeurs homogènes par - hypothèse par pas. Pour éviter les confusions, ne pas utiliser la classe - "OneVector" pour des données hétérogènes, mais bien "OneList". + Classe de stockage d'une liste de valeurs numériques homogènes par pas. Ne + pas utiliser cette classe pour des données hétérogènes, mais "OneList". """ def __init__(self, name="", unit="", basetype = numpy.ravel): Persistence.__init__(self, name, unit, basetype) class OneMatrix(Persistence): """ - Classe définissant le stockage d'une matrice de valeurs (numpy.matrix) par - pas + Classe de stockage d'une matrice de valeurs (numpy.matrix) par pas. """ def __init__(self, name="", unit="", basetype = numpy.matrix): Persistence.__init__(self, name, unit, basetype) class OneList(Persistence): """ - Classe définissant le stockage d'une liste de valeurs potentiellement - hétérogènes (list) par pas. Pour éviter les confusions, ne pas utiliser la - classe "OneVector" pour des données hétérogènes, mais bien "OneList". + Classe de stockage d'une liste de valeurs hétérogènes (list) par pas. Ne pas + utiliser cette classe pour des données numériques homogènes, mais + "OneVector". """ def __init__(self, name="", unit="", basetype = list): Persistence.__init__(self, name, unit, basetype) @@ -681,10 +679,10 @@ def NoType( value ): return value class OneNoType(Persistence): """ - Classe définissant le stockage d'un objet sans modification (cast) de type. - Attention, selon le véritable type de l'objet stocké à chaque pas, les - opérations arithmétiques à base de numpy peuvent être invalides ou donner - des résultats inattendus. Cette classe n'est donc à utiliser qu'à bon escient + Classe de stockage d'un objet sans modification (cast) de type. Attention, + selon le véritable type de l'objet stocké à chaque pas, les opérations + arithmétiques à base de numpy peuvent être invalides ou donner des résultats + inattendus. Cette classe n'est donc à utiliser qu'à bon escient volontairement, et pas du tout par défaut. """ def __init__(self, name="", unit="", basetype = NoType):