void QR_update (Matrix& Q, Matrix& R, VectorT& w, const VectorT& v) { Assert(Q.m == R.m && Q.n == R.m); Assert(w.n == R.m); Assert(v.n == R.n); int j, k; T w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to R, H = J_1^T ... J^T_(n-1) R so that H is upper Hessenberg. (12.5.2) */ for (k = R.m - 1; k > 0; k--) { double c, s; double wk = w(k); double wkm1 = w(k-1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_qr (R.m, R.n, Q, R, k - 1, k, c, s); } w0 = w(0); /* Add in w v^T (Equation 12.5.3) */ for (j = 0; j < R.n; j++) R(0,j) += w0 * v(j); /* Apply Givens transformations R' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k=1; k<Min(R.m,R.n+1); k++) { double c, s; double diag = R(k-1,k-1); double offdiag = R(k,k-1); create_givens (diag, offdiag, &c, &s); apply_givens_qr (R.m, R.n, Q, R, k - 1, k, c, s); R(k,k-1)=0; } }
int gsl_linalg_PTLQ_update (gsl_matrix * Q, gsl_matrix * L, const gsl_permutation * p, const gsl_vector * v, gsl_vector * w) { if (Q->size1 != Q->size2 || L->size1 != L->size2) { return GSL_ENOTSQR; } else if (L->size1 != Q->size2 || v->size != Q->size2 || w->size != Q->size2) { return GSL_EBADLEN; } else { size_t j, k; const size_t N = Q->size1; const size_t M = Q->size2; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to L, H = J_1^T ... J^T_(n-1) L so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in v w^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double lj0 = gsl_matrix_get (L, j, 0); size_t p_j = gsl_permutation_get (p, j); double vj = gsl_vector_get (v, p_j); gsl_matrix_set (L, j, 0, lj0 + w0 * vj); } /* Apply Givens transformations L' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < N; k++) { double c, s; double diag = gsl_matrix_get (L, k - 1, k - 1); double offdiag = gsl_matrix_get (L, k - 1, k ); create_givens (diag, offdiag, &c, &s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } return GSL_SUCCESS; } }
int gsl_linalg_LQ_update (gsl_matrix * Q, gsl_matrix * L, const gsl_vector * v, gsl_vector * w) { const size_t N = L->size1; const size_t M = L->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be N x N if L is M x N", GSL_ENOTSQR); } else if (w->size != M) { GSL_ERROR ("w must be length N if L is M x N", GSL_EBADLEN); } else if (v->size != N) { GSL_ERROR ("v must be length M if L is M x N", GSL_EBADLEN); } else { size_t j, k; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to L, H = J_1^T ... J^T_(n-1) L so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) /* loop from k = M-1 to 1 */ { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in v w^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double lj0 = gsl_matrix_get (L, j, 0); double vj = gsl_vector_get (v, j); gsl_matrix_set (L, j, 0, lj0 + w0 * vj); } /* Apply Givens transformations L' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < GSL_MIN(M,N+1); k++) { double c, s; double diag = gsl_matrix_get (L, k - 1, k - 1); double offdiag = gsl_matrix_get (L, k - 1 , k); create_givens (diag, offdiag, &c, &s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); gsl_matrix_set (L, k - 1, k, 0.0); /* exact zero of G^T */ } return GSL_SUCCESS; } }
int gsl_linalg_QRPT_update (gsl_matrix * Q, gsl_matrix * R, const gsl_permutation * p, gsl_vector * w, const gsl_vector * v) { const size_t M = R->size1; const size_t N = R->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be M x M if R is M x N", GSL_ENOTSQR); } else if (w->size != M) { GSL_ERROR ("w must be length M if R is M x N", GSL_EBADLEN); } else if (v->size != N) { GSL_ERROR ("v must be length N if R is M x N", GSL_EBADLEN); } else { size_t j, k; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to R, H = J_1^T ... J^T_(n-1) R so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in w v^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double r0j = gsl_matrix_get (R, 0, j); size_t p_j = gsl_permutation_get (p, j); double vj = gsl_vector_get (v, p_j); gsl_matrix_set (R, 0, j, r0j + w0 * vj); } /* Apply Givens transformations R' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < GSL_MIN(M,N+1); k++) { double c, s; double diag = gsl_matrix_get (R, k - 1, k - 1); double offdiag = gsl_matrix_get (R, k, k - 1); create_givens (diag, offdiag, &c, &s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); gsl_matrix_set (R, k, k - 1, 0.0); /* exact zero of G^T */ } return GSL_SUCCESS; } }