DreamEvaluator.cpp

Parent Previous Next

///////////////////////////////////////////////////////////////////////////////////////////////////

// DreamEvaluator.cpp

///////////////////////////////////////////////////////////////////////////////////////////////////


#include "stdafx.h"


///////////////////////////////////////////////////////////////////////////////////////////////////

// CDreamEvaluator


//-------------------------------------------------------------------------------------------------

 CDreamEvaluator::CDreamEvaluator() : m_cRef(0)

//-------------------------------------------------------------------------------------------------

/*

 Constructor. To initialize member variables, use rather CDreamEvaluator::InitData  

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

}


//-------------------------------------------------------------------------------------------------

 CDreamEvaluator::~CDreamEvaluator()

//-------------------------------------------------------------------------------------------------

/*

 Destructor

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::InitPlugin

//-------------------------------------------------------------------------------------------------

(

 IDreamPluginInfo* pIPluginInfo

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 This function is called immediately after creation of CDreamEvaluator and before using

 the evaluator (i.e. calling its other functions). It is intended for initialization of

 the dynamic library and connecting possible external servers.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetInputParams

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParams* pIDreamInputParams // Pointer to DREAM input data to be defined

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define default DREAM parameters for this particular project.

 This function is called by the main program to initialize data of each newly created simulation

 case. This data can be later modified in the GUI (except parameters locked by flag

 DreamSolver::disable_edit) or can be overwritten while reading case data from a file.


 In the AppTest console application, there is no GUI and this functions actually defines all

 input parameters that are subsequently used by DREAM Solver.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Always check pIDreamInputParams pointer

 if(pIDreamInputParams == nullptr)

 {

   return E_INVALIDARG;

 }


 // Dimensionality target distribution d

 pIDreamInputParams->SetProblemDimension(2, DreamSolver::disable_edit);


 // Number of Markov chains N

 pIDreamInputParams->SetNumberOfMarkovChains(10, DreamSolver::enable_edit);

 // Number of generations T

 pIDreamInputParams->SetNumberOfGenerations(1000, DreamSolver::enable_edit);

 // Choice of likelihood function

 pIDreamInputParams->SetLikelihoodChoice(eLikelihood::LIK_101, DreamSolver::enable_edit);


 // Number of crossover values nCR

 pIDreamInputParams->SetNumberOfCrossoverValues(3, DreamSolver::enable_edit);

 // Number chain pairs for proposal delta

 pIDreamInputParams->SetNumberChainPairs(3, DreamSolver::enable_edit);

 // Random error for ergodicity lambda

 pIDreamInputParams->SetRandomErrorForErgodicity(0.05, DreamSolver::enable_edit);

 // Randomization zeta

 pIDreamInputParams->SetRandomization(1.0e-12, DreamSolver::enable_edit);

 // Test to detect outlier chains

 pIDreamInputParams->SetOutlierTest(eOutlierTest::eOutlierIqr, DreamSolver::enable_edit);

 // Probability of jump rate of 1 pJumpRate_one

 pIDreamInputParams->SetProbabilityOfJumprate(0.2, DreamSolver::enable_edit);

 // Adapt selection prob. crossover pCR

 pIDreamInputParams->SetAdaptSelection(1, DreamSolver::enable_edit);

 // Each Tth sample is stored thinning

 pIDreamInputParams->SetThinnigSampleToStore(1, DreamSolver::enable_edit);

 // GLUE likelihood parameter

 pIDreamInputParams->SetGlueLikelihood(10, DreamSolver::enable_edit);

 // Scaling factor of built-in jump rate beta0

 pIDreamInputParams->SetScalingFactorOfJumpRate(1.0, DreamSolver::enable_edit);

 // Bayesian Model Averaging (BMA) with hydrologic data. Number of different models

 pIDreamInputParams->SetNumberOfDifferentModelsBMA(0, DreamSolver::enable_edit);


 // Initial sampling distribution type

 pIDreamInputParams->SetInitialDistribution(eInitDistrib::eInitPrior, DreamSolver::enable_edit);

 // Boundary handling type

 pIDreamInputParams->SetBoundHandling(eBoundHandling::eBoundUnbounded, DreamSolver::enable_edit);

 // Prior distribution type

 pIDreamInputParams->SetPriorDistributionType(ePriorType::eUnivariate, DreamSolver::enable_edit);

 // Use prior distribution even for m_InitialDistribution != eInitPrior? Values: 1=true, 0=false

 pIDreamInputParams->SetUsePriorDistribution(0, DreamSolver::enable_edit);


 // Can model run in parallel?

 // Values: eParallelModeYes, eParallelModeNotRecommended, eParallelModeNotPossible

 pIDreamInputParams->SetParallelMode(eParallelModeYes, DreamSolver::enable_edit);


 // Model vectorization? For eVectorization::eVectYes, function CDreamEvaluator::EvaluateProposal

 // must evaluate proposals for all Markov chains in one step/call. Parallelization is then

 // automatically switched off.

 pIDreamInputParams->SetVectorization(eVectorization::eVectNone, DreamSolver::disable_edit);


 // ToDo:

 // 1. Modify the above parameters according to this particular project

 // 2. Remove the following MessageBox and return S_OK

 std::wstring sMessage;

 sMessage  = L"Incorrect DREAM input data!\n";

 sMessage += L"Please modify function CDreamEvaluator::GetInputParams()\n";

 sMessage += L"in DREAM plugin module. Set correct parameters and implement\n";

 sMessage += L"all other plugin functions needed for the project.";

 MessageBox(NULL, sMessage.c_str(), L"DREAM Plugin Module", MB_OK | MB_ICONSTOP);


 return E_FAIL;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::InitData

//-------------------------------------------------------------------------------------------------

(

 IDreamPluginInfo* pIPluginInfo            // Plugin information

, IDreamInputParViewer* pIDreamInputParams  // Current DREAM input parameters

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 This function is called to prepare:

 A/ DREAM input data before accessing them via the IDreamDataSource interface and

 B/ all other local data required by evaluator for the calculation.  

 It can be also used to read needed data from a file in directory pIPluginInfo->m_strModelDataDir

 (directory ...Drm_ExampleXX\Model\Data).

         

 Remark 1: This function prepares DREAM input data in the evaluator according to current

 DREAM parameters defined by pIPluginInfo interface. Note that some parameters can be

 different from default parameters defined in function CEvaluatorExample::GetInputParams().


 Remark 2: This function should be called before using functions

 CEvaluatorExample::GetMinMaxData, ::GetNormalData, ::GetPriorData, ::GetPriorDataCustom,

 ::GetMeasurementData and ::GetBayesData. However, function CEvaluatorExample::GetInputParams()

 can be called independently.


 Remark 3: When using this evaluator for parallel calculations, member variables can be shared

 by multiple threads and thus their values should not be changed during the calculation or

 you should make the code thread-safe using standard tools (e.g. critical sections, etc.).

 Another option is to disable running in parallel mode, which can be done in function

 CDreamEvaluator::GetInputParams - pIDreamInputParams->m_ParallelMode = eParallelModeNotPossible;


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{


 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetMeasurementData

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar       // Interface to DREAM input parameters

, IDreamDataMeasurement* pIMeasureData  // Interface to measurement data

, BSTR strModelDataDir                  // Path to directory with measurement data

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to load measurement data from files located in strModelDataDir

 and fill the data structure pIMeasureData. Measurement data are required by some types

 of likelihood functions.


 Types of measurement data:

 1. Calibration data        (Y)

 2. Measurement error data  (Sigma)


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Specific file with measurement data (each line one number)

 std::wstring file(strModelDataDir);

 file += L"\\abundances.txt";


 // Load data to Y

 vector<double> Y;

 if(!CDreamMath<>::ReadData(file, Y))

 {

   return E_FAIL;

 }


 // Data are set to solver by function with length and data itself:

 pIMeasureData->AddCalibrationData((int)Y.size(), &Y(0));


 return S_OK;

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Always check pIMeasureData pointer

 if(pIMeasureData == nullptr)

 {

   return E_INVALIDARG;

 }


 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetMinMaxData

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar // Interface to DREAM input parameters

, IDreamDataMinMax* pIMinMaxData  // Interface to Min/Max data

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define min/max values for initial LATIN and UNIFORM sampling

 distribution or to define min/max additional data (Measurement Error, Nuisance variables) for likelihood

 functions LIK_211, LIK_212, LIK_213, LIK_214 and LIK_217.  


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Normal use for Latin sampling

 // Fill min, max data

 pIMinMaxData->AddItem(0.00,  1.0); // alpha  

 or

 pIMinMaxData->AddExtendedItem(0.00, 10.0, 0, 1); // delta


 // Special use for LIK_211, LIK_212 and LIK_213 to add measurement error variables

 // Fill min, max, value , is variable selected (1) or not (0)

 pIMinMaxData->AddMeasurementErrorItem(0.0, 1.0, 1.0, 0);


 // Special use for LIK_213, LIK_214 and LIK_217 to add Nuisance variables

 // Fill min, max, value of nuisance variable, is variable selected (1) or not (0)

 pIMinMaxData->AddLikelihoodItem(0.0, 1.0, 1.0, 0);


 // ONLY FOR LIK_217

 // Additional x-range values for PCHIP (Piecewise Cubic Hermite Interpolating Polynomial)

 // Fill x-range with non-decreasing data

 pIMinMaxData->SetLVInterpolationValues(0, 1, 2, 3);


 return S_OK

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Always check pIMinMaxData pointer

 if(pIMinMaxData == nullptr)

 {

   return E_INVALIDARG;

 }


 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetNormalData

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar   // Interface to DREAM input parameters

, IDreamDataNormal* pINormalData    // Interface to normal distribution data

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define mean vector and Covariance matrix data for initial

 NORMAL sampling distribution.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Fill mean vector data

 for(size_t iIndex = 0; iIndex < 10; iIndex++)

 {

   pINormalData->AddItem(0);

 }


 // Covariance matrix diagonal value

 pINormalData->SetCovarianceDiagonalValue(5.0);


 return S_OK

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Always check pINormalData pointer

 if(pINormalData == nullptr)

 {

   return E_INVALIDARG;

 }


 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetPriorData

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar // Interface to DREAM input parameters

, IDreamDataPrior* pIPriorData    // Interface to prior distribution data

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define data for INITIAL PRIOR and PRIOR sampling distribution.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Fill prior univariate data

 pIPriorData->AddUnivariateItem(0.067, 0.006, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(0.445, 0.009, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(-2.310, 0.060, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(0.223, 0.011, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(-1.160, 0.270, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(0.390, 1.470, eDistributionUnivariate::eUnivariate_Normal);

 pIPriorData->AddUnivariateItem(-250.0, -50.0, eDistributionUnivariate::eUnivariate_Uniform);

 // OR


 // Fill prior multivariate normal data

 vector<double> mean(m_dimension, -2);

 matrix<double> cov = identity_matrix<double>(m_dimension);

 CDreamVector cmean(mean);

 CDreamMatrix ccov(cov);

 pIPriorData->SetMultivariateNormalItem(&cmean, &ccov);


 return S_OK

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetPriorDataCustom

//-------------------------------------------------------------------------------------------------

(  

 IDreamInputParViewer* pInputPar // Interface to DREAM input parameters

, IDreamMatrix* x                 // Input matrix

, IDreamMatrix* PR                // Output matrix

, ePriorDistrib callType          // Type of call of this function

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define CUSTOM distribution type of prior distribution instead of

 GetPriorData() function. This function can be called in two different situations specified by the

 callType parameter:

 A) during initialization of dream solver (callType = ePriorInitialize)

 B) during DREAM calculation (callType = ePriorCalculate)


 The initial state (callType = ePriorInitialize) is usually defined by a function generating

 random numbers (e.g. PR = NormRnd(mu, sigma)), while the second type of call (callType = ePriorCalculate)

 typically uses a function dependent on x-matrix (e.g. PR = NormPdf(x, mu, sigma)).  

 

 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION (Example07):


 // Temporary matrices used for calculations

 matrix<double> tmpx(x->_rowCount, x->_colCount);


 // Copy data

 for(int iRow = 0; iRow < x->_rowCount; iRow++)

 {

   for(int iCol = 0; iCol < x->_colCount; iCol++)

   {

     tmpx(iRow, iCol) = x->_data[iRow * x->_colCount + iCol];

   }

 }


 matrix<double> tmpPR(PR->_rowCount, PR->_colCount);

 size_t d = tmpPR.size2();

 size_t N = tmpPR.size1();


 vector<double> mu(d);

 mu(0) =  0.067;

 mu(1) =  0.445;

 mu(2) = -2.310;

 mu(3) =  0.223;

 mu(4) = -1.160;

 mu(5) =  0.390;

 mu(6) = -250.0;


 vector<double> sigma(d);

 sigma(0) = 0.006;

 sigma(1) = 0.009;

 sigma(2) = 0.060;

 sigma(3) = 0.011;

 sigma(4) = 0.270;

 sigma(5) = 1.470;

 sigma(6) = -50.0;

 

 enum ePriorFunction { NormPdf, UnifPdf, NormRnd, UnifRnd };

 vector<ePriorFunction> funcType(d);

 funcType(0) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(1) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(2) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(3) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(4) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(5) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::NormPdf : ePriorFunction::NormRnd;

 funcType(6) = callType == ePriorDistrib::ePriorCalculate ? ePriorFunction::UnifPdf : ePriorFunction::UnifRnd;


 double dRandValue = 0.0;

 for(size_t i = 0; i < d; i++)

 {

   for(size_t j = 0; j < N; j++)

   {

     // Compute prior density of proposal

     switch(funcType(i))

     {

       case(ePriorFunction::NormPdf):

       {

         dRandValue = CDreamMath<double>::NormPdf(tmpx(j, i), mu(i), sigma(i));

         tmpPR(j, i) = max(dRandValue, 1.e-299);

         break;

       }

       case(ePriorFunction::UnifPdf):

       {

         dRandValue = CDreamMath<double>::UnifPdf(tmpx(j, i), mu(i), sigma(i));

         tmpPR(j, i) = max(dRandValue, 1.e-299);

         break;

       }

       case(ePriorFunction::NormRnd):

       {

         tmpPR(j, i) = CDreamMath<double>::NormRnd(mu(i), sigma(i));

         break;

       }

       case(ePriorFunction::UnifRnd):

       {

         tmpPR(j, i) = CDreamMath<double>::UnifRnd(mu(i), sigma(i));

         break;

       }

       default:

       {

         assert(false);

       }

     }

   }

 }


 // Replace content of res by tmp values

 for(int iRow = 0; iRow < PR->_rowCount; iRow++)

 {

   for(int iCol = 0; iCol < PR->_colCount; iCol++)

   {

     PR->_data[iRow * PR->_colCount + iCol] = tmpPR(iRow, iCol);

   }

 }


*/

