OpendTect  6.6
qrsolv.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*@+
4 ________________________________________________________________________
5 
6  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
7  Author: Arnaud Huck
8  Date: April 2015
9  RCS: $Id$
10 ________________________________________________________________________
11 
12 @$
13 */
14 
15 #include "arrayndimpl.h"
16 
17 #define TINY 1.0e-20
18 
26 template <class T>
28 {
29 public:
30  QRSolver(const Array2D<T>& A);
31  ~QRSolver();
32 
33  bool isFullRank() { return isfullrank_; }
34 
35  const Array1DImpl<T>* apply(const Array1D<T>& B) const;
36  const Array1DImpl<T>* apply(const Array2D<T>& B) const;
37  const Array2DImpl<T>* getQ() const;
38  const Array2DImpl<T>* getR() const;
39 
40 protected:
43  int m_;
44  int n_;
46 
47 };
48 
49 
50 template <class T> inline
52  : qr_(A)
53  , m_(A.info().getSize(0))
54  , n_(A.info().getSize(1))
55  , isfullrank_(true)
56 {
57  if ( A.info().getSize(0) < A.info().getSize(1) )
58  return;
59 
60  rdiag_ = new Array1DImpl<T>( n_ );
61  for ( int k=0; k<n_; ++k )
62  {
63  double norm = 0.;
64  for ( int i=k; i<m_; ++i )
65  norm = Math::Sqrt( norm*norm + qr_.get( i, k )*qr_.get( i, k ) );
66 
67  if ( mIsZero(norm,TINY) )
68  {
69  rdiag_->set( k, 0. );
70  isfullrank_ = false;
71  continue;
72  }
73 
74  if ( qr_.get( k, k ) < TINY )
75  norm *= -1.;
76 
77  for ( int i=k; i<m_; ++i )
78  qr_.set( i, k, qr_.get( i, k )/norm );
79 
80  qr_.set( k, k, qr_.get( k, k ) + 1. );
81 
82  for ( int j=k+1; j<n_; ++j )
83  {
84  double s = 0.;
85  for ( int i=k; i<m_; ++i )
86  s += qr_.get( i, k ) * qr_.get( i, j );
87 
88  s = -s / qr_.get( k, k );
89  for ( int i=k; i<m_; ++i )
90  qr_.set( i, j, qr_.get( i, j ) + s * qr_.get( i, k ) );
91  }
92 
93  rdiag_->set( k, -norm );
94  }
95 }
96 
97 
98 template <class T> inline
100 {
101  delete rdiag_;
102 }
103 
104 
105 template <class T> inline
107 {
108  if( !rdiag_ )
109  return 0;
110 
111  const int sz = b.info().getSize(0);
112  Array2DImpl<T>* arr = new Array2DImpl<T>( sz, 1 );
113  for ( int idx=0; idx<sz; idx++ )
114  arr->set( idx, 0, b.get( idx ) );
115 
116  const Array1DImpl<T>* out = apply( *arr );
117  delete arr;
118  return out;
119 }
120 
121 
122 template <class T> inline
124 {
125  if ( b.info().getSize(0) != m_ || !isfullrank_ || !rdiag_ )
126  return 0;
127 
128  const int nx = b.info().getSize(1);
129  Array2DImpl<T>* arr = new Array2DImpl<T>( b );
130 
131  // Compute Y = transpose(Q)*B.
132  for ( int k=0; k<n_; ++k )
133  {
134  for ( int j=0; j<nx; ++j )
135  {
136  double s = 0.;
137  for ( int i=k; i<m_; ++i )
138  s += qr_.get( i, k ) * arr->get( i, j );
139 
140  s = -s / qr_.get( k, k );
141  for ( int i=k; i<m_; ++i )
142  arr->set( i, j, arr->get( i, j ) + s * qr_.get( i, k ) );
143  }
144  }
145 
146  // Solve R*X = Y
147  for ( int k=n_-1; k>=0; --k )
148  {
149  for ( int j=0; j<nx; ++j )
150  arr->set( k, j, arr->get( k, j ) / rdiag_->get( k ) );
151 
152  for ( int i=0; i<k; ++i )
153  for ( int j=0; j<nx; ++j )
154  arr->set( i, j, arr->get( i, j ) -
155  arr->get( k, j ) * qr_.get( i, k ) );
156  }
157 
158 
159  Array1DImpl<T>* out = new Array1DImpl<T>( n_ );
160  for ( int idx=0; idx<n_; idx++ )
161  out->set( idx, arr->get(idx,0) );
162 
163  delete arr;
164  return out;
165 }
166 
167 
168 template <class T> inline
170 {
171  if( !rdiag_ )
172  return 0;
173 
174  Array2DImpl<T>* arr = new Array2DImpl<T>( m_, n_ );
175  for ( int k=n_-1; k>=0; --k )
176  {
177  for ( int i=0; i<m_; ++i )
178  arr->set( i, k, 0. );
179 
180  arr->set( k, k, 1. );
181  for ( int j=k; j<n_; ++j )
182  {
183  if ( mIsZero(qr_.get( k, k ),TINY) )
184  continue;
185 
186  double s = 0.;
187  for ( int i=k; i<m_; ++i )
188  s += qr_.get( i, k) * arr->get( i, j );
189 
190  s = -s / qr_.get( k, k );
191  for ( int i=k; i<m_; ++i )
192  arr->set( i, j, arr->get( i, j ) + s * qr_.get( i, k ) );
193  }
194  }
195 
196  return arr;
197 }
198 
199 #undef TINY
200 
201 
202 template <class T> inline
204 {
205  if( !rdiag_ )
206  return 0;
207 
208  Array2DImpl<T>* arr = new Array2DImpl<T>( n_, n_ );
209  for ( int i=0; i<n_; ++i )
210  {
211  arr->set( i, i, rdiag_->get( i ) );
212  for ( int j=i+1; j<n_; ++j )
213  arr->set( i, j, qr_.get( i, j ) );
214  }
215 
216  return arr;
217 }
218 
Array1DImpl
Implementation of Array1D.
Definition: arrayndimpl.h:52
QRSolver::getR
const Array2DImpl< T > * getR() const
Definition: qrsolv.h:203
QRSolver::QRSolver
QRSolver(const Array2D< T > &A)
Definition: qrsolv.h:51
QRSolver
QRSolver - QR decomposition of a matrix A For an m-by-n matrix A, with m>=n, the QR decomposition is ...
Definition: qrsolv.h:28
QRSolver::isFullRank
bool isFullRank()
Definition: qrsolv.h:33
ArrayNDInfo::getSize
virtual int getSize(int dim) const =0
QRSolver::m_
int m_
Definition: qrsolv.h:43
Array1D
Array1D ( Subclass of ArrayND ) is a one dimensional array.
Definition: arraynd.h:111
arrayndimpl.h
Array1D::info
virtual const Array1DInfo & info() const =0
Array1DImpl::set
void set(int pos, T)
Definition: arrayndimpl.h:409
QRSolver::qr_
Array2DImpl< T > qr_
Definition: qrsolv.h:41
TINY
#define TINY
Definition: qrsolv.h:17
QRSolver::rdiag_
Array1DImpl< T > * rdiag_
Definition: qrsolv.h:42
mIsZero
#define mIsZero(x, eps)
Definition: commondefs.h:66
QRSolver::n_
int n_
Definition: qrsolv.h:44
mClass
#define mClass(module)
Definition: commondefs.h:181
QRSolver::isfullrank_
bool isfullrank_
Definition: qrsolv.h:45
Array2D::info
virtual const Array2DInfo & info() const =0
QRSolver::getQ
const Array2DImpl< T > * getQ() const
Definition: qrsolv.h:169
Array2DImpl
Implementation of Array2D.
Definition: arrayndimpl.h:102
Array2DImpl::set
void set(int, int, T)
Definition: arrayndimpl.h:497
QRSolver::~QRSolver
~QRSolver()
Definition: qrsolv.h:99
Math::Sqrt
float Sqrt(float)
Array2DImpl::get
T get(int, int) const
Definition: arrayndimpl.h:519
Array1D::get
virtual T get(int) const =0
QRSolver::apply
const Array1DImpl< T > * apply(const Array1D< T > &B) const
Definition: qrsolv.h:106
Array2D
Array2D ( Subclass of ArrayND ) is a two dimensional array.
Definition: arraynd.h:140

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B.V. 1995-2021