From 73296b21422d4dfecd64192528f090eca39efddf Mon Sep 17 00:00:00 2001 From: Jean-Philippe ARGAUD Date: Sun, 10 Mar 2019 11:22:24 +0100 Subject: [PATCH] Updating documentation by review and snippets (10): EN part --- doc/en/index.rst | 50 ++--- doc/en/ref_covariance_requirements.rst | 50 ++++- doc/en/ref_observers_requirements.rst | 58 +++-- doc/en/ref_operator_requirements.rst | 250 ++++++++++++++------- doc/en/ref_options_AlgorithmParameters.rst | 42 +++- doc/en/theory.rst | 78 ++++--- 6 files changed, 344 insertions(+), 184 deletions(-) diff --git a/doc/en/index.rst b/doc/en/index.rst index 26bf2a1..36d88e7 100644 --- a/doc/en/index.rst +++ b/doc/en/index.rst @@ -32,9 +32,7 @@ ADAO documentation :alt: ADAO logo **The ADAO module provides data assimilation and optimization** features in -Python [Python]_ or SALOME context [Salome]_. It is based on usage of other -SALOME modules, namely YACS and EFICAS if they are available, and on usage of a -generic underlying data assimilation library. +Python [Python]_ or SALOME context [Salome]_. Briefly stated, Data Assimilation is a methodological framework to compute the optimal estimate of the inaccessible true value of a system state, eventually @@ -42,25 +40,28 @@ over time. It uses information coming from experimental measurements or observations, and from numerical *a priori* models, including information about their errors. Parts of the framework are also known under the names of *parameter estimation*, *inverse problems*, *Bayesian estimation*, *optimal -interpolation*, etc. More details can be found in the section -:ref:`section_theory`. +interpolation*, *field reconstruction*, etc. More details can be found in the +section :ref:`section_theory`. The documentation for this module is divided into several major categories, -related to the theoretical documentation (indicated in the title by **[DocT]**), -to the user documentation (indicated in the title by **[DocU]**), and to the -reference documentation (indicated in the title by **[DocR]**). +related to the theoretical documentation (indicated in the section title by +**[DocT]**), to the user documentation (indicated in the section title by +**[DocU]**), and to the reference documentation (indicated in the section title +by **[DocR]**). The first part is the :ref:`section_intro`. The second part introduces -:ref:`section_theory`, and their concepts, and the next part describes a -:ref:`section_methodology`. The fourth part describes :ref:`section_using`, and -the fifth part gives examples on ADAO usage as :ref:`section_examples`. Users -interested in quick use of the module can stop before reading the rest, but a -valuable use of the module requires to read and come back regularly to the -fourth and tenth parts. The sixth part indicates the :ref:`section_advanced`, -with how to obtain additional information or how to use non-GUI execution -scripting. The seventh part gives a detailed :ref:`section_reference`, with four -main sub-parts following, the last one giving a :ref:`section_tui` of the -module. And, to respect the module requirements, be sure to read the part +:ref:`section_theory`, and their concepts, and the next part describes the +:ref:`section_methodology`. For a standard user, the next parts describe +examples on ADAO usage as :ref:`section_tutorials_in_salome` or +:ref:`section_tutorials_in_python`, then indicates the :ref:`section_advanced`, +with how to obtain additional information or how to use non-GUI command +execution scripting. Users interested in quick use of the module can stop +before reading the rest, but a valuable use of the module requires to read and +come back regularly to these parts. The following parts describe +:ref:`section_gui_in_salome` and :ref:`section_tui`. The last main part gives a +detailed :ref:`section_reference`, with three essential main sub-parts +describing the details of commands and options of the algorithms. And, to +comply with the module requirements, be sure to read the part :ref:`section_license`. In all this documentation, we use standard notations of linear algebra, data @@ -70,8 +71,7 @@ written either normally, or with a condensed notation, consisting in the use of a space to separate values and a "``;``" to separate the rows, in a continuous line. -Table of contents ------------------ +**Table of contents** .. toctree:: :maxdepth: 2 @@ -79,17 +79,17 @@ Table of contents intro theory methodology - using - examples + tutorials_in_salome + tutorials_in_python advanced - reference + gui_in_salome tui + reference license glossary bibliography -Indices and tables ------------------- +**Indices and tables** * :ref:`genindex` * :ref:`search` diff --git a/doc/en/ref_covariance_requirements.rst b/doc/en/ref_covariance_requirements.rst index 14852fd..f3ec709 100644 --- a/doc/en/ref_covariance_requirements.rst +++ b/doc/en/ref_covariance_requirements.rst @@ -26,18 +26,25 @@ Requirements to describe covariance matrices -------------------------------------------- +.. index:: single: BackgroundError +.. index:: single: ObservationError +.. index:: single: EvolutionError +.. index:: single: setBackgroundError +.. index:: single: setObservationError +.. index:: single: setEvolutionError .. index:: single: covariance matrix .. index:: single: background error covariances .. index:: single: observation error covariances .. index:: single: covariances -In general, a covariance matrix (or a variance-covariance matrix) has to be -squared, symmetric, semi-definite positive. Each of its terms describes the -covariance of the two random variables corresponding to its position in the -matrix. The normalized form of the covariance is the linear correlation. One can -express the following relation, between a covariance matrix :math:`\mathbf{M}` -and its corresponding correlation matrix :math:`\mathbf{C}` (full matrix) and -standard deviation matrix :math:`\mathbf{\Sigma}` (diagonal matrix): +In general, a variance-covariance matrix, generally called a covariance matrix, +has to be squared, symmetric and semi-definite positive. Each of its terms +describes the covariance of the two random variables corresponding to its +position in the matrix. The normalized form of the covariance is the linear +correlation. One can express the following relation, between a covariance +matrix :math:`\mathbf{M}` and its corresponding correlation matrix +:math:`\mathbf{C}` (full matrix) and standard deviation matrix +:math:`\mathbf{\Sigma}` (diagonal matrix): .. math:: \mathbf{M} = \mathbf{\Sigma} * \mathbf{C} * \mathbf{\Sigma} @@ -46,9 +53,10 @@ optimization procedures. The main ones are the background error covariance matrix, noted as :math:`\mathbf{B}`, and the observation error covariance matrix, noted as :math:`\mathbf{R}`. -There are 3 practical methods for the user to provide a covariance matrix. The -method is chosen by the "*INPUT_TYPE*" keyword of each defined covariance -matrix, as shown by the following figure: +In the graphical interface EFICAS of ADAO, there are 3 practical methods for +the user to provide a covariance matrix. The method is chosen by the +"*INPUT_TYPE*" keyword of each defined covariance matrix, as shown by the +following figure: .. eficas_covariance_matrix: .. image:: images/eficas_covariance_matrix.png @@ -57,6 +65,14 @@ matrix, as shown by the following figure: .. centered:: **Choosing covariance matrix representation** +In the textual interface (TUI) of ADAO (see the part :ref:`section_tui`), the +same information can be given with the right command "*setBackgroundError*", +"*setObservationError*" or "*setEvolutionError*" depending on the physical +quantity to define. The other arguments "*Matrix*", "*ScalarSparseMatrix*" and +"*DiagonalSparseMatrix*" of the command allow to define it as described in the +following sub-parts. These information can also be given as a script in an +external file (argument "*Script*"). + First matrix form: using "*Matrix*" representation ++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -64,6 +80,9 @@ First matrix form: using "*Matrix*" representation .. index:: single: BackgroundError .. index:: single: EvolutionError .. index:: single: ObservationError +.. index:: single: setBackgroundError +.. index:: single: setObservationError +.. index:: single: setEvolutionError This first form is the default and more general one. The covariance matrix :math:`\mathbf{M}` has to be fully specified. Even if the matrix is symmetric by @@ -94,6 +113,9 @@ Second matrix form: using "*ScalarSparseMatrix*" representation .. index:: single: BackgroundError .. index:: single: EvolutionError .. index:: single: ObservationError +.. index:: single: setBackgroundError +.. index:: single: setObservationError +.. index:: single: setEvolutionError On the opposite, this second form is a very simplified method to provide a matrix. The covariance matrix :math:`\mathbf{M}` is supposed to be a positive @@ -115,7 +137,7 @@ file as:: BackgroundError = 1. -or, better, by a "*String*" directly in the ADAO case. +or, better, by a "*String*" directly in the graphical or textual ADAO case. Third matrix form: using "*DiagonalSparseMatrix*" representation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -124,6 +146,9 @@ Third matrix form: using "*DiagonalSparseMatrix*" representation .. index:: single: BackgroundError .. index:: single: EvolutionError .. index:: single: ObservationError +.. index:: single: setBackgroundError +.. index:: single: setObservationError +.. index:: single: setEvolutionError This third form is also a simplified method to provide a matrix, but a little more powerful than the second one. The covariance matrix :math:`\mathbf{M}` is @@ -149,3 +174,6 @@ python script file as:: or:: BackgroundError = numpy.ones(...) + +As previously indicated, one can also define this matrix by a "*String*" +directly in the graphical or textual ADAO case. diff --git a/doc/en/ref_observers_requirements.rst b/doc/en/ref_observers_requirements.rst index cf578ae..7db4be2 100644 --- a/doc/en/ref_observers_requirements.rst +++ b/doc/en/ref_observers_requirements.rst @@ -21,23 +21,26 @@ Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D -.. _ref_observers_requirements: +.. _section_ref_observers_requirements: Requirements for functions describing an "*observer*" ----------------------------------------------------- .. index:: single: Observer +.. index:: single: setObserver .. index:: single: Observer Template -Some special variables, internal to the optimization process, used inside -calculation, can be monitored during an ADAO calculation. These variables can be -printed, plotted, saved, etc. It can be done using some "*observer*", sometimes -also called "callback". They are Python scripts, each one associated to a given -variable. They are activated for each variable modification. +Some special variables, internal to the optimization process and used inside +calculation, can be monitored during an ADAO calculation. These variables can +be printed, plotted, saved, etc. by the user. This can be done using some +"*observer*", sometimes also called "callback". They are Python scripts, each +one associated to a given variable, and that are automatically activated for +each variable modification. -There are 3 practical methods to provide an "*observer*" in an ADAO case. The -method is chosen with the "*NodeType*" keyword of each "*observer*" entry type, as -shown in the following figure: +In the graphical interface EFICAS of ADAO, there are 3 practical methods to +provide an "*observer*" in an ADAO case. The method is chosen with the +"*NodeType*" keyword of each "*observer*" entry type, as shown in the following +figure: .. eficas_observer_nodetype: .. image:: images/eficas_observer_nodetype.png @@ -46,16 +49,25 @@ shown in the following figure: .. centered:: **Choosing for an "*observer*" its entry type** -The "*observer*" can be given as a explicit script (entry of type "*String*"), +The "*observer*" can be given as an explicit script (entry of type "*String*"), as a script in an external file (entry of type "*Script*"), or by using a template or pattern (entry of type"*Template*") available by default in ADAO -when using the graphical editor. These templates are simple scripts that can be -tuned by the user, either in the integrated edtition stage of the case, or in -the edition stage of the schema before execution, to improve the ADAO case -performance in the SALOME execution supervisor. - -General form of a script to define an *observer* -++++++++++++++++++++++++++++++++++++++++++++++++ +when using the graphical editor and detailed in the following part +:ref:`section_ref_observers_templates`. These templates are simple scripts that +can be tuned by the user, either in the integrated edition stage of the case +with EFICAS, or in the edition stage of the schema before execution, to improve +the ADAO case performance in the SALOME execution supervisor YACS. + +In the textual interface (TUI) of ADAO (see the part :ref:`section_tui`), the +same information can be given with the command "*setObserver*" applied to a +specific variable indicated in the argument "*Variable*". The other arguments +of this command allow to define the observer either as a template (argument +"*Template*") representing one of the scripts detailed in the part +:ref:`section_ref_observers_templates`, or as an explicit script (argument +"*String*"), or as a script in an external file (argument "*Script*"). + +General form for a script describing an *observer* +++++++++++++++++++++++++++++++++++++++++++++++++++ To use this capability, the user must have or build scripts that have on standard input (that is, in the naming space) the variables ``var`` and @@ -78,6 +90,8 @@ analysis, etc. Hereinafter we give the identifier and the contents of each model available. +.. _section_ref_observers_templates: + Inventory of available *observer* models ("*Template*") +++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -161,7 +175,7 @@ Save the value series of the variable in a file of the '/tmp' directory named 'v Template **ValuePrinterAndSaver** : ................................... -Print on standard output and, in the same time save in a file, the current value of the variable. +Print on standard output and, in the same time save in a file of the '/tmp' directory, the current value of the variable. :: @@ -183,7 +197,7 @@ Print on standard output and, in the same time save in a file, the current value Template **ValueIndexPrinterAndSaver** : ........................................ -Print on standard output and, in the same time save in a file, the current value of the variable, adding its index. +Print on standard output and, in the same time save in a file of the '/tmp' directory, the current value of the variable, adding its index. :: @@ -205,7 +219,7 @@ Print on standard output and, in the same time save in a file, the current value Template **ValueSeriePrinterAndSaver** : ........................................ -Print on standard output and, in the same time, save in a file the value series of the variable. +Print on standard output and, in the same time, save in a file of the '/tmp' directory, the value series of the variable. :: @@ -317,7 +331,7 @@ Print on standard output and, in the same time, graphically plot with Gnuplot th Template **ValuePrinterSaverAndGnuPlotter** : ............................................. -Print on standard output and, in the same, time save in a file and graphically plot the current value of the variable. +Print on standard output and, in the same, time save in a file of the '/tmp' directory and graphically plot the current value of the variable. :: @@ -350,7 +364,7 @@ Print on standard output and, in the same, time save in a file and graphically p Template **ValueSeriePrinterSaverAndGnuPlotter** : .................................................. -Print on standard output and, in the same, time save in a file and graphically plot the value series of the variable. +Print on standard output and, in the same, time save in a file of the '/tmp' directory and graphically plot the value series of the variable. :: diff --git a/doc/en/ref_operator_requirements.rst b/doc/en/ref_operator_requirements.rst index 65c7a60..860d67c 100644 --- a/doc/en/ref_operator_requirements.rst +++ b/doc/en/ref_operator_requirements.rst @@ -26,66 +26,88 @@ Requirements for functions describing an operator ------------------------------------------------- +.. index:: single: setObservationOperator +.. index:: single: setEvolutionModel +.. index:: single: setControlModel + The operators for observation and evolution are required to implement the data -assimilation or optimization procedures. They include the physical simulation by -numerical calculations, but also the filtering and restriction to compare the -simulation to observation. The evolution operator is considered here in its -incremental form, representing the transition between two successive states, and -is then similar to the observation operator. - -Schematically, an operator has to give a output solution given the input -parameters. Part of the input parameters can be modified during the optimization -procedure. So the mathematical representation of such a process is a function. -It was briefly described in the section :ref:`section_theory` and is generalized -here by the relation: +assimilation or optimization procedures. They include the physical simulation +by numerical calculations, but also the filtering and restriction to compare +the simulation to observation. The evolution operator is considered here in its +incremental form, representing the transition between two successive states, +and is then similar to the observation operator. + +Schematically, an operator :math:`O` has to give a output solution for +specified input parameters. Part of the input parameters can be modified during +the optimization procedure. So the mathematical representation of such a +process is a function. It was briefly described in the section +:ref:`section_theory` and is generalized here by the relation: .. math:: \mathbf{y} = O( \mathbf{x} ) -between the pseudo-observations :math:`\mathbf{y}` and the parameters -:math:`\mathbf{x}` using the observation or evolution operator :math:`O`. The -same functional representation can be used for the linear tangent model -:math:`\mathbf{O}` of :math:`O` and its adjoint :math:`\mathbf{O}^*`, also -required by some data assimilation or optimization algorithms. +between the pseudo-observations outputs :math:`\mathbf{y}` and the input +parameters :math:`\mathbf{x}` using the observation or evolution operator +:math:`O`. The same functional representation can be used for the linear +tangent model :math:`\mathbf{O}` of :math:`O` and its adjoint +:math:`\mathbf{O}^*`, also required by some data assimilation or optimization +algorithms. On input and output of these operators, the :math:`\mathbf{x}` and -:math:`\mathbf{y}` variables or their increments are mathematically vectors, -and they are given as non-oriented vectors (of type list or Numpy array) or -oriented ones (of type Numpy matrix). +:math:`\mathbf{y}` variables, or their increments, are mathematically vectors, +and they can be given by the user as non-oriented vectors (of type list or +Numpy array) or oriented ones (of type Numpy matrix). + +Then, **to fully describe an operator, the user has only to provide a function +that completely and only realize the functional operation**. + +This function is usually given as a Python function or script, that can be in +particular executed as an independent Python function or in a YACS node. These +function or script can, with no differences, launch external codes or use +internal Python or SALOME calls and methods. If the algorithm requires the 3 +aspects of the operator (direct form, tangent form and adjoint form), the user +has to give the 3 functions or to approximate them using ADAO. -Then, **to describe completely an operator, the user has only to provide a -function that fully and only realize the functional operation**. +There are for the user 3 practical methods to provide an operator functional +representation, which are different depending on the chosen argument: -This function is usually given as a script that can be executed in a YACS node. -This script can without difference launch external codes or use internal SALOME -calls and methods. If the algorithm requires the 3 aspects of the operator -(direct form, tangent form and adjoint form), the user has to give the 3 -functions or to approximate them. +- :ref:`section_ref_operator_one` +- :ref:`section_ref_operator_funcs` +- :ref:`section_ref_operator_switch` -There are 3 practical methods for the user to provide an operator functional -representation. These methods are chosen in the "*FROM*" field of each operator -having a "*Function*" value as "*INPUT_TYPE*", as shown by the following figure: +In case of ADAO scripted interface (TUI), only the first two are necessary +because the third is included in the second. In case of ADAO graphical +interface EFICAS, these methods are chosen in the "*FROM*" field of each +operator having a "*Function*" value as "*INPUT_TYPE*", as shown by the +following figure: .. eficas_operator_function: .. image:: images/eficas_operator_function.png :align: center :width: 100% .. centered:: - **Choosing an operator functional representation** + **Choosing graphically an operator functional representation** -First functional form: using "*ScriptWithOneFunction*" -++++++++++++++++++++++++++++++++++++++++++++++++++++++ +.. _section_ref_operator_one: +First functional form: one direct operator only ++++++++++++++++++++++++++++++++++++++++++++++++ + +.. index:: single: OneFunction .. index:: single: ScriptWithOneFunction .. index:: single: DirectOperator .. index:: single: DifferentialIncrement .. index:: single: CenteredFiniteDifference -The first one consist in providing only one potentially non-linear function, and -to approximate the tangent and the adjoint operators. This is done by using the -keyword "*ScriptWithOneFunction*" for the description of the chosen operator in -the ADAO GUI. The user have to provide the function in a script, with a -mandatory name "*DirectOperator*". For example, the script can follow the -template:: +The first one consist in providing only one function, potentially non-linear, +and to approximate the associated tangent and adjoint operators. + +This is done in ADAO by using in the graphical interface EFICAS the keyword +"*ScriptWithOneFunction*" for the description by a script. In the textual +interface, it is the keyword "*OneFunction*", possibly combined with "*Script*" +keyword depending on whether it is a function or a script. If it is by external +script, the user must provide a file containing a function that has the +mandatory name "*DirectOperator*". For example, an external script can follow +the generic template:: def DirectOperator( X ): """ Direct non-linear simulation operator """ @@ -95,18 +117,19 @@ template:: return Y=O(X) In this case, the user has also provide a value for the differential increment -(or keep the default value), using through the GUI the keyword -"*DifferentialIncrement*", which has a default value of 1%. This coefficient -will be used in the finite differences approximation to build the tangent and -adjoint operators. The finite differences approximation order can also be chosen -through the GUI, using the keyword "*CenteredFiniteDifference*", with 0 for an -uncentered schema of first order (which is the default value), and with 1 for a -centered schema of second order (of twice the first order computational cost). -If necessary and if possible, :ref:`subsection_ref_parallel_df` can be used. In -all cases, an internal cache mechanism is used to restrict the number of -operator evaluations at the minimum possible in a sequential or parallel -execution scheme for numerical approximations of the tangent and adjoint -operators, to avoid redundant calculations. +(or keep the default value), using through the graphical interface (GUI) or +textual one (TUI) the keyword "*DifferentialIncrement*" as parameter, which has +a default value of 1%. This coefficient will be used in the finite differences +approximation to build the tangent and adjoint operators. The finite +differences approximation order can also be chosen through the GUI, using the +keyword "*CenteredFiniteDifference*", with 0 for an uncentered schema of first +order (which is the default value), and with 1 for a centered schema of second +order (and of twice the first order computational cost). If necessary and if +possible, :ref:`subsection_ref_parallel_df` can be used. In all cases, an +internal cache mechanism is used to restrict the number of operator evaluations +at the minimum possible in a sequential or parallel execution scheme for +numerical approximations of the tangent and adjoint operators, to avoid +redundant calculations. This first operator definition form allows easily to test the functional form before its use in an ADAO case, greatly reducing the complexity of operator @@ -114,13 +137,16 @@ implementation. One can then use the "*FunctionTest*" ADAO checking algorithm (see the section on the :ref:`section_ref_algorithm_FunctionTest`) for this test. -**Important warning:** the name "*DirectOperator*" is mandatory, and the type of -the ``X`` argument can be either a list, a Numpy array or a Numpy 1D-matrix. The -user function has to accept and treat all these cases. +**Important warning:** the name "*DirectOperator*" is mandatory, and the type +of the ``X`` argument can be either a list of float values, a Numpy array or a +Numpy matrix. The user function has to accept and treat all these cases. + +.. _section_ref_operator_funcs: -Second functional form: using "*ScriptWithFunctions*" -+++++++++++++++++++++++++++++++++++++++++++++++++++++ +Second functional form: three operators direct, tangent and adjoint ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +.. index:: single: ThreeFunctions .. index:: single: ScriptWithFunctions .. index:: single: DirectOperator .. index:: single: TangentOperator @@ -133,9 +159,12 @@ detailed implementation as this second functional form.** The second one consist in providing directly the three associated operators :math:`O`, :math:`\mathbf{O}` and :math:`\mathbf{O}^*`. This is done by using the keyword "*ScriptWithFunctions*" for the description of the chosen operator -in the ADAO GUI. The user have to provide three functions in one script, with -three mandatory names "*DirectOperator*", "*TangentOperator*" and -"*AdjointOperator*". For example, the script can follow the template:: +in the ADAO graphical interface EFICAS. In the textual interface, it is the +keyword "*ThreeFunctions*", possibly combined with "*Script*" keyword depending +on whether it is a function or a script. The user have to provide in one script +three functions, with the three mandatory names "*DirectOperator*", +"*TangentOperator*" and "*AdjointOperator*". For example, the external script +can follow the template:: def DirectOperator( X ): """ Direct non-linear simulation operator """ @@ -144,15 +173,17 @@ three mandatory names "*DirectOperator*", "*TangentOperator*" and ... return something like Y - def TangentOperator( (X, dX) ): + def TangentOperator( pair = (X, dX) ): """ Tangent linear operator, around X, applied to dX """ + X, dX = pair ... ... ... return something like Y - def AdjointOperator( (X, Y) ): + def AdjointOperator( pair = (X, Y) ): """ Adjoint operator, around X, applied to Y """ + X, Y = pair ... ... ... @@ -164,23 +195,25 @@ operator implementation. For some algorithms, it is required that the tangent and adjoint functions can return the matrix equivalent to the linear operator. In this case, when -respectively the ``dX`` or the ``Y`` arguments are ``None``, the user has to -return the associated matrix. +respectively the ``dX`` or the ``Y`` arguments are ``None``, the user script +has to return the associated matrix. **Important warning:** the names "*DirectOperator*", "*TangentOperator*" and "*AdjointOperator*" are mandatory, and the type of the ``X``, Y``, ``dX`` -arguments can be either a python list, a Numpy array or a Numpy 1D-matrix. The -user has to treat these cases in his script. +arguments can be either a list of float values, a Numpy array or a Numpy +matrix. The user function has to treat these cases in his script. -Third functional form: using "*ScriptWithSwitch*" -+++++++++++++++++++++++++++++++++++++++++++++++++ +.. _section_ref_operator_switch: + +Third functional form: three operators with a switch +++++++++++++++++++++++++++++++++++++++++++++++++++++ .. index:: single: ScriptWithSwitch .. index:: single: DirectOperator .. index:: single: TangentOperator .. index:: single: AdjointOperator -**It is recommended not to use this third functional form without a solid +**It is recommended not to use this third functional form without a strong numerical or physical reason. A performance improvement is not a good reason to use the implementation complexity of this third functional form. Only an inability to use the first or second forms justifies the use of the third.** @@ -188,12 +221,14 @@ inability to use the first or second forms justifies the use of the third.** This third form give more possibilities to control the execution of the three functions representing the operator, allowing advanced usage and control over each execution of the simulation code. This is done by using the keyword -"*ScriptWithSwitch*" for the description of the chosen operator in the ADAO GUI. -The user have to provide a switch in one script to control the execution of the -direct, tangent and adjoint forms of its simulation code. The user can then, for -example, use other approximations for the tangent and adjoint codes, or -introduce more complexity in the argument treatment of the functions. But it -will be far more complicated to implement and debug. +"*ScriptWithSwitch*" for the description of the chosen operator in the ADAO +graphical interface EFICAS. In the textual interface, you only have to use the +keyword "*ThreeFunctions*" above to also define this case, with the right +functions. The user have to provide a switch in one script to control the +execution of the direct, tangent and adjoint forms of its simulation code. The +user can then, for example, use other approximations for the tangent and +adjoint codes, or introduce more complexity in the argument treatment of the +functions. But it will be far more complicated to implement and debug. If, however, you want to use this third form, we recommend using the following template for the switch. It requires an external script or code named here @@ -252,12 +287,13 @@ All various modifications could be done from this template hypothesis. .. _section_ref_operator_control: -Special case of controled evolution or observation operator -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Special case of controlled evolution or observation operator +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ In some cases, the evolution or the observation operator is required to be controlled by an external input control, given *a priori*. In this case, the -generic form of the incremental model is slightly modified as follows: +generic form of the incremental model :math:`O` is slightly modified as +follows: .. math:: \mathbf{y} = O( \mathbf{x}, \mathbf{u}) @@ -265,8 +301,9 @@ where :math:`\mathbf{u}` is the control over one state increment. In fact, the direct operator has to be applied to a pair of variables :math:`(X,U)`. Schematically, the operator has to be set as:: - def DirectOperator( (X, U) ): + def DirectOperator( pair = (X, U) ): """ Direct non-linear simulation operator """ + X, U = pair ... ... ... @@ -278,14 +315,16 @@ In such a case with explicit control, only the second functional form (using "*ScriptWithFunctions*") and third functional form (using "*ScriptWithSwitch*") can be used. +.. _section_ref_operator_dimensionless: + Additional notes on dimensionless transformation of operators +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. index:: single: Nondimensionalization .. index:: single: Dimensionless -It is common that physical quantities, in input or output of the operators, have -significant differences in magnitude or rate of change. One way to avoid +It is common that physical quantities, in input or output of the operators, +have significant differences in magnitude or rate of change. One way to avoid numerical difficulties is to use, or to set, a dimensionless version of calculations carried out in operators [WikipediaND]_. In principle, since physical simulation should be as dimensionless as possible, it is at first @@ -296,14 +335,59 @@ to surround the calculation to remove dimension for input or output. A simple way to do this is to convert the input parameters :math:`\mathbf{x}` which are arguments of a function like "*DirectOperator*". One mostly use the default values :math:`\mathbf{x}^b` (background, or nominal value). Provided that each -component of :math:`\mathbf{x}^b` is non zero, one can indeed put: +component of :math:`\mathbf{x}^b` is non zero, one can indeed use a +multiplicative correction. For this, one can for example state: .. math:: \mathbf{x} = \mathbf{\alpha}\mathbf{x}^b and then optimize the multiplicative parameter :math:`\mathbf{\alpha}`. This -parameter has as default value (or as background) a vector of 1. Be careful, -applying a process of dimensionless transformation also requires changing the -associated error covariances in an ADAO formulation of the optimization problem. +parameter has as default value (or as background) a vector of 1. In the same +way, one can use additive correction if it is more interesting from a physical +point of view. In this case, one can state: + +.. math:: \mathbf{x} =\mathbf{x}^b + \mathbf{\alpha} + +and then optimize the additive parameter :math:`\mathbf{\alpha}`. In this case, +the parameter has for background value a vector of 0. + +Be careful, applying a dimensionless transformation also requires changing the +associated error covariances in an ADAO formulation of the optimization +problem. Such a process is rarely enough to avoid all the numerical problems, but it often improves a lot the numeric conditioning of the optimization. + +Dealing explicitly with "multiple" functions +++++++++++++++++++++++++++++++++++++++++++++ + +.. warning:: + + it is strongly recommended not to use this explicit "multiple" functions + definition without a very strong computing justification. This treatment is + already done by default in ADAO to increase performances. Only the very + experienced user, seeking to manage particularly difficult cases, can be + interested in this extension. Despite its simplicity, there is an explicit + risk of significantly worsening performance. + +It is possible, when defining operator's functions, to set them as functions +that treat not only one argument, but a series of arguments, to give back on +output the corresponding value series. Writing it as pseudo-code, the +"multiple" function, here named ``MultiFunctionO``, representing the classical +operator :math:`O` named "*DirectOperator*", does:: + + def MultiFunctionO( Inputs ): + """ Multiple ! """ + Outputs = [] + for X in Inputs: + Y = DirectOperator( X ) + Outputs.append( Y ) + return Outputs + +The length of the output (that is, the number of calculated values) is equal to +the length of the input (that is, the number of states for which one want to +calculate the value by the operator). + +This possibility is only available in the textual interface for ADAO. For this, +when defining an operator's function, in the same time one usually define the +function or the external script, it can be set using a boolean parameter +"*InputFunctionAsMulti*" that the definition is one of a "multiple" function. diff --git a/doc/en/ref_options_AlgorithmParameters.rst b/doc/en/ref_options_AlgorithmParameters.rst index c693c6c..2739202 100644 --- a/doc/en/ref_options_AlgorithmParameters.rst +++ b/doc/en/ref_options_AlgorithmParameters.rst @@ -24,23 +24,35 @@ .. index:: single: AlgorithmParameters .. index:: single: Parameters .. index:: single: Defaults +.. index:: single: setAlgorithmParameters .. _section_ref_options_Algorithm_Parameters: -Description of options of an algorithm in "*AlgorithmParameters*" +Description of options of an algorithm by "*AlgorithmParameters*" ----------------------------------------------------------------- Each algorithm can be controlled using some specific options or parameters. They are given through the "*Parameters*" optional command included in the mandatory command "*AlgorithmParameters*". -There are 3 practical methods for the user to provide these options. The method -is determined as follows in the graphical user interface: - -#. firstly using the "*Parameters*" keyword in the "*AlgorithmParameters*" command, which allows to choose between "*Defaults*" (use of explicit pre-filled keywords by default parameters values) and "*Dict*" (use of a dictionary to fill the necessary keywords), -#. then secondly, only in the "*Dict*" case of "*Parameters*", by the included keyword "*FROM*" which allows to choose between a string entry and a Python script file entry. - -If an option or a parameter is specified by the user for an algorithm that -does not support it, the option is simply left unused and don't stop the +There are 3 practical methods for the user of the EFICAS graphical user +interface of ADAO (GUI) to provide these options. The method is determined as +follows in the EFICAS graphical user interface: + +#. firstly using the "*Parameters*" keyword in the "*AlgorithmParameters*" + command, which allows to choose between "*Defaults*" (use of explicit + pre-filled keywords by default parameters values) and "*Dict*" (use of a + dictionary to fill the necessary keywords), +#. then secondly or thirdly, only in the "*Dict*" case of "*Parameters*", by + the included keyword "*FROM*" which allows to choose between a string entry + and a Python script file entry. + +These two last options can be also used in the ADAO textual interface (TUI), +through the keywords "*Parameters*" and "*Script*" of the corresponding command +"*AlgorithmParameters*" (see the :ref:`section_tui` part for detailed +description). + +If an option or a parameter is specified by the user for an algorithm that does +not support it, the option is simply ignored (left unused) and don't stop the treatment. The meaning of the acronyms or particular names can be found in the :ref:`genindex` or the :ref:`section_glossary`. @@ -68,6 +80,8 @@ way. This method allows only to define authorized parameters for a given algorithm, and the defined values are not kept if the user changes the algorithm. +This method is naturally not usable in TUI interface. + Second method : using a string in the graphical interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -93,6 +107,9 @@ in particular to keep options or parameters for other algorithms than the currently used one. It is then easier to change of algorithm or to keep default values different of the standard defaults. +In the textual interface TUI, the dictionary has only to be given as argument +of the "*Parameters*" keyword. + Third method : using an external Python script file +++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -116,6 +133,9 @@ name "*AlgorithmParameters*", as in the following example:: "StoreSupplementaryCalculations" : ["APosterioriCovariance","OMA"], } -The file can also contain other Python commands. This method also allows, as the -previous one, to keep options or parameters for other algorithms than the +The file can also contain other Python commands. This method also allows, as +the previous one, to keep options or parameters for other algorithms than the currently used one. + +In the textual interface TUI, the file name has only to be given as argument of +the "*Script*" keyword. diff --git a/doc/en/theory.rst b/doc/en/theory.rst index 68d2c01..48efd92 100644 --- a/doc/en/theory.rst +++ b/doc/en/theory.rst @@ -189,14 +189,14 @@ expression: .. math:: \mathbf{R} = E[\mathbf{\epsilon}^o.{\mathbf{\epsilon}^o}^T] -The background can also be written formally as a function of the true value, by +The background can be written formally as a function of the true value, by introducing the errors vector :math:`\mathbf{\epsilon}^b` such that: .. math:: \mathbf{x}^b = \mathbf{x}^t + \mathbf{\epsilon}^b -The errors :math:`\mathbf{\epsilon}^b` are also assumed of zero mean, in the -same manner as for observations. We define the :math:`\mathbf{B}` matrix of -background error covariances by: +The background errors :math:`\mathbf{\epsilon}^b` are also assumed of zero +mean, in the same manner as for observations. We define the :math:`\mathbf{B}` +matrix of background error covariances by: .. math:: \mathbf{B} = E[\mathbf{\epsilon}^b.{\mathbf{\epsilon}^b}^T] @@ -243,17 +243,18 @@ The advantage of filtering is to explicitly calculate the gain, to produce then the *a posteriori* covariance analysis matrix. In this simple static case, we can show, under an assumption of Gaussian error -distributions (very little restrictive in practice), that the two *variational* -and *filtering* approaches give the same solution. +distributions (very little restrictive in practice) and of :math:`H` linearity, +that the two *variational* and *filtering* approaches give the same solution. It is indicated here that these methods of "*3D-VAR*" and "*BLUE*" may be extended to dynamic problems, called respectively "*4D-VAR*" and "*Kalman -filter*". They can take into account the evolution operator to establish an +filter*". They have to take into account the evolution operator to establish an analysis at the right time steps of the gap between observations and simulations, and to have, at every moment, the propagation of the background -through the evolution model. Many other variants have been developed to improve -the numerical quality of the methods or to take into account computer -requirements such as calculation size and time. +through the evolution model. In the same way, these methods can be used in case +of non linear observation or evolution operators. Many other variants have been +developed to improve the numerical quality of the methods or to take into +account computer requirements such as calculation size and time. Going further in the data assimilation framework ------------------------------------------------ @@ -289,6 +290,10 @@ Going further in the state estimation by optimization methods .. index:: single: state estimation .. index:: single: optimization methods +.. index:: single: DerivativeFreeOptimization +.. index:: single: ParticleSwarmOptimization +.. index:: single: DifferentialEvolution +.. index:: single: QuantileRegression As seen before, in a static simulation case, the variational data assimilation requires to minimize the goal function :math:`J`: @@ -306,34 +311,43 @@ reference general documents like [Tarantola87]_. State estimation possibilities extension, by using more explicitly optimization methods and their properties, can be imagined in two ways. -First, classical optimization methods involves using various gradient-based -minimizing procedures. They are extremely efficient to look for a single local -minimum. But they require the goal function :math:`J` to be sufficiently regular -and differentiable, and are not able to capture global properties of the -minimization problem, for example: global minimum, set of equivalent solutions -due to over-parametrization, multiple local minima, etc. **A way to extend -estimation possibilities is then to use a whole range of optimizers, allowing -global minimization, various robust search properties, etc**. There is a lot of -minimizing methods, such as stochastic ones, evolutionary ones, heuristics and -meta-heuristics for real-valued problems, etc. They can treat partially -irregular or noisy function :math:`J`, can characterize local minima, etc. The -main drawback is a greater numerical cost to find state estimates, and no -guarantee of convergence in finite time. Here, we only point the following -topics, as the methods are available in the ADAO module: *Quantile Regression* -[WikipediaQR]_ and *Particle Swarm Optimization* [WikipediaPSO]_. +First, classical optimization methods often involves using various +gradient-based minimizing procedures. They are extremely efficient to look for +a single local minimum. But they require the goal function :math:`J` to be +sufficiently regular and differentiable, and are not able to capture global +properties of the minimization problem, for example: global minimum, set of +equivalent solutions due to over-parametrization, multiple local minima, etc. +**A way to extend estimation possibilities is then to use a whole range of +optimizers, allowing global minimization, various robust search properties, +etc**. There is a lot of minimizing methods, such as stochastic ones, +evolutionary ones, heuristics and meta-heuristics for real-valued problems, +etc. They can treat partially irregular or noisy function :math:`J`, can +characterize local minima, etc. The main drawbacks are a greater numerical cost +to find state estimates, and often a lack of guarantee of convergence in finite +time. Here, we only point the following topics, as the methods are available in +ADAO: + +- *Derivative Free Optimization (or DFO)* (see :ref:`section_ref_algorithm_DerivativeFreeOptimization`), +- *Particle Swarm Optimization (or PSO)* (see :ref:`section_ref_algorithm_ParticleSwarmOptimization`), +- *Differential Evolution (or DE)* (see :ref:`section_ref_algorithm_DifferentialEvolution`), +- *Quantile Regression (or QR)* (see :ref:`section_ref_algorithm_QuantileRegression`). Secondly, optimization methods try usually to minimize quadratic measures of errors, as the natural properties of such goal functions are well suited for classical gradient optimization. But other measures of errors can be more adapted to real physical simulation problems. Then, **an another way to extend -estimation possibilities is to use other measures of errors to be reduced**. For -example, we can cite *absolute error value*, *maximum error value*, etc. These -error measures are not differentiable, but some optimization methods can deal -with: heuristics and meta-heuristics for real-valued problem, etc. As +estimation possibilities is to use other measures of errors to be reduced**. +For example, we can cite *absolute error value*, *maximum error value*, etc. +These error measures are not differentiable, but some optimization methods can +deal with: heuristics and meta-heuristics for real-valued problem, etc. As previously, the main drawback remain a greater numerical cost to find state -estimates, and no guarantee of convergence in finite time. Here again, we only -point the following methods as it is available in the ADAO module: *Particle -swarm optimization* [WikipediaPSO]_. +estimates, and often a lack of guarantee of convergence in finite time. Here +again, we only point the following methods as it is available in the ADAO +module: *Particle swarm optimization* [WikipediaPSO]_. + +- *Derivative Free Optimization (or DFO)* (see :ref:`section_ref_algorithm_DerivativeFreeOptimization`), +- *Particle Swarm Optimization (or PSO)* (see :ref:`section_ref_algorithm_ParticleSwarmOptimization`), +- *Differential Evolution (or DE)* (see :ref:`section_ref_algorithm_DifferentialEvolution`). The reader interested in the subject of optimization can look at [WikipediaMO]_ as a general entry point. -- 2.39.2