//////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetBayesData

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar // Interface to DREAM input parameters

, IDreamDataABC* pIBayesCompData  // Interface to Approximate Bayesian Computation data  

, BSTR strModelDataDir            // Directory with permanent data of the model

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to define summary metrics vector (S), corresponding ABC Epsilon

 vector and distance function which can be used for likelihood LIK_321 and LIK_322.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Set ABC distance function type

 pIBayesCompData->SetABCFunctionType(eDistanceFunction::eSqrt_1Over20_MultiplyBy_Sum_AminusBSquared);


 // Scalar/vector with summary metrics (S) and ABC Epsilon data

 vector<double> eps(m_d, 0.025);

 vector<double> rnd(m_d);

 Rand(rnd);

 vector<double> sumMetrics = m_min + element_prod(rnd, m_max - m_min);


 pIBayesCompData->AddComputationData((int)sumMetrics.size(), &sumMetrics[0], &eps(0));


*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Always check pIBayesCompData pointer

 if(pIBayesCompData == nullptr)

 {

   return E_INVALIDARG;

 }


 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::PrepareWorkDir

//-------------------------------------------------------------------------------------------------

(

 BSTR strSourceDir,     // Path to the permanent "Model\Data" directory

 BSTR strDestinationDir // Path to the temporary directory designated for the current thread

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to prepare files in special directories needed for DREAM

 multi-core calculations. These folders may be required by some models working with data

 in external files. Each calculation thread should then have its files in a designated

 directory to prevent sharing violation problems.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will continue)

 E_FAIL  - Operation failed (program will stop)

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::EvaluateProposal

