////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model update state (off-nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model update state (malfunctions).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Valve Controller model update state and update power at hardstops.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Powered Toggle Valve command unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Toggle Valve command default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Toggle Valve command nominal construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Toggle Valve command accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Toggle Valve command modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Toggle Valve command update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Toggle Valve Controller model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model update state (off-nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model update state (malfunctions).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Controller model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Powered Open/Close Valve command unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Open/Close Valve command default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Open/Close Valve command nominal construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Open/Close Valve command copy construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Open/Close Valve command assignment.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Dual Solenoid Valve Controller model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model construction of configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model update state (both solenoids driven).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model update state (malfunctions).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Controller model initialization with exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Position Valve Controller model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model update state (off-nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model update state (malfunctions).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Position Valve Controller model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Speed Valve Controller model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model update state (off-nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model update state (malfunctions).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Speed Valve Controller model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this TS21 Fluid Controller Manual T-Valve (3 way, 3 position)
///           Controller Model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///          update.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for TS21 Fluid Controller Manual T-Valve (3 way, 3 position) Controller Model
///           initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Powered Speed Valve command unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Speed Valve command default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Speed Valve command nominal construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Speed Valve command copy construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Powered Speed Valve command assignment.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller config data.
/// @param[in]  sensorOpen    (--)  Open sensor config data.
/// @param[in]  sensorClosed  (--)  Closed sensor config data.
///
/// @details  Default constructs this Toggle Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that  (--)  Object to copy.
///
/// @details  Copy constructs this Toggle Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller input data.
/// @param[in]  sensorOpen    (--)  Open sensor input data.
/// @param[in]  sensorClosed  (--)  Closed sensor input data.
///
/// @details  Default constructs this Toggle Valve Assembly input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that  (--)  Object to copy.
///
/// @details  Copy constructs this Toggle Valve Assembly input data.
//////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Toggle Valve Assembly model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] configData  (--)  Configuration data.
/// @param[in] inputData   (--)  Input data.
/// @param[in] name        (--)  Object name.
///
/// @return   void
///
/// @throws   TsInitializationException
///
/// @details  Initializes this Toggle Valve Assembly model with configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  dt  (s)  Execution time step
///
/// @return   void
///
/// @details  Updates the sensors and controller.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  supplyVoltageFlag  (--)  Power flag.
/// @param[in]  enable             (--)  Valve enable command.
/// @param[in]  toggle             (--)  Valve toggle command.
/// @param[in]  dt                 (s)   Time step.
///
/// @return   void
///
/// @details  Updates the sensors and controller with arguments, so it can be run from a container.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller config data.
/// @param[in]  sensorOpen    (--)  Open sensor config data.
/// @param[in]  sensorClosed  (--)  Closed sensor config data.
///
/// @details  Default constructs this Open/Close Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that   (--)  Source to copy.
///
/// @details  Copy constructs this Open/Close Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller input data.
/// @param[in]  sensorOpen    (--)  Open sensor input data.
/// @param[in]  sensorClosed  (--)  Closed sensor input data.
///
/// @details  Default constructs this Open/Close Valve Assembly input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that   (--)  Source to copy.
///
/// @details  Copy constructs this Open/Close Valve Assembly input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details    Default constructs this Open/Close Valve Assembly model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] configData  (--)  Configuration data.
/// @param[in] inputData   (--)  Input data.
/// @param[in] name        (--)  Object name.
///
/// @return   void
///
/// @throws   TsInitializationException
///
/// @details  Initializes this Open/Close Valve Assembly model with configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  supplyVoltageFlag  (--)  Power flag.
/// @param[in]  command            (--)  Valve open/close command.
/// @param[in]  dt                 (s)   Time step.
///
/// @return   void
///
/// @details  Updates the sensors and controller with arguments, so it can be run from a container.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller config data.
/// @param[in]  sensorOpen    (--)  Open sensor config data.
/// @param[in]  sensorClosed  (--)  Closed sensor config data.
///
/// @details  Default constructs this Dual Solenoid Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that  (--)  Object to copy.
///
/// @details  Copy constructs this Dual Solenoid Valve Assembly configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  controller    (--)  Valve controller input data.
/// @param[in]  sensorOpen    (--)  Open sensor input data.
/// @param[in]  sensorClosed  (--)  Closed sensor input data.
///
/// @details  Default constructs this Dual Solenoid Valve Assembly input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that  (--)  Object to copy.
///
/// @details  Copy constructs this Dual Solenoid Valve Assembly input data.
//////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Dual Solenoid Valve Assembly model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] configData  (--)  Configuration data.
/// @param[in] inputData   (--)  Input data.
/// @param[in] name        (--)  Object name.
///
/// @return   void
///
/// @throws   TsInitializationException
///
/// @details  Initializes this Dual Solenoid Valve Assembly model with configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  open   (--)  Valve open command/power input.
/// @param[in]  close  (--)  Valve close command/power input.
/// @param[in]  dt     (s)   Time step.
///
/// @return   void
///
/// @details  Updates the sensors and controller with arguments, so it can be run from a container.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Toggle Valve Assembly model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model construction of configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Toggle Valve Assembly model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Dual Solenoid Valve Assembly model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model construction of configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Dual Solenoid Valve Assembly model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Open/Close Valve Assembly model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model construction of configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Open/Close Valve Assembly model update state (nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  gainP      (--)   Proportional gain.
/// @param[in]  gainI      (1/s)  Integral gain.
/// @param[in]  gainD      (s)    Derivative gain.
/// @param[in]  interval   (s)    Control update interval.
/// @param[in]  limitLow   (--)   Lower limit on output value.
/// @param[in]  limitHigh  (--)   Upper limit on output value.
///
/// @details  Default constructs this PID Controller configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that  (--)  Source to copy.
///
/// @details  Copy constructs this PID Controller configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  input       (--)   Initial input process variable.
/// @param[in]  setpoint    (1/s)  Initial setpoint value to control to.
/// @param[in]  timer       (s)    Initial timer for control update interval.
/// @param[in]  integral    (s)    Initial controller integral value.
/// @param[in]  output      (--)   Initial output control value.
///
/// @details  Default constructs this PID Controller input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that  (--)  Source to copy.
///
/// @details  Copy constructs this PID Controller input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this PID Controller model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  configData  (--)  Configuration data.
/// @param[in]  inputData   (--)  Input data.
/// @param[in]  name        (--)  Instance name for messages.
///
/// @throws   TsInitializationException
///
/// @details  Initializes this PID Controller model with configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  configData  (--)  Configuration data.
///
/// @throws   TsInitializationException
///
/// @details  Validates this PID Controller model configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  dt     (s)   Execution time step.
///
/// @returns  double  (--)  Resulting output value.
///
/// @details  If the elapsed time since the last output update has passed the interval, then updates
///           the output value with the PID logic.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  dt     (s)   Execution time step.
/// @param[in]  input  (--)  Input value to control.
///
/// @returns  double  (--)  Resulting output value.
///
/// @details  Calls setInput with input, then calls update(dt) to update the controller.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this PID Controller model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model construction of configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model construction of input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model update method.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model update state (off-nominal).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for PID Controller model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************/
/* InputData class */
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  malfCmdOnFlag       (--)  Malfunction flag, heater command on
/// @param[in]  malfCmdOffFlag      (--)  Malfunction flag, heater command off
/// @param[in]  isKillSwitchEngaged (--)  Flag to open thermostat switch & kill the heater
///
/// @details    Default constructs this HtrControl model input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that   (--)  source to copy
///
/// @details    Copy constructs this HtrControl model input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************/
/* HtrControl class */
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details    Default HtrControl constructor. Defaults all pointers and members to zero.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  config  (--)  configuration data
/// @param[in]  input   (--)  input data
/// @param[in]  name    (--)  HtrControl name
///
/// @throw      TsInitializationException in validate() method.
///
/// @details    Initializes this HtrControl model from configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************/
/* ConfigData class */
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  sensorConfig         (--)  config data for Thermostat's sensor(s)
/// @param[in]  temperatureSetptLow  (K)   nominal thermostat low setpoint
/// @param[in]  temperatureSetptHigh (K)   nominal thermostat high setpoint
/// @param[in]  numTempSensors       (--)  number of temperature sensors monitored by thermostat
/// @param[in]  logicType            (--)  type of logic to apply to sensor readings;
///                                        (ThermostatConfigData::SINGLE, AND, or OR)
///
/// @details    Constructs this Thermostat model configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that   (--)  source to copy
///
/// @details    Copy constructs this Thermostat model configuration data.
////////////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************/
/* InputData class */
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  sensorInput         (--)  Input data for Thermostat's sensor(s)
/// @param[in]  malfCmdOnFlag       (--)  Malfunction flag, heater command on
/// @param[in]  malfCmdOffFlag      (--)  Malfunction flag, heater command off
/// @param[in]  malfSetptLowFlag    (--)  Malfunction flag, override temp setpoint-low
/// @param[in]  malfSetptHighFlag   (--)  Malfunction flag, override temp setpoint-high
/// @param[in]  malfSetptLowValue   (K)   Malfunction value, override setpoint-low
/// @param[in]  malfSetptHighValue  (K)   Malfunction value, override setpoint-high
///
/// @details    Default constructs this Thermostat model input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  that   (--)  source to copy
///
/// @details    Copy constructs this Thermostat model input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************/
/* Thermostat class */
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details    Default Thermostat constructor. Defaults all pointers and members to zero.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  config  (--)  configuration data
/// @param[in]  input   (--)  input data
/// @param[in]  name    (--)  Thermostat name
///
/// @throw      TsInitializationException in validate() method.
///
/// @details    Initializes this Thermostat model from configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  config  (--)  configuration data
/// @param[in]  input   (--)  input data
///
/// @throw      TsInitializationException if config/input parameters not valid.
///
/// @details    Validates this Thermostat model configuration and input data.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  timeStep  (s)   time step (passed to sensor update)
///
/// @throw      TsInitializationException if Thermostat not initialized.
///
/// @details    Updates this Thermostat model. Analyzes sensor readings and sets both
///             mCommandNominal and mCommandSetpt members. (These two command states will be
///             the same if the setpoint malf is not active.) Then, the command malf is considered,
///             and mCommandActual is set.
///
/// @note       mCommandSetpt is maintained as a separate member for one specific
///             scenario, when both Command:ON/OFF and Setpoint-override malfunctions are active.
///             At the point when Command:ON/OFF is de-activated, the Thermostat needs to return
///             to the malf'd-setpoint command state. This may or may not be equal to the
///             Nominal command status, which represents the status at a state where no malfunctions
///             are active.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  commandStatus (--)  default UserLoadMode status
///
/// @return     UserLoadMode  (--)  net LoadON / LoadOFF command status resulting from reading
///                                 the sensors
///
/// @details    Loops through all the thermostat's sensors, searching for a sensor that
///             evaluates to the "Primary" load mode, either ON or OFF.
///             Once a Primary is found, the loop breaks and the Primary command state is returned.
///             If no Primary is found, the the "Secondary" command state is returned.
///             Primary and Secondary values are specific to the logic pattern of the
///             Thermostat instance (single, OR, AND).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  commandStatus (--)  default UserLoadMode status to return if temp b/t setpoints
/// @param[in]  sensedTemp    (K)   temperature reading from sensor
///
/// @return     UserLoadMode  (--)  LoadON / LoadOFF command status resulting from these setpts
///
/// @details    Command status is determined based on the input sensed temperature and the given
///             setpoints. If the temperature is under the low setpoint, the command is returned
///             LoadON. If the temperature is above the high setpoint, the command is returned
///             LoadOFF. If the temperature is within both setpoints, the command is returned
///             unchanged from its passed-in value.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @return   UserLoadMode  (--)  Primary command mode based on logic-pattern for this thermostat.
///
/// @details  Returns Primary load mode for this thermostat. The "Primary" load mode is defined
///           as such: When just one of a thermostat's sensors evaluate to the Primary mode,
///           the overall command for the thermostat is set to the Primary mode.
///
/// @note     (AND) Since sensors are in series, it takes only one to evaluate to "LoadOFF" for
///                 an 'AND' thermostat to trip OFF. LoadOFF is returned as its Primary load mode.
///           (OR)  Since sensors are in parallel, it takes only one to evaluate to "LoadON" for
///                 an 'OR' thermostat to trip ON. LoadON is returned as its Primary load mode.
///
/// @note     (SINGLE) Since only one sensor is being read, it doesn't matter which is the Primary
///           mode for a single-sensor thermostat. LoadON is returned just to pick one.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @return   UserLoadMode  (--)  Secondary command mode based on logic-pattern for this thermostat.
///
/// @details  Returns Secondary load mode for this thermostat. The "Secondary"  load mode is defined
///           as such: If NONE of a thermostat's sensors evaluate to the Primary mode,
///           the overall command for the thermostat is set to the Secondary.
///
/// @note     (AND) Since sensors are in series, ALL of them must evaluate to "LoadON" for
///                 an 'AND' thermostat to trip ON. LoadON is returned as its Secondary load mode.
///           (OR)  Since sensors are in parallel, ALL of them must evaluate to "LoadOFF" for
///                 an 'OR' thermostat to trip OFF. LoadOFF is returned as its Secondary load mode.
///
/// @note     (SINGLE) Since only one sensor is being read, it doesn't matter which is the Seconday
///           mode for a single-sensor thermostat, as long is it's opposite to the Primary mode.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  bias  (K)  Value to set the commanded setpoint bias to.
///
/// @details  Sets mCommandSetptBias to the given value and back computes mTemperatureSetpt.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Thermostat model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Thermostat model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Thermostat model nominal initialization without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Thermostat model initialization exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Thermostat model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests for Thermostat model modifiers.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the nominal Thermostat behavior.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the behavior of the Thermostat with malfunctions activated.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the behavior of the Thermostat with setpoints malf active, biased low.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the behavior of the Thermostat with setpoints malf active, biased high.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the logic specific to a multi-sensor:AND thermostat.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  An intermediary method that runs assertion checks for a given article at a given
///           sensor temperature. Called by different test methods. The Command On/Off malfunctions
///           are tested here so that their behavior is verified at all the different temperature /
///           setpoint combinations. As is killswitch behavior.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  temperature  (K)  temperature to set on the sensor
///
/// @details    An intermediary method that sets all sensors to a given value.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  temperature  (K)   temperature to set on the sensor
/// @param[in]  index        (--)  index of the specific sensor within the mTempSensor array
///
/// @details    An intermediary method that sets one sensor to a given value.
////////////////////////////////////////////////////////////////////////////////////////////////////


