<T>LAPACK 0.1.2
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
tik_bidiag_elden.hpp
Go to the documentation of this file.
1
5//
6// Copyright (c) 2025, University of Colorado Denver. All rights reserved.
7//
8// This file is part of <T>LAPACK.
9// <T>LAPACK is free software: you can redistribute it and/or modify it under
10// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
11
12#ifndef TLAPACK_TIK_BIDIAG_ELDEN_HH
13#define TLAPACK_TIK_BIDIAG_ELDEN_HH
14
21
22#include "tlapack/blas/axpy.hpp"
23#include "tlapack/blas/rot.hpp"
24#include "tlapack/blas/rotg.hpp"
25
43using namespace tlapack;
44
45// /// Solves Tikhonov regularized least squares using special bidiag method
49void tik_bidiag_elden(matrixA_t& A, matrixb_t& b, real_t lambda)
50{
51 // check arguments
52 tlapack_check(nrows(A) >= ncols(A));
53
54 // Initliazation for basic utilities
55 using T = type_t<matrixA_t>;
56 using idx_t = size_type<matrixA_t>;
57
59
61
62 const idx_t m = nrows(A);
63 const idx_t n = ncols(A);
64 const idx_t k = ncols(b);
65
66 // Bidiagonal decomposition
67 std::vector<T> tauv(n);
68 std::vector<T> tauw(n);
69
70 bidiag(A, tauv, tauw);
72
73 // Initializiations for bidiag specialized decomposition
74
75 // Extract diagonal diagonal d and super diagonal e from decomposed A
76 std::vector<real_t> d(n);
77 std::vector<real_t> e(n - 1);
78
79 for (idx_t j = 0; j < n; ++j)
80 d[j] = real(A(j, j));
81 for (idx_t j = 0; j < n - 1; ++j)
82 e[j] = real(A(j, j + 1));
83
84 // Declare and initialize baug
85 std::vector<T> work_;
86 auto work = new_matrix(work_, n, k);
87
88 // Augment zeros onto b
89 laset(GENERAL, real_t(0), real_t(0), work);
90
92
95 real_t cs, sn;
96
97 for (idx_t i = 0; i < n; i++) {
99
100 // Step a: generate rotation
101
102 rotg(d[i], low_d, cs, sn);
103
104 // Step b: apply to next column in A
105 if (i < n - 1) {
106 low_e = -sn * e[i];
107 e[i] = cs * e[i];
108 }
109 // Step c: update right hand side b
110
111 if (i == 0) {
112 for (idx_t j = 0; j < k; ++j) {
113 work(0, j) = -sn * b(0, j);
114 b(0, j) = cs * b(0, j);
115 }
116 }
117 else {
118 auto bv = slice(b, i, range{0, k});
119 auto cv = slice(work, i, range{0, k});
120 rot(bv, cv, cs, sn);
121 }
122
124
125 if (i < n - 1) {
126 // Step a: generate rotation
127
128 low_d = lambda;
129 rotg(low_d, low_e, cs, sn);
130
131 // Step c: update right hand side b
132
133 for (idx_t j = 0; j < k; ++j) {
134 work(i + 1, j) = sn * work(i, j);
135 work(i, j) = cs * work(i, j);
136 }
137 }
138 }
139
140 // Solve the least squares problem
141
142 // Bidiag solving algorithm
143 auto xS0 = slice(b, n - 1, range{0, k});
144 rscl(d[n - 1], xS0);
145 for (idx_t i = n - 1; i-- > 0;) {
146 auto xS0 = slice(b, i, range{0, k});
147 auto xS1 = slice(b, i + 1, range{0, k});
148 axpy(-e[i], xS1, xS0);
149 rscl(d[i], xS0);
150 }
151
152 // Finish solving least squares problem
153 auto x2 = slice(b, range{1, n}, range{0, k});
154 unmlq(LEFT_SIDE, CONJ_TRANS, slice(A, range{0, n - 1}, range{1, n}),
155 slice(tauw, range{0, n - 1}), x2);
156}
157
158#endif // TLAPACK_TIK_BIDIAG_ELDEN_HH
#define TLAPACK_MATRIX
Macro for tlapack::concepts::Matrix compatible with C++17.
Definition concepts.hpp:896
#define TLAPACK_REAL
Macro for tlapack::concepts::Real compatible with C++17.
Definition concepts.hpp:918
void laset(uplo_t uplo, const type_t< matrix_t > &alpha, const type_t< matrix_t > &beta, matrix_t &A)
Initializes a matrix to diagonal and off-diagonal values.
Definition laset.hpp:38
void rscl(const alpha_t &alpha, vector_t &x)
Scale vector by the reciprocal of a constant, .
Definition rscl.hpp:22
void rotg(T &a, T &b, T &c, T &s)
Construct plane rotation that eliminates b, such that:
Definition rotg.hpp:39
void rot(vectorX_t &x, vectorY_t &y, const c_type &c, const s_type &s)
Apply plane rotation:
Definition rot.hpp:44
void axpy(const alpha_t &alpha, const vectorX_t &x, vectorY_t &y)
Add scaled vector, .
Definition axpy.hpp:34
int unmqr(side_t side, trans_t trans, const matrixA_t &A, const tau_t &tau, matrixC_t &C, const UnmqrOpts &opts={})
Applies orthogonal matrix op(Q) to a matrix C using a blocked code.
Definition unmqr.hpp:158
int unmlq(side_t side, trans_t trans, const matrixA_t &A, const tau_t &tau, matrixC_t &C, const UnmlqOpts &opts={})
Applies orthogonal matrix op(Q) to a matrix C using a blocked code.
Definition unmlq.hpp:159
#define tlapack_check(cond)
Throw an error if cond is false.
Definition exceptionHandling.hpp:98
int bidiag(matrix_t &A, vector_t &tauv, vector_t &tauw, const BidiagOpts &opts={})
Reduces a general m by n matrix A to an upper real bidiagonal form B by a unitary transformation:
Definition bidiag.hpp:134
Multiplies the general m-by-n matrix C by Q from tlapack::geqrf()
Sort the numbers in D in increasing order (if ID = 'I') or in decreasing order (if ID = 'D' ).
Definition arrayTraits.hpp:15
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113
constexpr real_type< T > real(const T &x) noexcept
Extends std::real() to real datatypes.
Definition utils.hpp:71
constexpr internal::GeneralAccess GENERAL
General access.
Definition types.hpp:180
constexpr internal::ConjTranspose CONJ_TRANS
conjugate transpose
Definition types.hpp:264
constexpr internal::LeftSide LEFT_SIDE
left side
Definition types.hpp:294
Multiplies the general m-by-n matrix C by Q from tlapack::gelqf()