Skylark (Sketching Library)  0.1
/var/lib/jenkins/jobs/Skylark/workspace/sketch/FRFT_data.hpp
Go to the documentation of this file.
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