/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Flat p.d.f. in N dimensions
// END_HTML
//

#include "RooFit.h"

#include "Riostream.h"
#include <math.h>

#include "RooUniform.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooRandom.h"
#include "RooMath.h"
#include "RooArgSet.h"

using namespace std;

ClassImp(RooUniform)


//_____________________________________________________________________________
RooUniform::RooUniform(const char *name, const char *title, const RooArgSet& _x) :
  RooAbsPdf(name,title),
  x("x","Observables",this,kTRUE,kFALSE)
{
  x.add(_x) ;
}



//_____________________________________________________________________________
RooUniform::RooUniform(const RooUniform& other, const char* name) : 
  RooAbsPdf(other,name), x("x",this,other.x)
{
}



//_____________________________________________________________________________
Double_t RooUniform::evaluate() const
{
  return 1 ;
}



//_____________________________________________________________________________
Int_t RooUniform::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const 
{
  // Advertise analytical integral

  Int_t nx = x.getSize() ;
  if (nx>31) {
    // Warn that analytical integration is only provided for the first 31 observables
    coutW(Integration) << "RooUniform::getAnalyticalIntegral(" << GetName() << ") WARNING: p.d.f. has " << x.getSize() 
		       << " observables, analytical integration is only implemented for the first 31 observables" << endl ;
    nx=31 ;
  }

  Int_t code(0) ;
  for (int i=0 ; i<x.getSize() ; i++) {
    if (allVars.find(x.at(i)->GetName())) {
      code |= (1<<i) ;
      analVars.add(*allVars.find(x.at(i)->GetName())) ;
    }
  }    
  return code ;
}



//_____________________________________________________________________________
Double_t RooUniform::analyticalIntegral(Int_t code, const char* rangeName) const 
{
  // Implement analytical integral
  Double_t ret(1) ;
  for (int i=0 ; i<32 ; i++) {
    if (code&(1<<i)) {
      RooAbsRealLValue* var = (RooAbsRealLValue*)x.at(i) ;
      ret *= (var->getMax(rangeName) - var->getMin(rangeName)) ;
    }    
  }
  return ret ;
}




//_____________________________________________________________________________
Int_t RooUniform::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t /*staticInitOK*/) const
{
  // Advertise internal generator 

  Int_t nx = x.getSize() ;
  if (nx>31) {
    // Warn that analytical integration is only provided for the first 31 observables
    coutW(Integration) << "RooUniform::getGenerator(" << GetName() << ") WARNING: p.d.f. has " << x.getSize() 
		       << " observables, internal integrator is only implemented for the first 31 observables" << endl ;
    nx=31 ;
  }
  
  Int_t code(0) ;
  for (int i=0 ; i<x.getSize() ; i++) {
    if (directVars.find(x.at(i)->GetName())) {
      code |= (1<<i) ;
      generateVars.add(*directVars.find(x.at(i)->GetName())) ;
    }
  }    
  return code ;
  return 0 ;
}



