00001 #ifndef cublas_algorithms_H
00002 #define cublas_algorithms_H
00003
00004 #include <iomanip>
00005
00006 #include <base/sign.h>
00007
00008 #include <lac/cublas_Vector.h>
00009
00010
00011 namespace bw_types {
00012
00013 template<typename T>
00014 struct numerical_zero {
00015 static T Tol();
00016 };
00017
00018
00019 template<>
00020 inline float numerical_zero<float>::Tol() { return 1e-8; }
00021
00022 template<>
00023 inline double numerical_zero<double>::Tol() { return 1e-16; }
00024
00025 template<typename T>
00026 inline T numerical_zero<T>::Tol() {
00027 AssertThrow(false,
00028 ::ExcMessage("Not implemented.") );
00029 }
00030
00031
00032
00033
00034
00035 template<typename T>
00036 struct algorithms {
00037
00038 template<typename BW>
00039 static bool check_orthogonality (bw_types::Matrix<T, BW> & Q)
00040 {
00041 typedef bw_types::Matrix<T, BW> M;
00042
00043 if(Q.n_rows() != Q.n_cols()) return false;
00044
00045 M Q_Q_t = Q * transpose<M>(Q);
00046
00047 M I = ::IdentityMatrix(Q.n_cols());
00048
00049
00050
00051 Q_Q_t -= I;
00052
00053 T l2_error = Q_Q_t.l2_norm();
00054
00055 if (l2_error < Q.n_cols()*numerical_zero<T>::Tol() )
00056 return true;
00057 else {
00058 std::cout << "Deviation from unit matrix : " << std::setprecision(16) << l2_error << "\n" << std::endl;
00059 return false;
00060 }
00061 }
00062
00063
00064
00065 template <typename VecView>
00066 static void test_householder_property(int t, T sigma, T alpha,
00067 const Vector<T, typename VecView::BW> & v,
00068 const VecView & sub_col_A);
00069
00070 template <typename VecView>
00071 inline static void compute_householder_vector(int t, T & alpha, T & sigma, Vector<T, typename VecView::BW> & W,
00072 const T A_tt, const VecView & entries2kill)
00073 {
00074
00075 typedef typename VecView::BW BW;
00076
00077 #ifdef HOUSEHOLDER_DEBUG
00078 std::cout << "\nZu eliminierende Eintraege :" << std::endl; entries2kill.print();
00079 #endif
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 alpha = sign(A_tt) * entries2kill.l2_norm();
00090 T beta_t = A_tt + alpha;
00091 sigma = + beta_t/alpha;
00092
00093 #ifdef HOUSEHOLDER_DEBUG
00094 std::cout << "t : " << t << ", alpha : " << std::setprecision(5)
00095 << alpha <<", y + alpha : "<< beta_t <<", sigma : "<< sigma << std::endl << std::endl;
00096 #endif
00097
00098
00099
00100
00101
00102 #ifdef HOUSEHOLDER_DEBUG
00103 std::cout << "\nalpha-Vektor :" << std::endl; alpha_v_m_d.print();
00104 #endif
00105
00106 W = entries2kill;
00107
00108
00109 W *= 1./beta_t;
00110
00111
00112 #ifdef HOUSEHOLDER_DEBUG
00113 std::cout << "\nAn dieser Stelle ist der Householder-Vektor fertig :" << std::endl;
00114 W.print();
00115 #endif
00116
00117 #ifdef HOUSEHOLDER_DEBUG
00118
00119
00120
00121 test_householder_property(t, sigma, -alpha, W, entries2kill);
00122 #endif
00123 }
00124 };
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 template<typename T>
00134 template <typename VecView>
00135 void bw_types::algorithms<T>::test_householder_property(int t, T sigma, T alpha,
00136 const bw_types::Vector<T, typename VecView::BW> &v,
00137 const VecView &col_A)
00138 {
00139
00140 typedef typename VecView::BW BW;
00141
00142 int n_entries = v.size();
00143
00144 bw_types::Vector<T, BW> entries2kill(n_entries);
00145
00146 entries2kill = col_A;
00147
00148 #ifdef HOUSEHOLDER_DEBUG
00149 bw_types::Matrix<T> UUt(n_entries, n_entries);
00150
00151 UUt.add_scaled_outer_product(-sigma, v, v);
00152
00153 std::cout << "\nAn dieser Stelle hat man -sigma vv^T :" << std::endl;
00154 UUt.print();
00155 #endif
00156
00157 bw_types::Matrix<T, BW> tmp_Id(n_entries, n_entries);
00158 tmp_Id = ::IdentityMatrix(n_entries);
00159
00160 tmp_Id.add_scaled_outer_product(-sigma, v, v);
00161
00162 bw_types::Vector<T, BW> new_col(n_entries);
00163
00164 tmp_Id.vmult(new_col, entries2kill);
00165
00166 #ifdef HOUSEHOLDER_DEBUG
00167 std::cout << "\nAn dieser Stelle hat man XXX -("
00168 << -alpha << ", 0, ... , 0) :" << std::endl;
00169 new_col.print();
00170 #endif
00171 }
00172
00173 #endif
00174