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