//_____________________________________________________________________________
void RooUniform::generateEvent(Int_t code)
{
  // Implement internal generator

  // Fast-track handling of one-observable case
  if (code==1) {
    ((RooAbsRealLValue*)x.at(0))->randomize() ;
    return ;
  }

  for (int i=0 ; i<32 ; i++) {
    if (code&(1<<i)) {
      RooAbsRealLValue* var = (RooAbsRealLValue*)x.at(i) ;
      var->randomize() ;
    }    
  }
}


 RooUniform.cxx:1
 RooUniform.cxx:2
 RooUniform.cxx:3
 RooUniform.cxx:4
 RooUniform.cxx:5
 RooUniform.cxx:6
 RooUniform.cxx:7
 RooUniform.cxx:8
 RooUniform.cxx:9
 RooUniform.cxx:10
 RooUniform.cxx:11
 RooUniform.cxx:12
 RooUniform.cxx:13
 RooUniform.cxx:14
 RooUniform.cxx:15
 RooUniform.cxx:16
 RooUniform.cxx:17
 RooUniform.cxx:18
 RooUniform.cxx:19
 RooUniform.cxx:20
 RooUniform.cxx:21
 RooUniform.cxx:22
 RooUniform.cxx:23
 RooUniform.cxx:24
 RooUniform.cxx:25
 RooUniform.cxx:26
 RooUniform.cxx:27
 RooUniform.cxx:28
 RooUniform.cxx:29
 RooUniform.cxx:30
 RooUniform.cxx:31
 RooUniform.cxx:32
 RooUniform.cxx:33
 RooUniform.cxx:34
 RooUniform.cxx:35
 RooUniform.cxx:36
 RooUniform.cxx:37
 RooUniform.cxx:38
 RooUniform.cxx:39
 RooUniform.cxx:40
 RooUniform.cxx:41
 RooUniform.cxx:42
 RooUniform.cxx:43
 RooUniform.cxx:44
 RooUniform.cxx:45
 RooUniform.cxx:46
 RooUniform.cxx:47
 RooUniform.cxx:48
 RooUniform.cxx:49
 RooUniform.cxx:50
 RooUniform.cxx:51
 RooUniform.cxx:52
 RooUniform.cxx:53
 RooUniform.cxx:54
 RooUniform.cxx:55
 RooUniform.cxx:56
 RooUniform.cxx:57
 RooUniform.cxx:58
 RooUniform.cxx:59
 RooUniform.cxx:60
 RooUniform.cxx:61
 RooUniform.cxx:62
 RooUniform.cxx:63
 RooUniform.cxx:64
 RooUniform.cxx:65
 RooUniform.cxx:66
 RooUniform.cxx:67
 RooUniform.cxx:68
 RooUniform.cxx:69
 RooUniform.cxx:70
 RooUniform.cxx:71
 RooUniform.cxx:72
 RooUniform.cxx:73
 RooUniform.cxx:74
 RooUniform.cxx:75
 RooUniform.cxx:76
 RooUniform.cxx:77
 RooUniform.cxx:78
 RooUniform.cxx:79
 RooUniform.cxx:80
 RooUniform.cxx:81
 RooUniform.cxx:82
 RooUniform.cxx:83
 RooUniform.cxx:84
 RooUniform.cxx:85
 RooUniform.cxx:86
 RooUniform.cxx:87
 RooUniform.cxx:88
 RooUniform.cxx:89
 RooUniform.cxx:90
 RooUniform.cxx:91
 RooUniform.cxx:92
 RooUniform.cxx:93
 RooUniform.cxx:94
 RooUniform.cxx:95
 RooUniform.cxx:96
 RooUniform.cxx:97
 RooUniform.cxx:98
 RooUniform.cxx:99
 RooUniform.cxx:100
 RooUniform.cxx:101
 RooUniform.cxx:102
 RooUniform.cxx:103
 RooUniform.cxx:104
 RooUniform.cxx:105
 RooUniform.cxx:106
 RooUniform.cxx:107
 RooUniform.cxx:108
 RooUniform.cxx:109
 RooUniform.cxx:110
 RooUniform.cxx:111
 RooUniform.cxx:112
 RooUniform.cxx:113
 RooUniform.cxx:114
 RooUniform.cxx:115
 RooUniform.cxx:116
 RooUniform.cxx:117
 RooUniform.cxx:118
 RooUniform.cxx:119
 RooUniform.cxx:120
 RooUniform.cxx:121
 RooUniform.cxx:122
 RooUniform.cxx:123
 RooUniform.cxx:124
 RooUniform.cxx:125
 RooUniform.cxx:126
 RooUniform.cxx:127
 RooUniform.cxx:128
 RooUniform.cxx:129
 RooUniform.cxx:130
 RooUniform.cxx:131
 RooUniform.cxx:132
 RooUniform.cxx:133
 RooUniform.cxx:134
 RooUniform.cxx:135
 RooUniform.cxx:136
 RooUniform.cxx:137
 RooUniform.cxx:138
 RooUniform.cxx:139
 RooUniform.cxx:140
 RooUniform.cxx:141
 RooUniform.cxx:142
 RooUniform.cxx:143
 RooUniform.cxx:144
 RooUniform.cxx:145
 RooUniform.cxx:146
 RooUniform.cxx:147
 RooUniform.cxx:148
 RooUniform.cxx:149
 RooUniform.cxx:150
 RooUniform.cxx:151
 RooUniform.cxx:152
 RooUniform.cxx:153
 RooUniform.cxx:154