//-------------------------------------------------------------------------------------------------

(

 IDreamInputParViewer* pInputPar // Interface to DREAM input parameters

, int iSim              // input parameter (i-th simulation / Markov chain)

, IDreamMatrix* x       // input matrix (m_NumberOfMarkovChains x m_ProblemDimension)

, IDreamMatrix* res     // output matrix (Data_Dimension x m_NumberOfMarkovChains)

, BSTR strWorkingDir    // path to the current working directory (for current calculation thread)

, BSTR strModelDataDir  // path to the permanent directory with model data

, BSTR strModelBinDir   // path to the permanent directory with model executables

)

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 The purpose of this function is to evaluate the current proposal (i.e. one single step

 of IDreamInputParams::GetNumberOfGenerations() steps) for iSim-th Markov chain. It computes

 the likelihood (or log-likelihood or the residual vector to be compared with the measurement

 - see the technical manual) for iSim-th row of input matrix "x" and returns the result

 in output matrix "res".  

 

 Parameter iSim is from interval <0, IDreamInputParams::GetNumberOfMarkovChains() - 1>.

 If pInputPar->GetVectorization() == eVectorization::eVectYes, then iSim = 0 and all proposals

 (for all Markov chains) should be evaluated in one step, i.e. during one call of this function.


 Data_Dimension:

 *************************************************************************************************

 ** ROW DIMENSION OF "RES" OUTPUT MATRIX:

 **

 **   if(calibration_data_avaliable && bayes_diagnostic && summary_metrics_data)

 **   {

 **     data_dimension = calibration_data_count + summary_metrics_data_count

 **   }

 **   else if(calibration_data_avaliable && (!bayes_diagnostic || !summary_metrics_data))

 **   {

 **     data_dimension = calibration_data_count

 **   }

 **   else if(summary_metrics_data_avaliable)

 **   {

 **     data_dimension = summary_metrics_data_count

 **   }

 **   else if(calibration_data_avaliable && summary_metrics_data_avaliable)

 **   {

 **     data_dimension = calibration_data_count > summary_metrics_data_count ?

 **                      calibration_data_count : summary_metrics_data_count

 **   }

 **   else

 **   {

 **     data_dimension = 1

 **   }

 *************************************************************************************************


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented (program will stop - this function must be implemented)

 E_FAIL  - Operation failed (program will stop)


 EXAMPLE OF IMPLEMENTATION:


 // Copy data of iSim-row of x-matrix to BOOST vector type

 vector<double> ix(x->_colCount);

 for(int iCol = 0; iCol < x->_colCount; iCol++)

 {

   ix(iCol) = x->_data[iSim * x->_colCount + iCol];

 }


 // Calculate log-likelihood of vector ix and store the result in vector tmpLog

 vector<double> tmpLog(res->_rowCount);

 for(int iRow = 0; iRow < res->_rowCount; iRow++)

 {

   tmpLog(iRow) = ... (F(ix))

 }


 // Replace content of res by calculated values

 for(int iRow = 0; iRow < res->_rowCount; iRow++)

 {

   res->_data[iRow * res->_colCount + iSim] = tmpLog(iRow);

 }


 return S_OK;

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // TODO: Implement this function and return S_OK

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::OnCalculationFinished()