// MultiLinearModel::MultiLinearModel()
//
// PURPOSE:
//      Constructor. Initializes model computation.
//
// INPUT:
//      covariates:                 one-dimensional array containing the values
//                                  of the independent variables concatenated in the same
//                                  order as the columns from left to right in the input data file.
//      covariatesUncertainties:    ome-dimensional array containing the values of the uncertainties on the independent variables concatenated
//                                  in the same order as the columns from left to right in the input data file
//      Nobservables:               the number of observables in the multilinear model
//


// MultiLinearModel::predict()
//
// PURPOSE:
//      Builds the predictions from a multilinear model of the type y = offset + a*x_1 + b*x_2 + c*x_3 ...
//      where offset, a, b, c, ... are the free parameters and x_i the independent covariates.
//      It is implicit that the covariates are expressed as natural logarithms, otherwise the
//      multilinear model is not valid. The order of the free parameters has to respect the same
//      column order as the input dataset. The offset parameter is always the last one.
//
// INPUT:
//      predictions:        one-dimensional array to contain the predictions
//                          from the model
//      modelParameters:    one-dimensional array where each element
//                          contains the value of a free parameter of the model
//
// OUTPUT:
//      void
//


// MultiLinearModel::computeVariance()
//
// PURPOSE:
//      Builds the total covariates uncertainties by applying a standard error propagation from the model equation.
//
// INPUT:
//      modelVariance:        one-dimensional array to contain the total variance on the covariates
//                            as computed by the model
//      modelParameters:      one-dimensional array where each element
//                            contains the value of a free parameter of the model
//
// OUTPUT:
//      void
//


