/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/algorithms/iterative/Householder.h Copyright (C) 2015 Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef HOUSEHOLDER_H #define HOUSEHOLDER_H #define TIMER(A) std::cout << GridLogMessage << __FUNC__ << " file "<< __FILE__ <<" line " << __LINE__ << std::endl; #define ENTER() std::cout << GridLogMessage << "ENTRY "<<__FUNC__ << " file "<< __FILE__ <<" line " << __LINE__ << std::endl; #define LEAVE() std::cout << GridLogMessage << "EXIT "<<__FUNC__ << " file "<< __FILE__ <<" line " << __LINE__ << std::endl; #include #include #include #include #include #include #include #include #include namespace Grid { /** Comparison function for finding the max element in a vector **/ template bool cf(T i, T j) { return abs(i) < abs(j); } /** Calculate a real Givens angle **/ template inline void Givens_calc(T y, T z, T &c, T &s){ RealD mz = (RealD)abs(z); if(mz==0.0){ c = 1; s = 0; } if(mz >= (RealD)abs(y)){ T t = -y/z; s = (T)1.0 / sqrt ((T)1.0 + t * t); c = s * t; } else { T t = -z/y; c = (T)1.0 / sqrt ((T)1.0 + t * t); s = c * t; } } template inline void Givens_mult(DenseMatrix &A, int i, int k, T c, T s, int dir) { int q ; SizeSquare(A,q); if(dir == 0){ for(int j=0;j inline void Householder_vector(DenseVector input, int k, int j, DenseVector &v, T &beta) { int N ; Size(input,N); T m = *max_element(input.begin() + k, input.begin() + j + 1, cf ); if(abs(m) > 0.0){ T alpha = 0; for(int i=k; i 0.0) v[k] = v[k] + (v[k]/abs(v[k]))*alpha; else v[k] = -alpha; } else{ for(int i=k; i inline void Householder_vector(DenseVector input, int k, int j, int dir, DenseVector &v, T &beta) { int N = input.size(); T m = *max_element(input.begin() + k, input.begin() + j + 1, cf); if(abs(m) > 0.0){ T alpha = 0; for(int i=k; i 0.0) v[dir] = v[dir] + (v[dir]/abs(v[dir]))*alpha; else v[dir] = -alpha; }else{ for(int i=k; i inline void Householder_mult(DenseMatrix &A , DenseVector v, T beta, int l, int k, int j, int trans) { int N ; SizeSquare(A,N); if(abs(beta) > 0.0){ for(int p=l; p inline void Householder_mult_tri(DenseMatrix &A , DenseVector v, T beta, int l, int M, int k, int j, int trans) { if(abs(beta) > 0.0){ int N ; SizeSquare(A,N); DenseMatrix tmp; Resize(tmp,N,N); Fill(tmp,0); T s; for(int p=l; p