MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseLinAlgPack_InvCholUpdate.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include <math.h>
43 
47 
48 namespace {
49 // sign function
50 inline int sign(double v) {
51  if(v > 0.0)
52  return 1;
53  else if(v == 0.0)
54  return 0;
55  else
56  return -1;
57 }
58 
59 }
60 
62  , const DVectorSlice& v)
63 {
64  DMatrixSlice &M = *pM;
65  DVectorSlice &u = *pu;
66 
68  if(M.rows() != u.dim() || u.dim() != v.dim())
69  throw std::length_error("update_chol_factor(): Sizes of matrix and vectors do not match");
70 
71  // Algorithm A3.4.1a in Dennis and Schabel
72 
73  // 0. Set lower diagonal to zero
74  M.diag(-1) = 0.0;
75 
76  // 1,2 Find the largest k such that u(k) != 0.0
77  size_type n = M.rows(), k = n;
78  {
80  while(*r_itr_u == 0.0 && k > 1) --k;
81  }
82 
83  // 3.
84  {
86  r_itr_u_i = u(1,k-1).rbegin(), // iterator for u(i), i = k-1,...,1
87  r_itr_u_ip1 = u(2,k).rbegin(); // iterator for u(i), i = k,...,2
88  for(size_type i = k-1; i > 0 ; ++r_itr_u_i, ++r_itr_u_ip1, --i) {
89  value_type u_i = *r_itr_u_i, u_ip1 = *r_itr_u_ip1;
90  jacobi_rotate(&M, i, u_i, - u_ip1); // 3.1
91  *r_itr_u_i = (u_i == 0.0) ? ::fabs(u_ip1) : ::sqrt(u_i * u_i + u_ip1 * u_ip1); // 3.2
92  }
93  }
94 
95  // 4. M.row(1) += u(1) * v
96  DenseLinAlgPack::Vp_StV(&M.row(1), u(1), v);
97 
98  // 5.
99  {
101  itr_M_i_i = M.diag().begin(), // iterator for M(i,i), for i = 1,...,k-1
102  itr_M_ip1_i = M.diag(-1).begin(); // iterator for M(i+1,i), for i = 1,...,k-1
103  for(size_type i = 1; i < k; ++i)
104  jacobi_rotate(&M, i, *itr_M_i_i++, - *itr_M_ip1_i++);
105  }
106 
107 /* This code does not work
108 
109  size_type n = M.rows();
110 
111  // 0.
112  {
113  for(size_type i = 2; i <= n; ++i)
114  M(i,i-1) = 0;
115  }
116 
117  // 1.
118  size_type k = n;
119 
120  // 2.
121  while(u(k) == 0.0 && k > 1) --k;
122 
123  // 3.
124  {
125  for(size_type i = k-1; i >= 1; --i) {
126  jacobi_rotate(M, i, u(i), - u(i+1));
127  if(u(i) == 0)
128  u(i) = ::fabs(u(i+1));
129  else
130  u(i) = ::sqrt(u(i) * u(i) + u(i+1) * u(i+1));
131  }
132  }
133 
134  // 4.
135  {
136  for(size_type j = 1; j <= n; ++j)
137  M(1,j) = M(1,j) + dot(u(1),v(j));
138  }
139 
140  // 5.
141  {
142  for(size_type i = 1; i <= k-1; ++i)
143  jacobi_rotate(M, i, M(i,i), - M(i+1,i));
144  }
145 
146 
147 
148 */
149 
150 
151 }
152 
154  , value_type beta)
155 {
156  DMatrixSlice &M = *pM;
157 
159 
160  // Algorithm A3.4.1a in Dennis and Schabel
161 
162  // 1.
163  value_type c, s;
164  if(alpha == 0.0) {
165  c = 0.0;
166  s = sign(beta);
167  }
168  else {
169  value_type den = ::sqrt(alpha * alpha + beta * beta);
170  c = alpha / den;
171  s = beta / den;
172  }
173 
174  // 2.
175  size_type i = row_i, n = M.rows();
176 
177  // Use iterators instead of element access
179  itr_M_i = M.row(i)(i,n).begin(), // iterator for M(i,j), for j = i,...,n
180  itr_M_i_end = M.row(i)(i,n).end(),
181  itr_M_ip1 = M.row(i+1)(i,n).begin(); // iterator for M(i+1,j), for j = i,...,n
182 
183  while(itr_M_i != itr_M_i_end) {
184  value_type y = *itr_M_i, w = *itr_M_ip1;
185  *itr_M_i++ = c * y - s * w;
186  *itr_M_ip1++ = s * y + c * w;
187  }
188 
189 /* This code does not work
190 
191  size_type n = M.rows(), i = row_i;
192 
193  // 1.
194  value_type c, s;
195  if(alpha == 0) {
196  c = 0.0;
197  s = ::fabs(beta);
198  }
199  else {
200  value_type den = ::sqrt(alpha*alpha + beta*beta);
201  c = alpha / den;
202  s = beta / den;
203  }
204 
205  // 2.
206  {
207  for(size_type j = i; j <= n; ++j) {
208  size_type y = M(i,j), w = M(i+1,j);
209  M(i,j) = c*y - s*w;
210  M(i+1,j) = s*y + c*w;
211  }
212  }
213 
214 
215 
216 */
217 
218 }
Teuchos::Ordinal size_type
Typedef for the size type of elements that are used by the library.
void assert_gms_square(const DMatrixSlice &gms)
Assert a matrix is square and throws length_error if it is not (LINALGPACK_CHECK_SLICE_SETUP).
void Vp_StV(DVectorSlice *vs_lhs, value_type alpha, const DVectorSlice &vs_rhs)
vs_lhs += alpha * vs_rhs (BLAS xAXPY)
void sign(const Vector &v, VectorMutable *z)
Compute the sign of each element in an input vector.
size_type dim() const
Returns the number of elements of the VectorSliceTmpl.
void jacobi_rotate(DMatrixSlice *UpTriM, size_type row_i, value_type alpha, value_type beta)
C++ Standard Library compatable iterator class for accesing nonunit stride arrays of data...
const f_int f_dbl_prec const f_int f_int const f_int f_int const f_dbl_prec f_int f_int f_dbl_prec w[]
const LAPACK_C_Decl::f_int & M
void sqrt(DVectorSlice *vs_lhs, const DVectorSlice &vs_rhs)
vs_lhs = sqrt(vs_rhs)
size_type rows() const
Return the number of rows.
DVectorSlice diag(difference_type k=0)
FortranTypes::f_dbl_prec value_type
Typedef for the value type of elements that is used for the library.
int n
const f_int f_dbl_prec const f_int f_int const f_int f_int const f_dbl_prec & u
void update_chol_factor(DMatrixSlice *UpTriM, DVectorSlice *u, const DVectorSlice &v)
DVectorSlice row(size_type i)
Return DVectorSlice object representing the ith row (1-based; 1,2,..,#this->rows()#, or throw std::out_of_range)