//-------------------------------------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////////////////////////////////

/*

 DESCRIPTION:


 This function is called after finishing the calculation to perform possible cleanup, etc.


 RETURN VALUE:


 S_OK    - Operation successful

 S_FALSE - Function not implemented

 E_FAIL  - Operation failed

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Not needed/implemented

 return S_FALSE;

}


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::GetLastError(BSTR* strErrorText)

//-------------------------------------------------------------------------------------------------

{

 // If there is an error, set the description and return S_OK. For example :

 // std::wstring m_MyLastError = ...

 // *strErrorText = SysAllocString(m_MyLastError.c_str());

 // return (SysStringLen(*strErrorText)>0) ? S_OK : S_FALSE;


 // If there is no error, return S_FALSE

 return S_FALSE;

}



///////////////////////////////////////////////////////////////////////////////////////////////////

// Implementation of COM IUnknown interface

///////////////////////////////////////////////////////////////////////////////////////////////////


//-------------------------------------------------------------------------------------------------

 HRESULT STDMETHODCALLTYPE CDreamEvaluator::QueryInterface(const IID& iid, void** ppv)

//-------------------------------------------------------------------------------------------------

/*

 Implementation of standard COM interface. No changes needed.

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Check parameters

 if(ppv == nullptr)

 {

   // Invalid argument

   return E_INVALIDARG;

 }


 // Always set pointer to nullptr

 *ppv = nullptr;


 if(InlineIsEqualGUID(iid, IID_IUnknown) || InlineIsEqualGUID(iid, IID_IDreamEvaluator))

 {

   // Return pointer to IDreamSolver interface

   *ppv = static_cast<IDreamEvaluator*>(this);

 }

 else

 {

   // Unimplemented interface

   *ppv = nullptr;

   return E_NOINTERFACE;

 }


 // Increment reference count

 reinterpret_cast<IUnknown*>(*ppv)->AddRef();

 return S_OK;

}


//-------------------------------------------------------------------------------------------------

 ULONG STDMETHODCALLTYPE CDreamEvaluator::AddRef()

//-------------------------------------------------------------------------------------------------

/*

 Implementation of standard COM interface. No changes needed.

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Increment reference count

 return ::InterlockedIncrement(&m_cRef);

}


//-------------------------------------------------------------------------------------------------

 ULONG STDMETHODCALLTYPE CDreamEvaluator::Release()

//-------------------------------------------------------------------------------------------------

/*

 Implementation of standard COM interface. No changes needed.

*/

///////////////////////////////////////////////////////////////////////////////////////////////////

{

 // Decrement reference count

 if(::InterlockedDecrement(&m_cRef) == 0)

 {

   // Object is not referenced, it is safe to delete it

   delete this;

   return 0;

 }


 // Return actual reference count

 return m_cRef;

}