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