// @(#)root/roostats:$Id$
// Authors: Kevin Belasco        17/06/2009
// Authors: Kyle Cranmer         17/06/2009
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML
<p>
UniformProposal is a concrete implementation of the ProposalFunction interface
for use with a Markov Chain Monte Carlo algorithm.  This proposal function is
a uniformly random distribution over the parameter space.  The proposal
ignores the current point when it proposes a new point.  The proposal
function is symmetric, though it may not cause a MetropolisHastings run to
converge as quickly as other proposal functions.
</p>
END_HTML
*/
//

#ifndef ROOT_Rtypes
#include "Rtypes.h"
#endif

#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif
#ifndef ROOSTATS_UniformProposal
#include "RooStats/UniformProposal.h"
#endif
#ifndef ROO_ARG_SET
#include "RooArgSet.h"
#endif
#ifndef ROO_MSG_SERVICE
#include "RooMsgService.h"
#endif
#ifndef ROO_REAL_VAR
#include "RooRealVar.h"
#endif
#ifndef ROOT_TIterator
#include "TIterator.h"
#endif

using namespace std;

ClassImp(RooStats::UniformProposal);

using namespace RooFit;
using namespace RooStats;

// Populate xPrime with a new proposed point
void UniformProposal::Propose(RooArgSet& xPrime, RooArgSet& /* x */)
{
   // kbelasco: remember xPrime and x have not been checked for containing
   // only RooRealVars
   RooStats::RandomizeCollection(xPrime);
}

// Determine whether or not the proposal density is symmetric for
// points x1 and x2 - that is, whether the probabilty of reaching x2
// from x1 is equal to the probability of reaching x1 from x2
Bool_t UniformProposal::IsSymmetric(RooArgSet& /* x1 */ , RooArgSet& /* x2 */)
{
   return true;
}

// Return the probability of proposing the point x1 given the starting
// point x2
Double_t UniformProposal::GetProposalDensity(RooArgSet& /* x1 */,
                                              RooArgSet& x2)
{
   // For a uniform proposal, all points have equal probability and the
   // value of the proposal density function is:
   // 1 / (N-dimensional volume of interval)
   Double_t volume = 1.0;
   TIterator* it = x2.createIterator();
   RooRealVar* var;
   while ((var = (RooRealVar*)it->Next()) != NULL)
      volume *= (var->getMax() - var->getMin());
   delete it;
   return 1.0 / volume;
}
 UniformProposal.cxx:1
 UniformProposal.cxx:2
 UniformProposal.cxx:3
 UniformProposal.cxx:4
 UniformProposal.cxx:5
 UniformProposal.cxx:6
 UniformProposal.cxx:7
 UniformProposal.cxx:8
 UniformProposal.cxx:9
 UniformProposal.cxx:10
 UniformProposal.cxx:11
 UniformProposal.cxx:12
 UniformProposal.cxx:13
 UniformProposal.cxx:14
 UniformProposal.cxx:15
 UniformProposal.cxx:16
 UniformProposal.cxx:17
 UniformProposal.cxx:18
 UniformProposal.cxx:19
 UniformProposal.cxx:20
 UniformProposal.cxx:21
 UniformProposal.cxx:22
 UniformProposal.cxx:23
 UniformProposal.cxx:24
 UniformProposal.cxx:25
 UniformProposal.cxx:26
 UniformProposal.cxx:27
 UniformProposal.cxx:28
 UniformProposal.cxx:29
 UniformProposal.cxx:30
 UniformProposal.cxx:31
 UniformProposal.cxx:32
 UniformProposal.cxx:33
 UniformProposal.cxx:34
 UniformProposal.cxx:35
 UniformProposal.cxx:36
 UniformProposal.cxx:37
 UniformProposal.cxx:38
 UniformProposal.cxx:39
 UniformProposal.cxx:40
 UniformProposal.cxx:41
 UniformProposal.cxx:42
 UniformProposal.cxx:43
 UniformProposal.cxx:44
 UniformProposal.cxx:45
 UniformProposal.cxx:46
 UniformProposal.cxx:47
 UniformProposal.cxx:48
 UniformProposal.cxx:49
 UniformProposal.cxx:50
 UniformProposal.cxx:51
 UniformProposal.cxx:52
 UniformProposal.cxx:53
 UniformProposal.cxx:54
 UniformProposal.cxx:55
 UniformProposal.cxx:56
 UniformProposal.cxx:57
 UniformProposal.cxx:58
 UniformProposal.cxx:59
 UniformProposal.cxx:60
 UniformProposal.cxx:61
 UniformProposal.cxx:62
 UniformProposal.cxx:63
 UniformProposal.cxx:64
 UniformProposal.cxx:65
 UniformProposal.cxx:66
 UniformProposal.cxx:67
 UniformProposal.cxx:68
 UniformProposal.cxx:69
 UniformProposal.cxx:70
 UniformProposal.cxx:71
 UniformProposal.cxx:72
 UniformProposal.cxx:73
 UniformProposal.cxx:74
 UniformProposal.cxx:75
 UniformProposal.cxx:76
 UniformProposal.cxx:77
 UniformProposal.cxx:78
 UniformProposal.cxx:79
 UniformProposal.cxx:80
 UniformProposal.cxx:81
 UniformProposal.cxx:82
 UniformProposal.cxx:83
 UniformProposal.cxx:84
 UniformProposal.cxx:85
 UniformProposal.cxx:86
 UniformProposal.cxx:87
 UniformProposal.cxx:88