// NestedSampler::NestedSampler()
//
// PURPOSE:
//      Constructor. Sets initial information, logEvidence and type
//      of prior and likelihood distributions to be used.
//
// INPUT:
//      printOnTheScreen:       Boolean value specifying whether the results are to
//                              be printed on the screen or not.
//      initialNlivePoints:        Initial number of live points to start the nesting process
//      minNlivePoints:            Minimum number of live points allowed in the nesting process
//      ptrPriors:              Vector of pointers to Prior class objects
//      likelihood:             Likelihood class object used for likelihood sampling.
//      metric:                 Metric class object to contain the metric used in the problem.
//      clusterer:              Clusterer class object specifying the type of clustering algorithm to be used.
//
// REMARK:
//      The desired model for predictions is to be given initially to
//      the likelihood object and is not feeded directly inside the
//      nested sampling process.
//


// NestedSampler::run()
//
// PURPOSE:
//      Start nested sampling computation. Save results in Eigen
//      Arrays logLikelihoodOfPosteriorSample, posteriorSample,
//      logWeightOfPosteriorSample,logEvidenceOfPosteriorSample,logMeanLiveEvidenceOfPosteriorSample.
//
// INPUT:
//      livePointsReducer:                    An object of a class that takes care of the way the number of live points
//                                            is reduced within the nesting process
//      NinitialIterationsWithoutClustering:  The first N iterations, no clustering will happen. I.e. It will be assumed that
//                                            there is only 1 cluster containing all the points. This is often useful because
//                                            initially the points may be sampled from a uniform prior, and we therefore don't
//                                            expect any clustering before the algorithm is able to tune in on the island(s) of
//                                            high likelihood. Clusters found in the first N initial iterations are therefore
//                                            likely purely noise.
//      NiterationsWithSameClustering:        A new clustering will only happen every N iterations.
//      maxNdrawAttempts:                     The maximum number of attempts allowed when drawing from a single ellipsoid.
//      minRatioOfRemainderToCurrentEvidence: The minimum fraction of remainder evidence to gained evidence used to terminate
//                                            the nested iteration loop. This value is also used as a tolerance on the final
//                                            evidence to update the number of live points in the nesting process.
//      pathPrefix:                           A string specifying the path where the output information from the Nested Sampler
//                                            has to be saved.
//
// OUTPUT:
//      void
//
// REMARKS:
//      Eigen Matrices are defaulted column-major. Hence the nestedSample and posteriorSample are resized as
//      (Ndimensions, ...), rather than (... , Ndimensions).
//


