Skylark (Sketching Library)  0.1
/var/lib/jenkins/jobs/Skylark/workspace/sketch/WZT_data.hpp
Go to the documentation of this file.
00001 #ifndef SKYLARK_WZT_DATA_HPP
00002 #define SKYLARK_WZT_DATA_HPP
00003 
00004 #ifndef SKYLARK_SKETCH_HPP
00005 #error "Include top-level sketch.hpp instead of including individuals headers"
00006 #endif
00007 
00008 #include "../utility/distributions.hpp"
00009 
00010 namespace skylark { namespace sketch {
00011 
00027 struct WZT_data_t : public hash_transform_data_t<
00028     boost::random::uniform_int_distribution,
00029     boost::random::exponential_distribution > {
00030 
00031     typedef hash_transform_data_t<
00032         boost::random::uniform_int_distribution,
00033         boost::random::exponential_distribution >  base_t;
00034 
00036     struct params_t : public sketch_params_t {
00037 
00038         params_t(double p) : p(p) {
00039 
00040         }
00041 
00042         const double p;
00043     };
00044 
00045     WZT_data_t(int N, int S, double p, base::context_t& context)
00046         : base_t(N, S, context, "WZT"), _P(p) {
00047 
00048         // TODO verify that p is in the correct range.
00049         if(p < 1 || 2 < p)
00050             SKYLARK_THROW_EXCEPTION (
00051                 base::sketch_exception()
00052                     << base::error_msg("WZT parameter p has to be in (1, 2)") );
00053 
00054         context = build();
00055     }
00056 
00057     WZT_data_t(int N, int S, const params_t& params, base::context_t& context)
00058         : base_t(N, S, context, "WZT"), _P(params.p) {
00059 
00060         // TODO verify that p is in the correct range.
00061         if(_P < 1 || 2 < _P)
00062             SKYLARK_THROW_EXCEPTION (
00063                 base::sketch_exception()
00064                     << base::error_msg("WZT parameter p has to be in (1, 2)") );
00065 
00066         context = build();
00067     }
00068 
00069 
00070     WZT_data_t(const boost::property_tree::ptree &pt) :
00071         base_t(pt.get<int>("N"), pt.get<int>("S"),
00072             base::context_t(pt.get_child("creation_context")), "WZT"),
00073         _P(pt.get<double>("P")) {
00074 
00075         base_t::build();
00076     }
00077 
00083     virtual
00084     boost::property_tree::ptree to_ptree() const {
00085         boost::property_tree::ptree pt;
00086         sketch_transform_data_t::add_common(pt);
00087         pt.put("P", _P);
00088         return pt;
00089     }
00090 
00091 protected:
00092     WZT_data_t(int N, int S, double p, const base::context_t& context,
00093         std::string type)
00094         : base_t(N, S, context, type), _P(p) {
00095 
00096         // TODO verify that p is in the correct range.
00097         if(p < 1 || 2 < p)
00098             SKYLARK_THROW_EXCEPTION (
00099                 base::sketch_exception()
00100                     << base::error_msg("WZT parameter p has to be in (1, 2)") );
00101     }
00102 
00103 private:
00104     double _P;
00105 
00106     base::context_t build() {
00107 
00108         // Since the distribution depends on the target p we have to pass p as
00109         // a parameter. We also cannot just use the distribution as template.
00110         // The only solution I found is to let the base class generate the
00111         // numbers and then modify them to the correct distribution.
00112         // We also need it to +/- with equal probability. This solves this as
00113         // well.
00114         base::context_t ctx = base_t::build();
00115         utility::rademacher_distribution_t<double> pmdist;
00116         std::vector<double> pmvals =
00117             ctx.generate_random_samples_array(base_t::_N, pmdist);
00118         for(int i = 0; i < base_t::_N; i++)
00119              base_t::row_value[i] =
00120                  pmvals[i] * pow(1.0 / base_t::row_value[i], 1.0 / _P);
00121         return ctx;
00122     }
00123 };
00124 
00125 } } 
00127 #endif // SKYLARK_MMT_DATA_HPP