Skylark (Sketching Library)
0.1
|
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