// NestedSampler::removeLivePointsFromSample()
//
// PURPOSE:
//          Resizes all eigen arrays and vectors of dimensions NlivePoints according to
//          new number of live points evaluated. The indices of the live points to be removed
//          are give as an input.
//          Also relative number of points in clusters are adjusted according to which live points
//          are removed.
//
// INPUT:
//          indicesOfLivePointsToRemove:        A vector of integers containing the indices of the live points
//                                              that must be removed from the sample.
//          clusterIndices:                     A vector of integers containing the indices of the clusters
//                                              all the live points belong to
//          clusterSizes:                       A vector of integers containing the sizes of the clusters
// OUTPUT:
//      void
//


// NestedSampler::printComputationalTime()
//
// PURPOSE:
//      Computes the total computational time of the nested sampling process
//      and prints the result expressed in either seconds, minutes or hours on the screen.
//
// INPUT:
//      startTime a double specifying the seconds at the moment the process started
//
// OUTPUT:
//      void
//


// NestedSampler::setPosteriorSample()
//
// PURPOSE:
//      Set private data member posteriorSample from the outside.
//      Used when merging of the results is needed.
//
// OUTPUT:
//      void
//


// NestedSampler::setLogLikelihoodOfPosteriorSample()
//
// PURPOSE:
//      Set private data member logLikelihoodOfPosteriorSample from the outside.
//      Used when merging of the results is needed.
//
// OUTPUT:
//      void
//


// NestedSampler::setLogWeightOfPosteriorSample()
//
// PURPOSE:
//      Set private data member logWeightOfPosteriorSample from the outside.
//      Used when merging of the results is needed.
//
// OUTPUT:
//      void
//


// Projector:Projector()
//
// PURPOSE:
//      Class constructor
//
// INPUT:
//      printNdimensions: a boolean specifying whether one wants the reduced number
//      of dimensions to be explicitly printed on the screen.
//      Sets projected data member to 0 by default.
//


// Results::posteriorProbability()
//
// PURPOSE:
//      Saves the posterior probability for the sample, obtained by
//      applying the Bayes theorem to the information coming from the
//      nested sampling, into a one-dimensional Eigen Array.
//
// OUTPUT:
//      An Eigen Array containing the values of the posterior probability
//      sorted according to the nesting process.
//
// REMARK:
//      Values are probabilities (and not probability densities),
//      hence their sum must equal the unity.
//      The array computed according to the definition of posterior probability
//      from the nesting algorithm is finally normalized by the sum
//      of its elements. This allows to get rid of small deviations
//      caused by the approximated value of the evidence.
//


// Results:writeMarginalDistributionToFile()
//
// PURPOSE:
//      Writes the interpolated grid of parameter values and its
//      corresponding marginal distribution as derived from parameterEstimation()
//      in an output ASCII file of two-columns format.
//      This information can then be used for plotting the marginal distribution
//      and for computing further operations on it, such as the derivation of error bars on the free parameter.
//
// INPUT:
//      parameterNumber:            an integer containing the number of the free parameter to save, together with
//                                  its marginal distribution.
//
// OUTPUT:
//      void.
//


// Results:computeCredibleLimits()
//
// PURPOSE:
//      Computes the shortest Bayesian credible intervals (CI) from a marginal distribution.
//
// INPUT:
//      credibleLevel:              a double number providing the desired credible
//                                  level to be computed.
//      skewness:                   the skewness of the sample distribution
//      NinterpolationsPerBin:      an integer containing the number of desired points to interpolate between.
//                                  two consecutive input data points.
//
// OUTPUT:
//      A one-dimensional Eigen Array containing the lower and upper credible limits, i.e. the boundaries
//      of the shortest credible intervals identified.
//
// REMARK:
//      The input number of interpolated points is to be considered as an estimate of the real number of interpolations occurring.
//      This is because the number of interpolations also depends on the spacing of the input grid for each bin, which is
//      not required to be regular.
//


// Results:parameterEstimation()
//
// PURPOSE:
//      Computes the expectation, median and mode values from the
//      marginalized posterior probability.
//      Shortest Bayesian credible intervals (CI) are also computed.
//
// INPUT:
//      credibleLevel:              a double number providing the desired credible
//                                  level to be computed. Default value corresponds to
//                                  credible level of 68.27 %.
//      writeMarginalDistribution:  a boolean variable specifying whether the marginal distribution for
//                                  each parameter has to be written in an output file.
//
// OUTPUT:
//      A bidimensional Eigen Array containing all the estimators of the
//      free parameters (one parameter per row). The output column order is:
//      (1) Mean (I Moment)
//      (2) Median
//      (3) Mode
//      (4) II Moment
//      (5) Lower CL
//      (6) Upper CL
//


// Results::writeParametersToFile()
//
// PURPOSE:
//      writes the parameters values from the nested sampling
//      in separate ASCII files having one column format each.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//


// Results::writeLogLikelihoodToFile()
//
// PURPOSE:
//      writes the log likelihood values from the nested sampling
//      into an ASCII file of one column format. The values are
//      sorted in increasing order.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//


// Results::writeLogWeightsToFile()
//
// PURPOSE:
//      writes the log(Weight) = log(dX) values from the nested sampling
//      into an ASCII file of one column format. The values are sorted according to the
//      ascending order in likelihood.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//


// Results::writeEvidenceInformationToFile()
//
// PURPOSE:
//      writes all the information related to the evidence computed from
//      the nested sampling into an ASCII file.
//      Skilling's evidence, evidence error and information gain are also included.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//


// Results::writePosteriorProbabilityToFile()
//
// PURPOSE:
//      writes the posterior probability for the sample obtained from the
//      nested sampling into an ASCII file of one column format.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//
// REMARK:
//      Note that these values are probabilities and not probability densities.
//


// Results::writeLogEvidenceToFile()
//
// PURPOSE:
//      writes the cumulated log(Evidence) obtained from the
//      nested sampling into an ASCII file of one column format.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//
// REMARK:
//      Note that these values are cumulated log(Evidence), hence they increase as the nested iteration
//      increases (i.e. the line number in the output file).
//      In addition, the number of values is limited to the number of nested iterations only, thus
//      leaving outside the final set of live points.
//


