RSMesh 1.0.0
一个曲面重构的系统,输入为点云,输出为obj,stl等主流格式的网格文件,使用的方法为径向基函数插值,采取了并行优化、Intel-MKL等优化措施,支持百万级别的点云
载入中...
搜索中...
未找到
gmres.cpp
1//
2// Created by RainSure on 2024/2/14.
3//
4#include <cmath>
5#include "krylov/gmres.h"
6
7namespace rsmesh::krylov {
8 gmres::gmres(const linear_operator& op, const valuesd& rhs, index_t max_iter)
9 : gmres_base(op, rhs, max_iter) {}
10
11 void gmres::iterate_process() {
12 if (iter_ == max_iter_) {
13 return;
14 }
15
16 auto j = iter_;
17
18 // Arnoldi process
19 auto z = right_preconditioned(vs_.at(j));
20 add_preconditioned_krylov_basis(z);
21 vs_.push_back(left_preconditioned(op_(z)));
22#pragma omp parallel for
23 for (index_t i = 0; i <= j; i++) {
24 r_(i, j) = vs_.at(i).dot(vs_.at(j + 1));
25 }
26 for (index_t i = 0; i <= j; i++) {
27 vs_.at(j + 1) -= r_(i, j) * vs_.at(i);
28 }
29 r_(j + 1, j) = vs_.at(j + 1).norm();
30 vs_.at(j + 1) /= r_(j + 1, j);
31
32 // Update matrix R by Givens rotation
33 for (index_t i = 0; i < j; i++) {
34 auto x = r_(i, j);
35 auto y = r_(i + 1, j);
36 auto tmp1 = c_(i) * x + s_(i) * y;
37 auto tmp2 = -s_(i) * x + c_(i) * y;
38 r_(i, j) = tmp1;
39 r_(i + 1, j) = tmp2;
40 }
41 auto x = r_(j, j);
42 auto y = r_(j + 1, j);
43 auto den = std::hypot(x, y);
44 c_(j) = x / den;
45 s_(j) = y / den;
46
47 r_(j, j) = c_(j) * x + s_(j) * y;
48 g_(j + 1) = -s_(j) * g_(j);
49 g_(j) = c_(j) * g_(j);
50
51 iter_++;
52 }
53} // namespace rsmesh::krylov