Skylark (Sketching Library)
0.1
|
00001 #ifndef SKYLARK_FRFT_DATA_HPP 00002 #define SKYLARK_FRFT_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 <vector> 00009 00010 #include "../utility/randgen.hpp" 00011 00012 namespace skylark { namespace sketch { 00013 00014 #if SKYLARK_HAVE_FFTW || SKYLARK_HAVE_SPIRALWHT 00015 00016 namespace bstrand = boost::random; 00017 00030 struct FastRFT_data_t : public sketch_transform_data_t { 00031 00032 typedef sketch_transform_data_t base_t; 00033 00034 FastRFT_data_t (int N, int S, skylark::base::context_t& context) 00035 : base_t(N, S, context, "FastRFT"), _NB(N), 00036 numblks(1 + ((base_t::_S - 1) / _NB)), 00037 scale(std::sqrt(2.0 / base_t::_S)), 00038 Sm(numblks * _NB) { 00039 00040 context = build(); 00041 } 00042 00043 FastRFT_data_t (const boost::property_tree::ptree &pt) 00044 : base_t(pt.get<int>("N"), pt.get<int>("S"), 00045 base::context_t(pt.get_child("creation_context")), "FastRFT"), 00046 _NB(base_t::_N), 00047 numblks(1 + ((base_t::_S - 1) / _NB)), 00048 scale(std::sqrt(2.0 / base_t::_S)), 00049 Sm(numblks * _NB) { 00050 00051 build(); 00052 } 00053 00059 virtual 00060 boost::property_tree::ptree to_ptree() const { 00061 boost::property_tree::ptree pt; 00062 sketch_transform_data_t::add_common(pt); 00063 return pt; 00064 } 00065 00066 00067 protected: 00068 FastRFT_data_t (int N, int S, const skylark::base::context_t& context, 00069 std::string type) 00070 : base_t(N, S, context, type), _NB(N), 00071 numblks(1 + ((base_t::_S - 1) / _NB)), 00072 scale(std::sqrt(2.0 / base_t::_S)), 00073 Sm(numblks * _NB) { 00074 00075 } 00076 00077 const int _NB; 00079 const int numblks; 00080 const double scale; 00081 std::vector<double> Sm; 00082 std::vector<double> B; 00083 std::vector<double> G; 00084 std::vector<size_t> P; 00085 std::vector<double> shifts; 00087 base::context_t build() { 00088 base::context_t ctx = base_t::build(); 00089 const double pi = boost::math::constants::pi<double>(); 00090 bstrand::uniform_real_distribution<double> dist_shifts(0, 2 * pi); 00091 shifts = ctx.generate_random_samples_array(base_t::_S, dist_shifts); 00092 utility::rademacher_distribution_t<double> dist_B; 00093 00094 B = ctx.generate_random_samples_array(numblks * _NB, dist_B); 00095 bstrand::normal_distribution<double> dist_G; 00096 G = ctx.generate_random_samples_array(numblks * _NB, dist_G); 00097 00098 // For the permutation we use Fisher-Yates (Knuth) 00099 // The following will generate the indexes for the swaps. However 00100 // the scheme here might have a small bias if NB is small 00101 // (has to be really small). 00102 bstrand::uniform_int_distribution<size_t> dist_P(0); 00103 P = ctx.generate_random_samples_array(numblks * (_NB - 1), dist_P); 00104 for(int i = 0; i < numblks; i++) 00105 for(int j = _NB - 1; j >= 1; j--) 00106 P[i * (_NB - 1) + _NB - 1 - j] = 00107 P[i * (_NB - 1) + _NB - 1 - j] % (j + 1); 00108 00109 // Fill scaling matrix with 1. Subclasses (which are adapted to concrete 00110 // kernels) should modify this. 00111 std::fill(Sm.begin(), Sm.end(), 1.0); 00112 00113 return ctx; 00114 } 00115 00116 00117 // TODO there is also the issue of type of FUT, which now depends on what 00118 // is installed. For seralization we need to add an indicator on type 00119 // of the underlying FUT. 00120 static int block_size(int N) { 00121 #if SKYLARK_HAVE_FFTW 00122 return N; 00123 #elif SKYLARK_HAVE_SPIRALWHT 00124 return (int)std::pow(2, std::ceil(std::log(N)/std::log(2))); 00125 #endif 00126 } 00127 00128 }; 00129 00130 struct FastGaussianRFT_data_t : 00131 public FastRFT_data_t { 00132 00133 typedef FastRFT_data_t base_t; 00134 00136 struct params_t : public sketch_params_t { 00137 00138 params_t(double sigma) : sigma(sigma) { 00139 00140 } 00141 00142 const double sigma; 00143 }; 00144 00145 FastGaussianRFT_data_t(int N, int S, double sigma, 00146 skylark::base::context_t& context) 00147 : base_t(N, S, context, "FastGaussianRFT"), _sigma(sigma) { 00148 00149 std::fill(base_t::Sm.begin(), base_t::Sm.end(), 00150 1.0 / (_sigma * std::sqrt(base_t::_N))); 00151 context = base_t::build(); 00152 } 00153 00154 FastGaussianRFT_data_t(int N, int S, const params_t& params, 00155 skylark::base::context_t& context) 00156 : base_t(N, S, context, "FastGaussianRFT"), _sigma(params.sigma) { 00157 00158 std::fill(base_t::Sm.begin(), base_t::Sm.end(), 00159 1.0 / (_sigma * std::sqrt(base_t::_N))); 00160 context = base_t::build(); 00161 } 00162 00163 FastGaussianRFT_data_t(const boost::property_tree::ptree &pt) : 00164 base_t(pt.get<int>("N"), pt.get<int>("S"), 00165 base::context_t(pt.get_child("creation_context")), "FastGaussianRFT"), 00166 _sigma(pt.get<double>("sigma")) { 00167 00168 std::fill(base_t::Sm.begin(), base_t::Sm.end(), 00169 1.0 / (_sigma * std::sqrt(base_t::_N))); 00170 base_t::build(); 00171 } 00172 00178 virtual 00179 boost::property_tree::ptree to_ptree() const { 00180 boost::property_tree::ptree pt; 00181 sketch_transform_data_t::add_common(pt); 00182 pt.put("sigma", _sigma); 00183 return pt; 00184 } 00185 00186 protected: 00187 FastGaussianRFT_data_t(int N, int S, double sigma, 00188 const skylark::base::context_t& context, std::string type) 00189 : base_t(N, S, context, type), _sigma(sigma) { 00190 00191 std::fill(base_t::Sm.begin(), base_t::Sm.end(), 00192 1.0 / (_sigma * std::sqrt(base_t::_N))); 00193 } 00194 00195 const double _sigma; 00197 }; 00198 00199 } } 00201 #endif // SKYLARK_HAVE_FFTW || SKYLARK_HAVE_SPIRALWHT 00202 #endif