// Results::writeLogMeanLiveEvidenceToFile()
//
// PURPOSE:
//      writes the remaining log(MeanLiveEvidence) obtained from the
//      nested sampling into an ASCII file of one column format.
//
// INPUT:
//      fileName:   a string variable containing the file name of the output file to be saved.
//
// OUTPUT:
//      void
//
// REMARK:
//      Note that these values are remaining log(MeanLiveEvidence), hence they decrease as the nested iteration
//      increases (i.e. the line number in the output file).
//      In addition, the number of values is limited to the number of nested iterations only, thus
//      leaving outside the final set of live points.
//      By dividing the MeanLiveEvidence at each iteration by the cumulated evidence in the same iteration, one obtains
//      the ratio condition used in the stopping criterion for the computations.
//


// Results:writeParametersSummaryToToFile()
//
// PURPOSE:
//      Writes the expectation, standard deviation, median and mode values from the
//      marginalized posterior probability into an ASCII file.
//      Shortest Bayesian credible intervals (CI) are also included.
//
// INPUT:
//      fileName:                   a string variable containing the filename of the output file.
//      credibleLevel:              a double number providing the desired credible
//                                  level to be computed. Default value corresponds
//                                  to a credible level of 68.27 %.
//      writeMarginalDistribution:  a boolean variable specifying whether the marginal distribution for
//                                  each parameter has to be written in an output file.
//
// OUTPUT:
//      void.
//


// MultiEllipsoidSampler::MultiEllipsoidSampler()
//
// PURPOSE:
//      Class constructor.
//
// INPUT:
//      printOnTheScreen:               true if the results are to be printed on the screen, false otherwise
//      ptrPriors:                      vector of Prior class objects containing the priors used in the problem.
//      likelihood:                     Likelihood class object used for likelihood sampling.
//      metric:                         Metric class object to contain the metric used in the problem.
//      clusterer:                      Clusterer class object specifying the type of clustering algorithm to be used.
//      initialNlivePoints:                Initial number of active points to start the nesting process
//      NlivePointsMinimum:                Minimum number of active points allowed in the nesting process
//      initialEnlargementFraction:     Initial value of the enlargement for the ellipsoids
//      shrinkingRate:                  Shrinking rate of the enlargement factors, between 0 and 1.
//


// MultiEllipsoidSampler::drawWithConstraint()
//
// PURPOSE:
//      Draws a new point from one of the ellipsoids built from the sample of identifed clusters.
//      The drawing process follows the adopted prior distributions. If no new point satisfying the
//      hard likelihood constraint is found, then a false boolean value is returned.
//      The ellipsoid to draw from is randomly selected according to its volume (Feroz F., Hobson M. P., 2008, MNRAS, 384, 449).
//      In case ellipsoids are overlapping, if the drawn point falls in a region where ellipsoids overlap,
//      then the point is selected with a probability inverse to the number of ellipsoids overlapping in that region.
//
// INPUT:
//      totalSample:                Eigen Array matrix of size (Ndimensions, NlivePoints)
//                                  containing the total sample of active points at a given nesting iteration
//      Nclusters:                  Optimal number of clusters found by clustering algorithm
//      clusterIndices:             Indices of clusters for each point of the sample
//      clusterSizes:               A vector of integers containing the number of points belonging to each cluster
//      drawnPoint:                 Eigen Array matrix of size (Ndimensions,Ndraws) to contain the
//                                  coordinates of the drawn point to be used for the next nesting loop.
//                                  When used for the first time, the array contains the coordinates of the
//                                  worst nested object to be updated.
//      logLikelihoodOfDrawnPoint:  the log(likelihood) value of the new drawn point, to be stored in the global
//                                  array containing the log(likelihood) values for each nested iteration.
//      maxNdrawAttempts:           Maximum number of attempts allowed when drawing from a single ellipsoid.
//
//
// OUTPUT:
//      A boolean value that is true if a new point in the sampling process is found and false otherwise.
//


// MultiEllipsoidSampler::verifySamplerStatus()
//
// PURPOSE:
//      Verifies whether the status of the sampler in use is successful.
//      If not, it prints the related error message and returns a false boolean value.
//      In this case, it concerns the error caused by a failure in the ellipsoid matrix
//      decomposition.
//
// OUTPUT:
//      void
//


// MultiEllipsoidSampler::computeEllipsoids()
//
// PURPOSE:
//      Computes covariance matrices and center coordinates of all the ellipsoids
//      associated to each cluster of the sample. The eigenvalue decomposition
//      is also done and eigenvalues are enlarged afterwards. All the results
//      are stored in the private data members.
//
// INPUT:
//      totalSample(Ndimensions, NlivePoints):     Complete sample (spread over all clusters) of points
//      Nclusters:                              The number of clusters identified by the clustering algorithm
//      clusterIndices(NlivePoints):               For each point, the integer index of the cluster to which it belongs
//      clusterSizes(Nclusters):                A vector of integers containing the number of points belonging to each cluster
//
// OUTPUT:
//      void
//


// MultiEllipsoidSampler::findOverlappingEllipsoids()
//
// PURPOSE:
//      For each ellipsoid, determine which other ellipsoids overlap with it, and
//      store the indices of those overlapping ellipsoids.
//
// INPUT:
//      overlappingEllipsoidsIndices[0..Nellipsoids-1]:     a vector of unordered_set of integers
//                                                          whose elements will contain the indices
//                                                          corresponding to the overlapping ellipsoids
//
// OUTPUT:
//      overlappingEllipsoidsIndices will have changed. Element [i] contains an unordered_set<> with
//      the indices of all ellipsoids that overlap with ellipsoid #i
//


// MultiEllipsoidSampler::updateEnlargementFraction()
//
// PURPOSE:
//      Updates the enlargementFraction adopted for the axes of the ellipsoid.
//      The formula takes into account the number of dimensions of the problem
//      and it is a modified version of the one adopted by Feroz F. et al. 2008.
//
// INPUT:
//      clusterSize:    an integer specifying the number of points used to construct the
//                      bounding ellipsoid.
//
// OUTPUT:
//      A double containing the value of the updated enlargement fraction.
//


// ZeroModel::ZeroModel()
//
// PURPOSE:
//      Constructor. Initializes model computation.
//
// INPUT:
//      covariates: one-dimensional array containing the values
//                  of the independent variable. These will be ignored
//                  as the zero model always returns zero.
//


