00001 #ifndef VIENNACL_LINALG_CIRCULANT_MATRIX_OPERATIONS_HPP_
00002 #define VIENNACL_LINALG_CIRCULANT_MATRIX_OPERATIONS_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/ocl/device.hpp"
00026 #include "viennacl/ocl/handle.hpp"
00027 #include "viennacl/ocl/kernel.hpp"
00028 #include "viennacl/scalar.hpp"
00029 #include "viennacl/vector.hpp"
00030 #include "viennacl/tools/tools.hpp"
00031 #include "viennacl/fft.hpp"
00032
00033
00034 namespace viennacl
00035 {
00036 namespace linalg
00037 {
00038
00039
00040
00048 template<class SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00049 vector_expression<const circulant_matrix<SCALARTYPE, ALIGNMENT>,
00050 const vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00051 op_prod > prod_impl(const circulant_matrix<SCALARTYPE, ALIGNMENT> & mat,
00052 const vector<SCALARTYPE, VECTOR_ALIGNMENT> & vec)
00053 {
00054 return vector_expression<const circulant_matrix<SCALARTYPE, ALIGNMENT>,
00055 const vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00056 op_prod >(mat, vec);
00057 }
00058
00059
00068 template<class SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00069 viennacl::vector_expression<const viennacl::circulant_matrix<SCALARTYPE, ALIGNMENT>,
00070 const viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00071 viennacl::op_prod > prod_impl(const viennacl::circulant_matrix<SCALARTYPE, ALIGNMENT> & mat,
00072 const viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> & vec,
00073 size_t NUM_THREADS)
00074 {
00075 return viennacl::vector_expression<const viennacl::circulant_matrix<SCALARTYPE, ALIGNMENT>,
00076 const viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00077 viennacl::op_prod >(mat, vec);
00078 }
00079
00088 template<class SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00089 void prod_impl(const viennacl::circulant_matrix<SCALARTYPE, ALIGNMENT> & mat,
00090 const viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> & vec,
00091 viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> & result)
00092 {
00093 assert(mat.size1() == result.size());
00094 assert(mat.size2() == vec.size());
00095
00096
00097
00098
00099 viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> circ(mat.elements().size() * 2);
00100 viennacl::detail::fft::real_to_complex(mat.elements(), circ, mat.elements().size());
00101
00102 viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> tmp(vec.size() * 2);
00103 viennacl::vector<SCALARTYPE, VECTOR_ALIGNMENT> tmp2(vec.size() * 2);
00104
00105 viennacl::detail::fft::real_to_complex(vec, tmp, vec.size());
00106 viennacl::linalg::convolve(circ, tmp, tmp2);
00107 viennacl::detail::fft::complex_to_real(tmp2, result, vec.size());
00108
00109 }
00110
00111 }
00112
00113
00114
00119 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00120 template <unsigned int MAT_ALIGNMENT>
00121 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00122 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator=(const viennacl::vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00123 const viennacl::vector<SCALARTYPE, ALIGNMENT>,
00124 viennacl::op_prod> & proxy)
00125 {
00126
00127 if (proxy.rhs().handle() == this->handle())
00128 {
00129 viennacl::vector<SCALARTYPE, ALIGNMENT> result(proxy.rhs().size());
00130 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00131 *this = result;
00132 return *this;
00133 }
00134 else
00135 {
00136 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
00137 return *this;
00138 }
00139 return *this;
00140 }
00141
00142
00147 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00148 template <unsigned int MAT_ALIGNMENT>
00149 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00150 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator+=(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00151 const vector<SCALARTYPE, ALIGNMENT>,
00152 op_prod> & proxy)
00153 {
00154 vector<SCALARTYPE, ALIGNMENT> result(proxy.lhs().size1());
00155 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00156 *this += result;
00157 return *this;
00158 }
00159
00164 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00165 template <unsigned int MAT_ALIGNMENT>
00166 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00167 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator-=(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00168 const vector<SCALARTYPE, ALIGNMENT>,
00169 op_prod> & proxy)
00170 {
00171 vector<SCALARTYPE, ALIGNMENT> result(proxy.get_lhs().size1());
00172 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00173 *this -= result;
00174 return *this;
00175 }
00176
00177
00178
00183 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00184 template <unsigned int MAT_ALIGNMENT>
00185 viennacl::vector<SCALARTYPE, ALIGNMENT>
00186 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator+(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00187 const vector<SCALARTYPE, ALIGNMENT>,
00188 op_prod> & proxy)
00189 {
00190 assert(proxy.get_lhs().size1() == size());
00191 vector<SCALARTYPE, ALIGNMENT> result(size());
00192 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00193 result += *this;
00194 return result;
00195 }
00196
00201 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00202 template <unsigned int MAT_ALIGNMENT>
00203 viennacl::vector<SCALARTYPE, ALIGNMENT>
00204 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator-(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00205 const vector<SCALARTYPE, ALIGNMENT>,
00206 op_prod> & proxy)
00207 {
00208 assert(proxy.get_lhs().size1() == size());
00209 vector<SCALARTYPE, ALIGNMENT> result(size());
00210 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00211 result = *this - result;
00212 return result;
00213 }
00214
00215 }
00216
00217
00218 #endif