User manual (PDF 12 MB) - PC

Transcription

User manual (PDF 12 MB) - PC
DREAM Suite
version 1
User Manual
A software package for Bayesian inference
of numerical simulation models
March 2016, PC-Progress, Prague, Czech Republic
© 2016 PC-Progress. All rights reserved.
Copyright © 2016 by PC-Progress s.r.o.. All Rights Reserved.
DREAM Suite 1
2
DREAM Suite 1
Table of contents
1. Introduction .............................................................................. 6
2. Getting started ........................................................................... 7
2.1. System requirements ............................................................................... 7
2.2. Authors and contact information ............................................................... 8
2.3. Installation ............................................................................................. 8
2.4. Authorization ........................................................................................ 11
2.4.1. Hardware key ................................................................................. 13
2.4.2. Software activation .......................................................................... 13
2.4.3. Software Deactivation ...................................................................... 18
2.4.4. Reinstallation and uninstallation ........................................................ 19
3. Graphical user interface ............................................................ 20
3.1. Project manager ....................................................................................
3.2. Library manager ....................................................................................
3.3. Project windows ....................................................................................
3.3.1. Project tree ....................................................................................
3.3.2. Project information .........................................................................
3.3.3. Model definition ..............................................................................
3.3.4. Simulations ....................................................................................
3.3.5. Simulation case ..............................................................................
3.3.6. DREAM algorithmic variables ............................................................
3.3.7. Parameter space .............................................................................
3.3.8. Likelihood function ..........................................................................
3.3.9. Prior distribution .............................................................................
3.3.10. Measurement data .........................................................................
3.3.11. Calculation ...................................................................................
3.3.12. Post-processing - tables .................................................................
3.3.13. Post-processing - charts .................................................................
3.4. Program options ....................................................................................
3.5. Dialog About DREAM Suite .....................................................................
3.6. Dialog DREAM Suite License ...................................................................
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
4. Demo examples ........................................................................ 39
4.1. Example 1 ............................................................................................
4.2. Example 2 ............................................................................................
4.3. Example 3 ............................................................................................
4.4. Example 4 ............................................................................................
4.5. Example 5 ............................................................................................
4.6. Example 6 ............................................................................................
4.7. Example 7 ............................................................................................
4.8. Example 8 ............................................................................................
4.9. Example 9 ............................................................................................
4.10. Example 10 .........................................................................................
4.11. Example 11 .........................................................................................
4.12. Example 12 .........................................................................................
3
40
45
49
54
55
55
57
65
66
68
70
70
DREAM Suite 1
4.13.
4.14.
4.15.
4.16.
4.17.
4.18.
4.19.
4.20.
4.21.
4.22.
4.23.
Example 13
Example 14
Example 15
Example 16
Example 17
Example 18
Example 19
Example 20
Example 21
Example 22
Example 23
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
.........................................................................................
72
73
74
75
77
78
79
82
83
85
86
5. Using DREAM ........................................................................... 88
5.1. DREAM projects .................................................................................... 88
5.1.1. Project files .................................................................................... 90
5.2. DREAM applications ............................................................................... 92
5.2.1. DREAM console application .............................................................. 93
5.3. DREAM plugins ..................................................................................... 95
5.3.1. C/C++ Plugin ................................................................................. 96
5.3.2. MATLAB Plugin .............................................................................. 97
5.4. DREAM Solver ..................................................................................... 100
5.4.1. Calculation observer ...................................................................... 104
6. Programming references .......................................................... 104
6.1. DREAM SDK ........................................................................................
6.2. Plugin module template ........................................................................
6.2.1. DreamEvaluator.h .........................................................................
6.2.2. DreamEvaluator.cpp ......................................................................
6.2.3. TestApp.h ....................................................................................
6.2.4. TestApp.cpp .................................................................................
6.3. Interfaces ............................................................................................
6.3.1. IDreamInputParViewer ..................................................................
6.3.2. IDreamInputParams ......................................................................
6.3.3. IDreamDataMinMax .......................................................................
6.3.4. IDreamDataNormal .......................................................................
6.3.5. IDreamDataPrior ...........................................................................
6.3.6. IDreamDataMeasurement ...............................................................
6.3.7. IDreamDataABC ............................................................................
6.3.8. IDreamDataSource ........................................................................
6.3.9. IDreamEvaluator ...........................................................................
6.3.10. IDreamObserver .........................................................................
6.3.11. IDreamSolver .............................................................................
6.4. Data structures ....................................................................................
6.4.1. IDreamPluginInfo .........................................................................
6.4.2. IDreamCalcSettings .......................................................................
6.4.3. IDreamErrorInfo ...........................................................................
6.4.4. IDreamMatrix ...............................................................................
6.4.5. IDreamVector ...............................................................................
6.5. Enumerators .......................................................................................
6.5.1. eBoundHandling ...........................................................................
4
104
105
105
106
117
119
126
126
128
129
129
130
130
130
131
131
132
132
133
133
133
134
134
134
135
135
DREAM Suite 1
6.5.2. eDistanceFunction .........................................................................
6.5.3. eDistributionMultivariate ................................................................
6.5.4. eDistributionUnivariate ..................................................................
6.5.5. eDreamError ................................................................................
6.5.6. eDreamInputPar ...........................................................................
6.5.7. eDreamPath .................................................................................
6.5.8. eDreamWarning ............................................................................
6.5.9. eErrType ......................................................................................
6.5.10. eInitDistrib .................................................................................
6.5.11. eLikelihood .................................................................................
6.5.12. eMeasureError ............................................................................
6.5.13. eOutlierTest ................................................................................
6.5.14. eParallelMode .............................................................................
6.5.15. ePluginType ...............................................................................
6.5.16. ePriorDistrib ...............................................................................
6.5.17. ePriorType .................................................................................
6.5.18. eVectorization .............................................................................
5
135
135
136
136
138
139
140
141
141
142
142
143
143
143
144
144
144
DREAM Suite 1
1 Introduction
DREAM Suite is a software package for the rapid development of applications based on theory of Markov
chain Monte Carlo (MCMC) simulation. This toolbox provides scientists and engineers with an arsenal of
options and utilities to solve posterior sampling problems involving (amongst others) bi modality, highdimensionality, summary statistics, bounded parameter spaces, dynamic simulation models, formal/
informal likelihood functions, diagnostic model evaluation, data assimilation, Bayesian model averaging,
distributed computation, and informative/non-informative prior distributions. DREAM Suite supports parallel
computing and returns to the user graphical output and convergence diagnostics of the sampled chain
trajectories.
DREAM Suite components
·
·
·
·
·
Main Program - the graphical user interface for the management of DREAM Suite projects,
preprocessing input data, running simulations and viewing results.
DREAM Solver - the calculation module, distributed in binary form (COM server) or with source code (C+
+ library).
DREAM SDK - Software Development Kit with interfaces and C++ libraries for the development of
DREAM Plugin modules.
Console Application - a simple C++ application illustrating the use of DREAM Solver. Distributed with
source code.
Examples - demo examples illustrating the main capabilities and functionalities of the DREAM Suite
package. These examples are available including C++ source code, are easy to adapt and can serve as
templates for other projects.
DREAM Editions and their features
Runtime
Edition
Standard
Edition
DREAM calculation module - COM Server
✓
✓
Support of programmable plugin modules
✓
✓
23 demo examples with results and C++ source code (DREAM plugins)
✓
✓
DREAM TestApp console (client application) with C++ source code
✓
✓
Authorization manager
✓
✓
Project manager
✓
✓
Features
DREAM Solver
Demo examples
DREAM Suite main program (GUI)
Data preprocessing - data input in dialogs and tables
✓
Calculation (including parallel calculation on multi-core PCs)
✓
Post-processing - graphical display of results in charts and tables
✓
DREAM SDK
C++ library for the development of DREAM plugin modules
✓
Generator of source code of DREAM plugin modules
✓
DREAM Suite applications
The DREAM Suite package enables users to rapidly create new Bayesian inference projects via plugin
modules. DREAM Solver can also be used as a library/software component for the development of new
standalone applications independent of DREAM Suite. DREAM Solver is available either in binary form
(COM server) or with all source code (C++ library - requires a special contract).
6
DREAM Suite 1
Required programming skills
Although DREAM Solver is a COM server, writing custom plugin modules does not require any special
knowledge of COM technology. DREAM Suite can generate source code of a new plugin module and users
just implement needed functions in C/C++ or another programming language (currently there is an interface
to MATLAB and several other similar interfaces are in development). Most of demo examples (library D3)
have been created in Visual C++ using STL and BOOST libraries, which can significantly speed up the
development. However, some examples (library D1) have been written in a very simple style in C/C++ so
that they were easy to understand even for less experienced programmers.
Required programming tools
Microsoft Visual Studio 2013 or later (free edition) and DREAM SDK. See also system requirements.
2 Getting started
Important notes for new users
·
·
·
The full version of DREAM Suite requires a valid license and authorization - see also DREAM installation
and activation. The demo version does not include the DREAM Server (the calculation module) and can
therefore not be used to rerun existing built-in examples or to calculate new project.
The DREAM installation package comes with many built-in examples which demonstrate same of the
main capabilities of DREAM Suite. The source code of each of these examples (i.e. their plug-in
modules) is available to users and can be accessed in a text editor and recompiled in Visual Studio.
The built-in examples of DREAM Suite (available in GUI of the main program) are easy to execute. For
each new project the user should have some basic understanding of the DREAM algorithm (DREAM
Solver), otherwise this might cause problems with implementation (incorrect use of prior distribution or
likelihood function, incorrect return argument from plugin, incorrect setup in GUI, etc.). The GUI
evaluates the validity of most input variables of DREAM Solver but cannot check your plugin module.
We therefore recommend that you carefully read the DREAM Technical manual before initiating a new
project in DREAM Suite. Furthermore, you should read documentation on the plugin module, a key
component of a key component of each DREAM Suite project.
Useful links
·
·
·
·
Web site: http://www.pc-progress.com/en/Default.aspx?dream
Frequently asked questions: http://www.pc-progress.com/en/Default.aspx?dream-faq
Discussion forum: http://www.pc-progress.com/forum
Customer support: [email protected]
2.1 System requirements
Supported operating systems
·
·
·
·
·
Windows
Windows
Windows
Windows
Windows
10 (32-bit and 64-bit)
8 (32-bit and 64-bit)
7 (32-bit and 64-bit)
Vista (32-bit and 64-bit)
Server 2008, 2012
DREAM Suite is not compatible with older Windows systems, Linux and Mac OS.
7
DREAM Suite 1
Minimum hardware requirements
·
·
·
·
·
X86 processor 2 GHz
2 GB RAM
10 GB free space on hard disk
Graphic card with minimum resolution of 1024 x 768 pixels and 16-bit color depth
Mouse
Tools for the development of DREAM applications
DREAM Solver is a standard COM server and therefore DREAM applications can be developed with any tool
and compiler that support COM technology. Yet, we recommend that you use Visual Studio 2013 Community Edition (or a more recent version), as the source code of DREAM Suite has been written in C+
+. Visual Studio is available, free of charge, for non-commercial applications.
·
·
Microsoft Visual Studio 2013 (with update 3 or newer)
Microsoft Visual Studio 2015 (with update 2 or newer)
2.2 Authors and contact information
Developers
DREAM Suite has been developed by Miroslav Šejna, Jasper Vrugt and PC-Progress s.r.o..
Copyright
© 2016 PC-Progress s.r.o.. All rights reserved.
Contact Information
PC-Progress s.r.o.
Korunní 2569/108a
Prague, 101 00
Czech Republic
Phone:
Fax:
e-mail:
web:
(+420) 222 514 225 or (+420) 245 008 033
(+420) 245 008 099
[email protected] or [email protected]
www.dreamsuite.eu or www.pc-progress.com
Customer Support
e-mail: [email protected]
Working hours: 9:00-17:00 (CET)
Disclaimer
The software has been verified against a large number of test cases. However, no warranty is given that the
program is completely error-free. If you do encounter problems with the code, find errors, or have
suggestions for improvement, please contact customer support at [email protected]
2.3 Installation
8
DREAM Suite 1
Installation program
The DREAM Suite installation program is available on the PC-Progress website http://www.pcprogress.com/en/Default.aspx?dream or in ELIS (PC-Progress client portal) at http://www.pc-progress.com/
en/Default.aspx?elis.
Running the installation
Download and run a self-extracting archive (e.g. DREAM_Suite_1.01.0010.exe), which will the extract
installation files to a temporary directory and start the installation program of DREAM Suite.
Selecting directories for DREAM Suite program files and data files
We recommend that you install the DREAM Suite program files in the default directory (e.g. C:\Program
Files (x86)\PC-Progress\DREAM Suite 1.x). Users can store their own data files in any other folder (see
Figure 2.3.1. "Installation Directories"). DREAM users must have "read/write" access to this folder. Data
files include demo examples, user's projects, files with user's settings and DREAM Suite SDK libraries.
Figure 2.3.1. Installation Directories.
Installation of HASP driver
If your license is protected by a hardware key, it is necessary to check the "Install hardware-key driver"
button (see Figure 2.3.2."Installation Features").
9
DREAM Suite 1
Figure 2.3.2. Installation Features.
Completing the installation
At the end of the installation process, it is necessary to launch DREAM Suite (check-box "Launch DREAM
Suite") so that the program can make the necessary changes in the Windows registration database and
thereby completing the installation.
10
DREAM Suite 1
2.4 Authorization
DREAM Suite is secured against unauthorized use by a hardware key (USB dongle - HASP) or software
activation. The method of protection can be selected at the time of purchase of a user license. Both
methods have their own advantages and disadvantages.
Hardware key
The hardware key is very simple to use and you can easily move the authorization from one computer to
another one. You just need to insert this USB device into your computer and DREAM Suite will find it
automatically. A problem may occur if the hardware key is lost, which can mean the loss of the license.
Software activation
The program activation is a process by which the authorization of DREAM Suite is based on a unique
numerical code, generated for a particular computer and for one-time use. The code is tied to the hardware
configuration, i.e. it cannot be used on another computer, or reused on the same computer if the
authorization is lost for some reason. Each activation is time-limited (even if you have a permanent license)
and must be prolonged before (or after) its expiration. The time-limited activation was introduced to prevent
unwanted consequences resulting from computer crashes and similar hardware problems that require a new
activation of DREAM Suite without its prior deactivation. The program can be deactivated manually and the
license transferred to another computer.
Verifying authorization
Authorization is verified when starting the program. If any failure occurs, a warning is displayed that the
program is running in a demo mode, in which DREAM Suite is not fully functional, i.e. it is not possible to
run the calculation.
DREAM Suite authorization dialog
Dialog with the authorization information and for the activation/deactivation of the program may be accessed
from the main menu - Help - DREAM Suite License.
11
DREAM Suite 1
Figure 2.4.1. Authorization status.
12
DREAM Suite 1
2.4.1 Hardware key
A Hardware Key (HASP), also called a "dongle", is a software copy protection device that is plugged into
the USB port of the computer. Upon startup, the application looks for the key and will run only if the key
contains the appropriate code. Hardware keys are very effective copy protection devices, because they
cannot be duplicated by the user.
·
·
The HASP for DREAM Suite is sent (by PC Progress) by mail and its use is very simple. You just
connect it to the computer via the USB port and DREAM Suite is then immediately authorized. The
DREAM Suite software then does not require any further activation.
Although the drivers for the HASP should normally be installed automatically when it is connected to the
USB (Windows operating system and Plug-and-play should take care of that), we still recommend
installing drivers at the same time the DREAM Suite software is installed (during the DREAM Suite
installation). In one of the dialog windows that appears during the installation, there is a special checkbox "Install the hardware-key driver", which needs to be checked - see Figure 2.3.1. "Installation
directories".
Advantages of HASP
·
·
·
·
Proven solutions by SafeNet, verified by hundreds of installations and users.
No activation of the software (e.g., DREAM Suite) is needed. Activation of the program brings some
disadvantages, such as that the program can be activated only on the allowed number of computers and
that the activation is always time-limited (up to 1 year) and needs to be repeatedly renewed. Under
certain circumstances, the activation code may not be immediately available and users will have to wait
untill they get it (e.g., activation by e-mail). The hardware key (dongle) provides users assurance that
the program can be easily installed and used, for example, on a new computer.
The program (e.g., DREAM Suite) can be used on multiple computers (e.g., desktop and laptop) by
transferring a small USB key.
Easier and safer installation of a network version. The network installation using a software key
(activation) is somewhat more complicated and some network administrators have complained about its
lack of flexibility. The use of HASP eliminates these problems.
2.4.2 Software activation
There are two options to activate DREAM Suite:
·
·
On-line activation (recommended)
Activation by e-mail (when the computer is not connected to the internet)
Time-limited activation
The activation of DREAM Suite is always time-limited (even if you have a permanent license) and the
maximum activation period is one year. You can prolong the activation anytime before its expiration using
the button "Extend activation on-line" in the DREAM Suite license dialog. After the authorization expires,
you can reactivate DREAM Suite using the on-line activation or by e-mail (see "Installation and Activation"
above). The time-limited activation was introduced to prevent unwanted consequences as the result of
computer crashes and similar hardware problems that require a new activation of DREAM Suite without its
prior deactivation.
Activation requires administrator's privileges
Activation of DREAM Suite requires elevated privileges, i.e. you need to run DREAM Suite "as
administrator" - see Figure 2.4.2. " Running DREAM Suite with ...".
13
DREAM Suite 1
Figure 2.4.2. Running DREAM Suite with elevated privileges.
2.4.2.1 On-line activation
For the on-line activation you will need the following information:
·
·
·
Your license number
DREAM Suite Edition to which you have a license and you wish to activate
Activation key
All this information is available in the system of the customer support ELIS http://www.pc-progress.com/en/
Default.aspx?elis. After purchasing a license, a customer will receive login data to ELIS by e-mail.
Figure 2.4.3. ELIS - on-line activation keys.
On-line activation proceeds as follows:
·
·
·
Start DREAM Suite (with administrator privileges) to access the dialog for the activation (see Figure
2.4.4. "On-line activation of DREAM Suite")
Fill in your license number, DREAM Suite edition you wish to activate and the activation code
Press the button "Activate Now"
After clicking on the Activate Now button, you will be asked to confirm all specified parameters (note that
you may be prompted by your firewall to allow communication between your computer and the license
14
DREAM Suite 1
server of PC Progress). At this point, all specified information will be verified against the data of our
electronic licensing system and if confirmed the actual activation of DREAM Suite will occur. This
communication applies only to data entered in the On-line Activation window, and no other information
stored on your PC is transferred. In case of unsuccessful activation, an error message is displayed
explaining the problem. After correcting the problem, you can use the Activate Now command again.
Figure 2.4.4. On-line activation of DREAM Suite.
2.4.2.2 Activation by e-mail
Activation by e-mail proceeds as follows:
·
·
·
·
·
·
·
Start DREAM Suite (with administrator privileges) and access the dialog for the activation as shown in
Figure 2.4.5."Activation by e-mail, generating request codes"
Fill in your license number, customer name and DREAM Suite edition you wish to activate
Press the button "Generate Request Codes"
On the following page of the dialog press the button "Copy request codes to the clipboard..."shown in
Figure 2.4.6. "Activation by e-mail, sending request codes to customer support"
Open the program for sending e-mails, paste the generated license request from the clipboard and send
it to customer support: [email protected]
DREAM Suite can be closed
Within one working day you will receive an activation code that should be inserted on the third page of
the activation dialog as shown in Figure 2.4.7. "Activation by e-mail, entering the activation code".
15
DREAM Suite 1
Figure 2.4.5. Activation by e-mail, generating request codes.
16
DREAM Suite 1
Figure 2.4.6. Activation by e-mail, sending request codes to customer support.
17
DREAM Suite 1
Figure 2.4.7. Activation by e-mail, entering the activation code
2.4.2.3 Extending the activation
The activation of DREAM Suite is always time-limited (even if you have a permanent license) and the
maximum activation period is one year. The time-limited activation was introduced to prevent unwanted
consequences as the result of computer crashes and similar hardware problems that require a new
activation of DREAM Suite without its prior deactivation. You can prolong the activation any time before its
expiration using the button "Extend activation on-line" in the DREAM Suite license dialog - see the
instructions below. After the authorization expires, you can reactivate DREAM Suite using the on-line
activation or by e-mail.
Extending the activation of DREAM Suite
·
·
·
·
·
Run DREAM Suite "As Administrator", i.e. click on the DREAM Suite icon by right mouse button and
select "Run as administrator".
Go to the main menu and click on the command "Help->DREAM Suite License and Authorization"
In the "DREAM Suite Authorization" dialog, press the button "Extend Activation on-line".
In the "Extend Activation Online" dialog, enter the Activation Key.
Press the button "Extend Activation Now". If you are prompted to allow DREAM Suite to connect to the
internet, allow it. The activation process is finished by a message confirming the successful activation or
displaying the reason of failure. If you need a help, please contact DREAM Suite customer support.
2.4.3 Software Deactivation
18
DREAM Suite 1
When you should deactivate DREAM Suite
·
·
·
·
·
·
Before any hardware changes (motherboard, hard-drives, graphic card, BIOS, etc.)
Before the re-installation of Windows
Before reformatting the hard-drive with DREAM Suite
Before changing the network path to DREAM Suite (applies to the network installation)
If you wish to move your license to another computer
If you know that you will not be using DREAM Suite for a long time
Deactivation - Common instructions
·
·
DREAM Suite deactivation requires administrator's privileges, i.e., you must run DREAM Suite “As
Administrator”
Open the DREAM Suite License and Activation dialog (main menu -> help -> DREAM Suite License
and Activation) and press the “Deactivate on-line” or “Deactivate by E-mail” button. If your computer is
connected to the internet, we recommend you use the on-line deactivation.
On-line deactivation
·
·
·
·
Press the "Deactivate on-line" button.
Enter the deactivation key (the same key which was used for DREAM Suite activation). If you forget this
key, you can obtain it in ELIS.
If you have a firewall, allow all internet connections in the pop-up window which may be displayed.
DREAM Suite will connect with our server and will be deactivated.
Deactivation by e-mail
·
·
·
·
Press the ”Deactivate by E-mail” button, which will deactivate DREAM Suite on your computer.
DREAM Suite will generate a special deactivation code, which serves as proof of deactivation. This
code will be displayed in the DREAM Suite License and Activation dialog.
Login to ELIS, go to Licenses and Workplaces, select the Workplace corresponding to the computer
that you just deactivated and deactivate this Workplace using the deactivation code. This will unlock the
WP and make it available for the activation on another computer.
You can also send the deactivation code to [email protected] or to your DREAM Suite reseller,
who will unlock the deactivated workplace in ELIS instead for you
2.4.4 Reinstallation and uninstallation
Information in this paragraph refers to the situation when DREAM Suite is secured via a software key
(activation). If you use a hardware key, a license transfer to another computer is simple - we just transfer
this USB key.
Reinstallation of DREAM Suite
If you reinstall DREAM Suite with the same version (or with a newer version) on an activated computer then
the authorization remains active automatically, i.e., you need not deactivate DREAM Suite before the
reinstallation and ask for new activation codes. This applies to the single-user license on a standalone
computer where DREAM Suite was working as the full version.
Moving DREAM Suite license to another computer
Moving DREAM Suite license to another computer is simple and you can do it yourself (without assistance
of customer support) either on-line or in ELIS in two steps:
·
Deactivate DREAM Suite on the old computer.
19
DREAM Suite 1
·
Activate DREAM Suite on the new computer
3 Graphical user interface
DREAM Suite main window allows you to open the Project Manager window and one or more Project
windows. It also contains a main menu with all available commands needed for working with DREAM Suite.
Main menu
·
File
·
·
·
·
·
·
·
·
·
·
·
·
·
New - creates a new project
Open - opens an existing project
Close - closes the active project
Save - saves the active project
Save As - saves the active project with a new name
Project Manager - shows or hides the Project Manager window
Library Manager - opens the Library Manager dialog
Recently Opened Projects - opens a recently opened project
Exit - quits the application
Edit (only available for "Project Information" window)
· Undo - undoes the previous action
· Cut - cuts the selection and puts it on the Clipboard
· Copy - copies the selection and puts it on the Clipboard
· Paste - insert Clipboard contents
View
· Project Information Window - shows or hides the Project Information panel in the Project
Manager window
· Toolbars and Docking Windows
· Standard - shows or hides the Standard toolbar.
· Status Bar - shows or hides the Status bar
· Reset Toolbars - resets all toolbars and docking panes to the default state
Options
· Program Options - opens a dialog with Program Options
Help
· Help - opens a window with DREAM Suite CHM help
· Technical Manual - opens PDF with DREAM Suite Technical manual
· User's Manual - opens PDF with DREAM Suite User's manual
· DREAM Suite on-line - opens DREAM Suite web page
· Check for updates - checks on-line for a new version of DREAM Suite
· DREAM Suite License - opens a dialog with information about DREAM Suite license and
authorization
· About DREAM Suite - opens a dialog with information about DREAM Suite
3.1 Project manager
Project Manager window displays DREAM Suite projects located in the current library directory and allows
to perform basic operations on them:
·
·
Button "New" - creates a new project
Button "Open" - opens a selected project
20
DREAM Suite 1
·
·
·
Button "Copy" - copies a selected project
Button "Rename" - renames a selected project or changes its description
Button "Delete" - deletes a selected project
Figure 3.1.1. Project Manager window.
Project Information window
The Project Information window displays detailed information about the currently selected project. It displays
HTML page ProjectInfo.htm located in the project directory, e.g. C:\Users\Public\Documents\PC-Progress
\DREAM Suite 1.x\SDK\Examples\Drm_Example01\Model\Info\ProjectInfo.htm. Content of this this page
can be changed in the built-in HTML editor (open the project and go to the "Project Information" page) or
directly in any other external HTML editor.
Location of projects
The current location of DREAM Suite projects can be quickly changed by the "Project Group" combo-box or
in the Project Group manager (button PG Manager).
3.2 Library manager
A "Library" is simply a directory containing DREAM projects, i.e. a location of projects.The Library Manager
window displays a list of all libraries and allows basic operations:
21
DREAM Suite 1
·
·
·
·
Button "New" - creates a new library, i.e. adds a new directory with DREAM projects
Button "Edit" - allows to edit a selected libraries, i.e. to change its directory, name or descriptions
Button "Remove" - removes selected libraries from the list. This operation does not delete any files or
directories
Button "Set Current" - marks a selected library as "current". Projects of this library are then displayed in
the Project Manager window.
Figure 3.2.1. Library Manager window
3.3 Project windows
The Project window has two parts: left panel with the project tree and right dialog corresponding to the
currently selected item in the tree (so called "Project dialogs").
22
DREAM Suite 1
Figure 3.3.1. Project window example.
Changing project data
When you open a project, all of its data files are copied to a temporary directory and all changes are
performed in this directory. This means that original files remain unchanged unless you utilize the "Save"
command. This allows you to make various changes, including deleting or recalculating results, without
losing the original data. A changed project can be easily recognized by the "*" symbol, which is added to
the project name displayed in the project window titlebar. When closing a changed project, the user is
prompted to save changes.
If you make any changes in the active project dialog, these changes are automatically accepted (i.e.
transferred from the dialog to project data in memory) when leaving the page. However, most project dialogs
have the buttons "Apply Changes" and "Cancel Changes" that enable you to apply or cancel latest changes
without leaving the page. If you enter an invalid data, you are not allowed to leave the page and you must
either fix the incorrect data or cancel your changes using the "Cancel Changes" button.
3.3.1 Project tree
The Project Tree window displays the entire structure of project data. In the upper part, you can find two
items defining general properties of the project - Project Information (the name of this item actually is the
project name) and Model Definition. The next item is called "Simulations", under which you can find so
called "Simulation cases", representing a series of independent calculation variants. Each simulation case
contains standard items, which may change dynamically according to options selected in the particular
case.
Hint: the user can quickly browse through all items of the tree using keys "Up" and "Down", which will
display all project data in project dialogs.
23
DREAM Suite 1
Figure 3.3.2. Project Tree window
3.3.2 Project information
Project Information dialog displays basic information about the project, i.e. its name, description and path to
the project file. While the description can be modified here, project name and location can only be changed
in the Project Manager.
Figure 3.3.3. Project information dialog.
24
DREAM Suite 1
HTML window - keyboard commands
Ctrl+B
Ctrl+I
Ctrl+U
Ctrl+K
Ctrl+spc
Ctrl+bksp
Ctrl+X
Ctrl+C
Ctrl+V
Ctrl+F
Ctrl+A
Ctrl+L
Ctrl+N
Ctrl+P
Bold
Italics
Underline
Create a hyperlink
Remove formatting
Undo (last text edit or format change)
Cut
Copy
Insert from clipboard
Find (highlights all occurrences)
Select All
Open new local HTML file
New browser window on current URL
Print...
3.3.3 Model definition
This dialog defines the number of model parameters and their names. It also specifies the name of the
plugin module, which is a dynamic library implementing the evaluation of proposals (hereinafter "Evaluator").
A skeleton of this plugin module can be generated automatically using the "Generate plugin project" button.
An existing project can be opened in the Visual Studio using the second button "Open plugin project".
Plugin type and creating DREAM plugins in other languages
DREAM Suite plugin can be implemented in various languages. This can be done either directly, when the
plugin DLL is created in a different language than C/C++ and connected with DREAM via the COM interface,
or indirectly, when the C++ plugin DLL serves just as an interface connecting DREAM with an external
module/server. The second case is demonstrated by two interfaces to MATLAB - see details in MATLAB
Plugin. For plugin types MATLAB_COM and MATLAB_Engine, plugin functions (definition of input data and
evaluation of proposals) are actually implemented in MATLAB *.m files. Another similar example is Example
5.
Loading the Plugin DLL
By default, the plugin DLL is automatically loaded when opening the project (if the DLL is available). The
plugin is then used to initialize data of new projects and check data of existing projects. During the
calculation, the plugin is used to calculate the probability of samples (see Differential Evolution Adaptive
Metropolis method). Check-box "Load plugin automatically..." allows users to disable this automatic
loading, which can be useful especially when loading the DLL takes a long time (e.g. when loading the
MATLAB server, etc.). If the automatic loading is turned off, plugin DLL is loaded just before the calculation.
25
DREAM Suite 1
Figure 3.3.4. Model definition dialog
3.3.4 Simulations
This page is intended for the management of simulations. Each simulation case (hereinafter "Case") uses
the same Evaluator but can have different DREAM input data. This allows the user to create multiple variants
of the same project with different settings and results.
Available operations with simulation cases
·
·
·
·
·
·
·
New Case - creates a new simulation case
Copy Case - creates copy of a selected simulation case
Rename Case - modifies case name and/or its description
Delete Cases - deletes one or more selected simulation cases
Delete Results of Selected Cases - deletes results of one or more selected simulation cases
Save Selected Modified Cases - saves data of selected modified cases
Restore Selected Modified Cases - cancels all changes in the selected cases and reloads their original
data
26
DREAM Suite 1
Figure 3.3.5. Simulations dialog.
3.3.5 Simulation case
This dialog displays basic information about a particular simulation case, i.e. its name, description and case
file and directory.
Available operations with the simulation case
·
·
·
·
·
·
·
New Case - creates a new simulation case
Copy Case - creates copy of the simulation case
Rename Case - modifies case name and/or its description
Delete Case - deletes the simulation case
Delete Result - deletes results of the simulation case
Save Modifications - saves data of the simulation cases
Cancel Modifications - cancels all changes in the case and reloads its original data
27
DREAM Suite 1
Figure 3.3.6. Simulation case dialog
3.3.6 DREAM algorithmic variables
This dialog can be used to set the basic DREAM algorithmic variables:
·
·
·
·
·
·
·
·
·
·
·
Number of Markov chains
Number of generations
Number of crossover values
Number of chain pairs for proposal
Random error for ergodicity
Randomization
Test function to detect out-lier chains
Probability of jump rate of 1
Option to adapt selection probability crossover
Option to store each T-th sample
Scaling factor of built-in jump rate
28
DREAM Suite 1
Figure 3.3.7. DREAM algorithmic variables dialog
3.3.7 Parameter space
This dialog is used for specification of initial sampling distribution, boundary handling and the use of prior
distribution.
Initial sampling distribution options
·
·
·
·
Uniform
Normal
Latin
Prior
Boundary handling options
·
·
·
·
None
Reflect
Bound
Fold
Use prior distribution
This option allows use of the prior distribution for initial sampling types different form "Prior"
29
DREAM Suite 1
Figure 3.3.8. Parameter space dialog.
3.3.8 Likelihood function
This dialog can be used to specify the likelihood function type and corresponding nuisance variables (if
applicable).
Likelihood function options
User-free likelihood functions
· 1 – Likelihood, L(x| Y)
· 2 – Log-likelihood, L(x| Y)
Formal likelihood functions
· 12 – Gaussian likelihood: homos/heteroscedastic data error
· 13 – Gaussian likelihood: with AR-1 model of error residuals
· 14 – Generalized likelihood function
· 15 – Whittle's likelihood (spectral analysis)
· 16 – Laplacian likelihood: homos/heteroscedastic data error
· 17 – Skewed Student likelihood function
ABC – diagnostic model evaluation
· 21 – Noisy ABC: Gaussian likelihood
· 22 – ABC: Boxcar likelihood
30
DREAM Suite 1
GLUE – limits of acceptability
· 23 – Limits of acceptability
GLUE – informal likelihood functions
· 31 – Inverse error variance with shaping factor
· 32 – Nash and Sutcliffe efficiency with shaping factor
· 33 – Exponential transform error variance with shaping factor
· 34 – Sum of absolute error residuals
GLUE likelihood parameter - the value of the shaping factor used within the (pseudo)likelihood functions of
GLUE.
Diagnostic Bayes - switch Bayes diagnostic on or off.
Figure 3.3.9. Likelihood function dialog.
3.3.9 Prior distribution
This dialog is intended to define the prior distribution type and its values.
Prior distribution types
·
·
Univariate
Multivariate
31
DREAM Suite 1
Figure 3.3.10. Prior distribution dialog.
3.3.10 Measurement data
This dialog can be used to enter data from measurements.
32
DREAM Suite 1
Figure 3.3.11. Measurement data dialog.
3.3.11 Calculation
This dialog is intended for specifying calculation parameters and running the simulation.
Output options
·
·
·
·
·
·
·
Save results in binary format - enables the saving of output files in binary format or text format. Binary
files have significantly smaller sizes and reading/writing is usually faster. Text files can us the check
values in the files.
Save within-chain diagnostic - creates file DREAM_Out_Diagnostic.txt with Coda diagnostic of each
chain
Save between-chain diagnostic - creates files DREAM_Out_BetweenChainDiagnostic_Rstat.txt (*.bin)
and DREAM_Out_BetweenChainDiagnostic_MRstat.txt (*.bin) with Save R- and MR-statistics
Save Markov chains - creates files DREAM_Out_ChainN.txt (*.bin) with Markov chains
Save ParSet - creates files DREAM_Out_ParSet.txt (*.bin) with ParSet matrix
Save model simulations - creates file DREAM_Out_FxSN.txt (*.bin) with calibration data of
measurements or ABC-summary metrics data.
Save summary statistics - creates file DREAM_Out_SN.txt (*.bin) with summary metrics in each
generation.
Calculation Options
·
Multi-core computation chains - enables the running of calculations in parallel mode
33
DREAM Suite 1
Calculation Options - Global Settings
·
·
·
Set the number of threads automatically - sets the number of calculation threads according to the
number of available cores (including hyper-threading)
Set custom number of threads - allows manual specification of the number of calculation threads
Set the highest priority to calculation threads - calculation will run with the highest system priority
Calculation commands
·
·
·
·
Calculate - starts the calculation
Stop - interrupts the running calculation
Refresh - updates the content of the output window, which may not be up-to-date if user clicked on it by
mouse or scrolled it.
Delete results - deletes existing results of the current simulation case
Figure 3.3.12. Calculation dialog
3.3.12 Post-processing - tables
This dialog displays results in tables. Selected values can be copied to the clipboard using the "Copy"
button.
34
DREAM Suite 1
Available tables
·
·
Parameter values
Correlation matrix
Figure 3.3.13. Post-processing - tables dialog.
3.3.13 Post-processing - charts
This dialog displays results in charts. The current chart may be copied to the clipboard as a metafile using
the "Copy" button. Chart settings can be customized by the "Options" button or using the pop-up menu
displayed after right-clicking on the chart.
Available charts
·
·
·
·
·
Algorithmic behavior of DREAM
Autocorrelation of sampled parameters
Convergence of individual chains to target distribution
Marginal densities of parameters
Histogram of marginal densities of parameters
35
DREAM Suite 1
Figure 3.3.14. Post-processing - charts dialog.
3.4 Program options
This dialog allows the specification and saving of some global options valid for a given computer. The
meanings of all options are obvious from their names.
w Program Startup
§ Open project manager
§ Open recently opened projects
§ Check for available updates (after a period of N days)
w Calculation
§ Multi-core computation chains
§ Set number of cores automatically
§ Set the highest priority to calculation threads
w Visual Studio
§ Path to Visual Studio IDE
w DREAM Suite SDK
§ Path to DREAM Suite SDK. This path corresponds to the DREAM1_SDK system environment
variable. Changing this path requires elevated privileges, i.e.DREAM Suite must be started in
the "Run As Administrator" mode.
36
DREAM Suite 1
Figure 3.3.15. Program Options dialog
3.5 Dialog About DREAM Suite
This dialog displays basic information about the program, e.g. program version, authors, copyright and
license agreement.
37
DREAM Suite 1
Figure 3.3.16. About DREAM Suite dialog
3.6 Dialog DREAM Suite License
This dialog displays information about DREAM Suite license and authorization.
38
DREAM Suite 1
Figure 3.3.17. DREAM Suite License dialog.
4 Demo examples
DREAM Suite includes many examples illustrating the main capabilities and functionalities of the DREAM
Suite package. These examples are available including source code, are easy to adapt and can serve as
templates for other projects. Since DREAM Plugin modules can be written in various languages and also
programming skills of DREAM users can be different, some selected examples are available in multiple
implementations. For example, library D3 contains examples written in C++ by professional programmers
using STL and BOOST libraries. Library D1 contains selected simplified examples (subset of D3) intended
for beginners and less-experienced programmers. Library D2 contains examples implemented in MATLAB
and demonstrates the ability of DREAM Suite to be used with other tools than Visual C++.
Libraries with demo examples
§
§
§
D1 - Selected simplified examples in C/C++
D2 - Selected examples implemented in MATLAB (*.m script files)
D3 - Advanced examples written in C++ using STL and BOOST
39
DREAM Suite 1
These examples and libraries can be found in the Library Manager.
List of available examples (category D)
Below you can find the list of all available examples and their mathematical description. Additional
information can be found directly in the source code of these examples, which is included in the DREAM
Suite package.
Name
Description
Example01 n-dimensional banana shaped Gaussian distribution
Example02 n-dimensional Gaussian distribution
Example03 n-dimensional multimodal mixture distribution
Example04 Real-world example using hymod rainfall - runoff model (HYMOD code in C++)
Example05 Real-world example using hymod rainfall - runoff model (HYMOD code in external FORTRAN
module)
Example06 Rainfall-runoff model with generalized log-likelihood function
Example07 HYDRUS-1D: using prior information on soil hydraulic parameters
Example08 1D mixture distribution: Approximate Bayesian Computation
Example09 Rainfall-runoff model with spectral likelihood function
Example10 Multimodel mixture distribution: multivariate prior
Example11 Multivariate student t-distribution
Example12 Pedometrics problem involving variogram fitting
Example13 Nash-Cascade hydrograph
Example14 ABC inference for hydrologic model
Example15 ABC inference using 10 bivariate normal distributions
Example16 Hydrogeophysical inference
Example17 Rainfall-runoff with inference discharge data error
Example18 Informal likelihood (GLUE): Lotka-Volterra model
Example19 Bayesian Model Averaging
Example20 GLUE - limits of acceptability: Soil temperature modeling
Example21 GLUE - limits of acceptability: HYDRUS-1D model
Example22 GLUE - limits of acceptability: Nash-Cascade example
Example23 GLUE - limits of acceptability: SAC-SMA model
4.1 Example 1
Case-Study I: d-dimensional banana shaped Gaussian distribution
The first case study considers a d=10-dimensional twisted Gaussian probability density function which is
given by the following unnormalized density (hence the proportionality sign)
(1.01)
where
is a function that is used to the multivariate normal to a
twisted (banana-shaped) distribution. Here,
signifies the probability density function of a multivariate
normal distribution,
, and thus
, where the
vector
stores
the mean of the distribution, and the
matrix signifies the variance-covariance matrix. The tilde
40
DREAM Suite 1
symbol ‟ ” means ‟distributed according to”. The probability density function of
is given by
(1.02)
where the symbol T denotes transpose, and |·| signifies the determinant operator,
The mean of the normal distribution,
as a diagonal matrix,
.
was set to zero (all elements), and the covariance matrix is defined
. The entries of this matrix outside the main diagonal are all zero
(1.03)
,
and the value of b = 0.1. The initial sample was drawn from
, a normal distribution centered at
zero and with covariance matrix equal to five times the identity matrix, , a
(square) matrix with ones
on the main diagonal and zeros elsewhere. We use N = 10 different chains with DREAM and apply default
values of the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D1\Drm_D1_Example01\Plugin
\Src_Cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// EvaluatorModel.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample01::GetInputParams
//------------------------------------------------------------------------------------------------(
IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define default DREAM parameters for this particular project.
This function is called by the main program to initialize data of each newly created simulation
case. This data can be later modified in the GUI (except parameters locked by flag
DreamSolver::disable_edit) or can be overwritten while reading case data from a file.
In the AppTest console application, there is no GUI and this functions actually defines all
input parameters that are subsequently used by DREAM Solver.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
41
DREAM Suite 1
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIDreamInputParams pointer
if(pIDreamInputParams == nullptr)
{
return E_INVALIDARG;
}
// Set default input parameters
pIDreamInputParams->SetProblemDimension(2, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfMarkovChains(10, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfGenerations(25000, DreamSolver::enable_edit);
pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_102, DreamSolver::disable_edit);
pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitNormal, DreamSolver::enable_edit);
pIDreamInputParams->SetOutlierTest(eOutlierTest::eOutlierIqr, DreamSolver::enable_edit);
pIDreamInputParams->SetBoundHandling(eBoundHandling::eBoundUnbounded, DreamSolver::enable_edit);
// Example can run in parallel mode (recommended mode)
pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample01::InitData
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
// Plugin information
, IDreamInputParViewer* pIDreamInputParams // Current DREAM input parameters
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called to prepare:
A/ DREAM input data before accessing them via the IDreamDataSource interface and
B/ all other local data required by evaluator for the calculation.
It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir
(directory ...Drm_ExampleXX\Model\Data).
Remark 1: This function prepares DREAM input data in the evaluator according to current
DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be
different from default parameters defined in function CEvaluatorExample::GetInputParams().
Remark 2: This function should be called before using functions
CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,
::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()
can be called independently.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Check parameters
if(pIPluginInfo == nullptr || pIDreamInputParams == nullptr)
{
// Invalid argument
return E_INVALIDARG;
}
// Free memory from previous calculation
FunctionsSC::DeleteMatrix(m_invC, m_invCSize);
// Target covariance
int iDim = m_invCSize = pIDreamInputParams->GetProblemDimension();
double** C = nullptr;
FunctionsSC::IdentityMatrix(C, iDim);
C[0][0] = 100.0;
42
DREAM Suite 1
FunctionsSC::CopyMatrix(m_invC, C, iDim);
if(!FunctionsSC::Inv(m_invC, iDim))
{
return E_FAIL;
}
// Calculate integration constant
double temp = pow(2.0 * pi<double>(), -(double)iDim / 2.0);
double det = FunctionsSC::DeterminantLU(C, iDim);
double temp2 = pow(det, -0.5);
m_logF = log(temp * temp2);
// log_F becomes - Inf for large d--> hence we set log_F to zero.
// Also need to resolve this in importance distribution as well!!
if(iDim > 150)
{
m_logF = 0.0;
}
m_b = 0.1;
// Free allocated memory
FunctionsSC::DeleteMatrix(C, iDim);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample01::GetNormalData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar
// Interface to DREAM input parameters
, IDreamDataNormal* pINormalData
// Interface to normal distribution data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pINormalData pointer
if(pINormalData == nullptr)
{
return E_INVALIDARG;
}
// Fill mu data
int iDim = pInputPar->GetProblemDimension();
for(int iIndex = 0; iIndex < iDim; iIndex++)
{
pINormalData->AddMeanItem(0.0);
}
// Covariance matrix diagonal value
pINormalData->SetCovarianceDiagonalValue(10.0);
// Data added successfully
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample01::EvaluateProposal
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, int iSim
// input parameter (i-th simulation / Markov chain)
, IDreamMatrix* x
// input matrix (m_NumberOfMarkovChains x m_ProblemDimension)
, IDreamMatrix* res
// output matrix (Data_Dimension x m_NumberOfMarkovChains)
, BSTR strWorkingDir
// path to the current working directory (for current calculation thread)
, BSTR strModelDataDir // path to the permanent directory with model data
, BSTR strModelBinDir
// path to the permanent directory with model executables
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to evaluate the current proposal (i.e. one single step
of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes
the likelihood (or log-likelihood or the residual vector to be compared with the measurement
- see the technical manual) for iSim-th row of input matrix "x" and returns the result
43
DREAM Suite 1
in output matrix "res".
Parameter iSim is from interval <0, IDreamInputParams::GetNumberOfMarkovChains() - 1>.
If pInputPar->GetVectorization() == eVectorization::eVectYes, then iSim = 0 and all proposals
(for all Markov chains) should be evaluated in one step, i.e. during one call of this function.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// We should have m_invC initialized
assert(m_invCSize != 0);
// Temporary vector used for calculations
double* tmpx = nullptr;
FunctionsSC::CopyRowFromIDreamMatrix(iSim, tmpx, x);
double logLtmp = 0.0;
if(x->_colCount == 1) // 1-dimensional Gaussian
{
// 1-dimensional twisted Gaussian probability density function
// logL = logF - 1/2 * invC * (x.^2)'
// where:
// x' - transposition of "x"
// .^2 - power of 2 of each element
logLtmp = m_logF - 0.5 * m_invC[0][0] * tmpx[0] * tmpx[0];
}
else // N-dimensional Gaussian
{
// Introduce banana shaped nonlinearity between x(1) and x(2)
// x(2) = x(2) + b * x(1)^2 - 100 * b
tmpx[1] += m_b * tmpx[0] * tmpx[0] - 100.0 * m_b;
//
//
//
//
//
//
N-dimensional twisted Gaussian probability density function
logL = m_logF - 1/2 * sum(x'.*(invC * x'));
where:
x' - transposition of matrix "x"
sum - returns the sum of the elements of input along the first array dimension
.* - multiplies arrays A and B element by element
// vector1 = invC * x'
double* vector1 = nullptr;
FunctionsSC::MatrixColumnVectorProduct(vector1, m_invC, m_invCSize, m_invCSize,
tmpx, x->_colCount);
// vector2 = x'.*(invC * x') = vector1 .* vector2
double* vector2 = nullptr;
FunctionsSC::VectorVectorElementProduct(vector2, tmpx, x->_colCount, vector1, x->_colCount);
// logL = m_logF - 1/2 * sum(x'.*(invC * x')) = m_logF - 0.5 sum(vector2)
logLtmp = m_logF - 0.5 * FunctionsSC::VectorElementSum(vector2, x->_colCount);
// Free allocated memory
FunctionsSC::DeleteVector(vector1);
FunctionsSC::DeleteVector(vector2);
}
// Replace content of res by tmp values
res->_data[iSim] = logLtmp;
// Free allocated memory
FunctionsSC::DeleteVector(tmpx);
return S_OK;
}
44
DREAM Suite 1
4.2 Example 2
Case-Study II: d-dimensional Gaussian distribution
To test the performance of DREAM in the presence of high-dimensionality, the second case study involves a
d = 100-dimensional multivariate normal distribution
(2.01)
,
where the
vector
stores the mean of the normal distribution, and the
signifies the variance-covariance matrix. The probability density function of
is given by
,
matrix
(2.02)
We assume a mean of zero,
, and define the covariance matrix, , in such a way that the variance
th
th
of the
variable is equal to
variable is equal to and all pairwise correlations are equivalent to 0.5 The
main diagonal thus has values of
. The correlation,
, between two entries
and of
can be calculated from their respective covariance value and individual variances according to
(2.03)
.
Entry
of matrix
can thus be calculated using
(2.04)
,
where the variances of and
and
, respectively.
are found on the main diagonal of
, and thus equivalent to entries
The initial population is drawn from the multivariate uniform distribution,
, using Latin hypercube
sampling. We assume a lower bound of each dimension equal to
and upper bound of
. The
initial value of each parameter {1,…,d} is thus drawn from this range. We use N = 100 chains with DREAM
and apply default values of the algorithmic variables, with the exception that we use thinning to reduce
memory storage. Indeed, only every 10th sample is stored in each Markov chain.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D1\Drm_D1_Example02\Plugin
\Src_Cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// EvaluatorModel.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample02::GetInputParams
//------------------------------------------------------------------------------------------------(
IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define default DREAM parameters for this particular project.
This function is called by the main program to initialize data of each newly created simulation
case. This data can be later modified in the GUI (except parameters locked by flag
DreamSolver::disable_edit) or can be overwritten while reading case data from a file.
45
DREAM Suite 1
In the AppTest console application, there is no GUI and this functions actually defines all
input parameters that are subsequently used by DREAM Solver.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIDreamInputParams pointer
if(pIDreamInputParams == nullptr)
{
return E_INVALIDARG;
}
// Set default input parameters
pIDreamInputParams->SetProblemDimension(100, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfMarkovChains(50, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfGenerations(10000, DreamSolver::enable_edit);
pIDreamInputParams->SetThinnigSampleToStore(10, DreamSolver::enable_edit);
pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_102, DreamSolver::disable_edit);
pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitLatin, DreamSolver::enable_edit);
// Example can run in parallel mode (recommended mode)
pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample02::InitData
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
// Plugin information
, IDreamInputParViewer* pIDreamInputParams // Current DREAM input parameters
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called to prepare:
A/ DREAM input data before accessing them via the IDreamDataSource interface and
B/ all other local data required by evaluator for the calculation.
It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir
(directory ...Drm_ExampleXX\Model\Data).
Remark 1: This function prepares DREAM input data in the evaluator according to current
DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be
different from default parameters defined in function CEvaluatorExample::GetInputParams().
Remark 2: This function should be called before using functions
CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,
::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()
can be called independently.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Check parameters
if(pIPluginInfo == nullptr || pIDreamInputParams == nullptr)
{
// Invalid argument
return E_INVALIDARG;
}
// Free memory from previous calculation
46
DREAM Suite 1
FunctionsSC::DeleteMatrix(m_invC, m_invCSize);
int d = pIDreamInputParams->GetProblemDimension();
// Construct the d x d covariance matrix
double** matrix1 = nullptr;
FunctionsSC::IdentityMatrix(matrix1, d, d, 0.5);
double** matrix2 = nullptr;
FunctionsSC::CreateMatrix(matrix2, d, d, 0.5);
double** A = nullptr;
FunctionsSC::MatrixMatrixAddition(A, matrix1, d, d, matrix2, d, d);
// Rescale to variance - covariance matrix of interest
double** C = nullptr;
FunctionsSC::CreateMatrix(C, d);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
C[i][j] = A[i][j] * sqrt((i + 1.0) * (j + 1.0));
}
}
m_invCSize = d;
FunctionsSC::CopyMatrix(m_invC, C, d);
if(!FunctionsSC::Inv(m_invC, d))
{
return E_FAIL;
}
// Calculate integration constant
double temp = pow(2 * pi<double>(), -(double)d / 2.0);
double det = FunctionsSC::DeterminantLU(C, d);
double temp2 = pow(det, -0.5);
m_logF = log(temp * temp2);
// log_F becomes - Inf for large d--> hence we set log_F to zero
// Also need to resolve this in importance distribution as well!!
if(d > 150)
{
m_logF = 0;
}
// Free allocated memory
FunctionsSC::DeleteMatrix(matrix1, d);
FunctionsSC::DeleteMatrix(matrix2, d);
FunctionsSC::DeleteMatrix(A, d);
FunctionsSC::DeleteMatrix(C, d);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample02::GetMinMaxData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataMinMax* pIMinMaxData // Interface to Min/Max data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIMinMaxData pointer
if(pIMinMaxData == nullptr)
{
return E_INVALIDARG;
}
int d = pInputPar->GetProblemDimension();
// Fill min max data
for(int i = 0; i < d; i++)
{
47
DREAM Suite 1
pIMinMaxData->AddItem(-5.0, 15.0);
}
// Data added successfully
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample02::EvaluateProposal
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, int iSim
// input parameter (i-th simulation / Markov chain)
, IDreamMatrix* x
// input matrix (m_NumberOfMarkovChains x m_ProblemDimension)
, IDreamMatrix* res
// output matrix (Data_Dimension x m_NumberOfMarkovChains)
, BSTR strWorkingDir
// path to the current working directory (for current calculation thread)
, BSTR strModelDataDir // path to the permanent directory with model data
, BSTR strModelBinDir
// path to the permanent directory with model executables
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to evaluate the current proposal (i.e. one single step
of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes
the likelihood (or log-likelihood or the residual vector to be compared with the measurement
- see the technical manual) for iSim-th row of input matrix "x" and returns the result
in output matrix "res".
Parameter iSim is from interval <1, IDreamInputParams::m_NumberOfMarkovChains> except
the case when pInputPar->GetVectorization() == eVectorization::eVectYes, when iSim = 0
and all proposals (for all Markov chains) are evaluated in one step.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Temporary vector used for calculations
double* tmpx = nullptr;
FunctionsSC::CopyRowFromIDreamMatrix(iSim, tmpx, x);
double logLtmp = 0.0;
if(x->_colCount == 1) // 1-dimensional Gaussian
{
// 1-dimensional twisted Gaussian probability density function
logLtmp = m_logF - 0.5 * m_invC[0][0] * tmpx[0] * tmpx[0];
}
else // N-dimensional Gaussian
{
// N-dimensional twisted Gaussian probability density function
// logL = m_logF - 1/2 * sum(x'.*(invC * x'));
// where:
// x' - transposition of matrix "x"
// sum - returns the sum of the elements of input along the first array dimension
// .* - multiplies arrays A and B element by element
// vector1 = invC * x'
double* vector1 = nullptr;
FunctionsSC::MatrixColumnVectorProduct(vector1, m_invC, m_invCSize, m_invCSize,
tmpx, x->_colCount);
// vector2 = x'.*(invC * x') = vector1 .* vector2
double* vector2 = nullptr;
FunctionsSC::VectorVectorElementProduct(vector2, tmpx, x->_colCount, vector1, x->_colCount);
// logL = m_logF - 1/2 * sum(x'.*(invC * x')) = m_logF - 0.5 sum(vector2)
logLtmp = m_logF - 0.5 * FunctionsSC::VectorElementSum(vector2, x->_colCount);
// Free allocated memory
FunctionsSC::DeleteVector(vector1);
48
DREAM Suite 1
FunctionsSC::DeleteVector(vector2);
}
// Replace content of res by tmp values
res->_data[iSim] = logLtmp;
// Free allocated memory
FunctionsSC::DeleteVector(tmpx);
return S_OK;
}
4.3 Example 3
Case-Study III: d-dimensional multimodal mixture distribution
To test the performance of DREAM in the presence of multi-modality, the third case study involves a d = 10dimensional bimodal mixture of two Gaussian distributions
(3.01)
,
where and -5 and 5 are d-dimensional vectors that define the mean of each normal distribution, and the
covariance matrix is equivalent to the identity-matrix Id, a
(square) matrix with ones on the main
diagonal and zeros elsewhere. The density of the target distribution is simply the sum of the pdfs of two
normal distributions
+
(3.02)
.
This equation can be simplified as
harm. This leads to
and the term
+
in the exponent can be removed without
.
(3.03)
The initial state of each Markov chain (= starting point) is drawn from
, the -variate normal
distribution with mean zero and covariance matrix equal to a multiple (five) of the identity matrix. We use N
= 20 different chains with DREAM and apply default values of the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D1\Drm_D1_Example03\Plugin
\Src_Cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// EvaluatorModel.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample03::GetInputParams
//------------------------------------------------------------------------------------------------(
IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define default DREAM parameters for this particular project.
This function is called by the main program to initialize data of each newly created simulation
49
DREAM Suite 1
case. This data can be later modified in the GUI (except parameters locked by flag
DreamSolver::disable_edit) or can be overwritten while reading case data from a file.
In the AppTest console application, there is no GUI and this functions actually defines all
input parameters that are subsequently used by DREAM Solver.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIDreamInputParams pointer
if(pIDreamInputParams == nullptr)
{
return E_INVALIDARG;
}
// Set default input parameters
pIDreamInputParams->SetProblemDimension(10, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfMarkovChains(pIDreamInputParams->GetProblemDimension(),
DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfGenerations(100000, DreamSolver::enable_edit);
pIDreamInputParams->SetThinnigSampleToStore(10, DreamSolver::enable_edit);
pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_102, DreamSolver::disable_edit);
pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitNormal, DreamSolver::enable_edit);
pIDreamInputParams->SetOutlierTest(eOutlierTest::eOutlierIqr, DreamSolver::enable_edit);
pIDreamInputParams->SetBoundHandling(eBoundHandling::eBoundUnbounded, DreamSolver::enable_edit);
// Example can run in parallel mode (recommended mode)
pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample03::InitData
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
// Plugin information
, IDreamInputParViewer* pIDreamInputParams // Current DREAM input parameters
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called to prepare:
A/ DREAM input data before accessing them via the IDreamDataSource interface and
B/ all other local data required by evaluator for the calculation.
It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir
(directory ...Drm_ExampleXX\Model\Data).
Remark 1: This function prepares DREAM input data in the evaluator according to current
DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be
different from default parameters defined in function CEvaluatorExample::GetInputParams().
Remark 2: This function should be called before using functions
CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,
::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()
can be called independently.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Check parameters
if(pIPluginInfo == nullptr || pIDreamInputParams == nullptr)
{
50
DREAM Suite 1
// Invalid argument
return E_INVALIDARG;
}
// Free memory from previous calculation
FunctionsSC::DeleteMatrix(m_L, m_Lsize, m_Lsize);
FunctionsSC::DeleteMatrix(m_invL, m_invLsize, m_invLsize);
FunctionsSC::DeleteMatrix(m_mu, m_k, m_muSize);
FunctionsSC::DeleteVector(m_logF);
int d = pIDreamInputParams->GetProblemDimension();
// How many Gaussians?
m_k = 2;
// Determine weight of each respective Gaussian
// log_prior = log ( [1/3 2/3] );
double* logPrior = nullptr;
FunctionsSC::CreateVector(logPrior, m_k);
logPrior[0] = log(1. / 3.);
logPrior[1] = log(2. / 3.);
// Mean of both modes
//mu = [ -5*ones(1,d) ; 5*ones(1,d) ];
m_muSize = d;
double* mu1 = nullptr;
double* mu2 = nullptr;
FunctionsSC::CreateVector(mu1, d, -5.0);
FunctionsSC::CreateVector(mu2, d, 5.0);
FunctionsSC::CreateMatrix(m_mu, m_k, d);
FunctionsSC::MatrixSetRow(0, mu1, m_mu, m_k, d);
FunctionsSC::MatrixSetRow(1, mu2, m_mu, m_k, d);
// Now compute the inverse of the covariance matrix
double** C = nullptr;
FunctionsSC::IdentityMatrix(C, d, d);
// compute the log determinant of covariance
m_Lsize = d;
if(!FunctionsSC::Cholesky(m_L, C, d))
{
return E_FAIL;
}
m_invLsize = d;
FunctionsSC::CopyMatrix(m_invL, m_L, d);
if(!FunctionsSC::Inv(m_invL, d))
{
return E_FAIL;
}
double* diagL = nullptr;
FunctionsSC::MatrixDiagonal(diagL, m_L, d);
// Calculate part of normalization constant
// logDetSigma = 2 * sum ( log ( diagL ) );
FunctionsSC::VectorElementLog(diagL, d);
double logDetSigma = 2.0 * FunctionsSC::VectorElementSum(diagL, d);
// Calculate total normalization constant (k values)
// m_log_F = -0.5 * logDetSigma + logPrior - d * log(2 * pi) / 2;
double value = -0.5 * logDetSigma - d * log(2 * pi<double>()) / 2.0;
double* vector2 = nullptr;
FunctionsSC::CreateVector(vector2, m_k, value);
FunctionsSC::VectorVectorAddition(m_logF, logPrior, m_k, vector2, m_k);
FunctionsSC::DeleteVector(mu1);
FunctionsSC::DeleteVector(mu2);
FunctionsSC::DeleteVector(logPrior);
FunctionsSC::DeleteVector(diagL);
FunctionsSC::DeleteVector(vector2);
FunctionsSC::DeleteMatrix(C, d, d);
51
DREAM Suite 1
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample03::GetMinMaxData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataMinMax* pIMinMaxData // Interface to Min/Max data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIMinMaxData pointer
if(pIMinMaxData == nullptr)
{
return E_INVALIDARG;
}
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample03::GetNormalData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar
// Interface to DREAM input parameters
, IDreamDataNormal* pINormalData
// Interface to normal distribution data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pINormalData pointer
if(pINormalData == nullptr)
{
return E_INVALIDARG;
}
size_t d = (size_t)pInputPar->GetProblemDimension();
// Fill mu data
for(size_t iIndex = 0; iIndex < d; iIndex++)
{
pINormalData->AddMeanItem(0.0);
}
// Covariance matrix diagonal value
pINormalData->SetCovarianceDiagonalValue(5.0);
// Data added successfully
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample03::EvaluateProposal
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, int iSim
// input parameter (i-th simulation / Markov chain)
, IDreamMatrix* x
// input matrix (m_NumberOfMarkovChains x m_ProblemDimension)
, IDreamMatrix* res
// output matrix (Data_Dimension x m_NumberOfMarkovChains)
, BSTR strWorkingDir
// path to the current working directory (for current calculation thread)
, BSTR strModelDataDir // path to the permanent directory with model data
, BSTR strModelBinDir
// path to the permanent directory with model executables
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to evaluate the current proposal (i.e. one single step
of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes
the likelihood (or log-likelihood or the residual vector to be compared with the measurement
- see the technical manual) for iSim-th row of input matrix "x" and returns the result
in output matrix "res".
52
DREAM Suite 1
Parameter iSim is from interval <0, IDreamInputParams::GetNumberOfMarkovChains() - 1>.
If pInputPar->GetVectorization() == eVectorization::eVectYes, then iSim = 0 and all proposals
(for all Markov chains) should be evaluated in one step, i.e. during one call of this function.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
/*
Vectorization:
If vectorization is set to "eVectYes" then EvaluateProposal function is called only once with
iSim = 0 and whole input matrix "x" has to be evaluated in one step to get output matrix res.
If vectorization is set to "eVectYes" then EvaluateProposal function is called "x->_colCount"-th
times with iSim = <0, x->_colCount-1> and input matrix "x" has to be avaluated for each column
of matrix "x" separately.
*/
// Temporary vector used for calculations
double* tmpx = nullptr;
FunctionsSC::CopyRowFromIDreamMatrix(iSim, tmpx, x);
// Now loop over each component of mixture
double* loglh = nullptr;
FunctionsSC::CreateVector(loglh, m_k);
for(int j = 0; j < m_k; j++)
{
// Calculate log_likelihood of jth component
// log_lh(:,j) = -0.5 * sum (x - mu(j,:)).^2 , 2) + logF(j);
// vector2 = mu(j,:)
double* vector2 = nullptr;
FunctionsSC::Row(j, vector2, m_mu, m_k, x->_colCount);
// mat1 = x - mu(j,:)
double* mat1 = nullptr;
FunctionsSC::VectorVectorSubtraction(mat1, tmpx, x->_colCount, vector2, x->_colCount);
// mat1 = (x - mu(j,:)).^2
FunctionsSC::VectorElementPow(2.0, mat1, x->_colCount);
// log_lh(j) = -0.5 * sum(mat1) + m_logF(j);
loglh[j] = -0.5 * FunctionsSC::VectorElementSum(mat1, x->_colCount) + m_logF[j];
FunctionsSC::DeleteVector(vector2);
FunctionsSC::DeleteVector(mat1);
}
// Now determine the overall log-likelihood
double maxll = FunctionsSC::VectorMaxElement(loglh, m_k);
// Minus maxll to avoid underflow
double* vector1 = nullptr;
FunctionsSC::CreateVector(vector1, m_k, -maxll);
double* post = nullptr;
FunctionsSC::VectorVectorAddition(post, loglh, m_k, vector1, m_k);
FunctionsSC::VectorElementExp(post, m_k);
// Density(i) is \sum_j \alpha_j P(x_i| \theta_j)/ exp(maxll(i))
double density = FunctionsSC::VectorElementSum(post, m_k);
// Calculate log-L
res->_data[iSim] = log(density) + maxll;
FunctionsSC::DeleteVector(tmpx);
FunctionsSC::DeleteVector(loglh);
FunctionsSC::DeleteVector(vector1);
53
DREAM Suite 1
FunctionsSC::DeleteVector(post);
return S_OK;
}
4.4 Example 4
Case-Study IV: Bayesian inference of a conceptual watershed model (HYMOD code in C/C++)
In this fifth study, we use the HYMOD conceptual watershed model, a parsimonious rainfall-runoff model
whose parameters are thought to vary between watersheds. This model has been used in a numerous
studies and has five parameters that need to be specified by the user. Inputs to the model include mean
areal precipitation (MAP), and potential evapotranspiration (PET), while the outputs are estimated channel
inflow. The HYMOD model has been discussed extensively in many previous papers that study streamflow
forecasting and automatic model calibration (Boyle 2000; Wagener et al. 2001; Vrugt et al. 2003). Details of
the model can be found therein.
In summary, HYMOD consists of a simple two-parameter rainfall excess model connected with two series of
linear reservoirs (three, identical, for the quick and a single reservoir for the slow response) in parallel as a
routing component (see Figure 4.01).
Figure 4.01: Conceptual representation of the HYMOD conceptual watershed model
The rainfall excess model is described in detail by Moore (1985, 1999). The model assumes that the soil
moisture storage capacity, c, varies across the catchment and, therefore, that the proportion of the
catchment with saturated soils varies over time. The spatial variability of the soil moisture capacity is
described by the following distribution function
,
(4.01)
where c(t) is the simulated soil water storage capacity at time t and cmax (mm) and bexp (-) are unknown
coefficients.
HYMOD has five different parameters whose values need to be determined from a measured discharge
record. The parameters and their prior uncertainty ranges are listed in Table 4.01. This includes cmax (L), the
maximum storage capacity in the catchment, bexp (-) the degree of spatial variability of the soil moisture
capacity within the catchment, α (-) a coefficient that distributes the flow between the fast and slow-flow
reservoirs, and rs (days) and rq (days), the residence time of the slow and fast-flow reservoir reservoirs,
respectively. The actual evapotranspiration is equal to its potential value if sufficient soil moisture is
available, otherwise it is reduced depending on the soil water status.
54
DREAM Suite 1
Parameter
Maximum interception
Symbol
Lower
10
Upper
1000
Units
mm
Soil water storage capacity
0
2
-
Maximum percolation rate
0
1
-
Recession constant slow-flow reservoir
-
Recession constant fast-flow reservoir
1
-
Table 4.01: Parameters of HYMOD and their prior uncertainty ranges
We use historical data from the Leaf River (1950 km2) watershed in Mississippi in the USA. The data
consists of daily MAP (mm/day), PET (mm/day), and streamflow (mm/day) values. A two year data record
is used for posterior inference of the HYMOD parameters. This includes the period from January 1, 1952 to
September 30, 1954. A multivariate uniform prior distributed is assumed for the parameters using the ranges
listed in Table 4.01. The posterior parameter distribution is now determined with DREAM using a simple
Gaussian likelihood function
(4.02)
,
where
and
are the observed and simulate discharge record,
respectively, n denotes the number of measurements, and |·| denotes the modulus operator (absolute value).
The initial population is drawn from the lower and upper ranges listed in Table 4.01 using Latin hypercube
sampling. We use N = 10 chains with DREAM and use standard settings for the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example04\Plugin\Src_Cpp
4.5 Example 5
Case-Study V: Bayesian inference of a conceptual watershed model (HYMOD in external Fortran
module)
This case study is identical to the previous case study with the exception that the HYMOD model has been
coded in Fortran instead. This demonstrates that DREAM can communicate with different computer
languages. Note that the plugin module here serves just as an interface to call HYMODsilent.exe, created in
Fortran and located in the Drm_Example05\Model\Bin subdirectory. Similar approach has been used to
create MATLAB examples in library D2.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example05\Plugin\Src_Cpp
4.6 Example 6
Case-Study VI: A conceptual watershed model with generalized log-likelihood function
The sixth case study involves flood forecasting, and consists of the calibration of a mildly complex lumped
watershed model using historical data from the Guadalupe River at Spring Branch, Texas. This is the driest
of the 12 MOPEX basins described in the study of Duan et al. (2006). The model structure and hydrologic
process representations are found in Schoups and Vrugt (2010). The model transforms rainfall into runoff at
the watershed outlet using explicit process descriptions of interception, throughfall, evaporation, runoff
generation, percolation, and surface and subsurface routing (see Figure 6.01).
55
DREAM Suite 1
Figure 6.01. Schematic representation of the hmodel conceptual watershed model.
Table 6.01 summarizes the seven different parameters of the hmodel and their prior uncertainty ranges.
While some of the values of parameters in conceptual rainfall-runoff models can be derived directly from
knowledge of physical watershed characteristics, others are effective quantities that cannot, in practice, be
measured in the field, and therefore have to be estimated through calibration against a measured streamflow
hydrograph using either a trial-and-error ‘manual approach' or an automated search algorithm (Boyle et al.,
2000; Madsen, 2000). The parameters, which are estimated in this manner, represent effective conceptual
representations of spatially and temporally heterogeneous watershed properties. A model calibrated by such
means can be used for the simulation or prediction of hydrologic events outside of the historical record used
for model calibration, if it can be reasonably assumed that the physical characteristics of the watershed and
the hydrologic/climate conditions remain similar (Gupta et al., 2002; Vrugt et al., 2006).
Parameter
Symbol
Lower
Upper
Units
Maximum interception
1
10
mm
Soil water storage capacity
10
1000
mm
Maximum percolation rate
0
100
mm/day
Evaporation parameter
0
100
-
-10
10
-
Time constant, fast reservoir
0
10
days
Time constant, slow reservoir
0
150
days
Runoff parameter
Table 6.01: Parameters of the hmodel and their prior uncertainty ranges
We calibrate the parameters of hmodel using daily discharge, mean areal precipitation, and mean areal
potential evapotranspiration from the French Broad watershed at Asheville, North Carolina. We assume a
multivariate uniform prior distribution for all seven model parameters using the ranges listed in Table 6.01.
An assumption made in many studies published in the literature is that the residuals between modeled and
observed discharge data are normally distributed. This then leads to a standard Gaussian likelihood function
(see previous two studies). We deviate from this assumption in this case study and use instead the
generalized likelihood function developed by Schoups and Vrugt (2010) which extends the applicability of
previously used likelihood functions to situations where residual errors are correlated, heteroscedastic, and
non-Gaussian with varying degrees of kurtosis and skewness. The approach focuses on a correct statistical
description of the data and the total model residuals, without separating out various error sources. The
generalized likelihood function is given by
(6.01)
56
DREAM Suite 1
where
is a n-vector with observed discharge data, n denotes the number of measurements,
is the estimated measurement error of the discharge data,
is a n-
vector of filtered error residuals using an autoregressive model with coefficients,
, and
,
, and
are computed as function of the skewness parameter, , and kurtosis parameter, , and |·|
denotes the modulus operator (absolute value). The scalars
are so called nuisance
variables whose values are either fixed or estimated jointly with the model parameters. These nuisance
variables are discussed in Table 6.02 below. The discharge measurement error is computed using
where
is the hmodel simulated record of discharge values using the
values of the model parameters and nuisance variables stored in the d-vector x.
Parameter
Lower
Upper
Units
Default
Heteroscedasticity intercept
0
1
mm/day
0.1
Heteroscedasticity slope
0
1
-
0
Autocorrelation coefficient
0
1
-
0
Kurtosis parameter
-1
1
-
0
Skewness parameter
0.1
10
-
1
Bias parameter
0
100
(day/mm)
0
Box-Cox transformation parameter
0
1
mm/day
0
Box-Cox transformation parameter
0.1
1
-
1
†
Symbol
The listed units and ranges depend on units and characteristics of calibration data (discharge in present case)
Table 6.02: Nuisance variables of the generalized log-likelihood function†
The nuisance variables that are highlighted in blue are estimated along with the parameters of the hmodel.
Their prior distribution is assumed uniform using the ranges listed above. The other nuisance variables in the
generalized likelihood function of Equation (6.01) are set to their default values. This equates in a total of 11
parameters whose posterior distribution needs to be sampled with DREAM by calibration of the hmodel
against the observed discharge data of the French Broad River. The initial population of the model
parameters and nuisance variables is drawn from the lower and upper ranges listed in Table 6.01 and 6.02
using Latin hypercube sampling. We use N = 11 chains with DREAM to generate samples from the
posterior parameter distribution using standard settings for the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example06\Plugin\Src_Cpp
4.7 Example 7
Case-Study VII: Bayesian inference of HYDRUS-1D using soil moisture data
The seventh case study considers the modeling of the soil moisture regime of an agricultural field near
Jülich, Germany. Soil moisture content was measured with Time Domain Reflectometry (TDR) probes at 6
cm deep at 61 locations in a 50 × 50 m plot. The TDR data were analysed using the algorithm described in
Heimovaara et al. (1990) and the measured apparent dielectric permittivities were converted to soil moisture
contents using the empirical relationship of Topp (1980). Measurements were taken on 29 days between 19
March and 14 October 2009, comprising a measurement campaign of 210 days. For the purpose of the
present study, the observed soil moisture data at the 61 locations were averaged to obtain a single time
series of water content. Precipitation and other meteorological variables were recorded at a meteorological
station located 100 m west of the measurement site. Details of the site, soil properties, experimental design
and measurements are given by Scharnagl et al. (2011) and interested readers are referred to this
publication for further details.
57
DREAM Suite 1
The HYDRUS-1D model of Simunek et al. (2008) was used to simulate variably saturated water flow in the
agricultural field (see Figure 7.01). This model solves Richards' equation for given (measured) initial and
boundary conditions
(7.1)
,
where θ (cm3/cm3) denotes moisture content, t (days) denotes time, z (cm) is the vertical (depth) coordinate,
h (cm) signifies the pressure head, and K(h) (cm day-1) is the unsaturated soil hydraulic conductivity.
Figure 7.01. Schematic representation of HYDRUS-1D model setup for a field plot near Jülich, Germany.
To solve Equation (7.01) numerically the soil hydraulic properties need to be defined. We use herein the van
Genuchten-Mualem (VGM) model (van Genuchten, 1980)
(7.01)
where θs (cm3/cm3) and θr (cm3/cm3) signify the saturated and residual soil water content, respectively, α
(cm-1), n (-) and m = 1 - 1/n (-) are shape parameters, Ks (cm day-1) denotes the saturated hydraulic
conductivity, and λ represents a pore-connectivity parameter. The effective saturation, Se (-) is defined as
(7.03)
58
DREAM Suite 1
Observations of daily precipitation and potential evapotranspiration were used to define the upper boundary
condition. In the absence of direct measurements, a constant head lower boundary condition was assumed,
hbot (cm), whose value is subject to inference with DREAM.
Table 7.01 lists the parameters of the HYDRUS-1D model and their prior ranges which are subject to
inference using the 210-day period of observed soil moisture measurements.
Parameter
Symbol
Lower
Upper
Units
Residual water content
0.043
0.091
cm3/cm3
Saturated water content
0.409
0.481
cm /cm
Reciprocal of air-entry value
-2.553
-2.071
cm-1
0.179
0.267
-
Saturated hydraulic conductivity
-2.237
-0.080
cm hour
Pore-connectivity
-5.49
6.27
-
Pressure head at lower boundary
-250
-50
cm
3
Prior distribution
†
3
£
Curve shape parameter
n
£
-1
£
†
‡
‡
is the normal probability density function with mean a and standard deviation b
is the uniform probability density function with lower bound a and upper bound b
£
These parameters are sampled in the log space
Table 7.01: Parameters of the HYDRUS-1D model and their prior uncertainty ranges
The pedotransfer toolbox of ROSETTA was used with soil textural data from the field site to derive prior
estimates of the MVG parameters (Scharnagl et al. 2011). These estimates were used to create an explicit
prior distribution for each soil hydraulic parameter. These distributions are defined in the last column of Table
7.01, and make sure that the inference with DREAM honors the values derived separately from ROSETTA.
Note that ROSETTA does not provide estimates of the parameter hbot, and this parameter was therefore
assumed to have a uniform prior with ranges listed in the bottom right cell of the Table.
A Gaussian likelihood was assumed to characterize in probabilistic terms the distance between the
HYDRUS-1D simulated soil moisture data and their observed values. This likelihood function is given by
(7.04)
,
where
and
are the observed and simulate soil moisture data,
respectively, I denotes the number of measurements, and |·| denotes the modulus operator (absolute value).
The initial population is drawn from the lower and upper ranges listed in Table 7.01 using Latin hypercube
sampling. We use N = 10 chains with DREAM to generate samples from the posterior parameter distribution
using standard settings for the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example07\Plugin\Src_Cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// EvaluatorModel.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::GetInputParams
//------------------------------------------------------------------------------------------------(
59
DREAM Suite 1
IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define default DREAM parameters for this particular project.
This function is called by the main program to initialize data of each newly created simulation
case. This data can be later modified in the GUI (except parameters locked by flag
DreamSolver::disable_edit) or can be overwritten while reading case data from a file.
In the AppTest console application, there is no GUI and this functions actually defines all
input parameters that are subsequently used by DREAM Solver.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIDreamInputParams pointer
if(pIDreamInputParams == nullptr)
{
return E_INVALIDARG;
}
// Set default input parameters
pIDreamInputParams->SetProblemDimension(7, DreamSolver::disable_edit);
pIDreamInputParams->SetNumberOfMarkovChains(10, DreamSolver::enable_edit);
pIDreamInputParams->SetNumberOfGenerations(1000, DreamSolver::enable_edit);
pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_102, DreamSolver::disable_edit);
pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitUniform, DreamSolver::enable_edit);
pIDreamInputParams->SetUsePriorDistribution(1, DreamSolver::enable_edit);
pIDreamInputParams->SetPriorDistributionType(ePriorType::eUnivariate, DreamSolver::enable_edit);
pIDreamInputParams->SetOutlierTest(eOutlierTest::eOutlierIqr, DreamSolver::enable_edit);
pIDreamInputParams->SetBoundHandling(eBoundHandling::eBoundUnbounded, DreamSolver::enable_edit);
// Example can run in parallel mode (recommended mode)
pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::InitData
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
// Plugin information
, IDreamInputParViewer* pIDreamInputParams // Current DREAM input parameters
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called to prepare:
A/ DREAM input data before accessing them via the IDreamDataSource interface and
B/ all other local data required by evaluator for the calculation.
It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir
(directory ...Drm_ExampleXX\Model\Data).
Remark 1: This function prepares DREAM input data in the evaluator according to current
DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be
different from default parameters defined in function CEvaluatorExample::GetInputParams().
Remark 2: This function should be called before using functions
CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,
::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()
can be called independently.
RETURN VALUE:
60
DREAM Suite 1
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Check parameters
if(pIPluginInfo == nullptr || pIDreamInputParams == nullptr)
{
// Invalid argument
return E_INVALIDARG;
}
// Load data only one time
if(LoadData(pIPluginInfo->m_strModelDataDir))
{
return S_OK;
}
return E_FAIL;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::GetMinMaxData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataMinMax* pIMinMaxData // Interface to Min/Max data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIMinMaxData pointer
if(pIMinMaxData == nullptr)
{
return E_INVALIDARG;
}
// Fill min max data
pIMinMaxData->AddItem( 0.0430, 0.0910);
pIMinMaxData->AddItem( 0.4090, 0.4810);
pIMinMaxData->AddItem(-2.5528, -2.0706);
pIMinMaxData->AddItem( 0.1790, 0.2670);
pIMinMaxData->AddItem(-2.2366, -0.0800);
pIMinMaxData->AddItem(-5.4900, 6.2700);
pIMinMaxData->AddItem(-250.0,
-50.0);
// Data added successfully
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::GetPriorData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataPrior* pIPriorData
// Interface to prior distribution data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
pIPriorData->AddUnivariateItem(0.067, 0.006, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.445, 0.009, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-2.310, 0.060, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.223, 0.011, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-1.160, 0.270, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.390, 1.470, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-250.0, -50.0, eDistributionUnivariate::eUnivariate_Uniform);
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::PrepareWorkDir
//-------------------------------------------------------------------------------------------------
61
DREAM Suite 1
(
BSTR strSourceDir
, BSTR strDestinationDir
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Copy all files to the new directory
if(!DrxCopyFiles(strSourceDir, strDestinationDir))
{
return E_FAIL;
}
// Create new level_01.dir with the correct path
std::wstring LevelDirFile(strDestinationDir);
LevelDirFile += L"\\level_01.dir";
std::wfstream ofs(LevelDirFile, std::ofstream::out | std::ofstream::trunc);
if(!ofs)
{
std::wcerr << L"Unable to create " << LevelDirFile << L"\n";
return E_FAIL;
}
std::wstring NewPath(strDestinationDir);
ofs << NewPath;
ofs.flush();
ofs.close();
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CEvaluatorExample07::EvaluateProposal
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, int iSim
// input parameter (i-th simulation / Markov chain)
, IDreamMatrix* x
// input matrix (m_NumberOfMarkovChains x m_ProblemDimension)
, IDreamMatrix* res
// output matrix (Data_Dimension x m_NumberOfMarkovChains)
, BSTR strWorkingDir
// path to the current working directory (for current calculation thread)
, BSTR strModelDataDir // path to the permanent directory with model data
, BSTR strModelBinDir
// path to the permanent directory with model executables
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to evaluate the current proposal (i.e. one single step
of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes
the likelihood (or log-likelihood or the residual vector to be compared with the measurement
- see the technical manual) for iSim-th row of input matrix "x" and returns the result
in output matrix "res".
Parameter iSim is from interval <0, IDreamInputParams::GetNumberOfMarkovChains() - 1>.
If pInputPar->GetVectorization() == eVectorization::eVectYes, then iSim = 0 and all proposals
(for all Markov chains) should be evaluated in one step, i.e. during one call of this function.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
vector<double> ix(x->_colCount);
// Copy row data
for(int iCol = 0; iCol < x->_colCount; iCol++)
{
ix(iCol) = x->_data[iSim * x->_colCount + iCol];
}
// Back-transform parameters
matrix<double> xv(1, ix.size(), 0);
row(xv, 0) = ix;
62
DREAM Suite 1
xv(0, 2) = pow(10.0, xv(0, 2));
xv(0, 3) = pow(10.0, xv(0, 3));
xv(0, 4) = pow(10.0, xv(0, 4));
// Working directory
std::wstring path(strWorkingDir);
// Modify SELECTOR.IN
if(!CDreamMath<>::ReplaceData(path + L"\\SELECTOR.IN", "thr",
project(xv, range(0, 1),range(0, 6))))
{
return E_FAIL;
}
// Modify PROFILE.DAT
matrix<double> initial(m_loadData.m_initial);
column(initial, 2) = vector<double>(initial.size1(), xv(0, 6));
if(!CDreamMath<>::ReplaceData(path + L"\\PROFILE.DAT", "Mat", initial))
{
return E_FAIL;
}
// Modify ATMOSPH.IN
matrix<double> boundary(m_loadData.m_boundary);
column(boundary, 6) = vector<double>(boundary.size1(), xv(0, 6));
if(!CDreamMath<>::ReplaceData(path + L"\\ATMOSPH.IN", "tAtm", boundary))
{
return E_FAIL;
}
// Run HYDRUS-1D
std::wstring strHydrusCalcExe = strModelBinDir;
strHydrusCalcExe += L"\\H1D_CALC.EXE";
if(!CDreamMath<>::RunEXE(strHydrusCalcExe, path))
{
return E_FAIL;
}
// Read text file containing the time series of simulated soil water contents
matrix<double> outputData;
if(!ReadDataHydrus1D(path + L"\\OBS_NODE.OUT", "time ", outputData))
{
return E_FAIL;
}
vector<double> hoy
= column(outputData, 0);
vector<double> water = column(outputData, 2);
// Filter sims for measurement dates
size_t nData = m_loadData.m_hoy.size();
vector<size_t> indeces(nData, 0);
for(size_t i = 0; i < nData; i++)
{
size_t iIndex;
if(!Find<double>(iIndex, hoy, m_loadData.m_hoy(i), [](double a, double b)
{return abs(a - b) < FLT_EPSILON ? true : false; }))
{
res->_data[iSim] = -1.e100; // If HYDRUS-1D did not converge,
// set the log-likelihood to some arbitrary low value
return S_OK;
}
indeces(i) = iIndex;
}
// Compute residuals
vector<double> waterModify;
CDreamMath<>::ObtainValuesFromIndeces(waterModify, indeces, water);
vector<double> epsilon = m_loadData.m_water - waterModify;
// Compute log-likelihood
ElementPow<double>(epsilon, 2);
res->_data[iSim] = -(double)nData / 2.0 * log(sum(epsilon));
return S_OK;
63
DREAM Suite 1
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Local functions
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------bool CEvaluatorExample07::ReadDataHydrus1D
//------------------------------------------------------------------------------------------------(
const std::wstring& file
, const std::string& keyWord
, matrix<double>& loadData
)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
std::ifstream ifs(file, std::ifstream::in);
if(!ifs)
{
std::wcerr << "Unable to open " << file <<"\n";
return false;
}
typedef boost::tokenizer<boost::char_separator<char>> Tokenizer;
boost::char_separator<char> sep(" ");
std::string data;
size_t iLine = 0;
size_t startLine = 0;
size_t endLine = 0;
size_t nTok = 0;
while(!ifs.eof())
{
getline(ifs, data);
Tokenizer tok(data, sep);
if(data.find(keyWord) != std::string::npos)
{
nTok = std::distance(tok.begin(), tok.end());
startLine = iLine + 1;
}
else if(data.find("end") != std::string::npos)
{
endLine = iLine;
}
iLine++;
}
size_t nRow = endLine - startLine;
loadData = matrix<double>(nRow, nTok);
ifs.clear();
ifs.seekg(0, std::ios::beg);
iLine = 0;
size_t iRow = 0;
while(!ifs.eof())
{
getline(ifs, data);
if(startLine <= iLine && iLine < endLine)
{
Tokenizer tok(data, sep);
vector<double> values(nTok);
size_t i = 0;
for(Tokenizer::iterator iter = tok.begin(); iter != tok.end(); ++iter)
{
try
{
if(*iter == "T")
{
values(i) = 1;
}
else if(*iter == "F")
{
values(i) = 0;
64
DREAM Suite 1
}
else
{
values(i) = boost::lexical_cast<double>(*iter);
}
}
catch(boost::bad_lexical_cast&)
{
std::wcerr << "warning: value on Line" << iLine << ", Column " << i << "from "
<< file << " could not be converted to double = 0." << std::endl;
values(i) = 0.;
}
i++;
}
row(loadData, iRow) = values;
iRow++;
}
iLine++;
}
ifs.close();
return true;
}
//------------------------------------------------------------------------------------------------bool CEvaluatorExample07::LoadData(std::wstring path)
//------------------------------------------------------------------------------------------------{
// Load structure with observation data
if(!CDreamMath<bool>::ReadData(path + L"\\Meas_WaterInd.txt", m_loadData.m_waterInd))
return false;
if(!CDreamMath<>::ReadData(path + L"\\Meas_Water.txt", m_loadData.m_water))
return false;
vector<double> water;
CDreamMath<double>::ObtainValuesFromBool(water, m_loadData.m_waterInd, m_loadData.m_water);
m_loadData.m_water = water;
if(!CDreamMath<>::ReadData(path + L"\\Meas_Hoy.txt", m_loadData.m_hoy))
return false;
vector<double> hoy;
CDreamMath<double>::ObtainValuesFromBool(hoy, m_loadData.m_waterInd, m_loadData.m_hoy);
m_loadData.m_hoy = hoy;
m_loadData.m_obsNode = 1;
// Provide data needed to modify initial condition
if(!CDreamMath<>::ReadData(path + L"\\ProfileDat_InitialConditions.txt", m_loadData.m_initial))
return false;
// Provide data needed to modify the lower boundary condition
if(!CDreamMath<>::ReadData(path + L"\\AtmosphIn_BoundConditions.txt", m_loadData.m_boundary))
return false;
return true;
}
4.8 Example 8
Case-Study VIII: Approximate Bayesian Computation of mixture distribution
This case study illustrates the ability of DREAM to perform statistical inference involving the use of
summary metrics. This functionality, also known as Approximate Bayesian Computation (ABC) has been
implemented in DREAM and the underlying theory and concepts have been published by Sadegh and Vrugt
(2014). The ABC approach is particularly useful for diagnostic model evaluation as it relaxes the need for an
explicit likelihood function in favor of one or multiple different summary statistics rooted in the relevant theory
65
DREAM Suite 1
that together have a clearer and more compelling diagnostic power than some average (likelihood)-measure
of the size of the error residuals. Vrugt and Sadegh (2013) have shown that this diagnostics approach
enhances considerably our chances to diagnose and detect model structural errors. Indeed, the use of
behavioral signatures helps to analyze and pinpoint which part of the model is malfunctioning and in need of
further improvement.
This eight case study benchmarks the implementation of the ABC method against a simple mixture of two
univariate normal distributions,
(8.01)
,
where
and
and
and
density function of
denote the mean of the first and second normal pdf of the mixture distribution,
define their corresponding variances, respectively. The probability
in Equation (2.01) is given by the following weighted sum of two normal densities
,
(8.02)
This Equation is easy to derive if you follow the steps in case study III. Indeed, the determinant of
is simply equivalent to 1 and 1/10 respectively, and
and
00.
and
We can easily generate samples from this target distribution with DREAM if we evaluate directly the density
of Equation (2.02). Instead, we follow a different procedure herein and use the ABC procedure in DREAM.
This requires the user to define signatures of system behavior, which in the present context is equivalent to
a summary metric of Equation (2.02). This summary metric,
, is defined as follows
(8.03)
,
where
is a vector with hundred elements and |·| denotes the modulus operator
(absolute value). The values of the
vector Y are drawn randomly from
the univariate normal
distribution with zero mean and unit standard deviation, thus
,
. The tilde
symbol ‟ ” means ‟distributed according to".
The following distance function,
value of the parameter, x or not
is used in DREAM to help determine whether we should accept the
(8.04)
.
The variable in Equation (8.04) denotes the observed value of the summary metric. This value is equal to
zero in the present study. If the value of the distance function is smaller than some small nominal value
then is accepted, and otherwise the proposed parameter value is rejected. The initial population is drawn
from the univariate uniform distribution
with
and
using Latin hypercube sampling. A
total of N = 8 chains are created with DREAM using standard settings for the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example08\Plugin\Src_Cpp
4.9 Example 9
66
DREAM Suite 1
Case-Study IX: Rainfall-runoff model with spectral likelihood function
Calibration of hydrological models in ungauged basins is the subject of increasing attention by the scientific
community. In fact, this is one of the main goals of the Prediction in Ungauged Basins (PUB) initiative
promoted by the International Association of Hydrological Sciences (Sivapalan et al., 2003). The present
study uses the spectral likelihood function of Whittle (1953) to derive the posterior distribution of the
parameters of a hydrologic model. This estimator has good statistical properties, is asymptotically
consistent, and has significant advantages over traditional goodness-of-fit criteria in that calibration can be
carried out, in principle, with information available in poorly gauged basins. Unlike most statistical
estimators that act on the residuals of the observed and simulated data, Whittle's estimator tries to match
the spectral densities of the model output and observed data.
Whittle's likelihood function is given by
(9.01)
where n is the number of calibration data measurements,
are the Fourier frequencies, J is the
periodogram (an estimate of the spectral density) of
the n-vector of observations,
is the
spectral density of the simulated discharge time series of the hmodel (depends on the parameter values
stored in d-vector x) and
is the spectral density of the autoregressive operator , which is equivalent
to
(9.02)
,
where
is the standard deviation of the residual vector,
and simulated,
discharge record,
modulus operator (absolute value).
The periodogram of some time series at the frequency
1987)
between the observed,
, and |·| denotes the
can be computed as follows (Brockwell and Davis,
(9.03)
where
is the sample autocovariance coefficient at lag k and i is the imaginary unit. A detailed
derivation of Equation (9.01) appears in Whittle (1953) and Beran (1994) provides further analysis of how the
spectral likelihood relates to a Gaussian likelihood. Interested readers are referred to these publications for
further details.
We now apply Whittle's estimator to the calibration of a mildly complex lumped watershed model using
historical data from the Guadalupe River at Spring Branch, Texas. This is the driest of the 12 MOPEX basins
described in the study of Duan et al. (2006). The model structure and hydrologic process representations
are found in Schoups and Vrugt (2010). The model transforms rainfall into runoff at the watershed outlet
using explicit process descriptions of interception, throughfall, evaporation, runoff generation, percolation,
and surface and subsurface routing (see Figure 9.01).
67
DREAM Suite 1
Figure 9.01. Schematic representation of the hmodel conceptual watershed model
Table 9.01 summarizes the seven different model parameters, and their prior uncertainty ranges. These
parameters represent conceptual properties of the watershed under investigation, and cannot be measured
directly in the field. We therefore derive their values by calibration of the hmodel against a historical record of
discharge data.
Parameter
Symbol
Maximum interception
Soil water storage capacity
Maximum percolation rate
Evaporation parameter
Runoff parameter
Time constant, fast reservoir
Time constant, slow reservoir
Lower
Upper
Units
1
10
0
0
-10
0
0
10
1000
100
100
10
10
150
mm
mm
mm/day
days
days
Table 9.01: Parameters of the hmodel and their prior uncertainty ranges
We use daily discharge, mean areal precipitation, and mean areal potential evapotranspiration from the
French Broad watershed at Asheville, North Carolina. We assume herein a multivariate uniform prior
distribution for the
parameters with ranges listed in Table 9.01. With the use of such flat prior, the
posterior density (product of prior and likelihood) is simply proportional to the spectral likelihood function of
Equation (9.01). The initial state of each of the N = 10 chains of DREAM is generated with Latin hypercube
sampling by drawing from the uniform prior parameter distribution. Standard settings are used for the
algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example09\Plugin\Src_Cpp
4.10 Example 10
Case-Study X: d-dimensional multimodal mixture distribution with multiplicative prior
According to Bayes law, the posterior density is equal to the product of the prior distribution and the
likelihood function or, p(x) = pr(x) × L(x). In the previous case studies we have assumed that the prior
distribution,
, is multivariate uniform, and thus
(10.01)
.
The value of this constant is thus fixed and independent of the model parameter values used. With the use
of such noninformative (flat) prior, the posterior density,
, is simply proportional to the value of the
likelihood function,
and thus,
. The value of in Equation (10.01) is easily derived if a
uniform prior is used. Certainly, we know that any prior distribution must integrate to unity – a requirement
for a proper probability distribution. If we apply this principle to the uniform prior distribution of the hmodel
68
DREAM Suite 1
parameters of Table 9.01 we can write
(10.02)
.
We also know that the uniform distribution produces the same density for each feasible solution within its
domain. Thus, the value of the constant is easily derived from the listed ranges of the hmodel parameters.
This gives
(10.03)
If we thus take into explicit consideration the effect of the prior distribution on the posterior density in the
previous case study we should write
(10.04)
.
Indeed, we can now use an equality sign rather than a proportionality sign. Nevertheless, this scaling factor
of the posterior density has no effect on the parameter inference with DREAM. This changes however, if we
use an informative prior distribution – that is – a distribution that is not flat but rather depends on the actual
values of the parameters. Indeed, in case study XII we have considered such example with soil hydraulic
parameters that were assumed to each have a Gaussian marginal prior distribution. Such distribution does
not assign an equal prior density to the parameter values, but rather favors certain solutions over others –
that is – parameter values that are close to the mean of the Gaussian prior will have a higher density than
those further removed from the center of this distribution. This will affect the inference with DREAM as
parameter values that do not agree with prior information are discouraged.
To explicate the effects of a prior distribution on the results of DREAM we consider in this tenth case study,
a simple multivariate normal prior distribution,
with mean
and
covariance matrix . We assume that the mean of the prior distribution is equal to -2, and the covariance
matrix is equivalent to Id, a
matrix with values of one on the main diagonal and zero elsewhere, and
thus
. The tilde symbol ‟ ” means ‟distributed according to".
We consider as likelihood function a mixture of two normal distributions
(10.05)
,
where the mean of the first and second component of the Gaussian mixture is equal to -5 and 5,
respectively, and the covariance matrix equal to the identity matrix, Id. Now we can calculate the posterior
density,
as product of the prior,
and likelihood,
using Bayes law
(10.06)
,
The initial population is drawn randomly from
(0,Id), the multivariate normal distribution with zero mean
and covariance matrix equal to the identity matrix. We use N = 10 different chains with DREAM and apply
default settings of the algorithmic variables.
Thus this case study does not use a uniform prior distribution for the parameters, but rather assumes an
informative prior distribution. Such prior allows users to take into explicit consideration in the present study,
parameter estimates or distributions derived from previous data and/or analysis.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example10\Plugin\Src_Cpp
69
DREAM Suite 1
4.11 Example 11
Case-Study XI: d-dimensional multivariate student T distribution
To test the performance of DREAM for distributions with a tail, the eleventh case study involves a d = 25dimensional student T distribution with 60 degrees of freedom. The target distribution can be written as
(11.01)
,
where
vector
given by
is the d-variate student distribution with v degrees of freedom (v > 1) centered at the
and with
scale (correlation) matrix . The probability density function of
is
(11.02)
,
where
denotes the Gamma function, and T denotes transpose. In the special case of v = 1, Equation
(11.02) reduces to the multivariate Cauchy distribution.
The values of are set to zero and all-pairwise correlations in the matrix
are set to 0.5, respectively. The
initial states of each of the
Markov chains are generated with Latin hypercube sampling by drawing
randomly from
, the
-variate uniform distribution with lower bound values of
and upper
ranges equal to
. Default values of the algorithmic variables are used.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example11\Plugin\Src_Cpp
4.12 Example 12
Case-Study XII: Pedometrics (variogram fitting)
The past decades have seen a growing interest in soil characterization, not only because many highly
interrelated water, carbon, and vegetation processes take place in this part of our ecosystem, but also
because the subsurface plays a major role in carbon storage, exchange of water and soil vapor with the
ambient atmosphere, and contaminant transport to the groundwater. Many soil properties not only exhibit
significant spatial and temporal variability, but are also difficult to measure directly. Geostatistics is primarily
concerned with the mathematical description, prediction, and uncertainty analysis of these spatially varying
variables.
The basis of geostatistical estimation is the assumption that an observation of a variable at location s is a
realization of a random field
. The random function is assumed to be intrinsically stationary (Webster
and Oliver, 2009)
(12.01)
and
(12.02)
where h is a lag vector, and γ(h) is the variogram. The method of moments is usually used to estimate the
so-called empirical variogram, and parameters of a variogram model are then estimated by fitting a model to
70
DREAM Suite 1
the empirical variogram. Thus, the accuracy of spatial prediction is determined by how the variogram is
estimated.
The paper of Diggle et al. (1998) introduced an alternative approach to geostatistical inference that is based
on the application of formal statistical methods. This so-called model-based Geostatistics relies on general
principles of statistical inference and use an explicit stochastic error model of the data. The use of a proper
likelihood function and a posteriori check of the error residual distribution not only constitutes good
statistical practice, but also facilitates the application of a powerful array of multivariate statistical analyses
to explore the marginal and joint posterior probability density functions of the nugget, sill and range. Other
formal statistical approaches include the generalized linear-mixed model and empirical best linear unbiased
prediction (EBLUP) (Zimmerman and Cressie, 1992). Despite this progress made, it remains typically
difficult to estimate the parameters of a variogram model and successfully solve the geostatistical inverse
problem. That is, the covariance structure of the residuals is required for variogram fitting, yet in most cases
is unknown a priori. The spatial covariance structure can only be obtained after fitting the trend. The residual
maximum likelihood (REML) approach is therefore advocated (Lark et al., 2006), because it allows for
independent estimation of the covariance structure by transforming the data into stationary increments that
filtered out the trend. Nevertheless, REML or related methods only attempt to find the maximum likelihood
values of the variogram parameters without recourse to estimating their underlying posterior uncertainty. This
posterior probability distribution function (pdf) contains important information about the uncertainty and
correlation of the various geostatistical parameters and can be used to derive meaningful estimates of
spatial prediction uncertainty.
In this twelfth case study we explore the use of Markov chain Monte Carlo simulation with DREAM to
characterize the uncertainty of the variogram parameters and their effect on spatial prediction uncertainty.
We assume herein a simple linear trend model for prediction of variable y at n different locations
. This model can be written as
(12.03)
where
, signifies a matrix with spatial coordinates,
is the design matrix of the
trend function
, is a vector of trend parameters, and is the vector of residuals with a mean of
zero and covariance matrix, K. This covariance can be described with the Matérn function
(12.04)
where Kij is the covariance between observation i and j, h represents the separation distance between i and
j,
denotes the Kronecker delta (
= 1 if i = j and
= 0 when i ≠ j), c0 is the nugget variance, and c0 +
c1 signifies the sill variance, Kn is a modified Bessel function of the second kind of order n, G is the gamma
function, r denotes the distance or ‘range' parameter and n is the “smoothness”. This latter parameter allows
for great flexibility in modelling of the local spatial covariance. The Matérn function is equivalent to the
exponential function for
, the Whittle model (1954) for
and approaches the Gaussian model
for
. The corresponding semivariance of the Matérn function is
(12.05)
The parameters of this function can be summarized in a single vector,
The value of
at the unsampled location
.
can be computed from
(12.06)
,
71
DREAM Suite 1
where
are the observed values at each of the n measurement locations, M is the
design matrix
,
variance of the prediction at location
, and
. The associated
is
(12.07)
,
where
and
.The unknown parameters in Equations (12.06) – (12.07) are
now combined in the vector,
and estimated using Markov chain Monte Carlo simulation with
DREAM. This allows for characterization of the uncertainty of the trend and variogram parameters and their
effect on spatial prediction uncertainty.
We use herein a single trend parameter for
(also referred to as “mean”), thus resulting in a
dimensional parameter estimation problem. Table 12.01 summarizes the trend and variogram parameters
which are subject to inference and their prior uncertainty ranges.
Parameter
Symbol
Trend parameter (“Mean”)
Nugget variance
Remaining variance to sill
Smoothness parameter
Distance or “range” parameter
†
Lower
Upper
Units
0
0
0
0
0
100
100
1000
1000
20
Cm
cm2
cm2
cm
Listed units and ranges depend on units and characteristics of calibration data
Table 12.01: Trend and variogram parameters and their prior uncertainty ranges
We use soil thickness data of the A horizon collected at an experimental field plot near Forbes, New South
Wales, Australia (Pettitt and McBratney, 1993). A nested sampling design was used where the field was
divided into 18 equal-sized blocks of 160 m2. In each block six sampling points were used along transects of
156 m long separated by 125 m, 25 m, 5 m, 1 m and 25 cm.
To successfully implement DREAM we need to define the parameter ranges, an initial sampling distribution,
and a likelihood function to compare the model predicted A-thickness with the observed data. In this case
study, we assume a uniform prior distribution with upper and lower bounds of the parameters listed in Table
12.01, and use Latin Hypercube sampling over this d-dimensional hypercube to initialize the starting points
of the N = 10 different Markov chains. The following formulation of the log-likelihood function,
is used
(Mardia and Marshall, 1984)
(12.08)
where
is the covariance matrix derived from the Matérn function,
signifies the determinant operator,
and
is a scalar whose value does not affect the posterior parameter distribution. This latter value is
therefore ignored. We assume default values for the algorithmic variables of DREAM.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example12\Plugin\Src_Cpp
4.13 Example 13
72
DREAM Suite 1
Case-Study XIII: Nash-Cascade model of hydrograph
The thirteenth case study considers the modeling of the instantaneous unit hydrograph using the ordinates
of Nash (1960) defined as
(13.01)
where (mm/day) is the simulated streamflow at time t (days), g (-) denotes the number of reservoirs, α
(days) signifies the recession constant, and
is the gamma function
(13.02)
which satisfies the recursion
.
A n = 25-day period with synthetic daily streamflow data was generated by driving Equation (13.01) with an
artificial precipitation record using g = 2 reservoirs, and a recession constant of α=4 days. This artificial data
set is subsequently perturbed with a heteroscedastic measurement error (non-constant variance) with
standard deviation equal to 10% of the original simulated discharge values. The DREAM algorithm is now
used to derive the posterior distribution of both parameters g and α using a bivariate uniform prior
distribution,
[1,10] and Gaussian likelihood function
(13.03)
,
where
and
are the observed and simulate discharge record,
respectively, and n denotes the number of measurements. The initial population is drawn from the prior
distribution using Latin hypercube sampling. We use N = 8 chains with DREAM to generate samples and
use standard settings for the algorithmic variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example13\Plugin\Src_Cpp
4.14 Example 14
Case-Study XIV: Approximate Bayesian inference for hydrologic watershed model
The fourteenth case study illustrates the ability of DREAM for diagnostic model evaluation. A rather
parsimonious 7-parameter lumped watershed model (also known as hmodel) is used with historical data
from the French Broad River at Asheville, North Carolina. This is the driest of the 12 MOPEX basins
described in the study of Duan et al. (2006). The model is illustrated schematically in Figure 14.01. The
model transforms rainfall into runoff at the watershed outlet using explicit process descriptions of
interception, throughfall, evaporation, runoff generation, percolation, and surface and subsurface routing.
73
DREAM Suite 1
Figure 14.01. Schematic representation of the hmodel conceptual watershed
Daily discharge, mean areal precipitation, and mean areal potential evapotranspiration were derived from
Duan et al. (2006) and used for diagnostic model evaluation with DREAM. Details about the basin and
experimental data, and likelihood function can be found there, and will not be discussed herein. The same
model was used in case study six to illustrate the generalized likelihood function.
Four different summary metrics of the discharge data are used for diagnostic inference with DREAM
(activated with likelihood function 22), including S1 (-), the annual runoff coefficient, S2 (-) the annual baseflow
coefficient, and S3 (day/mm) and S4 (-) two coefficients of the flow duration curve. The four different summary
metrics are stored in the vector
. . A detailed description of these summary metrics can be
found in Sadegh and Vrugt (2013) and interested readers are referred to this publication. The seven different
parameter values of the hmodel and their prior uncertainty ranges are listed in Table 6.01.
Each time the hmodel is executed with the seven different parameter values stored in the vector x the
simulated values of the summary metrics are computed from the modeled discharge record and stored in
the vector
. The following distance function,
is used in DREAM to help
determine whether we should accept the vector of proposed parameter values or not
(14.01)
,
where |·| denotes the modulus operator (absolute value). If this distance function is smaller than the small
positive threshold ϵ the proposed parameter values are considered to be a sample of the posterior
distribution. The initial population is drawn from the parameter ranges listed in Table 6.01 using Latin
hypercube sampling. The posterior target distribution is sampled with DREAM using N = 10 different chains
using standard settings for the algorithmic variables (default ϵ=0.025).
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example14\Plugin\Src_Cpp
4.15 Example 15
Case-Study XV: Approximate Bayesian inference using 10 bivariate normal distributions
In this fifteenth study we illustrate the use of Approximate Bayesian Computation (ABC) by application to a
target distribution consisting of ten bivariate normal distributions. We first sample randomly ten times the
mean,
, of a bivariate normal distribution,
by drawing randomly from a twodimensional uniform prior distribution,
with
and
or
, where the
tilde symbol ‟ ” means ‟distributed according to”. We then treat these i = 10 values as observations, and
store them in a vector,
. We now use this vector of with
observations to determine the
observed means by drawing ten different times a sample from a bivariate normal distribution
74
DREAM Suite 1
(15.01)
,
where
is the pair of parameter values created by DREAM and stored in vector x, and
. The values of
are stored in the vector,
. The distance between the
observed and simulated observations is not defined with a formal likelihood function, but rather with a
distance function,
as follows (Turner and Sederberg, 1980)
(15.02)
,
The proposal is considered to be behavioral (= posterior solution) if the value of the distance function is
smaller than , a small positive value. We approximate the posterior distribution of the ten means in
DREAM using N = 20 different chains and the distance function of Equation (15.02). The initial state of each
chain is sampled randomly from
and standard values are used of the algorithmic variables
(default
).
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example15\Plugin\Src_Cpp
4.16 Example 16
Case-Study XVI: Hydrogeophysics: Inference of the spatial distribution of soil properties
The sixteenth case study considers the application of DREAM to distributed soil moisture estimation using
travel-time observations from crosshole ground-penetrating radar experiments. This study differs from most
other built-in studies of DREAM suite as it requires two- dimensional numerical simulation and high
resolution spatial characterization. Such spatial inference problems can be much harder to solve than
problems involving temporal characterization of one or more variables of interest. This all has to do with
parameter selection. For temporal inference problems, the calibration parameters are usually unknowns in
the underlying (differential) equations of the model. These parameters are easy to isolate. For spatial
inference problems, it is not only clear how to describe mathematically or statistically the spatial properties
of the variable of interest, but it is also unclear how many parameters to use to characterize the observed
pattern.
The parameterization of the inverse model should ideally provide enough details to capture all relevant
variations in the Earth's property field and thereby avoid bias caused by model truncation (Trampert and
Snieder, 1996). In global earth seismology, it is widely recognized that differences between deterministic
inversion results based on the same data set are largely due to differences in spatial or spectral resolutions
used in the (inverse) parameterizations (e.g., Chiao and Kuo, 2001). Compactly supported pixels that in a
Cartesian coordinate system would be represented by, for example, uniform grid models, provide a very high
spatial resolution, whereas spherical harmonics or discrete cosine transform (DCT) in its Cartesian
counterpart provide a high spectral resolution. Many popular model parameterization schemes can be found
in-between these two opposing extremes, such as wavelets (e.g., Chiao and Kuo, 2001) and slepian
functions (e.g., Simons et al., 2006).
The uniform grid parameterization has the key advantage of a localized and uniform spatial resolution.
Inversion based on a uniform grid distribution is hence straightforward. One simply discretizes the spatial
domain of interest into a number of cells, and then treats each cell as a different parameter, say, the soil
moisture content. This Cartesian parameterization is perhaps straightforward to implement and use, but it is
rather inefficient as many thousands of unknowns are required to represent with some spatial resolution and
accuracy the soil moisture distribution. This inference problem is unnecessarily difficult and CPU-demanding
to solve for DREAM. We therefore use herein a more parsimonious, and perhaps more intelligent,
parameterization method and describe the value of the relative saturation (0-100%) of each grid cell using
the discrete cosine transform. This transformation, hereafter referred to as the DCT has desirable
75
DREAM Suite 1
advantages for stochastic inversion, in that (i) the resolution and separation of scales is explicitly defined, (ii)
the transformation is orthogonal and close to the optimal Karhunen-Loève transform, (iii) the computational
efficiency is high, (iv) the basis vectors depend only on the dimensionality of the model, and (v) the
transformation is linear and operates with real parameter values (Linde and Vrugt, 2013; Qin et al., 2016).
The DCT coefficient,
is computed using
(16.01)
where and denote the row and column number of the DCT coefficient-matrix, R and the
stores a map of discretized values of the relative saturation of the spatial domain of interest and
matrix Q
(16.02)
and
Close inspection of Equation (16.01) demonstrates that the size of matrix R is exactly similar to that of Q,
and thus the standard DCT operation does not reduce parameter dimensionality. Indeed, each coordinate of
the matrix Q with value of the soil moisture content, has its own DCT coefficient. We can transform the
matrix Q from the space domain to the frequency domain using the DCT coefficients stored in R. The
information in this transformation is concentrated in the lower frequencies DCT coefficients. We can thus
safely discard the higher frequency DCT coefficients without losing significant information about the spatial
pattern of the soil moisture content. The lower frequency DCT coefficients are retained and define the model
parameters,
that will be estimated using DREAM. This approach significantly reduces the
dimensionality of the parameter space (Linde and Vrugt, 2013; Qin et al., 2016) and has desirable
advantages for stochastic inversion.
For example, Figure 1 in Jafarpour et al. (2008) depicts the results for the first 8 ´ 8 DCT bases and shows
how the DCT transform coefficients relate to a given geological model. The more DCT coefficients are used
the better the reconstruction of the true field (see Qin et al., 2016). We use herein
DCT coefficients,
which jointly maintain about 95-97% of the variance of the original relative saturation space.
As a synthetic example, we use a soil moisture model from Kowalsky et al. (2005). This model was
constructed by simulating an infiltration experiment in a heterogeneous soil. The simulated soil moisture
distribution is transformed into a radar velocity model using Topp's equation (Topp et al., 1980) (Fig. 1a). A
synthetic data set of 900 travel-time observations is constructed for two different boreholes located 3 m apart
using a transmitter-receiver geometry consisting of multiple-offset gathers between 0 and 3 m depth with
sources and receiver intervals of 0.1 m. The resulting travel times calculated with the time3d algorithm
(Podvin and Lecomte, 1991) are contaminated with zero mean uncorrelated Gaussian noise with a standard
deviation of 0.5 nanoseconds, ns. This constitutes a high-quality GPR data set, which is subsequently used
to compare our MCMC inversion methodology against exact theory, but with noisy data.
We use a simple Gaussian likelihood function
(16.03)
,
where
and
are the observed and simulate travel-time data respectively,
and n denotes the number of measurements. The simulated travel-time data are derived from the DCT
coefficients of the relative moisture distribution using a simple linear travel-time simulator. This model is a
simplified version of the numerical model used by Linde and Vrugt (2013) as it considers straight rays only.
This simplification reduces the CPU-cost of the model tremendously, yet can only provide approximate
results.
76
DREAM Suite 1
The initial state of each Markov chain is drawn from
, a normal distribution centered at zero and with
covariance matrix equal to . All the off-diagonal elements of this matrix are set to zero and the main
diagonal contains values of about 0.017 (first element) and 0.05 and 0.07, respectively. These values are
deliberately set small so that DREAM needs relatively few iterations to converge to the posterior distribution.
We use N = 32 chains with DREAM to generate samples of the posterior distribution of the moisture
distribution and use thinning of the chains (each 5th sample is collected) to minimize memory storage.
Default settings are assumed for all other algorithmic variables of DREAM.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example16\Plugin\Src_Cpp
4.17 Example 17
Case-Study XVII: Rainfall-runoff modeling: Inference of the discharge measurement error
In this seventeenth study, we use the HYMOD conceptual watershed model, a parsimonious rainfall-runoff
model whose parameters are thought to vary between watersheds. This model has been used in a numerous
studies and has five parameters that need to be specified by the user. Inputs to the model include mean
areal precipitation (MAP), and potential evapotranspiration (PET), while the outputs are estimated channel
inflow. HYMOD consists of a simple two-parameter rainfall excess model connected with two series of linear
reservoirs (three, identical, for the quick and a single reservoir for the slow response) in parallel as a routing
component. A schematic representation and discussion of the model appears in case study IV (see Figure
4.01), and readers are referred to this section for further details.
HYMOD has five different parameters whose values need to be determined from a measured discharge
record. The parameters and their prior uncertainty ranges are listed in Table 4.01. This includes cmax (mm),
the maximum storage capacity in the catchment, bexp (-) the degree of spatial variability of the soil moisture
capacity within the catchment, α (-) a coefficient that distributes the flow between the fast and slow-flow
reservoirs, and rs (days) and rq (days), the residence time of the slow and fast-flow reservoir reservoirs,
respectively. The actual evapotranspiration is equal to its potential value if sufficient soil moisture is
available, otherwise it is reduced depending on the soil water status.
(17.01)
.
where
and
are the observed and simulate discharge record,
respectively, and n denotes the number of measurements.
(17.02)
This formulation contains two coefficients,
(mm/day) and
(-) whose values are unknown and are
therefore added to the vector of model parameters. This then leads to the inference of
parameters with
DREAM using the observed discharge data record and the likelihood function of Equation (17.01). The latent
variables
and
are assigned a uniform prior distribution with ranges listed in Table 17.01.
Parameter
Symbol
Intercept of measurement error function
Slope of measurement error function
†
Lower
Upper
Units
0
0
1
1
mm/day
-
The listed units and ranges depend on units and characteristics of calibration data (discharge in present case)
77
DREAM Suite 1
Table 17.01: Nuisance variables of the measurement error function in Equation (17.01)†
The initial population is drawn from the lower and upper ranges listed in Table 6.01 and 17.01 using Latin
hypercube sampling. We use N = 10 chains with DREAM and use standard settings for the algorithmic
variables.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example17\Plugin\Src_Cpp
4.18 Example 18
Case-Study XVIII: Lotka-Volterra: The use of informal likelihoods
The eighteenth case study reports on GLUE and involves application of an informal likelihood function to the
study of animal population dynamics. One of the first models to explain the interactions between predators
and prey was proposed in 1925 by the American biophysicist Alfred Lotka and the Italian mathematician
Vito Volterra. This model, one of the earliest in theoretical ecology, has been widely used to study
population dynamics, and is given by the following system of two coupled differential equations
(18.01)
where
and
denote the size of the prey and predator population at time t respectively, (-) is the prey
growth rate (assumed exponential in the absence of any predators),
(-) signifies the attack rate (prey
mortality rate for per-capita predation),
(-) represents the exponential death rate for predators in the
absence of any prey, and (-) is the efficiency of conversion from prey to predator.
A synthetic monthly data set of a prey and predator population is created by solving Equation (18.01)
numerically for a 20-year period using an implicit, time-variable, integration method. The initial states,
and
and parameter values
,
,
and
correspond to data collected by the Hudson Bay Company between 1900 and 1920. These synthetic
monthly observations are subsequently perturbed with a homoscedastic error, and this corrupted data set is
stored in the n-vector
and used for inference with DREAM. We now use this data set of
“observed” predator and prey abundances to determine the posterior parameter distribution of the four LotkaVolettera model parameters, hence the parameter vector,
.
Parameter
Symbol
Prey growth rate
Attack rate
Exponential death rate for predators without prey
Efficiency of conversion from predator to prey
Lower
Upper
Units
0
0
0
0
1
10
1
10
-
Table 18.01: Parameters of the Lotka Volterra model in Equation (18.01)
A uniform prior parameter distribution is assumed using the ranges listed in Table 18.01. The initial states of
each of the N = 10 Markov chains in DREAM are sampled randomly from the prior ranges using Latin
hypercube sampling. An informal GLUE-type likelihood function is used to determine the behavioral (=
posterior) solution space. The log-likelihood,
is given by
78
DREAM Suite 1
(18.02)
where
is a GLUE-coefficient which determines the peakedness of the likelihood surface, and the operator
computes the variance of the error residuals between the simulated and observed data (numerator)
and variance of the measurement data (denominator), respectively. We assume a value of
and use
default values of the algorithmic variables of DREAM.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example18\Plugin\Src_Cpp
4.19 Example 19
Case-Study XIX: Bayesian Model Averaging: Ensemble Forecasting
Predictive uncertainty analyses is typically carried out using a single conceptual mathematical model of the
system of interest, rejecting a priori valid 4 alternative plausible models and possibly underestimating
uncertainty in the model itself (Raftery et al., 1999; Hoeting et al., 1999; Neuman, 2003; Raftery et al., 1999;
Vrugt et al., 2006, Vrugt and Diks, 2010). Model averaging is a statistical methodology that is frequently
utilized in the statistical and meteorological literature to account explicitly for conceptual model uncertainty.
The motivating idea behind model averaging is that, with various competing models at hand, each having its
own strengths and weaknesses, it should be possible to combine the individual model forecasts into a
single new forecast that, up to one's favorite standard, is at least as good as any of the individual forecasts.
As usual in statistical model building, the aim is to use the available information efficiently, and to construct
a predictive model with the right balance between model flexibility and overfitting. Viewed as such, model
averaging is a natural generalization of the more traditional aim of model selection. Indeed, the model
averaging literature has its roots in the model selection literature, which continues to be a very active area of
research.
Figure 19.01 provides a simple overview of model averaging. Consider that at a given time we have available
the output of multiple different models (calibrated or not). Now the goal is to weight the different models in
such a way that the weighted estimate (model) is a better (point) predictor of the observed system behavior
(data) than any of the individual models. What is more, the density of the averaged model is hopefully a
good estimator of the total predictive uncertainty.
79
DREAM Suite 1
Figure 19.01. Schematic illustration of model averaging using a three member ensemble and single
prediction of interest. The forecast of each models are displayed with the solid red circle, blue square and
green diamond, respectively, and the verifying observation is indicated separately with the brown “x” symbol.
The dotted black line connected with the symbol “o" denotes the weighted average of the forecasts of the
three different models. This point predictor satisfies the underlying premise of model averaging as it is in
better agreement with the data (smaller distance) than any of the three models of the ensemble. Some
model averaging methods also construct a predictive density of this averaged forecast. This overall forecast
pdf (solid black line) can be used for probabilistic forecasting and uncertainty analysis, and is simply a
weighted average of each ensemble member's predictive distribution (indicated with solid red, blue and green
lines) centered at their respective forecasts
To formalize the various model averaging strategies considered herein, let us denote by
a
vector of measurements of a certain quantity of interest. Further assume that there is an ensemble
of K different models available with associated point forecasts
at one or more
locations s and time, t. If we merge the different model forecasts in a n × K matrix Y (each model has its
own column), we can combine their individual forecasts using weighted averaging
(19.01)
,
where
is the jth row of matrix Y which stores the forecasts of each of the K models at a given location
and time,
is a
vector that stores the weights of each individual model, the symbol T
denotes transpose, and
is a white noise sequence, which will be assumed to have a normal distribution
with zero mean and unknown variance.
(19.02)
,
will often suffice to derive the bias-corrected forecasts,
coefficients
and
for each of the models,
simple regression model
for each of the models of the ensemble. The
are found by ordinary least squares using the
(19.03)
,
and the observations in the calibration data set. Typically this bias correction leads to a small improvement
of the predictive performance of the individual models, with
close to zero and
close to 1. If the
calibration set has relatively few observations, the ordinary least squares estimates become unstable, and
bias correction may distort the ensemble (Vrugt and Robinson, 2007). Although a (linear) bias correction is
recommended for each of the constituent models of the ensemble, such correction is not made explicit in
subsequent notation. For convenience, we simply continue to use the notation
rather than
for the
bias corrected predictors of .
The point forecasts associated with model (19.01) are
(19.04)
,
where the superscript “e” is used to indicate the expected (predicted) value of the averaged model.
Ensemble Bayesian Model Averaging (BMA) proposed by Raftery et al. (2005) is one popular method for
model averaging that is widely used method for statistical post-processing of forecasts from an ensemble of
different models. The BMA predictive distribution of any future quantity of interest is a weighted average of
probability density functions centered on the bias-corrected forecasts from a set of individual models. The
weights are the estimated posterior model probabilities, representing each model's relative forecast skill in
the training (calibration) period.
Depending on the type of application one has in mind, different flavors of BMA can be used. For instance, it
makes a crucial difference whether one would like to average point forecasts (in which case some forecasts
80
DREAM Suite 1
may be assigned negative weights) or density forecasts (in which negative weights could lead to negative
forecast densities). We now describe the most popular BMA method which is particularly useful when
dealing with the output of dynamic simulation models.
In BMA, each ensemble member forecast,
, is associated with a conditional PDF,
, which can
be interpreted as the conditional PDF of
on
, given that
is the best forecast in the ensemble. If we
assume a conditional density,
, that is centered on the forecasts of each of the individual models of the
ensemble, we can derive the combined forecast density as follows (see also right-hand-side of Figure 19.01)
(19.05)
A popular choice for
is a normal distribution with mean
and variance,
(19.06)
,
and thus the BMA predictive density,
, consists of a mixture of normal distributions, each centered
around their individual point forecast
. To ensure that
represents a proper density, the BMA
weights are assumed to lie on the unit simplex,
. Thus, the ‘s are nonnegative and add up to one
(19.07)
;
and they can be viewed as weights reflecting an individual model's relative contribution to predictive skill over
the training (calibration) period.
The BMA point predictor is simply a weighted average of the individual models of the ensemble
(19.08)
which is a deterministic forecast in its own way, whose predictive performance can be compared with the
individual forecasts in the ensemble, or with the ensemble mean. The associated variance of Equation
(19.08) can be computed as (Raftery et al. 2005)
.
(19.09)
The variance of the BMA prediction defined in Equation (19.08) consists of two terms, the first representing
the ensemble spread, and the second representing the within-ensemble forecast variance.
Successful implementation of the BMA method described in the previous section requires estimates of the
weights and variances of the PDFs of the individual forecasts. Following Raftery et al. (2005), we use the
following formulation of the log-likelihood function,
to estimate the values of
and
in the BMA model
(19.10)
where n denotes the total number of measurements in the training data set. This formulation builds on the
assumption that the forecasts errors of the models are independent in space and time. Note, for reasons of
numerical stability we work with the log-likelihood function rather than the likelihood function itself. In the
case of a normal conditional pdf for
the formulation of Equation (19.10) is equivalent to
81
DREAM Suite 1
(19.11)
with
and
.
Unfortunately, no analytical solutions exist that conveniently maximize Equation (19.10). We therefore use
DREAM to derive the posterior distribution of the BMA weights and variances.
In this nineteenth study we apply the BMA method using 48-h forecasts of surface temperature and sea
level pressure in the Pacific Northwest in January - June 2000 using the University of Washington (UW)
mesoscale short-range ensemble system. This is a five member multianalysis ensemble (hereafter referred
to as the UW ensemble) consisting of different runs of the fifth-generation Pennsylvania State University National Center for Atmospheric Research Mesoscale Model (MM5), in which initial conditions are taken
from different operational centers. We assume that all models have a common BMA variance – and thus
– which involves inference of
parameters with DREAM. Note, we estimate
the standard deviation of the normal predictive pdf, rather than its variance,
as this has the advantage of
requiring a smaller search space.
A uniform prior distribution is assumed for the BMA weights and variance,
and
The initial states of the
chains are derived by sampling from the prior distribution of
default values are assumed for the other algorithmic variables.
.
and
Note, the BMA method of Raftery et al. (2005) was developed for weather quantities such as temperature
and sea-level pressure whose conditional pdfs are well described with a normal distribution. The DREAM
solver also implements other conditional pdfs that might be more appropriate if the data is skewed. This
includes the gamma distribution which much better describes data with a skew
(19.12)
,
where is a shape parameter, and denotes a scale parameter. These two values depend on the value of
but this is beyond of the present case study. Interested readers are referred to Vrugt and Robinson
(2007) for an explanation and treatment of three different conditional pdfs. This includes also treatment of
heteroscedasticity in the choice of the BMA variance (variance dependent on magnitude of model forecast).
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example19\Plugin\Src_Cpp
4.20 Example 20
Case-Study XX: Limits of Acceptability: Soil Temperature Modeling
In the manifesto for the equifinality thesis, Beven (2006) suggested that a more rigorous approach to model
evaluation would involve the use of limits of acceptability for each individual observation against which model
simulated values are compared. Within this framework, behavioral models are defined as those that satisfy
the limits of acceptability for each calibration observation. The twentieth case study briefly describes the
application of DREAM to sampling the behavioral parameter space that satisfies the limits of acceptability of
each observation.
We use a simple illustrative example involving modeling of the soil temperature, T, in degrees Celsius using
the following analytic equation
,
82
(20.01)
DREAM Suite 1
where z (cm) is the depth in the soil profile (positive downward), t (hour) denotes time, T0 (oC) is the annual
average temperature at the soil surface, A0 (oC) is the amplitude of the temperature fluctuation,
(hour-1) signifies the angular frequency,
(hour) is a phase constant, and z0 (cm) denotes
the characteristic damping depth.
A synthetic record of hourly soil temperature observations at 5, 10, and 15 cm depth is used to illustrate the
application of DREAM to informal Bayesian inference using a limits of acceptability approach. This data set
was created by solving Equation (20.01) numerically for a 2-day period using T0=20oC, A0=5oC, ϕ=8 hr and
z0=20 cm. The hourly data was subsequently perturbed with a normally distributed error of 0.5 oC and stored
as the n-vector
. The limits of acceptability were set to be equal to two degrees Celsius
for each of the n = 144 temperature observations at three depths. The four model parameters are listed in
Table 20.01 and stored in the d-vector
. We now determine the behavioral parameter
space from the observed temperature data using the following pseudo-type likelihood
(20.02)
,
where
is an indicator function that returns one if the condition a is satisfied and zero otherwise. A
behavioral solution will satisfy the limits of acceptability of each temperature observation in the soil and thus
receive a score of n.
Parameter
Symbol
Annual average temperature at soil surface
Amplitude of temperature fluctuations soil surface
Phase constant
Characteristic damping depth
Lower
Upper
Units
10
0
0
0
30
10
24
50
C
C
hour
cm
o
o
Table 20.01: Parameters of the soil temperature model in Equation (20.01)
We now explore the behavioral solution space (might not exist!) with DREAM. We assume a noninformative
(uniform) prior distribution for each of the four parameters using the ranges listed in Table 20.01. A total of N
= 10 different Markov chains are used with DREAM. Their initial position is drawn randomly from the
multivariate uniform prior using Latin hypercube sampling. Default values of the algorithmic variables are
used.
Note, in the present study each observation is assumed to have the same limits of acceptability. DERAM
allows the use of a different limits of acceptability for each individual observation. This will be demonstrated
explicitly in the next case study involving characterization of the spatial variability of soil moisture in a field
plot using numerical solution of Richards' equation.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example20\Plugin\Src_Cpp
4.21 Example 21
Case-Study XXI: Limits of Acceptability: HYDRUS-1D model
This twenty-first case study considers the application of the limits of acceptability framework to the
modeling of the spatial distribution of soil moisture in a field plot. Beven (2006) has suggested that this
framework constitutes a more rigorous approach to model evaluation. Within this framework, behavioral
83
DREAM Suite 1
models are defined as those that satisfy the limits of acceptability for each calibration observation. The
twentieth case study briefly describes the application of DREAM to sampling the behavioral parameter
space that satisfies the limits of acceptability of each observation.
We use soil moisture data from an agricultural field near Jülich, Germany. This data was measured over a
period of 210-days using Time Domain Reflectometry (TDR) probes installed at 6 cm deep and at 61 different
locations in a 50 × 50 m plot. The TDR data were analysed using the algorithm described in Heimovaara et
al. (1990) and the measured apparent dielectric permittivities were converted to soil moisture contents using
the empirical relationship of Topp (1980). Measurements were taken on 29 days between 19 March and 14
October 2009, comprising a measurement campaign of 210 days. The observed soil moisture data at the 61
different locations were averaged to obtain a single mean time series of water content for the experimental
plot. We store this data in the n-vector
.
The HYDRUS-1D model of Simunek et al. (2008) was used to simulate variably saturated water flow in the
agricultural field. This model solves Richards' equation for given (measured) initial and boundary conditions
(21.01)
,
where
(cm3/cm3) denotes moisture content, t (days) denotes time, z (cm) is the vertical (depth)
coordinate, h (cm) signifies the pressure head, and K(h) (cm day-1) is the unsaturated soil hydraulic
conductivity. Observations of daily precipitation and potential evapotranspiration were used to define the
upper boundary condition of the field plot. Precipitation and other meteorological variables were recorded at a
meteorological station located 100 m west of the measurement site. A schematic overview of the model
setup appears in Figure 7.01. Details of the site, soil properties, experimental design and measurements are
given by Scharnagl et al. (2011) and interested readers are referred to this publication for further details.
We have used a similar setup as in case study VII and interested readers are referred to this study for
further details. The MVG parameters
(cm3/cm3),
(cm3/cm3),
(cm-1), n (-) and
(cm day-1) are
subject to inference. In the absence of direct measurements, a constant head lower boundary condition,
(cm) was assumed. The value of
is assumed to be temporally invariant and subject to inference
with DREAM.
Table 21.01 lists the parameters of the HYDRUS-1D model and their prior ranges. These
parameters
are now subject to inference using the mean soil moisture values at the field plot and their associated limits
of acceptability.
Parameter
Symbol
Residual water content
Saturated water content
Reciprocal of air-entry value
Curve shape parameter
Saturated hydraulic conductivity
Pressure head at lower boundary
n
Lower
Upper
Units
0.0
0.30
0.02
1.05
0.01
-500
0.1
0.55
0.50
2.50
4.17
-10
cm3/cm3
cm3/cm3
cm-1
cm hour-1
cm
Table 21.01: HYDRUS-1D model parameters and their prior uncertainty ranges
We now determine the behavioral parameter space from the observed temperature data using the following
pseudo-type likelihood
(21.02)
,
where
is an indicator function that returns one if the condition a is satisfied and zero otherwise. A
behavioral solution will satisfy the limits of acceptability of each temperature observation in the soil and thus
receive a score of n.
84
DREAM Suite 1
We now explore the behavioral solution space (might not exist!) with DREAM by using the fitness function of
Equation (21.02). We assume a uniform prior distribution with ranges of the parameters listed in Table
21.01. We run a total of N = 8 different Markov chains whose initial state is drawn randomly from the uniform
prior distribution using Latin hypercube sampling. Default values of the algorithmic variables are used.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example21\Plugin\Src_Cpp
4.22 Example 22
Case-Study XXII: Limits of Acceptability: Nash-Cascade model
The twenty-second case study considers the modeling of the instantaneous unit hydrograph using the
ordinates of Nash (1960) defined as (see case study thirteen)
(22.01)
where
(mm/day) is the simulated streamflow at time t (days), g (-) denotes the number of reservoirs,
(days) signifies the recession constant, and
is the gamma function
(22.02)
which satisfies the recursion
.
A n = 25-day period with synthetic daily streamflow data was generated by driving Equation (22.01) with an
artificial precipitation record using g = 2 reservoirs, and a recession constant of
days. This artificial
data set is subsequently perturbed with a heteroscedastic measurement error (non-constant variance) with
standard deviation equal to 10% of the original simulated discharge values. We store this record in the nvector,
and use data set to derive the posterior distribution of the two Nash-Cascade
parameters of Equation (22.01).
We do not use a likelihood function herein (see case study XIII) but rather apply the concept of limits of
acceptability. We define these limits to be
for all the different observations,
and use
the following goodness-of-fit function to differentiate between behavioral and nonbehavioral solutions
(22.03)
,
where
is an indicator function that returns one if the condition a is satisfied and zero otherwise.
Parameter values whose Nash-Cascade simulation leads to a score of Equation (22.03) equal to , honor
the limits of acceptability of each discharge observation, and are called behavioral solutions.
We now explore the behavioral solution space (might not exist!) with DREAM. We assume a bivariate
uniform prior distribution,
[1,10], for the parameters
and g and draw the initial position of the N = 8
different Markov chains using Latin hypercube sampling. Default values of the algorithmic variables are used.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example22\Plugin\Src_Cpp
85
DREAM Suite 1
4.23 Example 23
Case-Study XXIII: Limits of Acceptability: The SAC-SMA flood forecasting model
The twenty-third case study involves the modeling of the rainfall-runoff transformation of the Leaf River
watershed in Mississippi. This temperate 1944 km2 watershed has been studied extensively in the
hydrologic literature which simplifies comparative analysis of the results. The rainfall-discharge relationship
of the Leaf River basin is simulated using the Sacramento soil moisture accounting (SAC-SMA) model of
Burnash (1973). This lumped conceptual watershed model is used by the National Weather Service for flood
forecasting through the United States. The SAC-SMA model uses six reservoirs (state variables) to
represent the rainfall-runoff transformation. These reservoirs represent the upper and lower part of the soil
and are filled with "tension" and "free" water, respectively. The upper zone simulates processes such as
direct runoff, surface runoff, and interflow, whereas the lower zone is used to mimic groundwater storage and
the baseflow component of the hydrograph.
Figure 23.01 provides a schematic overview of the SAC-SMA model. Nonlinear equations are used to relate
the absolute and relative storages of water within each reservoir and their states control the main watershed
hydrologic processes such as the partitioning of precipitation into overland flow, surface runoff, direct runoff,
infiltration to the upper zone, interflow, percolation to the lower zone, and primary and supplemental
baseflow. Saturation excess overland flow occurs when the upper zone is fully saturated and the rainfall rate
exceeds interflow and percolation capacities. Percolation from the upper to the lower layer is controlled by a
nonlinear process that depends on the storage in both soil zones.
Figure 23.01. Schematic representation of the Sacramento soil moisture accounting (SAC-SMA) conceptual
watershed model. The parameters of the SAC-SMA model appear in Comic Sans font type (black), whereas
Courier font type is used to denote the individual fluxes computed by the model. Numbers are used to
denote the different SAC-SMA state variables, (1) ADIMC, (2) UZTWC, (3) UZFWC, (4) LZTWC, (5) LZFPC,
and (6) LZFSC. The ratio of deep recharge to channel base ow (SIDE) and other remaining SAC-SMA
parameters RIVA and RSERV are set to their default values of 0.0, 0.0 and 0.3, respectively
The SAC-SMA model has thirteen user-specifiable (and three fixed) parameters and an evapotranspiration
demand curve (or adjustment curve). Inputs to the model include mean areal precipitation (MAP) and
potential evapotranspiration (PET) while the outputs are estimated evapotranspiration and channel inflow. A
unit hydrograph or kinematic wave routing model is often used to rout channel inflow downstream to the
gauging point. Here, I use instead a Nash-Cascade series of three linear reservoirs to rout the upper zone
channel inflow whereas the baseflow generated by the lower zone recession is passed directly to the
gauging point. This configuration adds one parameter and three state variables to the SAC-SMA model. The
86
DREAM Suite 1
use of the three reservoirs improves considerably the CPU-efficiency as it avoids the need for
computationally expensive convolution. Our formulation of the model therefore has fourteen time-invariant
parameters which are subject to inference using observed discharge data. Table 23.01 summarizes the
fourteen SAC-SMA parameters and their prior uncertainty ranges. We also list the six main state variables.
Parameter
UZTWM
UZFWM
LZTWM
LZFPM
LZFSM
ADIMP
UZK
LZPK
LZSK
ZPERC
REXP
PCTIM
PFREE
RQOUT
Description
upper zone tension water maximum storage
upper zone free water maximum storage
lower zone tension water maximum storage
lower zone free water primary maximum storage
lower zone free water supplemental maximum storage
additional impervious area
upper zone free water lateral depletion rate
lower zone primary free water depletion rate
lower zone supplemental free water depletion rate
maximum percolation rate
exponent of the percolation equation
impervious fraction of the watershed area
fraction that percolates from upper to lower zone free water
Recession constant three linear routing reservoirs
Lower
Upper
Units
1
1
1
1
1
0
0.1
0.0001
0.01
1
0
0
0
0
150
150
500
1000
1000
0.4
0.5
0.025
0.25
250
5
0.1
0.1
1.0
mm
mm
mm
mm
mm
day-1
day-1
day-1
-
State variables
UZTWC
Upper-zone tension water storage content
0
150
mm
UZFWC
LZTWC
LZFPC
LZFSC
ADIMC
Upper-zone free water storage content
Lower-zone tension water storage content
Lower-zone free primary water storage content
Lower-zone free secondary water storage content
Additional impervious area content
0
0
0
0
0
150
500
1000
1000
650
mm
mm
mm
mm
mm
Table 23.01: Parameters of the SAC-SMA model and their prior uncertainty ranges
In the manifesto for the equifinality thesis, Beven (2006) suggested that a more rigorous approach to model
evaluation would involve the use of limits of acceptability for each individual observation against which model
simulated values are compared. Within this framework, behavioral models are defined as those that satisfy
the limits of acceptability for each observation. Ideally, the limits of acceptability should reflect the
observational error of the variable being compared, together with the effects of input error and
commensurability errors resulting from time or space scale differences between observed and predicted
values Beven (2014). The limits of acceptability approach has been used by various authors (Blazkova and
Beven, 2009; Dean et al., 2009; Krueger et al., 2009; Liu et al., 2009; Mcmillan et al., 2010; Westerberg et
al., 2011), although earlier publications used similar ideas within GLUE based on fuzzy measures (Page et
al., 2003; Freer et al.,2004; Page et al., 2004, 2007, Pappenberger et al., 2005, 2007). The limits of
acceptability framework might be considered more objective than the standard GLUE approach advocated in
Beven (1992) as the limits are defined before running the model on the basis of best available hydrologic
knowledge.
In this study we apply the limits of acceptability approach to the SAC-SMA model using data from the Leaf
River watershed in the USA. A 10-year historical record (1/10/1952 - 30/9/1962) with daily data of discharge
(mm/day), mean areal precipitation (mm/day), and mean areal potential evapotranspiration (mm/day) is used
herein for SAC-SMA model calibration. A 65-day spin-up period is used to reduce sensitivity of the model to
state-value initialization. We store the daily discharge observations in the n-vector,
.
We are now left with definition of the effective observation error (limits of acceptability) of each discharge
87
DREAM Suite 1
observation. This error varies dynamically with flow level and constitutes the combined effect of input data,
model structural and calibration data measurement error. Here, we follow the approach of Sadegh and Vrugt
(2013) and define the limits of acceptability as a multiple of the actual discharge measurement error. I follow
Vrugt et al. (2005) and use a nonparametric estimator to calculate the measurement data error of the n
discharge observations, hereafter referred to as
computed as multiple of
or
. The limits of acceptability are now
using
. This leads to effective observation errors on the
order of
. The following pseudo-likelihood function is used to determine the goodness-of-fit of
each simulated discharge record
(23.01)
,
where
is an indicator function that returns one if the condition a is satisfied and zero otherwise.
Parameter values whose SAC-SMA simulation leads to a score of Equation (23.01) equal to , honor the
limits of acceptability of each discharge observation, and are called behavioral solutions.
We now explore the behavioral solution space (might not exist!) with DREAM. We assume a uniform prior
parameter distribution using the ranges listed in Table 23.01 and draw the initial position of the
different Markov chains using Latin hypercube sampling. Default values of the algorithmic variables are used.
Implementation of plugin functions
The complete source code can be found in DREAM SDK - Examples\D3\Drm_Example23\Plugin\Src_Cpp
5 Using DREAM
The DREAM Suite package can be used to create new Bayesian inference projects via plugin modules or
can be also used as a library/software component for the development of new standalone applications
independent of DREAM Suite GUI. In the first case, one can work with the project (i.e. define input data, run
the calculation and view results) using the DREAM Suite GUI. This kind of work can be demonstrated by
opening demo examples in DREAM Suite main program. In the second case, one can develop his own
application that prepares input data, calls DREAM Solver and performs a custom post-processing of results.
An example of this situation is the DREAM console application.
5.1 DREAM projects
Working with existing projects in DREAM Suite is quite easy. One can simply change input data in the GUI
and recalculate results. However, developing a new project is more difficult, since one has to define the
model and create a plugin module for the evaluation of proposals during the Markov chain calculation and
implementing other needed functions. This may require a thorough understanding to mathematical methods
used in DREAM Solver, which are described in DREAM Technical manual. We recommend you to read this
manual before you start developing a new project in DREAM Suite.
Creating a new project from scratch
There are two ways how to create a new project: create a project from scratch or copy an existing project
and modify it according to your needs. The following text explains how to create a project from scratch.
·
In the Project Manager, click on the "New"button. Fill in a project name and description and press OK.
This action will create files and directories of the new project and open a project window.
88
DREAM Suite 1
Figure 5.1. New Project.
·
On the first project page, you can modify project description (both short one and detailed one).
Figure 5.2. First Project page.
·
On the Model Definition page, you should specify a number of model parameters and their names (if you
wish). The next step is to create the plugin module.
89
DREAM Suite 1
Figure 5.3. Model Definition page.
·
·
To create a plugin module, enter a plugin name on the Model Definition page and click on button
"Generate plugin project". This action will generate plugin files from a source code template and prompt
the user to open the project in Visual Studio (you must have installed VS 2013 or VS 2015).
The next step is to implement all needed functions of the plugin and build the plugin DLL. More
information can be found in plugin module details and programming references. Once the plugin module
is ready, can start creating new simulations.
5.1.1 Project files
DREAM Suite project data is stored in the main project file and a directory containing other files and
subdirectories. Project directory name is derived from the project name by adding Drm_ prefix (see Figure
5.1.1. "Project file and directory"). This means that, if you are copying of deleting a project, you must copy/
delete both - the file and the directory. The main project file (*.drm) and simulation files (so called "case
files" - *.drs) are text files with a very simple format and can be easily edited using Notepad or another text
editor.
90
DREAM Suite 1
Figure 5.1.1. Project File and Directory.
Project Directory
·
Drm_Examle01 - project directory of project "Example01"
· Model - directory for model-specific files
· Bin - external executable files (see Example07)
· Data - static model data, such as measurement data, etc. (see Example07)
· Info - contains file ProjectInfo.htm with detailed description of the project
· Plugin - directory for plugin files
· Bin - contains the plugin 32-bit dynamic library
· Bin_x64 - contains the plugin 64-bit dynamic library
· Src_Cpp - contains plugin C/C++ source code (Visual Studio project and plugin source
code)
· Src_Matlab - contains MATLAB *.m files if the plugin type is MATLAB COM or
MATLAB Engine
· Src_Python - contains Python files if the plugin type is Python (not available in the
current version)
Simulations
- directory for simulations. Each simulation has its data in a file and a special
·
directory
· Case1.drs - so called "Case File" with input data of simulation "Case1"
· Case1 - so called "Case Directory" for output files of simulation "Case1"
· CaseX.drs - file with input data of simulation "CaseX"
· CaseX - directory for output files of simulation "CaseX". Files can be in text format
(*.txt) or binary format (*.bin) according to the selected option "Save results in binary
format"
· DREAM_Out_AR.txt (*.bin) - Evolution of acceptance rate.
· DREAM_Out_AutoCorrN.txt (*.bin) - Autocorrelation of sampled parameters.
· DREAM_Out_BetweenChainDiagnostic_Rstat.txt (*.bin) - Between-chain
diagnostic with R-statistics. Optional - see "Save between-chain diagnostic".
· DREAM_Out_BetweenChainDiagnostic_MRstat.txt (*.bin) - Between-chain
91
DREAM Suite 1
·
diagnostic with MR-statistics. Optional - see "Save between-chain diagnostic".
· DREAM_Out_Corr.txt (*.bin) - d-dimensional parameter correlation matrix.
· DREAM_Out_CR.txt (*.bin) - Evolution of crossover selection probabilities.
· DREAM_Out_Diagnostic.txt - Coda diagnostic of each chain. Optional - see
"Save within-chain diagnostic". This file is always in text format.
· DREAM_Out_FxSN.txt (*.bin) - calibration data of measurements or ABC summary metrics data. Optional - see "Save model simulations".
· DREAM_Out_HistsMargDensitiesN.txt (*.bin) - Data for histograms of marginal
densities for each chain.
· DREAM_Out_HistsSummaryStatisticsN.txt (*.bin) - Data for histograms of
summary statistics for each chain. Files are exported only for likelihood 21, 22
and 23.
· DREAM_Out_ChainN.txt (*.bin) - Markov chains. Optional - see "Save Markov
chains".
· DREAM_Out_ChainCovergenceN.txt (*.bin) - Convergence of individual chains
to target distribution.
· DREAM_Out_ChainSizes.txt (*.bin) - Sizes of Markov chains. Optional - see
"Save Markov chains".
· DREAM_Out_LogObs.txt - Calculation observer log file with information about
the calculation progress. This file is always in text format.
· DREAM_Out_LogLikelihoodData.txt - Statistic likelihood data
· DREAM_Out_LogPriorData.txt - Statistic prior data. Available only if prior is
used
· DREAM_Out_Map.txt (*.bin) - The maximum aposteriori parameter values.
· DREAM_Out_MargDensitiesN.txt (*.bin) - Marginal densities of each
parameter.
· DREAM_Out_Mean.txt (*.bin) - The mean posterior value of each parameter.
· DREAM_Out_Median.txt (*.bin) - The median posterior values of each
parameter.
· DREAM_Out_MRstat.txt (*.bin) - Multivariate convergence of sampled chains.
· DREAM_Out_ParSet.txt (*.bin) - Single matrix with values sampled by chains.
Optional - see "Save ParSet".
· DREAM_Out_Rstat.txt (*.bin) - Univariate convergence of sampled chains.
· DREAM_Out_SN.txt (*.bin) - Summary metrics in each generation. Optional see "Save summary statistics".
· DREAM_Out_Std.txt (*.bin) - The posterior standard deviation of the
parameters.
· DREAM_Out_SummaryMeasurementsData.txt (*.bin) - Input measurement
data
Temp - temporary directory. Contains a working copy of the Simulations directory while the
project is open and its content is deleted when closing the project. Case directories may
contain additional subdirectores named 1,2,3,...,N that are created during parallel calculation
and their names 1,...,N correspond to the number of calculation threads (cores).
5.2 DREAM applications
DREAM application is a program consisting of three components:
·
·
·
Main program (GUI) - allows to enter input data, run the calculation (DREAM Solver) and view results
DREAM Solver - the calculation module available as COM server or C++ library, calls the DREAM
Plugin to evaluate proposals
DREAM Plugin - user-programmable DLL implementing the evaluation of proposals and optionally
defining some input data
92
DREAM Suite 1
The main program of DREAM Suite represents a kind of DREAM application, which has been designed to
work with many different examples and demonstrate capabilities of DREAM Suite. However, DREAM Solver
can also be used to develop independent DREAM applications with own GUI and custom data
preprocessing and post-processing. A very simple example of such application is the DREAM console
application, available including source code and showing how to call DREAM Solver and other components
from your own program.
Figure 5.2. DREAM Application schema.
5.2.1 DREAM console application
DREAM Suite installation includes a simple console application, which calls DREAM Solver and plugin
modules of demo examples. It can be used to recalculate all demo examples (under assumption that the
user has a valid license for DREAM Solver). The C++ source code of this application is available in DREAM
SDK\DreamAppTest directory (the full path is usually C:\Users\Public\Documents\PC-Progress\DREAM
Suite 1.x\SDK\DreamAppTest) and demonstrates how to initialize DREAM Solver (COM Server), attach a
plugin module and calculation observer and run the calculation. It simply shows how to use DREAM Solver
outside DREAM Suite main program (GUI).
93
DREAM Suite 1
Figure 5.2.1. DREAM Console Application schema.
Running DREAM Console Application
Compiled executable DreamTest.exe is available in DREAM Suite program files directory (the full path is
usually C:\Program Files (x86)\PC-Progress\DREAM Suite 1.x\Bin) and its shortcut is available in All
Programs (All apps) – PC-Progress – DREAM Test Console. Note that when working with DREAM Console
application, most of input data are defined by the plugin module - unlike the DREAM Suite main program,
which allows entering data via GUI.
Opening DREAM Console Application in Visual Studio
To open DREAM Console Application in Visual Studio, open solution DreamAppTest.sln located in DREAM
SDK directory (the full path is usually C:\Users\Public\Documents\PC-Progress\DREAM Suite 1.x\SDK
\DreamAppTest.sln). Note that all DREAM Suite projects have been developed in Visual Studio 2013. If you
are using Visual Studio 2015 (or a newer version), you will need to upgrade the projects, which can be done
automatically when opening the solution in Visual Studio (see figure 6.1.2) - just click the OK button. More
information about using the DREAM Solver can be found in DREAM Solver documentation.
94
DREAM Suite 1
Figure 6.1.2. Convert DREAM Console Application solution (developed in VS 2013) to VS 2015 format
5.3 DREAM plugins
Each DREAM project requires a special plugin module, implementing the evaluation of proposals and other
project-specific functions. This plugin can be written in C/C++ or other languages and is linked with DREAM
Suite as a dynamic library. To simplify the development of this module, DREAM Suite can generate a
skeleton of the plugin module, which should be then modified according to needs of the particular project.
Main functions of the DREAM Plugin module and the order in which they are called
·
·
·
Function defining DREAM input parameters (required, called always)
§ InitPlugin - Plugin initialization (can connect an external server, etc.)
§ GetInputParams - Defines initial/default values of DREAM parameters
§ InitData - Prepares input data needed for the calculation. Called only once.
Functions defining other input data (optional, called according to project settings)
§ GetMinMaxData
§ GetNormalData
§ GetPriorData
§ GetPriorDataCustom
§ GetMeasurementData
§ GetBayesData
Function evaluating each proposal during DREAM calculation (required, called always)
§ EvaluateProposal
Additional information can be found in the documentation to programming interfaces IDreamDataSource and
IDreamEvaluator.
Plugin types and implementation in other languages
We believe that C/C++ is the ideal programming language for the development of DREAM Suite plugin
modules. However, DREAM Suite plugins can be also written in other languages, such as Fortran, MATLAB
and other. To demonstrate this feature, we have created a special interface that allows users to implement
DREAM plugins using MATLAB *.m files. MATLAB plugin examples can be found in library D2 of demo
examples. Other interfaces (e.g. for Python, etc.) can be developed later according to demands of DREAM
Suite users.
·
·
C/C++ plugin modules
MATLAB plugin modules
95
DREAM Suite 1
5.3.1 C/C++ Plugin
We believe that C/C++ is the best language for the development of DREAM Suite plugin modules because
of the following reasons:
·
·
·
·
·
High performance (C++ is about as fast as C or Fortran)
Great level of abstraction and organization of code
Large number of libraries of all kinds, usually free. In our examples we use STL, BOOST and EIGEN.
Professional development tools (Microsoft Visual Studio, including free editions)
Accessibility of all latest technologies for scientific computing
To simplify the development of this module, DREAM Suite can generate a skeleton of the plugin module and
create a new Visual Studio project, which can be immediately recompiled and is automatically linked with
DREAM Suite (see button "Generate plugin project" on the Model Definition page). The user should then
implement project-specific functions into the existing C++ source code. The code contains many useful
comments and one can also learn form the source code of many examples distributed with DREAM Suite.
Remark 1: Note that all DREAM Suite projects have been developed in Visual Studio 2013. If you are using
Visual Studio 2015 (or a newer version), you will need to upgrade the projects, which can be done
automatically when opening the project/solution in Visual Studio (see figure 6.1.2).
Remark 2: Although DREAM Solver is a COM server, writing custom plugin modules does not require any
knowledge of COM technology.
Developing the plugin module
The automatically generated Visual Studio solution contains two projects: AppTest and the plugin project
(see "MyPlugin" in Figure 5.3.1. "Plugin Test Application"). The AppTest project is a simple console
application, which enables to develop and test the Plugin module independently of DREAM Suite. You can
compile both projects and run AppTest, which connects to DREAM COM Server and subsequently calls
functions from your evaluator (MyPlugin.dll). You can also place breakpoints to these functions if you wish
to debug your code. However, please note that your plugin should define all input data needed for the given
problem in DREAM Solver. AppTest does not offer any other way to define the input data and transfer them
to the solver (unlike DREAM Suite, in which input data can be entered via GUI). This input data should be
specified in functions CDreamEvaluator::GetEvaluationParams (always required) and GetMinMaxData,
GetNormalData, GetPriorData, CalcCustomPriorData, GetMeasurementData and GetBayesCompData
(optional). The next key function CDreamEvaluator::Evaluate implements the evaluation of samples similarly as can be seen in demo examples.
96
DREAM Suite 1
Figure 5.3.1. Plugin Test Application.
5.3.2 MATLAB Plugin
DREAM Suite plugin modules can also be implemented in MATLAB script files (*.m). To prepare such a
plugin, take the following steps:
1. On the Model Definition page, select plugin type MATLAB COM or MATLAB Engine. MATLAB COM
interface is more general in terms of combining 32-bit/64-bit program versions, i.e. you can then use 64bit MATLAB with 32-bit DREAM Suite, which is not possible with the MATLAB Engine interface (64-bit
MATLAB requires 64-bit DREAM Suite). On the other hand, the MATLAB Engine interface is a bit faster
than MATLAB COM (but still significantly slower than C/C++ plugins).
97
DREAM Suite 1
Figure 5.3.2. MATLAB Plugin Type
2. Create two *.m files named according to the project name in the Src_Matlab subdirectory. The first file
(e.g. Example01.m) should contain definitions of DREAM parameters and the second file
(Example01_Evaluate.m) contains the function for evaluations of proposals. Names of DREAM
parameters are identical with names described in the DREAM Suite technical manual or in the manual
for MATLAB Implementation of DREAM (J.Vrugt).
98
DREAM Suite 1
Figure 5.3.3. MATLAB files
Figure 5.3.4. MATLAB file with DREAM Parameters
99
DREAM Suite 1
Figure 5.3.5. MATLAB file with the evaluation function
Remarks on using the MATLAB interface
·
·
·
·
·
·
When using the MATLAB interface in DREAM Suite, you need to have MATLAB installed and activated
on your computer.
Demo examples using the MATLAB interface can be found in library D2 in the Library Manager.
All demo examples in library D2 have been tested in MATLAB R2016a, 64-bit version. We cannot
guarantee that the interface will work correctly with older version of MATLAB.
The parallel computing is disabled in the MATLAB interface.
The MATLAB interface (both COM and Engine) is in general significantly slower that the standard C/C+
+ plugins.
The source code of both MATLAB interfaces is available in DREAM SDK (subdirectory Templates/
PluginMatlabCom and Templates/PluginMatlabEng)
5.4 DREAM Solver
DREAM Solver is the main calculation module implementing mathematical methods described in the
Technical Manual. It actually is a C++ library wrapped by C/COM interfaces, which enable using this library
in a binary form.
Main functions of DREAM Server
·
·
·
·
LoadPlugin - loads the plugin DLL
InitEvaluatorExt - initializes the evaluator and sets input data from an external source (e.g. GUI)
InitEvaluatorDef - initializes the evaluator and sets input data from the evaluator
StartCalculation - starts DREAM calculation
Additional information about DREAM Solver functions and interfaces can be found in IDreamSolver and
100
DREAM Suite 1
programming documentation.
Using DREAM Server (an example)
The use of DREAM Solver is demonstrated by the C++ code below, which is part of a simple console
application (DREAM Client) generated by DREAM Suite when creating a plugin module for a new project.
Another example of the DREAM Console Application. Please note that DREAM COM server must be
properly registered, which can be done during the installation process (see Figure 2.3.2. "Installation
Features"). The use of DREAM COM server also requires a valid license and authorization.
//------------------------------------------------------------------------------------------------int _tmain(int argc, _TCHAR* argv[])
//------------------------------------------------------------------------------------------------{
// Return value
HRESULT hRes = S_OK;
// Initialize COM subsystem
hRes = CoInitialize(NULL);
if(SUCCEEDED(hRes))
{
// Display info
wprintf(L"##################################################\n");
wprintf(L" DREAM Suite 1.0 - Plugin Test Application\n");
wprintf(L"##################################################\n");
wprintf(L"This application is intended for testing of DREAM plugin modules.\n");
int iRunTest = GetUserChoice(L"Do you want to run the test? (Yes/No = 1/0) : ", 0, 1);
if(iRunTest == 0)
return 0;
// We will assume that the current directory is "Project\Plugin\Bin"
_bstr_t bstrPluginBin = boost::filesystem::current_path().c_str();
// Path to the project directory
_bstr_t bstrExampleDir = bstrPluginBin;
bstrExampleDir += L"\\..\\..";
// Path to Evaluator DLL
_bstr_t bstrPluginDllName = L"$DREAM(ProjectName)";
_bstr_t bstrEvaluatorPath = bstrPluginBin;
bstrEvaluatorPath += L"\\";
bstrEvaluatorPath += bstrPluginDllName;
bstrEvaluatorPath += L".dll";
// Path to directory with Example data
_bstr_t bstrModelData = bstrExampleDir;
bstrModelData += L"\\Model\\Data";
// Path to directory with Example executables
_bstr_t bstrModelBin = bstrExampleDir;
bstrModelBin += L"\\Model\\Bin";
// Path to working directory
_bstr_t bstrWorkingDir = bstrExampleDir;
bstrWorkingDir += L"\\Temp\\Simulations\\Case1";
// Delete old working directory (to clear old files)
DrxDeleteDirectory(std::wstring(bstrWorkingDir));
// Create new working directory
DrxCreateDirectory(std::wstring(bstrWorkingDir));
// Calc observer for communication, logging...
CCalcObserver calcObserver(bstrWorkingDir);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Run DREAM Solver
/////////////////////////////////////////////////////////////////////////////////////////////////
bool bDisplayInfoAboutCalculationResults = false;
bool bLogInfoAvailable = false;
try
{
wprintf(L"Connecting DREAM Server...\n");
101
DREAM Suite 1
// Try to create DreamSolver in COM way
IDreamSolverPtr pSolver(__uuidof(IDreamSolver));
// Check if the creation of solver succeeded
if(pSolver != nullptr)
{
// Setup calculation observer
IDreamObserverPtr pIDreamCalcObserver = nullptr;
hRes = calcObserver.QueryInterface(IID_IDreamObserver, (void**)&pIDreamCalcObserver);
if(SUCCEEDED(hRes))
{
// Establish communication with solver
pSolver->AttachObserver(pIDreamCalcObserver);
bLogInfoAvailable = true;
}
// Set directories
pSolver->SetPath(ePathProjectDir, bstrExampleDir);
pSolver->SetPath(ePathModelData, bstrModelData);
pSolver->SetPath(ePathModelBin, bstrModelBin);
pSolver->SetPath(ePathPluginBin, bstrPluginBin);
pSolver->SetPath(ePathWorkingDir, bstrWorkingDir);
// Load plugin module
hRes = pSolver->LoadPlugin(bstrEvaluatorPath);
if(SUCCEEDED(hRes))
{
// Plugin info
CDreamPluginInfo pluginInfo;
pluginInfo.m_PluginType = ePluginType::ePlugin_DLL;
pluginInfo.m_strPluginName = bstrPluginDllName.copy();
pluginInfo.m_strModelDataDir = bstrModelData.copy();
// DREAM calculation parameters
CDreamCalcParams calcParamInfo;
// Convergence diagnostics?
calcParamInfo.m_SaveWithinChainDiagnostics = GetUserChoice(L"Do you want convergence
diagnostics? (Yes/No = 1/0) : ", 0, 1);
// Export Markov chains?
calcParamInfo.m_SaveMarkovChains = GetUserChoice(L"Do you want to export Markov chains?
No = 1/0) : ", 0, 1);
// Number of cores
calcParamInfo.m_NumberOfCPUs = GetUserChoice(L"Number of cores <1,20>, N > 1 = parallel
calculation : ", 1, 20);
calcParamInfo.m_RunParallel = calcParamInfo.m_NumberOfCPUs > 1 ? 1 : 0;
// Initialize the evaluator and all input data by values obtained from the evaluator
hRes = pSolver->InitEvaluatorDef(&pluginInfo, &calcParamInfo);
if(SUCCEEDED(hRes))
{
// Get pointer to evaluator
IDreamEvaluatorPtr pEvaluator = nullptr;
hRes = pSolver->GetEvaluator(&pEvaluator);
if(SUCCEEDED(hRes))
{
// Set signal handler (Ctrl+C)
pTheOnlySolverInThisProcess = pSolver;
SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalHandler, TRUE);
// Prepare the console to display calculation progress (%)
wprintf(L"Starting calculation...\n");
wprintf(L"(press Ctrl+C to interrupt the calculation)\n");
// Perform calculations
hRes = pSolver->StartCalculation();
if(SUCCEEDED(hRes))
{
wprintf(L"Calculation succeeded.\n");
}
else
{
// Check errors
_bstr_t message;
CDreamErrorInfo lastErrorInfo;
102
(Yes/
DREAM Suite 1
if(pSolver->GetLastError(&lastErrorInfo) != S_OK && lastErrorInfo.GetErrType() ==
eTypeError)
message = L"Calculation failed with error:\n" +
_bstr_t(lastErrorInfo.GetErrDescription()) + L"\n";
else
message = L"Calculation failed.\n";
wprintf(message);
}
bDisplayInfoAboutCalculationResults = true;
}
// Failed to get pointer to evaluator
else
{
wprintf(L"Failed to get pointer to evaluator.\n");
}
}
// Failed to initialize evaluator
else
{
wprintf(L"Failed to initialize evaluator.\n");
}
}
// Failed to load plugin module
else
{
wprintf(L"Failed to load plugin module.\n");
}
}
// Failed to create Dream solver
else
{
wprintf(L"Failed to create Dream solver.\n");
}
}
catch(_com_error& e)
{
// Dream solver creation failed
std::wstring message = L"COM error: ";
message += e.ErrorMessage();
message += L"\n";
PrintMessageUTF8(message);
}
// Clean-up
if(pTheOnlySolverInThisProcess != nullptr)
{
// Release solver interface - it must be done here, because it fails after CoUnitialize()
pTheOnlySolverInThisProcess = nullptr;
}
// Output information
if(bDisplayInfoAboutCalculationResults)
{
// Output files
wprintf(L"Output and log files are available in directory:\n" + bstrWorkingDir + L"\n");
}
// Error info
if(bLogInfoAvailable)
{
// Number of errors and warnings returned by the solver
int nErrors = calcObserver.GetNoOfErrors();
int nWarnings = calcObserver.GetNoOfWarnings();
wprintf(L"Number of errors: %d, Number of warnings: %d\n", nErrors, nWarnings);
// Print logged messages (errors, warnings, messages and calculation time)?
int iPrintLogInfo = GetUserChoice(L"Do you want to display log-file content? (Yes/No = 1/0) : ",
0, 1);
if(iPrintLogInfo == 1)
103
DREAM Suite 1
{
wprintf(L"Log file contents:\n");
calcObserver.PrintMessages();
}
}
// Clean-up COM services
CoUninitialize();
}
// Wait for ENTER
std::wcin.ignore(1024, '\n');
std::cout << "\nPress Enter to continue...";
std::wcin.get();
// Return result
return hRes;
}
5.4.1 Calculation observer
Calculation Observer is an optional object, which can be connected to the DREAM Solver to receive a
variety of information during the calculation, such as information needed for updating the progress bar, error
messages, convergence information, signal to interrupt the calculation by user, error messages, etc. More
details can be found in IDreamObserver documentation. An example of DREAM calculation observer is
available in the DREAM Console application.
6 Programming references
6.1 DREAM SDK
DREAM Suite Software Development Kit is a package of C++ libraries and source files needed for the
development of DREAM plugin modules or DREAM applications. This SDK is installed to the “DREAM Data”
directory selected during installation of DREAM Suite. The default location is C:\Users\Public\Documents
\PC-Progress\DREAM Suite 1.x\SDK_102 ("102" corresponds to version 1.02)
DREAM SDK components
·
·
·
·
·
DreamAppTest – contains the project and source code of the DREAM console application. VS solution
DreamAppTest.sln is located in the DREAM SDK root directory.
DreamShared – contains files with common C++ functions used by multiple Examples. It also includes
DREAM Solver type-library DreamServer.tlb
Examples - contains directories with all demo examples. Each example contains source code of its
plugin module in “Plugin\Src” subdirectory
Templates – contains templates for generating the source code of DREAM plugin modules
Tools – contains third-party libraries BOOST and EIGEN
Using DREAM SDK
Although DREAM Solver is a COM server and its use is not limited to C++ language, all demo examples
have been developed in C++ using Microsoft Visual Studio. For a hassle-free development of DREAM plugin
modules, we recommend using VS 2013 or 2015 (e.g. the Community Edition, which is free for individual
programmers). Using other compilers may require additional work and modification of prepared examples
and templates.
When compiling a DREAM plugin module, Visual Studio needs to know the path to the DREAM SDK
directory to locate libraries and files described above. This path is defined by system environment variable
DREAM1_SDK, which is created by the DREAM Suite installation program or can be created / modified
manually (see Figure 6.1.1. "DREAM1_SDK environment variable"). Please note that a change of this
104
DREAM Suite 1
environment variable always requires restarting Visual Studio and may also require restarting Windows to
reflect this change in command prompt and console applications. You can change the path to DREAM SDK
directory in DREAM Program Options dialog or directly in Windows system settings - see figure 6.1.1.
Figure 6.1.1. DREAM1_SDK environment variable.
6.2 Plugin module template
The plugin template is located in directory DREAM1_SDK\Templates\PluginGeneratorSrc and contains
source code used to generate the plugin project.
6.2.1 DreamEvaluator.h
///////////////////////////////////////////////////////////////////////////////////////////////////
// DreamEvaluator.h
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
///////////////////////////////////////////////////////////////////////////////////////////////////
// CDreamEvaluator
class CDreamEvaluator : public IDreamEvaluator
{
public:
/// <summary>Constructor</summary>
CDreamEvaluator();
/// <summary>Destructor</summary>
~CDreamEvaluator();
/// <summary>Plugin initialization. The first function called before using the evaluator</summary>
virtual HRESULT STDMETHODCALLTYPE InitPlugin(IDreamPluginInfo* pIPluginInfo) override;
/// <summary>Prepare input data and all other local data needed for the calculation.</summary>
virtual HRESULT STDMETHODCALLTYPE InitData(IDreamPluginInfo* pIPluginInfo,
IDreamInputParViewer* pIDreamInputParams
105
DREAM Suite 1
) override;
/// <summary>Prepare files in working directory for parallel calculation (one thread)</summary>
virtual HRESULT STDMETHODCALLTYPE PrepareWorkDir(BSTR strSourceDir,
BSTR strDestinationDir) override;
/// <summary>Calculate the likelihood of each proposal during DREAM calculation</summary>
virtual HRESULT STDMETHODCALLTYPE EvaluateProposal(IDreamInputParViewer* pInputPar, int iSim,
IDreamMatrix* x, IDreamMatrix* res,
BSTR strWorkingDir, BSTR strModelDataDir,
BSTR strModelBinDir) override;
/// <summary>Called after finishing the calculation</summary>
virtual HRESULT STDMETHODCALLTYPE OnCalculationFinished() override;
/// <summary>Return description of the last error</summary>
virtual HRESULT STDMETHODCALLTYPE GetLastError(BSTR* strErrorText) override;
/// <summary>Return default DREAM parameters</summary>
virtual HRESULT STDMETHODCALLTYPE GetInputParams(IDreamInputParams* pIDreamInputParams) override;
/// <summary>Return MinMax data</summary>
virtual HRESULT STDMETHODCALLTYPE GetMinMaxData(IDreamInputParViewer* pInputPar,
IDreamDataMinMax* pIMinMaxData) override;
/// <summary>Return Normal data</summary>
virtual HRESULT STDMETHODCALLTYPE GetNormalData(IDreamInputParViewer* pInputPar,
IDreamDataNormal* pINormalData) override;
/// <summary>Return Prior data</summary>
virtual HRESULT STDMETHODCALLTYPE GetPriorData(IDreamInputParViewer* pInputPar,
IDreamDataPrior* pIPriorData) override;
/// <summary>Return Custom Prior data</summary>
virtual HRESULT STDMETHODCALLTYPE GetPriorDataCustom(IDreamInputParViewer* pInputPar,
IDreamMatrix* x, IDreamMatrix* PR,
ePriorDistrib callType) override;
/// <summary>Return Measurement data</summary>
virtual HRESULT STDMETHODCALLTYPE GetMeasurementData(IDreamInputParViewer* pInputPar,
IDreamDataMeasurement* pIMeasureData,
BSTR strModelDataDir) override;
/// <summary>Return Approximate Bayesian Computation data</summary>
virtual HRESULT STDMETHODCALLTYPE GetBayesData(IDreamInputParViewer* pInputPar,
IDreamDataABC* pIBayesCompData,
BSTR strModelDataDir) override;
/// <summary>COM implementation</summary>
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid, void** ppv) override;
virtual ULONG STDMETHODCALLTYPE AddRef() override;
virtual ULONG STDMETHODCALLTYPE Release() override;
private:
/// <summary>Reference counter</summary>
long m_cRef;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
6.2.2 DreamEvaluator.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// DreamEvaluator.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
// CDreamEvaluator
//------------------------------------------------------------------------------------------------CDreamEvaluator::CDreamEvaluator() : m_cRef(0)
//------------------------------------------------------------------------------------------------/*
Constructor. To initialize member variables, use rather CDreamEvaluator::InitData
*/
106
DREAM Suite 1
///////////////////////////////////////////////////////////////////////////////////////////////////
{
}
//------------------------------------------------------------------------------------------------CDreamEvaluator::~CDreamEvaluator()
//------------------------------------------------------------------------------------------------/*
Destructor
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::InitPlugin
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called immediately after creation of CDreamEvaluator and before using
the evaluator (i.e. calling its other functions). It is intended for initialization of
the dynamic library and connecting possible external servers.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetInputParams
//------------------------------------------------------------------------------------------------(
IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define default DREAM parameters for this particular project.
This function is called by the main program to initialize data of each newly created simulation
case. This data can be later modified in the GUI (except parameters locked by flag
DreamSolver::disable_edit) or can be overwritten while reading case data from a file.
In the AppTest console application, there is no GUI and this functions actually defines all
input parameters that are subsequently used by DREAM Solver.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIDreamInputParams pointer
if(pIDreamInputParams == nullptr)
{
return E_INVALIDARG;
}
// Dimensionality target distribution d
pIDreamInputParams->SetProblemDimension(2, DreamSolver::disable_edit);
107
DREAM Suite 1
// Number of Markov chains N
pIDreamInputParams->SetNumberOfMarkovChains(10, DreamSolver::enable_edit);
// Number of generations T
pIDreamInputParams->SetNumberOfGenerations(1000, DreamSolver::enable_edit);
// Choice of likelihood function
pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_101, DreamSolver::enable_edit);
// Number of crossover values nCR
pIDreamInputParams->SetNumberOfCrossoverValues(3, DreamSolver::enable_edit);
// Number chain pairs for proposal delta
pIDreamInputParams->SetNumberChainPairs(3, DreamSolver::enable_edit);
// Random error for ergodicity lambda
pIDreamInputParams->SetRandomErrorForErgodicity(0.05, DreamSolver::enable_edit);
// Randomization zeta
pIDreamInputParams->SetRandomization(1.0e-12, DreamSolver::enable_edit);
// Test to detect outlier chains
pIDreamInputParams->SetOutlierTest(eOutlierTest::eOutlierIqr, DreamSolver::enable_edit);
// Probability of jump rate of 1 pJumpRate_one
pIDreamInputParams->SetProbabilityOfJumprate(0.2, DreamSolver::enable_edit);
// Adapt selection prob. crossover pCR
pIDreamInputParams->SetAdaptSelection(1, DreamSolver::enable_edit);
// Each Tth sample is stored thinning
pIDreamInputParams->SetThinnigSampleToStore(1, DreamSolver::enable_edit);
// GLUE likelihood parameter
pIDreamInputParams->SetGlueLikelihood(10, DreamSolver::enable_edit);
// Scaling factor of built-in jump rate beta0
pIDreamInputParams->SetScalingFactorOfJumpRate(1.0, DreamSolver::enable_edit);
// Bayesian Model Averaging (BMA) with hydrologic data. Number of different models
pIDreamInputParams->SetNumberOfDifferentModelsBMA(0, DreamSolver::enable_edit);
// Initial sampling distribution type
pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitPrior, DreamSolver::enable_edit);
// Boundary handling type
pIDreamInputParams->SetBoundHandling(eBoundHandling::eBoundUnbounded, DreamSolver::enable_edit);
// Prior distribution type
pIDreamInputParams->SetPriorDistributionType(ePriorType::eUnivariate, DreamSolver::enable_edit);
// Use prior distribution even for m_InitialDistribution != eInitPrior? Values: 1=true, 0=false
pIDreamInputParams->SetUsePriorDistribution(0, DreamSolver::enable_edit);
// Can model run in parallel?
// Values: eParallelModeYes, eParallelModeNotRecommended, eParallelModeNotPossible
pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);
// Model vectorization? For eVectorization::eVectYes, function CDreamEvaluator::EvaluateProposal
// must evaluate proposals for all Markov chains in one step/call. Parallelization is then
// automatically switched off.
pIDreamInputParams->SetVectorization(eVectorization::eVectNone, DreamSolver::disable_edit);
// ToDo:
// 1. Modify the above parameters according to this particular project
// 2. Remove the following MessageBox and return S_OK
std::wstring sMessage;
sMessage = L"Incorrect DREAM input data!\n";
sMessage += L"Please modify function CDreamEvaluator::GetInputParams()\n";
sMessage += L"in DREAM plugin module. Set correct parameters and implement\n";
sMessage += L"all other plugin functions needed for the project.";
MessageBox(NULL, sMessage.c_str(), L"DREAM Plugin Module", MB_OK | MB_ICONSTOP);
return E_FAIL;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::InitData
//------------------------------------------------------------------------------------------------(
IDreamPluginInfo* pIPluginInfo
// Plugin information
, IDreamInputParViewer* pIDreamInputParams // Current DREAM input parameters
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called to prepare:
108
DREAM Suite 1
A/ DREAM input data before accessing them via the IDreamDataSource interface and
B/ all other local data required by evaluator for the calculation.
It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir
(directory ...Drm_ExampleXX\Model\Data).
Remark 1: This function prepares DREAM input data in the evaluator according to current
DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be
different from default parameters defined in function CEvaluatorExample::GetInputParams().
Remark 2: This function should be called before using functions
CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,
::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()
can be called independently.
Remark 3: When using this evaluator for parallel calculations, member variables can be shared
by multiple threads and thus their values should not be changed during the calculation or
you should make the code thread-safe using standard tools (e.g. critical sections, etc.).
Another option is to disable running in parallel mode, which can be done in function
CDreamEvaluator::GetInputParams - pIDreamInputParams->m_ParallelMode = eParallelModeNotPossible;
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetMeasurementData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar
// Interface to DREAM input parameters
, IDreamDataMeasurement* pIMeasureData // Interface to measurement data
, BSTR strModelDataDir
// Path to directory with measurement data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to load measurement data from files located in strModelDataDir
and fill the data structure pIMeasureData. Measurement data are required by some types
of likelihood functions.
Types of measurement data:
1. Calibration data
(Y)
2. Measurement error data (Sigma)
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Specific file with measurement data (each line one number)
std::wstring file(strModelDataDir);
file += L"\\abundances.txt";
// Load data to Y
vector<double> Y;
if(!CDreamMath<>::ReadData(file, Y))
{
return E_FAIL;
}
// Data are set to solver by function with length and data itself:
pIMeasureData->AddCalibrationData((int)Y.size(), &Y(0));
109
DREAM Suite 1
return S_OK;
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIMeasureData pointer
if(pIMeasureData == nullptr)
{
return E_INVALIDARG;
}
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetMinMaxData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataMinMax* pIMinMaxData // Interface to Min/Max data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define min/max values for initial LATIN and UNIFORM sampling
distribution or to define min/max additional data (Measurement Error, Nuisance variables) for
likelihood
functions LIK_211, LIK_212, LIK_213, LIK_214 and LIK_217.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Normal use for Latin sampling
// Fill min, max data
pIMinMaxData->AddItem(0.00, 1.0); // alpha
or
pIMinMaxData->AddExtendedItem(0.00, 10.0, 0, 1); // delta
// Special use for LIK_211, LIK_212 and LIK_213 to add measurement error variables
// Fill min, max, value , is variable selected (1) or not (0)
pIMinMaxData->AddMeasurementErrorItem(0.0, 1.0, 1.0, 0);
// Special use for LIK_213, LIK_214 and LIK_217 to add Nuisance variables
// Fill min, max, value of nuisance variable, is variable selected (1) or not (0)
pIMinMaxData->AddLikelihoodItem(0.0, 1.0, 1.0, 0);
// ONLY FOR LIK_217
// Additional x-range values for PCHIP (Piecewise Cubic Hermite Interpolating Polynomial)
// Fill x-range with non-decreasing data
pIMinMaxData->SetLVInterpolationValues(0, 1, 2, 3);
return S_OK
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIMinMaxData pointer
if(pIMinMaxData == nullptr)
{
return E_INVALIDARG;
}
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetNormalData
110
DREAM Suite 1
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar
// Interface to DREAM input parameters
, IDreamDataNormal* pINormalData
// Interface to normal distribution data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define mean vector and Covariance matrix data for initial
NORMAL sampling distribution.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Fill mean vector data
for(size_t iIndex = 0; iIndex < 10; iIndex++)
{
pINormalData->AddItem(0);
}
// Covariance matrix diagonal value
pINormalData->SetCovarianceDiagonalValue(5.0);
return S_OK
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pINormalData pointer
if(pINormalData == nullptr)
{
return E_INVALIDARG;
}
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetPriorData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataPrior* pIPriorData
// Interface to prior distribution data
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define data for INITIAL PRIOR and PRIOR sampling distribution.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Fill prior univariate data
pIPriorData->AddUnivariateItem(0.067, 0.006, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.445, 0.009, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-2.310, 0.060, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.223, 0.011, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-1.160, 0.270, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(0.390, 1.470, eDistributionUnivariate::eUnivariate_Normal);
pIPriorData->AddUnivariateItem(-250.0, -50.0, eDistributionUnivariate::eUnivariate_Uniform);
// OR
111
DREAM Suite 1
// Fill prior multivariate normal data
vector<double> mean(m_dimension, -2);
matrix<double> cov = identity_matrix<double>(m_dimension);
CDreamVector cmean(mean);
CDreamMatrix ccov(cov);
pIPriorData->SetMultivariateNormalItem(&cmean, &ccov);
return S_OK
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetPriorDataCustom
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamMatrix* x
// Input matrix
, IDreamMatrix* PR
// Output matrix
, ePriorDistrib callType
// Type of call of this function
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define CUSTOM distribution type of prior distribution instead of
GetPriorData() function. This function can be called in two different situations specified by the
callType parameter:
A) during initialization of dream solver (callType = ePriorInitialize)
B) during DREAM calculation (callType = ePriorCalculate)
The initial state (callType = ePriorInitialize) is usually defined by a function generating
random numbers (e.g. PR = NormRnd(mu, sigma)), while the second type of call (callType =
ePriorCalculate)
typically uses a function dependent on x-matrix (e.g. PR = NormPdf(x, mu, sigma)).
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION (Example07):
// Temporary matrices used for calculations
matrix<double> tmpx(x->_rowCount, x->_colCount);
// Copy data
for(int iRow = 0; iRow < x->_rowCount; iRow++)
{
for(int iCol = 0; iCol < x->_colCount; iCol++)
{
tmpx(iRow, iCol) = x->_data[iRow * x->_colCount + iCol];
}
}
matrix<double> tmpPR(PR->_rowCount, PR->_colCount);
size_t d = tmpPR.size2();
size_t N = tmpPR.size1();
vector<double> mu(d);
mu(0) = 0.067;
mu(1) = 0.445;
mu(2) = -2.310;
mu(3) = 0.223;
mu(4) = -1.160;
mu(5) = 0.390;
mu(6) = -250.0;
vector<double> sigma(d);
112
DREAM Suite 1
sigma(0)
sigma(1)
sigma(2)
sigma(3)
sigma(4)
sigma(5)
sigma(6)
=
=
=
=
=
=
=
0.006;
0.009;
0.060;
0.011;
0.270;
1.470;
-50.0;
enum ePriorFunction { NormPdf, UnifPdf, NormRnd, UnifRnd
vector<ePriorFunction> funcType(d);
funcType(0) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(1) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(2) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(3) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(4) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(5) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::NormRnd;
funcType(6) = callType == ePriorDistrib::ePriorCalculate
ePriorFunction::UnifRnd;
double dRandValue = 0.0;
for(size_t i = 0; i < d; i++)
{
for(size_t j = 0; j < N; j++)
{
// Compute prior density of proposal
switch(funcType(i))
{
case(ePriorFunction::NormPdf):
{
dRandValue = CDreamMath<double>::NormPdf(tmpx(j,
tmpPR(j, i) = max(dRandValue, 1.e-299);
break;
}
case(ePriorFunction::UnifPdf):
{
dRandValue = CDreamMath<double>::UnifPdf(tmpx(j,
tmpPR(j, i) = max(dRandValue, 1.e-299);
break;
}
case(ePriorFunction::NormRnd):
{
tmpPR(j, i) = CDreamMath<double>::NormRnd(mu(i),
break;
}
case(ePriorFunction::UnifRnd):
{
tmpPR(j, i) = CDreamMath<double>::UnifRnd(mu(i),
break;
}
default:
{
assert(false);
}
}
}
}
};
? ePriorFunction::NormPdf :
? ePriorFunction::NormPdf :
? ePriorFunction::NormPdf :
? ePriorFunction::NormPdf :
? ePriorFunction::NormPdf :
? ePriorFunction::NormPdf :
? ePriorFunction::UnifPdf :
i), mu(i), sigma(i));
i), mu(i), sigma(i));
sigma(i));
sigma(i));
// Replace content of res by tmp values
for(int iRow = 0; iRow < PR->_rowCount; iRow++)
{
for(int iCol = 0; iCol < PR->_colCount; iCol++)
{
PR->_data[iRow * PR->_colCount + iCol] = tmpPR(iRow, iCol);
}
}
*/
//////////////////////////////////////////////////////////////////////////////////////////////////
113
DREAM Suite 1
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetBayesData
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, IDreamDataABC* pIBayesCompData // Interface to Approximate Bayesian Computation data
, BSTR strModelDataDir
// Directory with permanent data of the model
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to define summary metrics vector (S), corresponding ABC Epsilon
vector and distance function which can be used for likelihood LIK_321 and LIK_322.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Set ABC distance function type
pIBayesCompData->SetABCFunctionType(eDistanceFunction::eSqrt_1Over20_MultiplyBy_Sum_AminusBSquared);
// Scalar/vector with summary metrics (S) and ABC Epsilon data
vector<double> eps(m_d, 0.025);
vector<double> rnd(m_d);
Rand(rnd);
vector<double> sumMetrics = m_min + element_prod(rnd, m_max - m_min);
pIBayesCompData->AddComputationData((int)sumMetrics.size(), &sumMetrics[0], &eps(0));
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Always check pIBayesCompData pointer
if(pIBayesCompData == nullptr)
{
return E_INVALIDARG;
}
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::PrepareWorkDir
//------------------------------------------------------------------------------------------------(
BSTR strSourceDir,
// Path to the permanent "Model\Data" directory
BSTR strDestinationDir // Path to the temporary directory designated for the current thread
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to prepare files in special directories needed for DREAM
multi-core calculations. These folders may be required by some models working with data
in external files. Each calculation thread should then have its files in a designated
directory to prevent sharing violation problems.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will continue)
E_FAIL - Operation failed (program will stop)
*/
114
DREAM Suite 1
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::EvaluateProposal
//------------------------------------------------------------------------------------------------(
IDreamInputParViewer* pInputPar // Interface to DREAM input parameters
, int iSim
// input parameter (i-th simulation / Markov chain)
, IDreamMatrix* x
// input matrix (m_NumberOfMarkovChains x m_ProblemDimension)
, IDreamMatrix* res
// output matrix (Data_Dimension x m_NumberOfMarkovChains)
, BSTR strWorkingDir
// path to the current working directory (for current calculation thread)
, BSTR strModelDataDir // path to the permanent directory with model data
, BSTR strModelBinDir
// path to the permanent directory with model executables
)
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
The purpose of this function is to evaluate the current proposal (i.e. one single step
of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes
the likelihood (or log-likelihood or the residual vector to be compared with the measurement
- see the technical manual) for iSim-th row of input matrix "x" and returns the result
in output matrix "res".
Parameter iSim is from interval <0, IDreamInputParams::GetNumberOfMarkovChains() - 1>.
If pInputPar->GetVectorization() == eVectorization::eVectYes, then iSim = 0 and all proposals
(for all Markov chains) should be evaluated in one step, i.e. during one call of this function.
Data_Dimension:
*************************************************************************************************
** ROW DIMENSION OF "RES" OUTPUT MATRIX:
**
**
if(calibration_data_avaliable && bayes_diagnostic && summary_metrics_data)
**
{
**
data_dimension = calibration_data_count + summary_metrics_data_count
**
}
**
else if(calibration_data_avaliable && (!bayes_diagnostic || !summary_metrics_data))
**
{
**
data_dimension = calibration_data_count
**
}
**
else if(summary_metrics_data_avaliable)
**
{
**
data_dimension = summary_metrics_data_count
**
}
**
else if(calibration_data_avaliable && summary_metrics_data_avaliable)
**
{
**
data_dimension = calibration_data_count > summary_metrics_data_count ?
**
calibration_data_count : summary_metrics_data_count
**
}
**
else
**
{
**
data_dimension = 1
**
}
*************************************************************************************************
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented (program will stop - this function must be implemented)
E_FAIL - Operation failed (program will stop)
EXAMPLE OF IMPLEMENTATION:
// Copy data of iSim-row of x-matrix to BOOST vector type
vector<double> ix(x->_colCount);
for(int iCol = 0; iCol < x->_colCount; iCol++)
{
ix(iCol) = x->_data[iSim * x->_colCount + iCol];
}
115
DREAM Suite 1
// Calculate log-likelihood of vector ix and store the result in vector tmpLog
vector<double> tmpLog(res->_rowCount);
for(int iRow = 0; iRow < res->_rowCount; iRow++)
{
tmpLog(iRow) = ... (F(ix))
}
// Replace content of res by calculated values
for(int iRow = 0; iRow < res->_rowCount; iRow++)
{
res->_data[iRow * res->_colCount + iSim] = tmpLog(iRow);
}
return S_OK;
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// TODO: Implement this function and return S_OK
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::OnCalculationFinished()
//------------------------------------------------------------------------------------------------///////////////////////////////////////////////////////////////////////////////////////////////////
/*
DESCRIPTION:
This function is called after finishing the calculation to perform possible cleanup, etc.
RETURN VALUE:
S_OK
- Operation successful
S_FALSE - Function not implemented
E_FAIL - Operation failed
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Not needed/implemented
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetLastError(BSTR* strErrorText)
//------------------------------------------------------------------------------------------------{
// If there is an error, set the description and return S_OK. For example :
// std::wstring m_MyLastError = ...
// *strErrorText = SysAllocString(m_MyLastError.c_str());
// return (SysStringLen(*strErrorText)>0) ? S_OK : S_FALSE;
// If there is no error, return S_FALSE
return S_FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of COM IUnknown interface
///////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CDreamEvaluator::QueryInterface(const IID& iid, void** ppv)
//------------------------------------------------------------------------------------------------/*
Implementation of standard COM interface. No changes needed.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Check parameters
if(ppv == nullptr)
{
// Invalid argument
return E_INVALIDARG;
}
116
DREAM Suite 1
// Always set pointer to nullptr
*ppv = nullptr;
if(InlineIsEqualGUID(iid, IID_IUnknown) || InlineIsEqualGUID(iid, IID_IDreamEvaluator))
{
// Return pointer to IDreamSolver interface
*ppv = static_cast<IDreamEvaluator*>(this);
}
else
{
// Unimplemented interface
*ppv = nullptr;
return E_NOINTERFACE;
}
// Increment reference count
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
//------------------------------------------------------------------------------------------------ULONG STDMETHODCALLTYPE CDreamEvaluator::AddRef()
//------------------------------------------------------------------------------------------------/*
Implementation of standard COM interface. No changes needed.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Increment reference count
return ::InterlockedIncrement(&m_cRef);
}
//------------------------------------------------------------------------------------------------ULONG STDMETHODCALLTYPE CDreamEvaluator::Release()
//------------------------------------------------------------------------------------------------/*
Implementation of standard COM interface. No changes needed.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Decrement reference count
if(::InterlockedDecrement(&m_cRef) == 0)
{
// Object is not referenced, it is safe to delete it
delete this;
return 0;
}
// Return actual reference count
return m_cRef;
}
6.2.3 TestApp.h
///////////////////////////////////////////////////////////////////////////////////////////////////
// DreamTestApp.h
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once;
///////////////////////////////////////////////////////////////////////////////////////////////////
// CCalcObserver
class CCalcObserver : public IDreamObserver
{
public:
/// <summary>Constructor</summary>
CCalcObserver();
CCalcObserver(_bstr_t path);
/// <summary>Destructor</summary>
virtual ~CCalcObserver();
117
DREAM Suite 1
/// <summary>Print logged messages</summary>
void PrintMessages() const;
/// <summary>Returs number of errors</summary>
int GetNoOfErrors() const {return m_iNoOfErrors;}
/// <summary>Returs number of warnings</summary>
int GetNoOfWarnings() const {return m_iNoOfWarnings;}
/// <summary>Adds new message to log</summary>
virtual HRESULT STDMETHODCALLTYPE OnLogMessage(BSTR strLogMessage) override;
/// <summary>Provides info about calculation error</summary>
virtual HRESULT STDMETHODCALLTYPE OnError(IDreamErrorInfo* pErrorInfo) override;
/// <summary>Set current evaluation step</summary>
virtual HRESULT STDMETHODCALLTYPE SetCurrentStep(float fStep) override;
/// <summary>Set convergence information</summary>
virtual HRESULT STDMETHODCALLTYPE SetConvergenceInfo(float fInfo) override;
/// <summary>Called after the calculation was terminated by user</summary>
virtual HRESULT STDMETHODCALLTYPE OnCalculationTerminatedByUser() override;
/// <summary>Called after finishing the calculation</summary>
virtual HRESULT STDMETHODCALLTYPE OnCalculationFinished() override;
/// <summary>Called before exporting output data</summary>
virtual HRESULT STDMETHODCALLTYPE OnPreparingOutputData() override;
/// <summary>Was calculation terminated by user? Yes (S_OK) or not (S_FALSE)</summary>
virtual HRESULT STDMETHODCALLTYPE CalculationTerminatedByUser() override;
/// <summary>IUnknown implementation</summary>
virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid,void** ppv) override;
virtual ULONG STDMETHODCALLTYPE AddRef() override;
virtual ULONG STDMETHODCALLTYPE Release() override;
private:
/// <summary>Log file name</summary>
_bstr_t m_LogFile;
/// <summary>Current step</summary>
int
m_iCurrentStep;
/// <summary>Convergence info</summary>
float m_fConvergenceInfo;
/// <summary>Reference counter</summary>
long m_cRef;
/// <summary>Number of errors</summary>
int
m_iNoOfErrors;
/// <summary>Number of warnings</summary>
int
m_iNoOfWarnings;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// CDreamErrorInfo
class CDreamErrorInfo : public IDreamErrorInfo
{
public:
/// <summary>Constructor</summary>
CDreamErrorInfo() {}
/// <summary>Destructor</summary>
virtual ~CDreamErrorInfo() {}
int GetErrID() const { return _errorID; }
int GetErrType() const { return _type; }
BSTR GetErrDescription() const { return _errorDesc; }
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Struct for example info
struct CExample
{
const wchar_t* m_strName;
const wchar_t* m_strText;
};
118
DREAM Suite 1
///////////////////////////////////////////////////////////////////////////////////////////////////
// Help functions
/// <summary>Get user's choice - a number from interval <0,N></summary>
int GetUserChoice(std::wstring wsPromptLine, int iMinNo, int iMaxNo);
/// <summary>Single handler - interrupts the calculation after Ctrl+C</summary>
BOOL SignalHandler(DWORD fdwCtrlType);
/// <summary>Prints text to console using UTF8</summary>
void PrintMessageUTF8(const std::wstring sLine);
///////////////////////////////////////////////////////////////////////////////////////////////////
6.2.4 TestApp.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// TestApp.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "testapp.h"
#include
#include
#include
#include
<iostream>
<limits>
<signal.h>
<boost/filesystem.hpp> // Dictionaries manipulation
#include
#include
#include
#include
<codecvt>
<fcntl.h>
<io.h>
<tchar.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// Global pointer to DreamSolver (used for signal handling)
static IDreamSolverPtr pTheOnlySolverInThisProcess = nullptr;
//------------------------------------------------------------------------------------------------int _tmain(int argc, _TCHAR* argv[])
//------------------------------------------------------------------------------------------------{
// Return value
HRESULT hRes = S_OK;
// Initialize COM subsystem
hRes = CoInitialize(NULL);
if(SUCCEEDED(hRes))
{
// Display info
wprintf(L"##################################################\n");
wprintf(L" DREAM Suite 1.0 - Plugin Test Application\n");
wprintf(L"##################################################\n");
wprintf(L"This application is intended for testing of DREAM plugin modules.\n");
int iRunTest = GetUserChoice(L"Do you want to run the test? (Yes/No = 1/0) : ", 0, 1);
if(iRunTest == 0)
return 0;
// We will assume that the current directory is "Project\Plugin\Bin"
_bstr_t bstrPluginBin = boost::filesystem::current_path().c_str();
// Path to the project directory
_bstr_t bstrExampleDir = bstrPluginBin;
bstrExampleDir += L"\\..\\..";
// Path to Evaluator DLL
_bstr_t bstrPluginDllName = L"$DREAM(ProjectName)";
_bstr_t bstrEvaluatorPath = bstrPluginBin;
bstrEvaluatorPath += L"\\";
bstrEvaluatorPath += bstrPluginDllName;
bstrEvaluatorPath += L".dll";
// Path to directory with Example data
_bstr_t bstrModelData = bstrExampleDir;
bstrModelData += L"\\Model\\Data";
119
DREAM Suite 1
// Path to directory with Example executables
_bstr_t bstrModelBin = bstrExampleDir;
bstrModelBin += L"\\Model\\Bin";
// Path to working directory
_bstr_t bstrWorkingDir = bstrExampleDir;
bstrWorkingDir += L"\\Temp\\Simulations\\Case1";
// Delete old working directory (to clear old files)
DrxDeleteDirectory(std::wstring(bstrWorkingDir));
// Create new working directory
DrxCreateDirectory(std::wstring(bstrWorkingDir));
// Calc observer for communication, logging...
CCalcObserver calcObserver(bstrWorkingDir);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Run DREAM Solver
/////////////////////////////////////////////////////////////////////////////////////////////////
bool bDisplayInfoAboutCalculationResults = false;
bool bLogInfoAvailable = false;
try
{
wprintf(L"Connecting DREAM Server...\n");
// Try to create DreamSolver in COM way
IDreamSolverPtr pSolver(__uuidof(IDreamSolver));
// Check if the creation of solver succeeded
if(pSolver != nullptr)
{
// Setup calculation observer
IDreamObserverPtr pIDreamCalcObserver = nullptr;
hRes = calcObserver.QueryInterface(IID_IDreamObserver, (void**)&pIDreamCalcObserver);
if(SUCCEEDED(hRes))
{
// Establish communication with solver
pSolver->AttachObserver(pIDreamCalcObserver);
bLogInfoAvailable = true;
}
// Set directories
pSolver->SetPath(ePathProjectDir, bstrExampleDir);
pSolver->SetPath(ePathModelData, bstrModelData);
pSolver->SetPath(ePathModelBin, bstrModelBin);
pSolver->SetPath(ePathPluginBin, bstrPluginBin);
pSolver->SetPath(ePathWorkingDir, bstrWorkingDir);
// Load plugin module
hRes = pSolver->LoadPlugin(bstrEvaluatorPath);
if(SUCCEEDED(hRes))
{
// Plugin info
CDreamPluginInfo pluginInfo;
pluginInfo.m_PluginType = ePluginType::ePlugin_DLL;
pluginInfo.m_strPluginName = bstrPluginDllName.copy();
pluginInfo.m_strModelDataDir = bstrModelData.copy();
// DREAM calculation parameters
CDreamCalcParams calcParamInfo;
// Convergence diagnostics?
calcParamInfo.m_SaveWithinChainDiagnostics = GetUserChoice(L"Do you want convergence
diagnostics? (Yes/No = 1/0) : ", 0, 1);
// Export Markov chains?
calcParamInfo.m_SaveMarkovChains = GetUserChoice(L"Do you want to export Markov chains?
No = 1/0) : ", 0, 1);
// Number of cores
calcParamInfo.m_NumberOfCPUs = GetUserChoice(L"Number of cores <1,20>, N > 1 = parallel
calculation : ", 1, 20);
calcParamInfo.m_RunParallel = calcParamInfo.m_NumberOfCPUs > 1 ? 1 : 0;
// Initialize the evaluator and all input data by values obtained from the evaluator
hRes = pSolver->InitEvaluatorDef(&pluginInfo, &calcParamInfo);
if(SUCCEEDED(hRes))
120
(Yes/
DREAM Suite 1
{
// Get pointer to evaluator
IDreamEvaluatorPtr pEvaluator = nullptr;
hRes = pSolver->GetEvaluator(&pEvaluator);
if(SUCCEEDED(hRes))
{
// Set signal handler (Ctrl+C)
pTheOnlySolverInThisProcess = pSolver;
SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalHandler, TRUE);
// Prepare the console to display calculation progress (%)
wprintf(L"Starting calculation...\n");
wprintf(L"(press Ctrl+C to interrupt the calculation)\n");
// Perform calculations
hRes = pSolver->StartCalculation();
if(SUCCEEDED(hRes))
{
wprintf(L"Calculation succeeded.\n");
}
else
{
// Check errors
_bstr_t message;
CDreamErrorInfo lastErrorInfo;
if(pSolver->GetLastError(&lastErrorInfo) != S_OK && lastErrorInfo.GetErrType() ==
eTypeError)
message = L"Calculation failed with error:\n" +
_bstr_t(lastErrorInfo.GetErrDescription()) + L"\n";
else
message = L"Calculation failed.\n";
wprintf(message);
}
bDisplayInfoAboutCalculationResults = true;
}
// Failed to get pointer to evaluator
else
{
wprintf(L"Failed to get pointer to evaluator.\n");
}
}
// Failed to initialize evaluator
else
{
wprintf(L"Failed to initialize evaluator.\n");
}
}
// Failed to load plugin module
else
{
wprintf(L"Failed to load plugin module.\n");
}
}
// Failed to create Dream solver
else
{
wprintf(L"Failed to create Dream solver.\n");
}
}
catch(_com_error& e)
{
// Dream solver creation failed
std::wstring message = L"COM error: ";
message += e.ErrorMessage();
message += L"\n";
PrintMessageUTF8(message);
}
// Clean-up
121
DREAM Suite 1
if(pTheOnlySolverInThisProcess != nullptr)
{
// Release solver interface - it must be done here, because it fails after CoUnitialize()
pTheOnlySolverInThisProcess = nullptr;
}
// Output information
if(bDisplayInfoAboutCalculationResults)
{
// Output files
wprintf(L"Output and log files are available in directory:\n" + bstrWorkingDir + L"\n");
}
// Error info
if(bLogInfoAvailable)
{
// Number of errors and warnings returned by the solver
int nErrors = calcObserver.GetNoOfErrors();
int nWarnings = calcObserver.GetNoOfWarnings();
wprintf(L"Number of errors: %d, Number of warnings: %d\n", nErrors, nWarnings);
// Print logged messages (errors, warnings, messages and calculation time)?
int iPrintLogInfo = GetUserChoice(L"Do you want to display log-file content? (Yes/No = 1/0) : ",
0, 1);
if(iPrintLogInfo == 1)
{
wprintf(L"Log file contents:\n");
calcObserver.PrintMessages();
}
}
// Clean-up COM services
CoUninitialize();
}
// Wait for ENTER
std::wcin.ignore(1024, '\n');
std::cout << "\nPress Enter to continue...";
std::wcin.get();
// Return result
return hRes;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CCalcObserver
//------------------------------------------------------------------------------------------------CCalcObserver::CCalcObserver()
//------------------------------------------------------------------------------------------------: m_cRef(1)
, m_iCurrentStep(0)
, m_fConvergenceInfo(0.0f)
, m_iNoOfErrors(0)
, m_iNoOfWarnings(0)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Path to logfile
m_LogFile = boost::filesystem::current_path().c_str();
m_LogFile += "\\DREAM_Out_LogObs.txt";
}
//------------------------------------------------------------------------------------------------CCalcObserver::CCalcObserver(_bstr_t path)
//------------------------------------------------------------------------------------------------: m_cRef(1)
, m_iCurrentStep(0)
, m_fConvergenceInfo(0.f)
, m_iNoOfErrors(0)
, m_iNoOfWarnings(0)
///////////////////////////////////////////////////////////////////////////////////////////////////
{
// Path to logfile
m_LogFile = path;
122
DREAM Suite 1
m_LogFile += "\\DREAM_Out_LogObs.txt";
}
//------------------------------------------------------------------------------------------------CCalcObserver::~CCalcObserver()
//------------------------------------------------------------------------------------------------{
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::OnLogMessage(BSTR strLogMessage)
//------------------------------------------------------------------------------------------------{
// Use stream to log messages to a file
std::wofstream fs(m_LogFile.GetBSTR(), std::ofstream::out | std::ofstream::app);
std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
fs.imbue(loc);
// Write message to stream
fs << strLogMessage << L"\n";
// Write
fs.flush();
fs.close();
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::OnError(IDreamErrorInfo* pErrorInfo)
//------------------------------------------------------------------------------------------------{
// Check input parameter
if(pErrorInfo == nullptr)
{
return E_INVALIDARG;
}
// Use stream to log messages to a file
std::wofstream fs(m_LogFile.GetBSTR(), std::ofstream::out | std::ofstream::app);
// String for message
std::wstring message;
if(pErrorInfo->_type == eTypeWarning)
{
message = L"Warning No. ";
m_iNoOfWarnings++;
}
else
{
message = L"Error No. ";
m_iNoOfErrors++;
}
// Write message to stream
fs << message << pErrorInfo->_errorID << " - " << pErrorInfo->_errorDesc << "\n";
// Write
fs.flush();
fs.close();
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::SetCurrentStep(float fStep)
//------------------------------------------------------------------------------------------------{
m_iCurrentStep = (int)fStep;
std::cout << "Finished: " << m_iCurrentStep << " %
" << "\r";
return S_OK;
}
123
DREAM Suite 1
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::SetConvergenceInfo(float fInfo)
//------------------------------------------------------------------------------------------------{
m_fConvergenceInfo = fInfo;
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::OnCalculationTerminatedByUser()
//------------------------------------------------------------------------------------------------{
// Use stream to write info to a file
std::wofstream fs(m_LogFile.GetBSTR(), std::ofstream::out | std::ofstream::app);
// Write message to stream
fs << "Calculation was terminated by user. Please wait..." << "\n";
// Write
fs.flush();
fs.close();
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::CalculationTerminatedByUser()
//------------------------------------------------------------------------------------------------{
// In this application, calculation is terminated directly by calling
// pTheOnlySolverInThisProcess->BreakCalculation();
// Terminating the calculation via observer is important when the calculation runs
// in a worker thread and solver cannot be accessed from GUI.
return S_FALSE;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::OnPreparingOutputData()
//------------------------------------------------------------------------------------------------{
wprintf(L"Calculation finished, preparing output data...\n");
return S_OK;
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::OnCalculationFinished()
//------------------------------------------------------------------------------------------------{
// Use stream to write info to a file
std::wofstream fs(m_LogFile.GetBSTR(), std::ofstream::out | std::ofstream::app);
// Write message to stream
fs << "Calculation finished." << "\n";
// Write
fs.flush();
fs.close();
return S_OK;
}
//------------------------------------------------------------------------------------------------void CCalcObserver::PrintMessages() const
//------------------------------------------------------------------------------------------------{
// Get messages from the log file
_bstr_t ff = m_LogFile;
std::wifstream fs(ff.GetBSTR(), std::ofstream::in | std::ofstream::app);
std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
fs.imbue(loc);
// Print all messages to std output (convert to UTF8)
UINT oldcp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
124
DREAM Suite 1
std::wstring wsLine;
while (std::getline(fs, wsLine))
{
wsLine += L"\n";
std::string utf8str = DrxWStr2Str(wsLine);
printf(utf8str.c_str());
}
fs.close();
SetConsoleOutputCP(oldcp);
}
//------------------------------------------------------------------------------------------------HRESULT STDMETHODCALLTYPE CCalcObserver::QueryInterface(const IID& iid, void** ppv)
//------------------------------------------------------------------------------------------------{
// Check parameters
if(ppv == nullptr)
{
// Invalid argument
return E_INVALIDARG;
}
// Always set pointer to nullptr
*ppv = nullptr;
if(InlineIsEqualGUID(iid, IID_IUnknown) || InlineIsEqualGUID(iid, IID_IDreamObserver))
{
// Return pointer to IDreamObserver interface
*ppv = static_cast<IDreamObserver*>(this);
}
else
{
// Unimplemented interface
*ppv = nullptr;
return E_NOINTERFACE;
}
// Increment reference count
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
//------------------------------------------------------------------------------------------------ULONG STDMETHODCALLTYPE CCalcObserver::AddRef()
//------------------------------------------------------------------------------------------------{
// Increment reference count
return ::InterlockedIncrement(&m_cRef);
}
//------------------------------------------------------------------------------------------------ULONG STDMETHODCALLTYPE CCalcObserver::Release()
//------------------------------------------------------------------------------------------------{
// Decrement reference count
if(::InterlockedDecrement(&m_cRef) == 0)
{
// Object is not referenced, it is safe to delete it
delete this;
return 0;
}
// Return actual reference count
return m_cRef;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Help functions
//------------------------------------------------------------------------------------------------BOOL SignalHandler(DWORD fdwCtrlType)
//------------------------------------------------------------------------------------------------// Signal handler - Ctrl+C
125
DREAM Suite 1
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal
case CTRL_C_EVENT:
{
if(pTheOnlySolverInThisProcess != nullptr)
{
pTheOnlySolverInThisProcess->BreakCalculation();
wprintf(L"Calculation interrupted by user!\n");
wprintf(L"Terminating process...\n");
}
return TRUE;
}
default:
return FALSE;
}
}
//------------------------------------------------------------------------------------------------int GetUserChoice(std::wstring wsPromptLine, int iMinNo, int iMaxNo)
//------------------------------------------------------------------------------------------------// Get user's choice (an integer number from interval <iMinNo, iMaxNo>)
{
int iUserChoice = -1;
do
{
// Display the prompt line
wprintf(wsPromptLine.c_str());
// Read user's input
if(scanf(" %d", &iUserChoice) > 0)
{
// Check whether the number is correct
if(iUserChoice >= iMinNo && iUserChoice <= iMaxNo)
return iUserChoice;
}
// Failed
wprintf(L"Incorrect input.\n");
// Needed
getchar();
} while (1);
// Wrong choice
return -1;
}
//------------------------------------------------------------------------------------------------void PrintMessageUTF8(const std::wstring sLine)
//------------------------------------------------------------------------------------------------{
// Print a message converted to UTF8
UINT oldcp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
std::string utf8str = DrxWStr2Str(sLine);
printf(utf8str.c_str());
SetConsoleOutputCP(oldcp);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
6.3 Interfaces
The documentation of COM interfaces contains just copies of corresponding IDL code with short
descriptions in the "helpstring" items. A more detailed description can be found in the plugin source code
template or demo in examples.
6.3.1 IDreamInputParViewer
126
DREAM Suite 1
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamInputParViewer
[
object,
uuid(E895898B-5DA1-4E74-B636-7991FCF85396),
local,
helpstring("IDreamInputParViewer - reader interface to DreamParams"),
pointer_default(unique)
]
interface IDreamInputParViewer : IUnknown
{
[helpstring("Dimensionality target distribution d")]
int GetProblemDimension();
[helpstring("Number of Markov chains N")]
int GetNumberOfMarkovChains();
[helpstring("Number of generations T")]
int GetNumberOfGenerations();
[helpstring("Choice of likelihood function")]
eLikelihood GetLikelihoodChoice();
[helpstring("Number of crossover values nCR")]
int GetNumberOfCrossoverValues();
[helpstring("Number chain pairs for proposal delta")]
int GetNumberChainPairs();
[helpstring("Random error for ergodicity lambda")]
double GetRandomErrorForErgodicity();
[helpstring("Randomization zeta")]
double GetRandomization();
[helpstring("Test to detect outlier chains")]
eOutlierTest GetOutlierTest();
[helpstring("Probability of jump rate of 1 pJumpRate_one")]
double GetProbabilityOfJumprate();
[helpstring("Adapt selection prob. crossover pCR")]
int GetAdaptSelection();
[helpstring("Each Tth sample is stored thinning")]
int GetThinnigSampleToStore();
[helpstring("GLUE likelihood parameter")]
int GetGlueLikelihood();
[helpstring("Diagnostic Bayes? Values: 1=true, 0=false")]
int GetBayesDiagnostic();
[helpstring("Scaling factor of built-in jump rate beta0")]
double GetScalingFactorOfJumpRate();
[helpstring("Bayesian Model Averaging (BMA) with hydrologic data. Number of different models")]
int GetNumberOfDifferentModelsBMA();
[helpstring("Model vectorization type")]
eVectorization GetVectorization();
[helpstring("Number of steps after which the convergence is checked and updated")]
int GetSteps();
[helpstring("Initial sampling distribution type")]
eInitDistrib GetInitialDistribution();
[helpstring("Boundary handling type")]
eBoundHandling GetBoundHandling();
[helpstring("Use prior distribution even for m_InitialDistribution != eInitPrior? Values: 1/0")]
int GetUsePriorDistribution();
127
DREAM Suite 1
[helpstring("Prior distribution type")]
ePriorType GetPriorDistributionType();
[helpstring("Evaluator can run in parallel?")]
eParallelMode GetParallelMode();
[helpstring("Parameter p is locked and cannot be changed in GUI. Values: 1/0 = yes/no")]
int IsParLocked([in] eDreamInputPar p);
};
6.3.2 IDreamInputParams
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamInputParams
[
object,
uuid(DF761E08-C84F-4AF4-8E86-77FEEE8B046A),
local,
helpstring("IDreamInputParams - reader/writer interface to DreamParams"),
pointer_default(unique)
]
interface IDreamInputParams : IDreamInputParViewer
{
[helpstring("Dimensionality target distribution d")]
HRESULT SetProblemDimension([in] int problemDimension, [in] int iLock);
[helpstring("Number of Markov chains N")]
HRESULT SetNumberOfMarkovChains([in] int numberOfMarkovChains, [in] int iLock);
[helpstring("Number of generations T")]
HRESULT SetNumberOfGenerations([in] int numberOfGenerations, [in] int iLock);
[helpstring("Choice of likelihood function")]
HRESULT SetLikelihoodChoice([in] eLikelihood likelihoodChoice, [in] int iLock);
[helpstring("Number of crossover values nCR")]
HRESULT SetNumberOfCrossoverValues([in] int numberOfCrossoverValues, [in] int iLock);
[helpstring("Number chain pairs for proposal delta")]
HRESULT SetNumberChainPairs([in] int numberChainPairs, [in] int iLock);
[helpstring("Random error for ergodicity lambda")]
HRESULT SetRandomErrorForErgodicity([in] double randomErrorForErgodicity, [in] int iLock);
[helpstring("Randomization zeta")]
HRESULT SetRandomization([in] double randomization, [in] int iLock);
[helpstring("Test to detect outlier chains")]
HRESULT SetOutlierTest([in] eOutlierTest outlierTest, [in] int iLock);
[helpstring("Probability of jump rate of 1 pJumpRate_one")]
HRESULT SetProbabilityOfJumprate([in] double probabilityOfJumprate, [in] int iLock);
[helpstring("Adapt selection prob. crossover pCR")]
HRESULT SetAdaptSelection([in] int adaptSelection, [in] int iLock);
[helpstring("Each Tth sample is stored thinning")]
HRESULT SetThinnigSampleToStore([in] int thinnigSampleToStore, [in] int iLock);
[helpstring("GLUE likelihood parameter")]
HRESULT SetGlueLikelihood([in] int glueLikelihood, [in] int iLock);
[helpstring("Diagnostic Bayes? Values: 1=true, 0=false")]
HRESULT SetBayesDiagnostic([in] int bayesDiagnostic, [in] int iLock);
[helpstring("Scaling factor of built-in jump rate beta0")]
HRESULT SetScalingFactorOfJumpRate([in] double scalingFactorOfJumpRate, [in] int iLock);
[helpstring("Bayesian Model Averaging (BMA) with hydrologic data. Number of different models")]
HRESULT SetNumberOfDifferentModelsBMA([in] int numberOfDifferentModelsBMA, [in] int iLock);
128
DREAM Suite 1
[helpstring("Model vectorization type")]
HRESULT SetVectorization([in] eVectorization vectorization, [in] int iLock);
[helpstring("Number of steps after which the convergence is checked and updated")]
HRESULT SetSteps([in] int steps, [in] int iLock);
[helpstring("Initial sampling distribution type")]
HRESULT SetInitialDistribution([in] eInitDistrib initialDistribution, [in] int iLock);
[helpstring("Boundary handling type")]
HRESULT SetBoundHandling([in] eBoundHandling boundHandling, [in] int iLock);
[helpstring("Use prior distribution even for m_InitialDistribution != eInitPrior? Values: 1/0")]
HRESULT SetUsePriorDistribution([in] int usePriorDistribution, [in] int iLock);
[helpstring("Prior distribution type")]
HRESULT SetPriorDistributionType([in] ePriorType priorDistributionType, [in] int iLock);
[helpstring("Evaluator can run in parallel?")]
HRESULT SetParallelMode([in] eParallelMode parallelMode, [in] int iLock);
[helpstring("Lock/unlock parameter p to prevent changes in GUI. Values of p: 1/0 = lock/unlock")]
HRESULT LockParameter([in] eDreamInputPar p, [in] int iLock);
};
6.3.3 IDreamDataMinMax
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataMinMax
[
object,
uuid(8421C9F5-51EE-44E2-A8AA-BA6712A2FD2F),
local,
helpstring("IDreamDataMinMax - interface to min/max data"),
pointer_default(unique)
]
interface IDreamDataMinMax : IUnknown
{
[helpstring("Min/Max values will be defined in solver? Values: 1/0")]
HRESULT SetMinMaxValuesDefinedInSolver([in] int value);
[helpstring("Add new MinMaxItem")]
HRESULT AddItem([in] double minimum, [in] double maximum);
[helpstring("Add new MinMaxItem")]
HRESULT AddExtendedItem([in] double minimum, [in] double maximum, [in] double value,
[in] int selected);
[helpstring("Add new MinMaxItem for measurement error")]
HRESULT AddMeasurementErrorItem([in] double minimum, [in] double maximum);
[helpstring("Add new MinMaxItem for Likelihood")]
HRESULT AddLikelihoodItem([in] double minimum, [in] double maximum, [in] double value,
[in] int selected);
[helpstring("Additional x-range values for PCHIP (Piecewise Cubic Hermite Interpol. Polynom.)")]
HRESULT SetLVInterpolationValues([in] double a, [in] double b, [in] double c, [in] double d);
};
6.3.4 IDreamDataNormal
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataNormal
[
object,
uuid(B5A5CAA7-922E-414F-A1B8-4076BF85C879),
local,
129
DREAM Suite 1
helpstring("IDreamDataNormal - interface to normal data"),
pointer_default(unique)
]
interface IDreamDataNormal : IUnknown
{
[helpstring("Add new MuItem")]
HRESULT AddMeanItem([in] double mu);
[helpstring("Set diagonal value for covariance matrix")]
HRESULT SetCovarianceDiagonalValue([in] double diagonalValue);
[helpstring("Set diagonal values for covariance matrix")]
HRESULT SetCovarianceDiagonalVector([in] int nCount, [in] const double* pValues);
};
6.3.5 IDreamDataPrior
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataPrior
[
object,
uuid(3D4B197C-184F-4EC2-AC06-4D3ECA76156D),
local,
helpstring("IDreamDataPrior - interface to prior data"),
pointer_default(unique)
]
interface IDreamDataPrior : IUnknown
{
[helpstring("Add new item of univariate distribution")]
HRESULT AddUnivariateItem([in] double mu, [in] double sigma, [in] eDistributionUnivariate type);
[helpstring("Set multivariate normal data")]
HRESULT SetMultivariateNormalData([in] IDreamVector* mean, [in] IDreamMatrix* covariance);
[helpstring("Set item for multivariate student T distribution")]
HRESULT SetMultivariateTdistributionData([in] IDreamMatrix* correlation,
[in] int degreeOfFreedom);
};
6.3.6 IDreamDataMeasurement
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataMeasurement
[
object,
uuid(DF82B5CD-0DBE-4C85-9415-0AE60DCC7F72),
local,
helpstring("IDreamDataMeasurement - interface to measurement data"),
pointer_default(unique)
]
interface IDreamDataMeasurement : IUnknown
{
[helpstring("Set measurement error function type")]
HRESULT SetMeasurementErrorType(eMeasureError type);
[helpstring("Add scalar/vector with corresponding calibration data and measurement errors")]
HRESULT AddMeasurementData([in] int nCount, [in] const double* pCalibrationValues,
[in] const double* pErrorValues);
};
6.3.7 IDreamDataABC
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataABC
[
object,
uuid(628FE6EF-2086-4A6B-BBFA-0961E6755A7F),
130
DREAM Suite 1
local,
helpstring("IDreamDataABC - interface to Approximate Bayesian Computation data"),
pointer_default(unique)
]
interface IDreamDataABC : IUnknown
{
[helpstring("Set ABC distance function type")]
HRESULT SetABCFunctionType([in] eDistanceFunction eABCParam);
[helpstring("Scalar/vector with summary metrics and ABC Epsilon data")]
HRESULT AddComputationData([in] int nCount, [in] double* pMetricsValues, [in] double* pEpsValues);
};
6.3.8 IDreamDataSource
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamDataSource
[
object,
uuid(63AACA44-751A-402B-A0EB-21DF33841473),
local,
helpstring("IDreamDataSource - interface to DREAM data source"),
pointer_default(unique)
]
interface IDreamDataSource : IUnknown
{
[helpstring("Get initial/default values of DREAM parameters")]
HRESULT GetInputParams([in, out] IDreamInputParams* pIDreamInputParams);
[helpstring("Get MinMax data")]
HRESULT GetMinMaxData([in] IDreamInputParViewer* pInputPar, [in] IDreamDataMinMax* pIMinMaxData);
[helpstring("Get Normal data")]
HRESULT GetNormalData([in] IDreamInputParViewer* pInputPar, [in] IDreamDataNormal* pINormalData);
[helpstring("Get Prior data")]
HRESULT GetPriorData([in] IDreamInputParViewer* pInputPar, [in] IDreamDataPrior* pIPriorData);
[helpstring("Get Custom Prior data")]
HRESULT GetPriorDataCustom([in] IDreamInputParViewer* pInputPar, [in] IDreamMatrix* x,
[out] IDreamMatrix* PR, [in] ePriorDistrib callType);
[helpstring("Get Measurement data")]
HRESULT GetMeasurementData([in] IDreamInputParViewer* pInputPar,
[in] IDreamDataMeasurement* pIMeasureData, [in] BSTR strModelDataDir);
[helpstring("Get Approximate Bayesian Computation data")]
HRESULT GetBayesData([in] IDreamInputParViewer* pInputPar, [in] IDreamDataABC* pIBayesCompData,
[in] BSTR strModelDataDir);
};
6.3.9 IDreamEvaluator
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamEvaluator
[
object,
uuid(FF5B9D3D-C36B-49BB-A0A2-E6818BB79367),
local,
helpstring("IDreamEvaluator - interface to DREAM Evaluator"),
pointer_default(unique)
]
interface IDreamEvaluator : IDreamDataSource
{
[helpstring("Plugin initialization - the first function called before using the evaluator")]
HRESULT InitPlugin([in] IDreamPluginInfo* pIPluginInfo);
[helpstring("Prepare a directory for parallel calculation")]
HRESULT PrepareWorkDir([in] BSTR strSourceDir, [in] BSTR strDestinationDir);
131
DREAM Suite 1
[helpstring("Prepare input data needed for the calculation. Called only once.")]
HRESULT InitData([in] IDreamPluginInfo* pIPluginInfo,
[in] IDreamInputParViewer* pIDreamInputParams);
[helpstring("Calculate the likelihood of each proposal during DREAM calculation")]
HRESULT EvaluateProposal([in] IDreamInputParViewer* pInputPar, [in] int sim,
[in] IDreamMatrix* x, [in, out] IDreamMatrix* res,
[in] BSTR strWorkingDir, [in] BSTR strModelDataDir,
[in] BSTR strModelBinDir);
[helpstring("Get description of the last error.")]
HRESULT GetLastError([out] BSTR* strErrorText);
[helpstring("Called after finishing the calculation.")]
HRESULT OnCalculationFinished();
};
6.3.10 IDreamObserver
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamObserver
[
object,
uuid(403837B3-648A-4EEB-ACDC-24209CEF3F31),
local,
helpstring("IDreamObserver - interface to calculation observer"),
pointer_default(unique)
]
interface IDreamObserver : IUnknown
{
[helpstring("Add new message to log")]
HRESULT OnLogMessage([in] BSTR strLogMessage);
[helpstring("Provides information about calculation error")]
HRESULT OnError([in] IDreamErrorInfo* pErrorInfo);
[helpstring("Progress evaluation step")]
HRESULT SetCurrentStep([in] float iStep);
[helpstring("Set convergence information")]
HRESULT SetConvergenceInfo([in] float fInfo);
[helpstring("Called after the calculation was terminated by user")]
HRESULT OnCalculationTerminatedByUser();
[helpstring("Called after finishing the calculation")]
HRESULT OnCalculationFinished();
[helpstring("Called before exporting output data")]
HRESULT OnPreparingOutputData();
[helpstring("Was the calculation terminated by user? Yes (S_OK) or not (S_FALSE)")]
HRESULT CalculationTerminatedByUser();
};
6.3.11 IDreamSolver
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamSolver
[
object,
uuid(BD3A86B4-805E-48D7-8366-A96191D9A0E6),
local,
helpstring("IDreamSolver - interface to DREAM Solver"),
pointer_default(unique)
]
interface IDreamSolver : IUnknown
{
[helpstring("Load plugin module")]
132
DREAM Suite 1
HRESULT LoadPlugin([in] BSTR strPluginPath);
[helpstring("Return pointer to evaluator")]
HRESULT GetEvaluator([out] IDreamEvaluator** pIEvaluator);
[helpstring("Initialize evaluator and set input data from external source")]
HRESULT InitEvaluatorExt([in] IDreamPluginInfo* pIPluginInfo,
[in] IDreamCalcSettings* pISettings,
[in] IDreamDataSource* pIDataSource);
[helpstring("Initialize evaluator and set default input data from the evaluator")]
HRESULT InitEvaluatorDef([in] IDreamPluginInfo* pIPluginInfo,
[in] IDreamCalcSettings* pISettings);
[helpstring("Attach calculation observer")]
HRESULT AttachObserver([in] IDreamObserver* pICalcObserver);
[helpstring("Start DREAM calculation")]
HRESULT StartCalculation();
[helpstring("Interrupt DREAM calculation")]
HRESULT BreakCalculation();
[helpstring("Return path of given type")]
BSTR GetPath([in] eDreamPath pathType);
[helpstring("Set path of given type")]
HRESULT SetPath([in] eDreamPath pathType, [in] BSTR strPath);
[helpstring("Return the last error")]
HRESULT GetLastError([in] IDreamErrorInfo* pErrorInfo);
};
6.4 Data structures
6.4.1 IDreamPluginInfo
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamPluginInfo
[helpstring("IDreamPluginInfo - Plugin information data structure")]
typedef struct IDreamPluginInfo
{
[helpstring("Path to model data directory")]
BSTR m_strModelDataDir;
[helpstring("Path to plugin script directory")]
BSTR m_strPluginScriptDir;
[helpstring("Path to plugin engine directory (MATLAB, etc.)")]
BSTR m_strEngineDir;
[helpstring("Plugin name (used for names of script files)")]
BSTR m_strPluginName;
[helpstring("Plugin type")]
ePluginType m_PluginType;
} IDreamPluginInfo;
6.4.2 IDreamCalcSettings
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamCalcSettings
[helpstring("IDreamCalcSettings - structure with calculation options")]
typedef struct IDreamCalcSettings
{
[helpstring("Save DREAM output during the run? Values: 1=true, 0=false")]
int m_SaveOutput;
133
DREAM Suite 1
[helpstring("Restart calculation?
int m_RestartRun;
Values: 1=true, 0=false")]
[helpstring("Save results in binary format? Values: 1=true, 0=false")]
int m_SaveResultsBin;
[helpstring("Save within-chain diagnostics? Values: 1=true, 0=false")]
int m_SaveWithinChainDiagnostics;
[helpstring("Save R_stat and MR_stat?
int m_SaveBetweenChainDiagnostics;
Values: 1=true, 0=false")]
[helpstring("Save Markov chains? Values: 1=true, 0=false")]
int m_SaveMarkovChains;
[helpstring("Save ParSet matrix result? Values: 1=true, 0=false")]
int m_SaveParSetMatrix;
[helpstring("Save model (function) simulations?
int m_SaveModelSimulations;
[helpstring("Save Summary statistics?
int m_SaveSummaryStatistics;
Values: 1=true, 0=false")]
Values: 1=true, 0=false")]
[helpstring("Number of used CPUs")]
int m_NumberOfCPUs;
[helpstring("Run in parallel?
int m_RunParallel;
} IDreamCalcSettings;
Values: 1=true, 0=false")]
6.4.3 IDreamErrorInfo
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamErrorInfo
[helpstring("Error info structure")]
typedef struct IDreamErrorInfo
{
[helpstring("Type - error/warning")]
eErrType _type;
[helpstring("Error ID")]
int _errorID;
[helpstring("Error description")]
BSTR _errorDesc;
} IDreamErrorInfo;
6.4.4 IDreamMatrix
///////////////////////////////////////////////////////////////////////////////////////////////////
// Interface IDreamMatrix
[helpstring("Matrix structure")]
typedef struct IDreamMatrix
{
[helpstring("Row count")]
int _rowCount;
[helpstring("Column count")]
int _colCount;
[helpstring("Matrix data")]
double* _data;
} IDreamMatrix;
6.4.5 IDreamVector
///////////////////////////////////////////////////////////////////////////////////////////////////
134
DREAM Suite 1
// Interface IDreamVector
[helpstring("Vector structure")]
typedef struct IDreamVector
{
[helpstring("Item count")]
int _itemCount;
[helpstring("Vector data")]
double* _data;
} IDreamVector;
6.5 Enumerators
6.5.1 eBoundHandling
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eBoundHandling
[helpstring("Boundary handling types.")]
typedef enum eBoundHandling
{
[helpstring("No boundary handling (see Technical Manual)")]
eBoundUnbounded,
[helpstring("\"Reflect\" boundary handling (see Technical Manual)")]
eBoundReflect,
[helpstring("\"Bound\" boundary handling (see Technical Manual)")]
eBoundBound,
[helpstring("\"Fold\" boundary handling (see Technical Manual)")]
eBoundFold
} eBoundHandling;
6.5.2 eDistanceFunction
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eABC Distance Function
[helpstring("ABC distance function between the simulated and observed summary statistics.")]
typedef enum eDistanceFunction
{
[helpstring("A-B distance function")]
eAminusB,
[helpstring("Abs(A-B) distance function")]
eAbsOfAminusB,
[helpstring("Sqrt(1/20*(A-B)^2)) distance function")]
eSqrt_1Over20_MultiplyBy_Sum_AminusBSquared
} eDistanceFunction;
6.5.3 eDistributionMultivariate
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDistributionMultivariate
[helpstring("Probability density function for Multivariate Prior type.")]
typedef enum eDistributionMultivariate
{
[helpstring("Multivariate Normal distribution")]
eMultivariate_Normal,
[helpstring("Multivariate T-distribution")]
eMultivariate_T
} eDistributionMultivariate;
135
DREAM Suite 1
6.5.4 eDistributionUnivariate
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDistributionUnivariate
[helpstring("Probability density function for Univariate Prior type.")]
typedef enum eDistributionUnivariate
{
[helpstring("Univariate F-distribution")]
eUnivariate_F,
[helpstring("Univariate Gamma-distribution")]
eUnivariate_Gamma,
[helpstring("Univariate Uniform-distribution")]
eUnivariate_Uniform,
[helpstring("Univariate T-distribution")]
eUnivariate_T,
[helpstring("Univariate Normal distribution")]
eUnivariate_Normal
} eDistributionUnivariate;
6.5.5 eDreamError
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDreamError
[helpstring("DREAM errors")]
typedef enum eDreamError
{
[helpstring("No error")]
ERR_NONE = 0,
[helpstring("No authorization to run DREAM Solver")]
ERR_NO_AUTHORIZATION,
[helpstring("Incorrect path to ePathProjectDir directory")]
ERR_INCORRECT_PROJECT_DIRECTORY,
[helpstring("Incorrect path to ePathModelBin directory")]
ERR_INCORRECT_MODELBIN_DIRECTORY,
[helpstring("Incorrect path to ePathModelData directory")]
ERR_INCORRECT_MODELDATA_DIRECTORY,
[helpstring("Incorrect path to ePathPluginBin directory")]
ERR_INCORRECT_PLUGINBIN_DIRECTORY,
[helpstring("Incorrect path to ePathWorkingDir directory")]
ERR_INCORRECT_WORKING_DIRECTORY,
[helpstring("Source directory does not exist or is not a directory")]
ERR_INCORRECT_SOURCE_DIRECTORY,
[helpstring("Access to working directory denied")]
ERR_INCORRECT_DESTINATION_DIRECTORY,
[helpstring("Unable to create destination directory")]
ERR_FILE_SYSTEM_ERROR,
[helpstring("File system error")]
ERR_WORKDIR_ACCES_DENIED,
[helpstring("Dimensionality should be larger than zero")]
ERR_INPUT_PARAMETER_D,
[helpstring("Evaluation cannot be run in parallel mode")]
ERR_INPUT_PARAMETER_PARALLEL,
136
DREAM Suite 1
[helpstring("Unknown choice of likelihood function")]
ERR_INPUT_PARAMETER_LIK,
[helpstring("Not enough data from input")]
ERR_INPUT_PARAMETER_LIK_217,
[helpstring("Wrong input data for LIK_217. Constants a, b, c, d must be non-decreasing")]
ERR_INPUT_PARAMETER_LIK_217_INTERPOLATION,
[helpstring("Not enough chains pairs for sampling")]
ERR_INPUT_PARAMETER_DELTA,
[helpstring("Not enough chains pairs for sampling")]
ERR_INPUT_PARAMETER_N,
[helpstring("Not enough generations")]
ERR_INPUT_PARAMETER_T,
[helpstring("At least one crossover value")]
ERR_INPUT_PARAMETER_NCR,
[helpstring("Thinning parameter should be positive")]
ERR_INPUT_PARAMETER_THINNING,
[helpstring("Jump rate multiplier should be larger than zero")]
ERR_INPUT_PARAMETER_BETA0,
[helpstring("GLUE likelihood variable larger than zero")]
ERR_INPUT_PARAMETER_GLUE,
[helpstring("Lambda have to be positive")]
ERR_INPUT_PARAMETER_LAMBDA,
[helpstring("Zeta have to be positive")]
ERR_INPUT_PARAMETER_ZETA,
[helpstring("Unit jump rate probability between 0 and 1")]
ERR_INPUT_PARAMETER_PUNITGAMMA,
[helpstring("Adaptation of crossover values should be true (default) or false")]
ERR_INPUT_PARAMETER_ADAPTPCR,
[helpstring("Sigma needs to be specified")]
ERR_INPUT_PARAMETER_LIKELIHOOD,
[helpstring("Latin hypercube sampling selected but minimum/maximum parameters not defined")]
ERR_INPUT_PARAMETER_INIT_DIST_LATIN,
[helpstring("Uniform initial sampling selected but minimum, maximum parameters not defined")]
ERR_INPUT_PARAMETER_INIT_DIST_UNIFORM,
[helpstring("Normal distribution selected to sample from but unknown mean, covariance")]
ERR_INPUT_PARAMETER_INIT_DIST_NORMAL_1,
[helpstring("Mean of normal distribution mu should be a row vector")]
ERR_INPUT_PARAMETER_INIT_DIST_NORMAL_2,
[helpstring("Covariance of normal distribution cov should be a square matrix")]
ERR_INPUT_PARAMETER_INIT_DIST_NORMAL_3,
[helpstring("Prior distribution selected but unknown prior array defined")]
ERR_INPUT_PARAMETER_INIT_DIST_PRIOR,
[helpstring("Dimension of univariate prior data mismatch")]
ERR_INPUT_PARAMETER_DIST_PRIOR_1,
[helpstring("Dimension of multivariate normal prior data mismatch")]
ERR_INPUT_PARAMETER_DIST_PRIOR_2,
[helpstring("Dimension of multivariate students T prior data mismatch")]
ERR_INPUT_PARAMETER_DIST_PRIOR_3,
[helpstring("Boundary handling is used but minimum, maximum parameter values not defined")]
ERR_INPUT_PARAMETER_BOUNDING,
137
DREAM Suite 1
[helpstring("Number of elements of field min, max should be equal to d")]
ERR_INPUT_PARAMETER_BOUNDING_INIT_DIST,
[helpstring("Field Y of measurement data has to be defined")]
ERR_INPUT_MEASURE_PARAM_Y,
[helpstring("Field S of measurement data has to be defined")]
ERR_INPUT_MEASURE_PARAM_S,
[helpstring("Sigma incorrect length")]
ERR_INPUT_MEASURE_PARAM_SIGMA_1,
[helpstring("At least one value of the specified Sigma is negative or zero")]
ERR_INPUT_MEASURE_PARAM_SIGMA_2,
[helpstring("Number of elements of epsilon does not match that of S")]
ERR_INPUT_SETTING_PARAM_EPSILON_1,
[helpstring("Value of epsilon should be larger than zero")]
ERR_INPUT_SETTING_PARAM_EPSILON_2,
[helpstring("Loading additional input data (MinMax/CovMu) failed")]
ERR_INPUT_LOAD_ADDITIONAL_DATA,
[helpstring("Loading measurement data failed")]
ERR_INPUT_LOAD_MEASUREMENT_DATA,
[helpstring("Diagnostic Bayes is allowed only for likelihood 11, 31, 32, 33, 34")]
ERR_INPUT_DIAGNOSTIC_BAYES,
[helpstring("Evaluation likelihood and log-likelihood failed")]
ERR_SOLVER_LIKELIHOOD_EVALUATION,
[helpstring("Unssuported model of CalcDensity")]
ERR_SOLVER_LIKELIHOOD_UNKNOWN,
[helpstring("Calculation of density failed")]
ERR_SOLVER_CALC_DENSITY,
[helpstring("Calculation of distance function failed")]
ERR_SOLVER_CALC_DISTANCE_FUNCTION_RHO,
[helpstring("Log-likelihood and simulation of regression model failed")]
ERR_SOLVER_SIMULATION_OF_REGRESSION_MODELS,
[helpstring("Implementation of likelihood function not available")]
ERR_SOLVER_NOT_IMPLEMENTED_LIKELIHOOD_FUNCTION,
[helpstring("Wrong Min/Max data dimension for measurement error function")]
ERR_SOLVER_MIN_MAX_FOR_ERROR_FUNCTION
} eDreamError;
6.5.6 eDreamInputPar
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDreamInputPar
[helpstring("DREAM Input parameters")]
typedef enum eDreamInputPar
{
[helpstring("Dimensionality target distribution d")]
eParProblemDimension,
[helpstring("Number of Markov chains N")]
eParNumberOfMarkovChains,
[helpstring("Number of generations T")]
eParNumberOfGenerations,
[helpstring("Choice of likelihood function")]
138
DREAM Suite 1
eParLikelihoodChoice,
[helpstring("Number of crossover values nCR")]
eParNumberOfCrossoverValues,
[helpstring("Number chain pairs for proposal delta")]
eParNumberChainPairs,
[helpstring("Random error for ergodicity lambda")]
eParRandomErrorForErgodicity,
[helpstring("Randomization zeta")]
eParRandomization,
[helpstring("Test to detect outlier chains")]
eParOutlierTest,
[helpstring("Probability of jump rate of 1 pJumpRate_one")]
eParProbabilityOfJumprate,
[helpstring("Adapt selection prob. crossover pCR")]
eParAdaptSelection,
[helpstring("Each Tth sample is stored thinning")]
eParThinnigSampleToStore,
[helpstring("GLUE likelihood parameter")]
eParGlueLikelihood,
[helpstring("Diagnostic Bayes? Values: 1=true, 0=false")]
eParBayesDiagnostic,
[helpstring("Scaling factor of built-in jump rate beta0")]
eParScalingFactorOfJumpRate,
[helpstring("Bayesian Model Averaging (BMA) with hydrologic data. Number of different models")]
eParNumberOfDifferentModelsBMA,
[helpstring("Model vectorization type")]
eParVectorization,
[helpstring("Number of steps after which the convergence is checked and updated")]
eParSteps,
[helpstring("Initial sampling distribution type")]
eParInitialDistribution,
[helpstring("Boundary handling type")]
eParBoundHandling,
[helpstring("Use prior distribution even for m_InitialDistribution != eInitPrior? Values: 1/0")]
eParUsePriorDistribution,
[helpstring("Prior distribution type")]
eParPriorDistributionType,
[helpstring("Evaluator can run in parallel?")]
eParParallelMode,
[helpstring("Dummy: number if input parameters")]
eParMax,
} eDreamInputPar;
6.5.7 eDreamPath
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDreamPath
[helpstring("Paths to subdirectories of a DREAM project.")]
typedef enum eDreamPath
{
[helpstring("Project directory, e.g. ...\\Projects\\Drm_Example07")]
ePathProjectDir,
139
DREAM Suite 1
[helpstring("Directory with model executables, e.g. ...\\Projects\\Drm_Example07\\Model\\Bin")]
ePathModelBin,
[helpstring("Directory with model data files, e.g. ...\\Projects\\Drm_Example07\\Model\\Data")]
ePathModelData,
[helpstring("Directory with plugin DLL, e.g. ...\\Projects\\Drm_Example07\\Plugin\\Bin")]
ePathPluginBin,
[helpstring("Working directory, e.g. ...\\Projects\\Drm_Example07\\Temp\\Case1")]
ePathWorkingDir,
[helpstring("Number of possible paths (not a path)")]
ePathMax,
} eDreamPath;
6.5.8 eDreamWarning
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eDreamWarning
[helpstring("DREAM warnings")]
typedef enum eDreamWarning
{
[helpstring("No warning")]
WAR_NONE = 1,
[helpstring("Parallel mode of evaluation is not recommended")]
WAR_INPUT_PARAMETER_PARALLEL,
[helpstring("Delta set rather large")]
WAR_INPUT_PARAMETER_DELTA,
[helpstring("Parameter N set rather large")]
WAR_INPUT_PARAMETER_N,
[helpstring("Parameter T set rather large")]
WAR_INPUT_PARAMETER_T,
[helpstring("Too many crossover values")]
WAR_INPUT_PARAMETER_NCR,
[helpstring("Parameter thinning set rather large")]
WAR_INPUT_PARAMETER_THINNING,
[helpstring("Parameter beta0 set rather large")]
WAR_INPUT_PARAMETER_BETA0,
[helpstring("Parameter GLUE set rather large")]
WAR_INPUT_PARAMETER_GLUE,
[helpstring("Parameter lambda set rather large")]
WAR_INPUT_PARAMETER_LAMBDA,
[helpstring("Parameter GLUE set rather large")]
WAR_INPUT_PARAMETER_ZETA,
[helpstring("Peirce will use r-values of N = 60")]
WAR_INPUT_PARAMETER_OUTLIER,
[helpstring("Thinning reduces length of the sampled chain")]
WAR_INPUT_PARAMETERS_T_THINNING_1,
[helpstring("Thinning reduces length of the sampled chain")]
WAR_INPUT_PARAMETERS_T_THINNING_2,
[helpstring("Likelihood function selected that contains nuisance variables")]
WAR_INPUT_PARAMETER_LIKELIHOOD_2,
[helpstring("Only a single calibration data observation is used")]
WAR_INPUT_MEASURE_PARAM_Y,
140
DREAM Suite 1
[helpstring("Only a single summary metric value is used")]
WAR_INPUT_MEASURE_PARAM_S,
[helpstring("ABC approach: Default value of epsilon will be used")]
WAR_INPUT_SETTING_PARAM_EPSILON_1,
[helpstring("If so desired you can use a different value of epsilon")]
WAR_INPUT_SETTING_PARAM_EPSILON_2,
[helpstring("Enough RAM memory to store model simulation")]
WAR_SOLVER_STORE_FX,
[helpstring("Can not allocate enough memory")]
WAR_SOLVER_ALLOC,
[helpstring("Model simulation variable fx is too large and can not be allocated in memory. Results
will not be avaliable.")]
WAR_SOLVER_MODEL_SIMULATION,
[helpstring("Wrong dimension of Bayesian Model Averaging (BMA). Bayesian Model Averaging will be
skiped.")]
WAR_SOLVER_BAYESIAN_MODEL_AVERAGING,
[helpstring("Be sure that function \"GetPriorDataCustom\" is implemented in Evaluator")]
WAR_INPUT_PARAMETER_DIST_PRIOR,
[helpstring("At least 200 iterations is needed for coda diagnostic.")]
WAR_OUTPUT_CODA_DIAGNOSTIC_200_ITERATIONS,
[helpstring("Finalization of outputs failed")]
WAR_OUTPUT_CODA_DIAGNOSTIC_GENERAL_PROBLEM,
[helpstring("Minimum draws for coda diagnostic is 50. Diagnostic will not be avaliable.")]
WAR_OUTPUT_CODA_DIAGNOSTIC_MIN_50_DRAWS
} eDreamWarning;
6.5.9 eErrType
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eErrType
[helpstring("DREAM error message types")]
typedef enum eErrType
{
[helpstring("No error - just information")]
eTypeNone,
[helpstring("No error - just a warning")]
eTypeWarning,
[helpstring("An error")]
eTypeError
} eErrType;
6.5.10 eInitDistrib
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eInitDistrib
[helpstring("Initial distribution types (initial state of of the Markov chain(s)).")]
typedef enum eInitDistrib
{
[helpstring("Uniform initial sampling")]
eInitUniform,
[helpstring("Latin initial sampling")]
eInitLatin,
[helpstring("Normal initial sampling")]
eInitNormal,
141
DREAM Suite 1
[helpstring("Prior initial sampling")]
eInitPrior
} eInitDistrib;
6.5.11 eLikelihood
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eLikelihood
[helpstring("Likelihood function types.")]
typedef enum eLikelihood
{
[helpstring("Lik=1, Likelihood, L(x|~Y)")]
LIK_101 = 0,
[helpstring("Lik=2, Log-likelihood, L(x|~Y)")]
LIK_102,
[helpstring("Lik=11, Gaussian likelihood: measurement error integrated out")]
LIK_211,
[helpstring("Lik=12, Gaussian likelihood: homos/heteroscedastic data error")]
LIK_212,
[helpstring("Lik=13, Gaussian likelihood: with AR-1 model of error residuals")]
LIK_213,
[helpstring("Lik=14, Generalized likelihood function")]
LIK_214,
[helpstring("Lik=15, Whittle's likelihood (spectral analysis)")]
LIK_215,
[helpstring("Lik=16, Laplacian likelihood: homos/heteroscedastic data error")]
LIK_216,
[helpstring("Lik=17, Skewed Student likelihood function")]
LIK_217,
[helpstring("Lik=21, Noisy ABC: Gaussian likelihood")]
LIK_321,
[helpstring("Lik=22, ABC: Boxcar likelihood")]
LIK_322,
[helpstring("Lik=23, Limits of acceptability")]
LIK_323,
[helpstring("Lik=31, Inverse error variance with shaping factor")]
LIK_431,
[helpstring("Lik=32, Nash and Sutcliffe efficiency with shaping factor")]
LIK_432,
[helpstring("Lik=33, Exponential transform error variance with shaping factor")]
LIK_433,
[helpstring("Lik=34, Sum of absolute error residuals")]
LIK_434,
[helpstring("Undefined likelihood function")]
unknown
} eLikelihood;
6.5.12 eMeasureError
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eMeasureError
[helpstring("Measurement error types.")]
typedef enum eMeasureError
142
DREAM Suite 1
{
[helpstring("Measurement error set by user")]
eMeasUserDefError,
[helpstring("Homoscedastic (constant) error")]
eMeasConstantError,
[helpstring("Heteroscedastic (variable) error")]
eMeasVariableError
} eMeasureError;
6.5.13 eOutlierTest
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eOutlierTest
[helpstring("Functions for detection of outlier chains")]
typedef enum eOutlierTest
{
[helpstring("Iqr - Upton and Cook, 1996")]
eOutlierIqr,
[helpstring("Grubbs - Grubbs, 1950")]
eOutlierGrubbs,
[helpstring("Peirce - Peirce, 1852")]
eOutlierPeirce,
[helpstring("Chauvenet - Chauvenet, 1960")]
eOutlierChauvenet
} eOutlierTest;
6.5.14 eParallelMode
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eParallelMode
[helpstring("Options for the parallel mode of evaluation")]
typedef enum eParallelMode
{
[helpstring("Parallel mode is possible and recommended")]
eParallelModeYes,
[helpstring("Parallel mode is possible but not recommended")]
eParallelModeNotRecommended,
[helpstring("Parallel mode is not possible")]
eParallelModeNotPossible
} eParallelMode;
6.5.15 ePluginType
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum ePluginType
[helpstring("Plugin types")]
typedef enum ePluginType
{
[helpstring("Plugin is a standard DLL")]
ePlugin_DLL,
[helpstring("Plugin uses MATLAB COM server")]
ePlugin_MatlabCOM,
[helpstring("Plugin uses MATLAB Engine")]
ePlugin_MatlabEngine,
[helpstring("Plugin uses Python")]
ePlugin_Python,
} ePluginType;
143
DREAM Suite 1
6.5.16 ePriorDistrib
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum ePriorDistribution
[helpstring("Reason of calling function CDreamEvaluator::GetPriorDataCustom")]
typedef enum ePriorDistrib
{
[helpstring("Function called during initialization of dream solver")]
ePriorInitialize,
[helpstring("Function called during DREAM calculation")]
ePriorCalculate,
} ePriorDistrib;
6.5.17 ePriorType
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum ePriorType
[helpstring("Type of prior distribution.")]
typedef enum ePriorType
{
[helpstring("Univariate prior distribution")]
eUnivariate,
[helpstring("Multivariate prior distribution")]
eMultivariate,
[helpstring("Distribution calculated in CDreamEvaluator::GetPriorDataCustom")]
eCustom
} ePriorType;
6.5.18 eVectorization
///////////////////////////////////////////////////////////////////////////////////////////////////
// enum eVectorization
[helpstring("Option for vectorization.")]
typedef enum eVectorization
{
[helpstring("Vectorization not used")]
eVectNone,
[helpstring("Vectorization used")]
eVectYes
} eVectorization;
144