// ZeroModel::predict()
//
// PURPOSE:
//      The predicted values of the ZeroModel are all zero.
//
// INPUT:
//      predictions: One-dimensional array to contain the predictions from the model
//                   These will all be set to zero
//      modelParameters: one-dimensional array containing the value of the free fit parameters
//
// OUTPUT:
//      void
//


// GaussianModel::GaussianModel()
//
// PURPOSE:
//      Constructor. Initializes model computation.
//
// INPUT:
//      multiCovariates:        one-dimensional array containing the values
//                              of the independent variables concatenated in the same
//                              order as the columns from left to right in the input data file.
//      Nobservables:           the number of observables in the multilinear model
//


// GaussianModel::predict()
//
// PURPOSE:
//      Builds the predictions from a multi-dimensional Gaussian model as a function of the
//      x_i the independent covariates.
//
// INPUT:
//      predictions:        one-dimensional array to contain the predictions
//                          from the model
//      modelParameters:    one-dimensional array where each element
//                          contains the value of a free parameter of the model
//
// OUTPUT:
//      void
//


// ExponentialLikelihood::logValue()
//
// PURPOSE:
//      Compute the natural logarithm of the exponential likelihood, which
//      s a generalized chi-square distribution with 2 d.o.f.
//
// INPUT:
//      modelParameters: a one-dimensional array containing the actual
//      values of the free parameters that describe the model.
//
// OUTPUT:
//      a double number containing the natural logarithm of the
//      exponential likelihood
//


// GridUniformPrior::GridUniformPrior()
//
// PURPOSE:
//      Derived class constructor. Builds a grid prior with uniform sampling
//      only inside the gridPoints of the grid.
//
// INPUT:
//      startingCoordinate: an array containing the starting point of the grid prior in each coordinate.
//      startingCoordinate: an array containing the ending point of the grid prior in each coordinate.
//      NgridPoints:        an array containing the number of grid points in each dimension (considered as an integer number).
//      tolerance:          an array containing the tolerance of the grid points in percentage. This tolerance defines the width of each grid point.
//                          If the tolerance is set to 1 (100%) for a given coordinate, then the grid has no empty spaces in that coordinate.
//


// GridUniformPrior::logDensity()
//
// PURPOSE:
//      Compute the logarithm of the probability density distribution evaluated in 'x'.
//
// INPUT:
//      x:                   Point in which the log(pdf) should be evaluated.
//      includeConstantTerm: If true : compute the exact log(density),
//                           If false: ignore the constant terms (with factors of pi, 2, etc.)
//
// OUTPUT:
//      Natural logarithm of the probability density evaluation in x.
//


// GridUniformPrior::drawnPointIsAccepted()
//
// PURPOSE:
//      Checks whether a new drawn point to be verified is accepted
//      according to the prior distribution.
//
// INPUT:
//      drawnPoint:     an Eigen array containing the coordinates
//                      of the new drawn point to be verified
//
// OUTPUT:
//      Returns true if the new point is accepted, false if not.
//


// GridUniformPrior::draw()
//
// PURPOSE:
//      Draw a sample of parameters values from a grid uniform prior
//      distribution. The parameters are in number Ndimensions
//      and contain Npoints values each.
//
// INPUT:
//      drawnSample:    two-dimensional Eigen Array to contain
//                      the resulting parameters values.
//
// OUTPUT:
//      void
//


// GridUniformPrior::drawWithConstraint()
//
// PURPOSE:
//      Replace an old set of parameters values with a new one
//      having higher likelihood value.
//
// INPUT:
//      drawnPoint:     one-dimensional Eigen Array containing the set of
//                      parameters values to be updated.
//      likelihood:     an object to compute the corresponding likelihood value.
//
// OUTPUT:
//      void
//
// NOTE:
//      parameters refers to the worst object identified in the nested
//      sampling loop. Thus, the array contains Ndimensions elements.
//


// GridUniformPrior::writeHyperParametersToFile()
//
// PURPOSE:
//      Store prior hyper parameters in an output ASCII file.
//
// INPUT:
//      fullPath:     a string containing the full filename for the output ASCII file
//
// OUTPUT:
//      void
//


// NormalLikelihood::NormalLikelihood()
//
// PURPOSE:
//      Derived class onstructor.
//
// INPUT:
//      observations: array containing the dependent variable values
//      uncertainties: array containing the uncertainties of the observations
//      model: object specifying the model to be used.
//


// NormalLikelihood::logValue()
//
// PURPOSE:
//      Compute the natural logarithm of the normal likelihood for
//      a given set of observations, uncertainties and predictions.
//
// INPUT:
//      modelParameters: a one-dimensional array containing the actual
//      values of the free parameters that describe the model.
//
// OUTPUT:
//      a double number containing the natural logarithm of the
//      normal likelihood
//


// SuperGaussianPrior:SuperGaussianPrior()
//
// PURPOSE:
//      Derived class constructor.
//
// INPUT:
//      center:             array containing values of the center for constructing
//                          the multi-dimensional Super-Gaussian prior.
//      sigma:              array containing the sigma values corresponding to the
//                          width of wings of the multi-dimensional Super-Gaussian prior.
//      widthOfPlateau:     array containing the widths of the plateau, i.e. the flat
//                          region of the multi-dimensional Super-Gaussian prior.
//


// SuperGaussianPrior::logDensity()
//
// PURPOSE:
//      Compute the logarithm of the probability density distribution evaluated in 'x'.
//
// INPUT:
//      x:                   Point in which the log(pdf) should be evaluated.
//      includeConstantTerm: If true : compute the exact log(density),
//                           If false: ignore the constant terms (with factors of pi, 2, etc.)
//
// OUTPUT:
//      Natural logarithm of the probability density evaluation in x.
//


// SuperGaussianPrior::drawnPointIsAccepted()
//
// PURPOSE:
//      Checks wheter a new drawn point to be verified is accepted
//      according to the prior distribution.
//
// INPUT:
//      drawnPoint:     an Eigen array containing the coordinates
//                      of the new drawn point to be verified
//
// OUTPUT:
//      Returns true if the new point is accepted, false if not.
//


