Skylark (Sketching Library)
0.1
|
00001 #ifndef SKYLARK_RFT_ELEMENTAL_HPP 00002 #define SKYLARK_RFT_ELEMENTAL_HPP 00003 00004 namespace skylark { 00005 namespace sketch { 00006 00010 template <typename ValueType, 00011 template <typename> class InputType, 00012 template <typename> class KernelDistribution> 00013 struct RFT_t < 00014 InputType<ValueType>, 00015 elem::Matrix<ValueType>, 00016 KernelDistribution> : 00017 public RFT_data_t<KernelDistribution> { 00018 // Typedef value, matrix, transform, distribution and transform data types 00019 // so that we can use them regularly and consistently. 00020 typedef ValueType value_type; 00021 typedef InputType<value_type> matrix_type; 00022 typedef elem::Matrix<value_type> output_matrix_type; 00023 typedef RFT_data_t<KernelDistribution> data_type; 00024 private: 00025 typedef skylark::sketch::dense_transform_t <matrix_type, 00026 output_matrix_type, 00027 KernelDistribution> 00028 underlying_t; 00029 00030 00031 protected: 00035 RFT_t (int N, int S, base::context_t& context) 00036 : data_type (N, S, context) { 00037 00038 } 00039 00040 public: 00044 RFT_t(const RFT_t<matrix_type, 00045 output_matrix_type, 00046 KernelDistribution>& other) 00047 : data_type(other) { 00048 00049 } 00050 00054 RFT_t(const data_type& other_data) 00055 : data_type(other_data) { 00056 00057 } 00058 00062 template <typename Dimension> 00063 void apply (const matrix_type& A, 00064 output_matrix_type& sketch_of_A, 00065 Dimension dimension) const { 00066 try { 00067 apply_impl(A, sketch_of_A, dimension); 00068 } catch (std::logic_error e) { 00069 SKYLARK_THROW_EXCEPTION ( 00070 base::elemental_exception() 00071 << base::error_msg(e.what()) ); 00072 } catch(boost::mpi::exception e) { 00073 SKYLARK_THROW_EXCEPTION ( 00074 base::mpi_exception() 00075 << base::error_msg(e.what()) ); 00076 } 00077 } 00078 00079 private: 00084 void apply_impl(const matrix_type& A, 00085 output_matrix_type& sketch_of_A, 00086 skylark::sketch::columnwise_tag tag) const { 00087 00088 // TODO verify sizes etc. 00089 underlying_t underlying(*data_type::_underlying_data); 00090 underlying.apply(A, sketch_of_A, tag); 00091 00092 # if SKYLARK_HAVE_OPENMP 00093 # pragma omp parallel for collapse(2) 00094 # endif 00095 for(int j = 0; j < base::Width(A); j++) 00096 for(int i = 0; i < data_type::_S; i++) { 00097 value_type x = sketch_of_A.Get(i, j); 00098 x += data_type::_shifts[i]; 00099 00100 # ifdef SKYLARK_EXACT_COSINE 00101 x = std::cos(x); 00102 # else 00103 // x = std::cos(x) is slow 00104 // Instead use low-accuracy approximation 00105 if (x < -3.14159265) x += 6.28318531; 00106 else if (x > 3.14159265) x -= 6.28318531; 00107 x += 1.57079632; 00108 if (x > 3.14159265) 00109 x -= 6.28318531; 00110 x = (x < 0) ? 00111 1.27323954 * x + 0.405284735 * x * x : 00112 1.27323954 * x - 0.405284735 * x * x; 00113 # endif 00114 00115 x = data_type::_outscale * x; 00116 sketch_of_A.Set(i, j, x); 00117 } 00118 } 00119 00124 void apply_impl(const matrix_type& A, 00125 output_matrix_type& sketch_of_A, 00126 skylark::sketch::rowwise_tag tag) const { 00127 00128 // TODO verify sizes etc. 00129 underlying_t underlying(*data_type::_underlying_data); 00130 underlying.apply(A, sketch_of_A, tag); 00131 00132 # if SKYLARK_HAVE_OPENMP 00133 # pragma omp parallel for collapse(2) 00134 # endif 00135 for(int j = 0; j < data_type::_S; j++) 00136 for(int i = 0; i < base::Height(A); i++) { 00137 value_type x = sketch_of_A.Get(i, j); 00138 x += data_type::_shifts[j]; 00139 00140 # ifdef SKYLARK_EXACT_COSINE 00141 x = std::cos(x); 00142 # else 00143 // x = std::cos(x) is slow 00144 // Instead use low-accuracy approximation 00145 if (x < -3.14159265) x += 6.28318531; 00146 else if (x > 3.14159265) x -= 6.28318531; 00147 x += 1.57079632; 00148 if (x > 3.14159265) 00149 x -= 6.28318531; 00150 x = (x < 0) ? 00151 1.27323954 * x + 0.405284735 * x * x : 00152 1.27323954 * x - 0.405284735 * x * x; 00153 # endif 00154 00155 x = data_type::_outscale * x; 00156 sketch_of_A.Set(i, j, x); 00157 } 00158 } 00159 }; 00160 00164 template <typename ValueType, 00165 elem::Distribution ColDist, 00166 template <typename> class KernelDistribution> 00167 struct RFT_t < 00168 elem::DistMatrix<ValueType, ColDist, elem::STAR>, 00169 elem::DistMatrix<ValueType, ColDist, elem::STAR>, 00170 KernelDistribution> : 00171 public RFT_data_t<KernelDistribution> { 00172 // Typedef value, matrix, transform, distribution and transform data types 00173 // so that we can use them regularly and consistently. 00174 typedef ValueType value_type; 00175 typedef elem::DistMatrix<value_type, ColDist, elem::STAR> matrix_type; 00176 typedef elem::DistMatrix<value_type, 00177 ColDist, elem::STAR> output_matrix_type; 00178 typedef RFT_data_t<KernelDistribution> data_type; 00179 private: 00180 typedef skylark::sketch::dense_transform_t <matrix_type, 00181 output_matrix_type, 00182 KernelDistribution> 00183 underlying_t; 00184 00185 protected: 00186 00187 // Allow only creation by subclasses. 00188 00192 RFT_t (int N, int S, base::context_t& context) 00193 : data_type (N, S, context) { 00194 00195 } 00196 00197 public: 00198 00202 RFT_t(const RFT_t<matrix_type, 00203 output_matrix_type, 00204 KernelDistribution>& other) 00205 : data_type(other) { 00206 00207 } 00208 00212 RFT_t(const data_type& other_data) 00213 : data_type(other_data) { 00214 00215 } 00216 00220 template <typename Dimension> 00221 void apply (const matrix_type& A, 00222 output_matrix_type& sketch_of_A, 00223 Dimension dimension) const { 00224 00225 switch(ColDist) { 00226 case elem::VR: 00227 case elem::VC: 00228 try { 00229 apply_impl_vdist (A, sketch_of_A, dimension); 00230 } catch (std::logic_error e) { 00231 SKYLARK_THROW_EXCEPTION ( 00232 base::elemental_exception() 00233 << base::error_msg(e.what()) ); 00234 } catch(boost::mpi::exception e) { 00235 SKYLARK_THROW_EXCEPTION ( 00236 base::mpi_exception() 00237 << base::error_msg(e.what()) ); 00238 } 00239 00240 break; 00241 00242 default: 00243 SKYLARK_THROW_EXCEPTION ( 00244 base::unsupported_matrix_distribution() ); 00245 } 00246 } 00247 00248 private: 00253 void apply_impl_vdist (const matrix_type& A, 00254 output_matrix_type& sketch_of_A, 00255 skylark::sketch::columnwise_tag tag) const { 00256 underlying_t underlying(*data_type::_underlying_data); 00257 underlying.apply(A, sketch_of_A, tag); 00258 elem::Matrix<value_type> &Al = sketch_of_A.Matrix(); 00259 for(int j = 0; j < base::Width(Al); j++) 00260 for(int i = 0; i < data_type::_S; i++) { 00261 value_type val = Al.Get(i, j); 00262 value_type trans = 00263 data_type::_outscale * std::cos(val + data_type::_shifts[i]); 00264 Al.Set(i, j, trans); 00265 } 00266 } 00267 00272 void apply_impl_vdist(const matrix_type& A, 00273 output_matrix_type& sketch_of_A, 00274 skylark::sketch::rowwise_tag tag) const { 00275 00276 // TODO verify sizes etc. 00277 underlying_t underlying(*data_type::_underlying_data); 00278 underlying.apply(A, sketch_of_A, tag); 00279 elem::Matrix<value_type> &Al = sketch_of_A.Matrix(); 00280 for(int j = 0; j < data_type::_S; j++) 00281 for(int i = 0; i < base::Height(Al); i++) { 00282 value_type val = Al.Get(i, j); 00283 value_type trans = 00284 data_type::_outscale * std::cos(val + data_type::_shifts[j]); 00285 Al.Set(i, j, trans); 00286 } 00287 } 00288 00289 }; 00290 00291 } } 00293 #endif // SKYLARK_RFT_ELEMENTAL_HPP