Go to the documentation of this file.00001 #ifndef _VIENNACL_CIRCULANT_MATRIX_HPP
00002 #define _VIENNACL_CIRCULANT_MATRIX_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include "viennacl/forwards.h"
00025 #include "viennacl/vector.hpp"
00026 #include "viennacl/ocl/context.hpp"
00027
00028 #include "viennacl/linalg/circulant_matrix_operations.hpp"
00029
00030 #include "viennacl/fft.hpp"
00031
00032 namespace viennacl
00033 {
00039 template<class SCALARTYPE, unsigned int ALIGNMENT>
00040 class circulant_matrix
00041 {
00042 public:
00047 explicit circulant_matrix()
00048 {
00049 viennacl::linalg::kernels::fft<SCALARTYPE, 1>::init();
00050 }
00051
00058 explicit circulant_matrix(std::size_t rows, std::size_t cols) : elements_(rows)
00059 {
00060 assert(rows == cols && "Circulant matrix must be square!");
00061 viennacl::linalg::kernels::fft<SCALARTYPE, 1>::init();
00062 }
00063
00070 void resize(size_t sz, bool preserve = true)
00071 {
00072 elements_.resize(sz, preserve);
00073 }
00074
00079 viennacl::ocl::handle<cl_mem> handle() const { return elements_.handle(); }
00080
00085 viennacl::vector<SCALARTYPE, ALIGNMENT> & elements() { return elements_; }
00086 viennacl::vector<SCALARTYPE, ALIGNMENT> const & elements() const { return elements_; }
00087
00091 std::size_t size1() const { return elements_.size(); }
00092
00096 std::size_t size2() const { return elements_.size(); }
00097
00103 std::size_t internal_size() const { return elements_.internal_size(); }
00104
00112 entry_proxy<SCALARTYPE> operator()(std::size_t row_index, std::size_t col_index)
00113 {
00114 int index = static_cast<int>(row_index) - static_cast<int>(col_index);
00115
00116 assert(row_index < size1() && col_index < size2() && "Invalid access");
00117
00118 while (index < 0)
00119 index += size1();
00120 return elements_[index];
00121 }
00122
00129 circulant_matrix<SCALARTYPE, ALIGNMENT>& operator +=(circulant_matrix<SCALARTYPE, ALIGNMENT>& that)
00130 {
00131 elements_ += that.elements();
00132 return *this;
00133 }
00134
00135 private:
00136 circulant_matrix(circulant_matrix const & t) {}
00137 circulant_matrix & operator=(circulant_matrix const & t) {}
00138
00139 viennacl::vector<SCALARTYPE, ALIGNMENT> elements_;
00140 };
00141
00148 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00149 void copy(std::vector<SCALARTYPE>& cpu_vec, circulant_matrix<SCALARTYPE, ALIGNMENT>& gpu_mat)
00150 {
00151 assert(cpu_vec.size() == gpu_mat.size1() && "Size mismatch");
00152 copy(cpu_vec, gpu_mat.elements());
00153 }
00154
00161 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00162 void copy(circulant_matrix<SCALARTYPE, ALIGNMENT>& gpu_mat, std::vector<SCALARTYPE>& cpu_vec)
00163 {
00164 assert(cpu_vec.size() == gpu_mat.size1() && "Size mismatch");
00165 copy(gpu_mat.elements(), cpu_vec);
00166 }
00167
00174 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00175 void copy(circulant_matrix<SCALARTYPE, ALIGNMENT>& circ_src, MATRIXTYPE& com_dst) {
00176 std::size_t size = circ_src.size1();
00177 assert(size == com_dst.size1() && "Size mismatch");
00178 assert(size == com_dst.size2() && "Size mismatch");
00179 std::vector<SCALARTYPE> tmp(size);
00180 copy(circ_src, tmp);
00181
00182 for (std::size_t i = 0; i < size; i++) {
00183 for (std::size_t j = 0; j < size; j++) {
00184 int index = static_cast<int>(i) - static_cast<int>(j);
00185 if (index < 0)
00186 index = size + index;
00187 com_dst(i, j) = tmp[index];
00188 }
00189 }
00190 }
00191
00198 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00199 void copy(MATRIXTYPE& com_src, circulant_matrix<SCALARTYPE, ALIGNMENT>& circ_dst) {
00200 std::size_t size = circ_dst.size1();
00201 assert(size == com_src.size1() && "Size mismatch");
00202 assert(size == com_src.size2() && "Size mismatch");
00203
00204 std::vector<SCALARTYPE> tmp(size);
00205
00206 for(std::size_t i = 0; i < size; i++) tmp[i] = com_src(i, 0);
00207
00208 copy(tmp, circ_dst);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00234 template<class SCALARTYPE, unsigned int ALIGNMENT>
00235 std::ostream & operator<<(std::ostream& s, circulant_matrix<SCALARTYPE, ALIGNMENT>& gpu_matrix)
00236 {
00237 std::size_t size = gpu_matrix.size1();
00238 std::vector<SCALARTYPE> tmp(size);
00239 copy(gpu_matrix, tmp);
00240 s << "[" << size << "," << size << "](";
00241
00242 for(std::size_t i = 0; i < size; i++) {
00243 s << "(";
00244 for(std::size_t j = 0; j < size; j++) {
00245 int index = (int)i - (int)j;
00246 if(index < 0) index = size + index;
00247 s << tmp[index];
00248
00249 if(j < (size - 1)) s << ",";
00250 }
00251 s << ")";
00252 }
00253 s << ")";
00254 return s;
00255 }
00256 }
00257
00258 #endif // _VIENNACL_CIRCULANT_MATRIX_HPP