// SuperGaussianPrior::draw()
//
// PURPOSE:
//      Draw a sample of parameters values from a Super-Gaussian prior
//      distribution. The parameters are in number Ndimensions
//      and contain Npoints values each.
//
// INPUT:
//      drawnSample:    two-dimensional Eigen Array to contain
//                      the resulting parameters values.
//
// OUTPUT:
//      void
//


// SuperGaussianPrior::drawWithConstraint()
//
// PURPOSE:
//      Replace an old set of parameters values with a new one
//      having higher likelihood value.
//
// INPUT:
//      drawnPoint: one-dimensional array containing the set of parameters
//                  values to be updated. Initially it should contain the coordinates
//                  of the point with the worst likelihood.
//      likelihood: an object to compute the likelihood values.
//
// OUTPUT:
//      void


// SuperGaussianPrior::writeHyperParametersToFile()
//
// PURPOSE:
//      Store prior hyper parameters in an output ASCII file.
//
// INPUT:
//      fullPath:     a string containing the full filename for the output ASCII file
//
// OUTPUT:
//      void
//


// PolynomialModel::PolynomialModel()
//
// PURPOSE:
//      Constructor. Initializes model computation.
//
// INPUT:
//      covariates:                 one-dimensional array containing the values
//                                  of the independent variable.
//      covariatesUncertainties:    ome-dimensional array containing the values of the uncertainties on the independent variable
//      Ndegrees:                   an integer containing the degree of the polynomial to fit.
//                                  A polynomial of the type y(x) = a*x + b has degree = 1.
//      covariatesOffset:           a double specifying the starting point of the intercept in the covariates
//


// PolynomialModel::predict()
//
// PURPOSE:
//      Builds the predictions from a polynomial model of the type f = offset + a*x + b*x^2 + c*x^3 + ...
//      where offset, a, b, c, ... are the free parameters and x the covariates.
//      The free parameters related to the covariates have to be sorted in increasing degree order.
//
// INPUT:
//      predictions:        one-dimensional array to contain the predictions
//                          from the model
//      modelParameters:    one-dimensional array where each element
//                          contains the value of a free parameter of the model
//
// OUTPUT:
//      void
//


// PolynomialModel::computeVariance()
//
// PURPOSE:
//      Builds the total covariates uncertainties by applying a standard error propagation from the model equation.
//
// INPUT:
//      modelVariance:        one-dimensional array to contain the total variance on the covariates
//                            as computed by the model
//      modelParameters:      one-dimensional array where each element
//                            contains the value of a free parameter of the model
//
// OUTPUT:
//      void
//


// Model::Model()
//
// PURPOSE:
//      Constructor. Initializes model computation.
//
// INPUT:
//      covariates: one-dimensional array containing the values
//      of the independent variable.
//


// GaussianMixtureLikelihood::GaussianMixtureLikelihood()
//
// PURPOSE:
//      Derived class onstructor.
//
// INPUT:
//      observations: array containing the dependent variable values
//      uncertainties: array containing the uncertainties of the observations
//      model: object specifying the model to be used.
//


// GaussianMixtureLikelihood::logValue()
//
// PURPOSE:
//      Compute the natural logarithm of the normal likelihood for
//      a given set of observations, uncertainties and predictions.
//
// INPUT:
//      modelParameters: a one-dimensional array containing the actual
//      values of the free parameters that describe the model.
//
// OUTPUT:
//      a double number containing the natural logarithm of the
//      normal likelihood
//


// Functions::lorentzProfile()
//
// PURPOSE:
//      Computes a simple Lorentzian profile given the centroid, the amplitude and the width.
//
// INPUT:
//      predictions : vector containing the result
//      covariates : vector containing independent variable values
//      centroid : centroid of the Lorentzian profile (default = 0)
//      amplitude : maximum height of the Lorentzian profile (default = 1)
//      gamma : width of the Lorentzian profile (default = 1)
//
// OUTPUT:
//      void
//
// REMARKS:
//      Saves the predictions into the input vector predictions.
//


// Functions::modeProfile()
//
// PURPOSE:
//      Computes a single Lorentzian profile that models an oscillation mode in a power spectrum.
//      The profile is computed given the centroid, the height and the linewidth.
//
// INPUT:
//      predictions : vector containing the result
//      covariates : vector containing independent variable values
//      centroid : centroid of the Lorentzian profile (default = 0), expressed in muHz
//      height : height of the Lorentzian profile (default = 1), expressed in ppm^2 / muHz
//      linewidth : width of the Lorentzian profile (mode linewidth) (default = 1), expressed in muHz
//
// OUTPUT:
//      void
//
// REMARKS:
//      Saves the predictions into the input vector predictions.
//


// Functions::modeProfileWithAmplitude()
//
// PURPOSE:
//      Computes a single Lorentzian profile that models an oscillation mode in a power spectrum.
//      The profile is computed given the centroid, the amplitude and the linewidth.
//
// INPUT:
//      predictions : vector containing the result
//      covariates : vector containing independent variable values
//      centroid : centroid of the Lorentzian profile (default = 0), expressed in muHz
//      amplitude : amplitude of the Lorentzian profile (default = 1), expressed in ppm
//      linewidth : width of the Lorentzian profile (mode linewidth) (default = 1), expressed in muHz
//
// OUTPUT:
//      void
//
// REMARKS:
//      Saves the predictions into the input vector predictions.
//


// Functions::modeProfileAsymmetricWithAmplitude()
//
// PURPOSE:
//      Computes a single asymmetric Lorentzian profile that models an oscillation mode in a power spectrum.
//      The profile is computed given the centroid, the amplitude and the linewidth.
//      Nigam & Kosovichev 1998 profile.
//
// INPUT:
//      predictions : vector containing the result
//      covariates : vector containing independent variable values
//      centroid : centroid of the Lorentzian profile (default = 0), expressed in muHz
//      amplitude : amplitude of the Lorentzian profile (default = 1), expressed in ppm
//      linewidth : width of the Lorentzian profile (mode linewidth) (default = 1), expressed in muHz
//      asymmetry : adimensional parameter for the asymmetric of the mode profile
//
// OUTPUT:
//      void
//
// REMARKS:
//      Saves the predictions into the input vector predictions.
//


