iterative-solver 0.0
gram_schmidt.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_GRAM_SCHMIDT_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_GRAM_SCHMIDT_H
3#include <molpro/linalg/array/ArrayHandler.h>
4#include <molpro/linalg/itsolv/helper.h>
5#include <molpro/linalg/itsolv/subspace/Matrix.h>
6#include <molpro/linalg/itsolv/wrap.h>
7
38template <typename T>
39std::vector<T> gram_schmidt(const Matrix<T>& s, Matrix<T>& l, T norm_thresh = precision_scaled<T>(1e-14)) {
40 assert(s.rows() == s.cols());
41 auto n = s.rows();
42 l.fill(0);
43 l.resize({n, n});
44 auto norm = std::vector<T>(n, 0);
45 auto w = std::vector<T>{};
46 for (size_t i = 0; i < n; ++i) {
47 w.assign(i, 0.);
48 for (size_t j = 0; j < i; ++j) {
49 for (size_t k = 0; k <= j; ++k) {
50 w[j] += s(i, k) * l(j, k);
51 }
52 }
53 for (size_t j = 0; j < i; ++j) {
54 if (norm[j] > norm_thresh) {
55 for (size_t k = 0; k <= j; ++k) {
56 l(i, k) -= w[j] / norm[j] * l(j, k);
57 }
58 }
59 }
60 l(i, i) = 1.;
61 for (size_t j = 0; j <= i; ++j) {
62 for (size_t k = 0; k < j; ++k) {
63 norm[i] += 2 * l(i, j) * l(i, k) * s(j, k);
64 }
65 norm[i] += l(i, j) * l(i, j) * s(j, j);
66 }
67 }
68 std::transform(begin(norm), end(norm), begin(norm), [](auto el) { return std::sqrt(std::abs(el)); });
69 return norm;
70}
71
72// FIXME This is implicitly constructed in Gram Schmidt and we can make it an opitonal return variable
98template <typename value_type, typename value_type_abs>
100 const Matrix<value_type>& lin_trans,
101 const std::vector<value_type_abs>& norm) {
102 const auto nrows = lin_trans.rows();
103 const auto ncols = lin_trans.cols();
104 auto t = Matrix<value_type>({nrows, ncols});
105 for (size_t i = 0; i < nrows; ++i) {
106 for (size_t j = 0; j < i; ++j) {
107 for (size_t k = 0; k <= j; ++k) {
108 t(i, j) -= lin_trans(j, k) * overlap(i, k) / std::pow(norm[j], 2);
109 }
110 }
111 }
112 return t;
113}
114
128template <class R, typename value_type_abs>
129auto modified_gram_schmidt(VecRef<R>& params, array::ArrayHandler<R, R>& handler, value_type_abs null_thresh) {
130 auto null_param_indices = std::vector<size_t>{};
131 const size_t n = params.size();
132 for (size_t i = 0; i < n; ++i) {
133 auto norm = handler.dot(params[i], params[i]);
134 norm = std::sqrt(std::abs(norm));
135 if (norm > null_thresh) {
136 handler.scal(1. / norm, params[i]);
137 for (size_t j = i + 1; j < n; ++j) {
138 auto ov = handler.dot(params[i], params[j]);
139 handler.axpy(-ov, params[i], params[j]);
140 }
141 } else {
142 null_param_indices.emplace_back(i);
143 }
144 }
145 return null_param_indices;
146}
147
148} // namespace molpro::linalg::itsolv::subspace::util
149
150#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_GRAM_SCHMIDT_H
Enhances various operations between pairs of arrays and allows dynamic code injection with uniform in...
Definition: ArrayHandler.h:162
virtual value_type dot(const AL &x, const AR &y)=0
virtual void scal(value_type alpha, AL &x)=0
virtual void axpy(value_type alpha, const AR &x, AL &y)=0
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition: Matrix.h:30
void fill(T value)
Sets all elements of matrix to value.
Definition: Matrix.h:91
void resize(const coord_type &dims)
Resize the matrix. The old data is preserved and any new rows/cols are zeroed.
Definition: Matrix.h:128
index_type rows() const
Definition: Matrix.h:167
index_type cols() const
Definition: Matrix.h:168
Definition: gram_schmidt.h:8
std::vector< T > gram_schmidt(const Matrix< T > &s, Matrix< T > &l, T norm_thresh=precision_scaled< T >(1e-14))
Performs Gram-Schmidt orthogonalisation without normalisation.
Definition: gram_schmidt.h:39
Matrix< value_type > construct_lin_trans_in_orthogonal_set(const Matrix< value_type > &overlap, const Matrix< value_type > &lin_trans, const std::vector< value_type_abs > &norm)
Construct Gram-Schmidt linear transformation in orthogonal vectors.
Definition: gram_schmidt.h:99
auto modified_gram_schmidt(VecRef< R > &params, array::ArrayHandler< R, R > &handler, value_type_abs null_thresh)
Apply modified Gram-Schmidt procedure to orthonormalise parameters.
Definition: gram_schmidt.h:129
auto overlap(const CVecRef< R > &left, const CVecRef< Q > &right, array::ArrayHandler< Z, W > &handler) -> std::enable_if_t< detail::Z_and_W_are_one_of_R_and_Q< R, Q, Z, W >, Matrix< typename array::ArrayHandler< Z, W >::value_type > >
Calculates overlap matrix between left and right vectors.
Definition: util.h:51
std::vector< std::reference_wrapper< A > > VecRef
Definition: wrap.h:11