00001 #ifndef VIENNACL_TOEPLITZ_MATRIX_HPP
00002 #define VIENNACL_TOEPLITZ_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/fft.hpp"
00029
00030 #include "viennacl/linalg/toeplitz_matrix_operations.hpp"
00031
00032
00033 namespace viennacl {
00034
00040 template<class SCALARTYPE, unsigned int ALIGNMENT>
00041 class toeplitz_matrix
00042 {
00043 public:
00044
00049 explicit toeplitz_matrix()
00050 {
00051 viennacl::linalg::kernels::fft<SCALARTYPE, 1>::init();
00052 }
00053
00059 explicit toeplitz_matrix(std::size_t rows, std::size_t cols) : elements_(rows * 2)
00060 {
00061 assert(rows == cols && "Toeplitz matrix must be square!");
00062 viennacl::linalg::kernels::fft<SCALARTYPE, 1>::init();
00063 }
00064
00065
00072 void resize(size_t sz, bool preserve = true) {
00073 elements_.resize(sz * 2, preserve);
00074 }
00075
00080 viennacl::ocl::handle<cl_mem> handle() const { return elements_.handle(); }
00081
00086 viennacl::vector<SCALARTYPE, ALIGNMENT> & elements() { return elements_; }
00087 viennacl::vector<SCALARTYPE, ALIGNMENT> const & elements() const { return elements_; }
00088
00089
00093 std::size_t size1() const { return elements_.size() / 2; }
00094
00098 std::size_t size2() const { return elements_.size() / 2; }
00099
00105 std::size_t internal_size() const { return elements_.internal_size(); }
00106
00107
00115 entry_proxy<SCALARTYPE> operator()(std::size_t row_index, std::size_t col_index)
00116 {
00117 assert(row_index < size1() && col_index < size2() && "Invalid access");
00118
00119 int index = static_cast<int>(col_index) - static_cast<int>(row_index);
00120
00121 if (index < 0)
00122 index = -index;
00123 else if
00124 (index > 0) index = 2 * size1() - index;
00125 return elements_[index];
00126 }
00127
00128
00135 toeplitz_matrix<SCALARTYPE, ALIGNMENT>& operator +=(toeplitz_matrix<SCALARTYPE, ALIGNMENT>& that) {
00136 elements_ += that.elements();
00137 return *this;
00138 }
00139
00140 private:
00141 toeplitz_matrix(toeplitz_matrix const & t) {}
00142 toeplitz_matrix & operator=(toeplitz_matrix const & t) {}
00143
00144
00145 viennacl::vector<SCALARTYPE, ALIGNMENT> elements_;
00146 };
00147
00154 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00155 void copy(std::vector<SCALARTYPE> const & cpu_vec, toeplitz_matrix<SCALARTYPE, ALIGNMENT>& gpu_mat)
00156 {
00157 std::size_t size = gpu_mat.size1();
00158 assert((size * 2 - 1) == cpu_vec.size() && "Size mismatch");
00159 std::vector<SCALARTYPE> rvrs(cpu_vec.size());
00160 std::copy(cpu_vec.begin(), cpu_vec.end(), rvrs.begin());
00161 std::reverse(rvrs.begin(), rvrs.end());
00162
00163 std::vector<SCALARTYPE> tmp(size * 2);
00164 std::copy(rvrs.begin() + size - 1, rvrs.end(), tmp.begin());
00165 std::copy(rvrs.begin(), rvrs.begin() + size - 1, tmp.begin() + size + 1);
00166 tmp[size] = 0.0;
00167 copy(tmp, gpu_mat.elements());
00168 }
00169
00176 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00177 void copy(toeplitz_matrix<SCALARTYPE, ALIGNMENT> const & gpu_mat, std::vector<SCALARTYPE> & cpu_vec)
00178 {
00179 std::size_t size = gpu_mat.size1();
00180 assert((size * 2 - 1) == cpu_vec.size() && "Size mismatch");
00181 std::vector<SCALARTYPE> tmp(size * 2);
00182 copy(gpu_mat.elements(), tmp);
00183 std::reverse(tmp.begin(), tmp.end());
00184
00185 std::copy(tmp.begin(), tmp.begin() + size - 1, cpu_vec.begin() + size);
00186 std::copy(tmp.begin() + size, tmp.end(), cpu_vec.begin());
00187
00188 }
00189
00196 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00197 void copy(toeplitz_matrix<SCALARTYPE, ALIGNMENT> const & tep_src, MATRIXTYPE & com_dst)
00198 {
00199 std::size_t size = tep_src.size1();
00200 assert(size == com_dst.size1() && "Size mismatch");
00201 assert(size == com_dst.size2() && "Size mismatch");
00202 std::vector<SCALARTYPE> tmp(tep_src.size1() * 2 - 1);
00203 copy(tep_src, tmp);
00204
00205 for(std::size_t i = 0; i < size; i++)
00206 for(std::size_t j = 0; j < size; j++)
00207 com_dst(i, j) = tmp[static_cast<int>(j) - static_cast<int>(i) + static_cast<int>(size) - 1];
00208 }
00209
00216 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00217 void copy(MATRIXTYPE const & com_src, toeplitz_matrix<SCALARTYPE, ALIGNMENT>& tep_dst)
00218 {
00219 std::size_t size = tep_dst.size1();
00220 assert(size == com_src.size1() && "Size mismatch");
00221 assert(size == com_src.size2() && "Size mismatch");
00222
00223 std::vector<SCALARTYPE> tmp(2*size - 1);
00224
00225 for(int i = size - 1; i >= 0; i--)
00226 tmp[size - i - 1] = com_src(i, 0);
00227
00228 for(std::size_t i = 1; i < size; i++)
00229 tmp[size + i - 1] = com_src(0, i);
00230
00231 copy(tmp, tep_dst);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00257 template<class SCALARTYPE, unsigned int ALIGNMENT>
00258 std::ostream & operator<<(std::ostream & s, toeplitz_matrix<SCALARTYPE, ALIGNMENT>& gpu_matrix)
00259 {
00260 std::size_t size = gpu_matrix.size1();
00261 std::vector<SCALARTYPE> tmp(2*size - 1);
00262 copy(gpu_matrix, tmp);
00263 s << "[" << size << "," << size << "](";
00264
00265 for(std::size_t i = 0; i < size; i++) {
00266 s << "(";
00267 for(std::size_t j = 0; j < size; j++) {
00268 s << tmp[(int)j - (int)i + (int)size - 1];
00269
00270 if(j < (size - 1)) s << ",";
00271 }
00272 s << ")";
00273 }
00274 s << ")";
00275 return s;
00276 }
00277
00278 }
00279
00280 #endif // _VIENNACL_TOEPLITZ_MATRIX_HPP