// Functions::modeProfileSinc()
//
// PURPOSE:
//      Computes a normalized single sinc-square profile that models an unresolved oscillation mode in the power spectrum.
//      The profile is computed given the centroid, the height and the resolution of the dataset.
//
// INPUT:
//      predictions : vector containing the result
//      covariates : vector containing independent variable values
//      centroid : centroid of the Lorentzian profile (default = 0), expressed in muHz
//      height : height of the sinc-square profile (default = 1), expressed in ppm^2 / muHz
//      resolution : the distance from the centroid to the first zero of the sinc-square (default = 1), expressed in muHz
//
// OUTPUT:
//      void
//
// REMARKS:
//      Saves the predictions into the input vector predictions.
//


// Functions::logGaussProfile()
//
// PURPOSE:
//      Computes the logarithm of a Gaussian profile given the centroid,
//      the standard deviation and the amplitude, for one given x-value
//
// INPUT:
//      covariate : independent variable
//      mu : mean value of the Gaussian profile (default = 0)
//      sigma : standard deviation of the Gaussian profile (default = 1)
//      amplitude : maximum amplitude of the Gaussian profile (default = 1)
//
// OUTPUT:
//      The natural logarithm of the Gaussian profile value of the independent variable.
//


// Functions::logGaussProfile()
//
// PURPOSE:
//      Computes the logarithm of a Gaussian profile given the centroid,
//      the standard deviation and the amplitude for a set of values (overloaded)
//
// INPUT:
//      predictions : Eigen array containing the result
//      covariates : Eigen array containing independent variable values
//      mu : mean value of the Gaussian profile (default = 0)
//      sigma : standard deviation of the Gaussian profile (default = 1)
//      amplitude : maximum amplitude of the Gaussian profile (default = 1)
//
// OUTPUT:
//      void
//


// Functions::logGaussLikelihood()
//
// PURPOSE:
//      Computes the log-Gaussian likelihood from a set of observations,
//      uncertainties, and theoretical predictions.
//
// INPUT:
//      observations : array containing the oberved values
//      predictions : array containing the corresponding predicted values of x
//      uncertainties : array containing the uncertanties on the observed values
//
// OUTPUT:
//      The resulting value of the log-Gaussian likelihood.
//


// Functions::clusterCovariance()
//
// PURPOSE:
//      Compute the covariance matrix of a set of points belonging to a cluster.
//
// INPUT:
//      clusterSample: an Eigen Array matrix of size (Ndimensions, Npoints)
//      containing coordinates of all the points belonging to the cluster.
//      covarianceMatrix: an Eigen Array matrix of size (Ndimensions, Ndimensions) where the
//      covariance matrix is stored.
//      centerCoordinates: an Eigen Array of size Ndimensions where the coordinates of the
//      center (mean values) of the cluster of points are stored.
//
// OUTPUT:
//      void
//


// Functions::selfAdjointMatrixDecomposition()
//
// PURPOSE:
//      Compute the decomposition of a covariance matrix into eigenvectors and eigenvalues.
//
// INPUT:
//      covarianceMatrix:       an Eigen Array matrix to be decomposed
//                              eigenvalues: an Eigen Array to contain the eigenvalues
//                              of the covariance matrix.
//      eigenvalues:            an Eigen Array containing the eigenvalues of the covariance matrix
//                              listed in ascending order.
//      eigenvectorsMatrix:     an Eigen Array matrix to contain the matrix of
//                              the eigenvectors of the covariance matrix.
//
// OUTPUT:
//      A boolean value that is true if the decomposition was successfull, false otherwise.
//


// Functions::topDownMerge()
//
// PURPOSE:
//      This function does the sorting of the input array1 and sorts the elements of
//      array2 according to this sorting.
//
// INPUT:
//      array1: a first Eigen Array of double numbers to be sorted in increasing order
//      array2: a second Eigen Array to be sorted according to array1
//      arrayCopy1: a copy of array1 containing the effect of the merge sorting
//      arrayCopy2: a copy of array2 reflecting the sorting performed on arrayCopy1
//      beginIndex: an integer specifying the starting index of the sorting process
//      middleIndex: an integer specifying the mid-point of the array to be sorted
//      endIndex: an integer specifying the ending index of the sorting process
//
// OUTPUT:
//      void
//
// REMARK:
//      This function is not intented to be used separately
//      but only through the call to topDownMergeSort. It is used
//      within the function topDownSplitMerge.
//


// Functions::topDownMergeSort()
//
// PURPOSE:
//      This function splits the input array in two parts and repeat the process
//      until only 1-element segments are found. Then sorts all the segments and
//      merges them into a total, sorted array.
//
// INPUT:
//      array1: a first Eigen Array of double numbers to be sorted in increasing order
//      array2: a second Eigen Array to be sorted according to array1
//      arrayCopy1: a copy of array1 containing the effect of the merge sorting
//      arrayCopy2: a copy of array2 reflecting the sorting performed on arrayCopy1
//      beginIndex: an integer specifying the starting index of the sorting process
//      endIndex: an integer specifying the ending index of the sorting process
//
// OUTPUT:
//      void
//
// REMARK:
//      This function calls itself recursively. It is not intented to be used separately
//      but only through the call to topDownMergeSort.
//


// Functions::topDownMergeSort()
//
// PURPOSE:
//      Sorts the element of the first input array in increasing order
//      and the elements of the second input array according to the
//      sorting of the first array. This is done according to the
//      top-down implementation of the mergesort algorithm.
//
// INPUT:
//      array1: a first Eigen Array of double numbers to be sorted in increasing order
//      array2: a second Eigen Array to be sorted according to array1
//
// OUTPUT:
//      void
//
// REMARK:
//      This function uses the separate function topDownSplitMerge defined above.
//


// Functions::sortElementsDouble()
//
// PURPOSE:
//      Sorts the element of the first input array in increasing order
//      and the elements of the second input array according to the
//      sorting of the first array.
//
// INPUT:
//      array1: a first Eigen Array of double numbers to be sorted in increasing order
//      array2: a second Eigen Array to be sorted according to array1
//
// OUTPUT:
//      void
//


// Functions::sortElementsInt()
//
// PURPOSE:
//      Sorts the element of the first input array in increasing order
//      and the elements of the second input array according to the
//      sorting of the first array.
//
// INPUT:
//      array1: vector of integer values to be sorted in increasing order
//      array2: a second Eigen Array to be sorted according to array1
//
// OUTPUT:
//      void
//