00001 #ifndef HADAMARD_H 00002 #define HADAMARD_H 00003 00004 #include <iostream> 00005 #include <vector> 00006 #include <lac/full_matrix.h> 00007 #include <lac/FullMatrixAccessor.h> 00008 #include <cmath> 00009 00010 struct MatrixCreator{ 00011 template <typename T> 00012 static void hadamard(int log2N, ::FullMatrix<T>& H); 00013 00014 template <typename T> 00015 static void normalized_hadamard(int log2N, ::FullMatrix<T>& H); 00016 00017 template <typename T> 00018 static void extended_hadamard(size_t n_rows, ::FullMatrix<T>& H); 00019 00020 template <typename T> 00021 static void extended_normalized_hadamard(size_t n_rows, ::FullMatrix<T>& H); 00022 00023 template <typename T> 00024 static void vandermonde_row_wise(::FullMatrix<T>& V,const ::Vector<T>& x){ 00025 vandermonde(V,x,true); 00026 } 00027 00028 template <typename T> 00029 static void vandermonde_col_wise(::FullMatrix<T>& V,const ::Vector<T>& x){ 00030 vandermonde(V,x,false); 00031 } 00032 00033 template <typename T> 00034 static void toepliz(::FullMatrix<T>& M, const ::Vector<T>& r); 00035 00036 private: 00037 template <typename T> 00038 static void vandermonde(::FullMatrix<T>& V,const ::Vector<T>& x, bool rowwise = true); 00039 }; 00040 00041 template <typename T> 00042 void MatrixCreator::hadamard(int log2N, ::FullMatrix<T>& H){ 00043 int N = std::pow(2.0,log2N); 00044 H.reinit(N,N); 00045 H(0,0) = 1; 00046 00047 for (int n = 1; n < N; n += n) { 00048 for (int i = 0; i < n; i++) { 00049 for (int j = 0; j < n; j++) { 00050 H(i+n,j) = H(i,j); 00051 H(i,j+n) = H(i,j); 00052 H(i+n,j+n) = -1 * H(i,j); 00053 } 00054 } 00055 } 00056 } 00057 00058 template <typename T> 00059 void MatrixCreator::extended_normalized_hadamard(size_t n_rows, ::FullMatrix<T>& H){ 00060 H.reinit(n_rows,n_rows); 00061 size_t block_size; 00062 size_t n_rows_rest=n_rows; 00063 size_t block_begin=0; 00064 while(true){ 00065 block_size=std::pow(2.,std::floor(log2(n_rows_rest))); 00066 n_rows_rest-=block_size; 00067 00068 ::FullMatrix<T> H_tmp(block_size); 00069 normalized_hadamard(log2(block_size),H_tmp); 00070 H.fill(H_tmp,block_begin,block_begin,0,0); 00071 block_begin+=block_size; 00072 00073 if(n_rows_rest==0) 00074 break; 00075 } 00076 } 00077 00078 template <typename T> 00079 void MatrixCreator::extended_hadamard(size_t n_rows, ::FullMatrix<T>& H){ 00080 H.reinit(n_rows,n_rows); 00081 size_t block_size; 00082 size_t n_rows_rest=n_rows; 00083 size_t block_begin=0; 00084 while(true){ 00085 block_size=std::pow(2.,std::floor(log2(n_rows_rest))); 00086 n_rows_rest-=block_size; 00087 00088 ::FullMatrix<T> H_tmp(block_size); 00089 hadamard(log2(block_size),H_tmp); 00090 H.fill(H_tmp,block_begin,block_begin,0,0); 00091 block_begin+=block_size; 00092 00093 if(n_rows_rest==0) 00094 break; 00095 } 00096 00097 } 00098 00099 template <typename T> 00100 void MatrixCreator::normalized_hadamard(int log2N, ::FullMatrix<T>& H) 00101 { 00102 MatrixCreator::hadamard(log2N, H); 00103 00104 H /= std::sqrt(H.n_rows() ); 00105 } 00106 00107 00108 00109 template <typename T> 00110 void MatrixCreator::vandermonde(::FullMatrix<T>& V,const ::Vector<T>& x, bool rowwise){ 00111 int N = x.size(); 00112 V.reinit(N,N); 00113 if(rowwise == false){ 00114 for(int i = 0; i<N ; i++){ 00115 for(int j = 0; j<N; j++){ 00116 V(i,j) = pow(x(i),j); 00117 } 00118 } 00119 } 00120 if(rowwise == true){ 00121 for(int i = 0; i<N ; i++){ 00122 for(int j = 0; j<N; j++){ 00123 V(j,i) = pow(x(i),j); 00124 } 00125 } 00126 } 00127 } 00128 00129 template <typename T> 00130 void MatrixCreator::toepliz(::FullMatrix<T>& M, const ::Vector<T>& r){ 00131 if (r.size()%2 == 0){ 00132 std::cout<<"Toepliz: Nur ungerade Anzahl an Elemente sind Erlaubt"<<std::endl; 00133 }else{ 00134 int N = (r.size()/2)+1; 00135 M.reinit(N,N); 00136 for(int i = 0; i<N; i++){ 00137 for (int j = 0; j<N; j++){ 00138 M(i,j) = r(((N-1)-j)+i); 00139 } 00140 } 00141 } 00142 00143 00144 } 00145 00146 #endif // HADAMARD_H 00147