preCICE v3.3.0
Loading...
Searching...
No Matches
QRFactorization.cpp
Go to the documentation of this file.
1
2#include <Eigen/Core>
3#include <algorithm> // std::sort
4#include <cmath>
5#include <cstddef>
6#include <iostream>
7#include <memory>
8#include <utility>
9#include <vector>
10
13#include "com/Communication.hpp"
14#include "com/SharedPointer.hpp"
15#include "logging/LogMacros.hpp"
17#include "utils/IntraComm.hpp"
18#include "utils/assertion.hpp"
19
21
23 Eigen::MatrixXd Q,
24 Eigen::MatrixXd R,
25 int rows,
26 int cols,
27 int filter,
28 double omega,
29 double theta,
30 double sigma)
31
32 : _Q(std::move(Q)),
33 _R(std::move(R)),
34 _rows(rows),
35 _cols(cols),
36 _filter(filter),
37 _omega(omega),
38 _theta(theta),
39 _sigma(sigma),
41 _fstream_set(false),
43{
44 PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
45 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
46 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
47 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
48}
49
54 Eigen::MatrixXd A,
55 int filter,
56 double omega,
57 double theta,
58 double sigma)
59 : _Q(),
60 _R(),
61 _rows(A.rows()),
62 _cols(0),
63 _filter(filter),
64 _omega(omega),
65 _theta(theta),
66 _sigma(sigma),
68 _fstream_set(false),
69 _globalRows(A.rows())
70{
71 int m = A.cols();
72 for (int k = 0; k < m; k++) {
73 Eigen::VectorXd v = A.col(k);
74 insertColumn(k, v);
75 }
76 // PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
77 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
78 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
79 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
80 PRECICE_ASSERT(_cols == m, _cols, m);
81}
82
87 int filter,
88 double omega,
89 double theta,
90 double sigma)
91 : _Q(),
92 _R(),
93 _rows(0),
94 _cols(0),
95 _filter(filter),
96 _omega(omega),
97 _theta(theta),
98 _sigma(sigma),
100 _fstream_set(false),
101 _globalRows(0)
102{
103}
104
110
111void QRFactorization::applyFilter(double singularityLimit, std::vector<int> &delIndices, Eigen::MatrixXd &V)
112{
114 delIndices.resize(0);
116 bool linearDependence = true;
117 std::vector<int> delFlag(_cols, 0);
118 int delCols = 0;
119 while (linearDependence) {
120 linearDependence = false;
121 int index = 0; // actual index of checked column, \in [0, _cols] and _cols is decreasing
122 if (_cols > 1) {
123 for (size_t i = 0; i < delFlag.size(); i++) {
124 // index is not incremented, if columns has been deleted in previous rounds
125 if (delFlag[i] > 0)
126 continue;
127
128 // QR1-filter
129 if (index >= cols())
130 break;
131 PRECICE_ASSERT(index < _cols, index, _cols);
132 double factor = (_filter == Acceleration::QR1FILTER_ABS) ? 1.0 : _R.norm();
133 if (std::fabs(_R(index, index)) < singularityLimit * factor) {
134
135 linearDependence = true;
136 deleteColumn(index);
137 delFlag[i]++;
138 delIndices.push_back(i);
139 delCols++;
140 // break;
141 index--; // check same column index, as cols are shifted left
142 }
143 PRECICE_ASSERT(delCols + _cols == (int) delFlag.size(), (delCols + _cols), delFlag.size());
144 index++;
145 }
146 }
147 }
148 } else if (_filter == Acceleration::QR2FILTER) {
149 resetFilter(singularityLimit, delIndices, V);
150
151 } else if (_filter == Acceleration::QR3FILTER) {
152 int index = cols() - 1;
153 // Iterate from the last column to the 2nd column from the left
154 for (size_t i = index; i > 0; i--) {
155 Eigen::VectorXd v = V.col(i);
156 double rho0 = utils::IntraComm::l2norm(v);
157 if (std::fabs(_R(i, i)) < rho0 * singularityLimit) {
158 _computeQR2Filter = true;
159 break;
160 }
161 }
162 if (_computeQR2Filter) {
163 PRECICE_DEBUG("Pre-scaling weights were reset. Reverting to QR2 and rebuilding QR.");
164 resetFilter(singularityLimit, delIndices, V);
165 }
166 _computeQR2Filter = false;
167 PRECICE_DEBUG("Deleting {} columns in QR3 Filter", delIndices.size());
168 }
169 std::sort(delIndices.begin(), delIndices.end());
170}
171
177void QRFactorization::resetFilter(double singularityLimit, std::vector<int> &delIndices, Eigen::MatrixXd &V)
178{
179 _Q.resize(0, 0);
180 _R.resize(0, 0);
181 _cols = 0;
182 _rows = V.rows();
183 // starting with the most recent input/output information, i.e., the latest column
184 // which is at position 0 in _matrixV (latest information is never filtered out!)
185 for (int k = 0; k < V.cols(); k++) {
186 Eigen::VectorXd v = V.col(k);
187 // this is the same as pushBack(v) as _cols grows within the insertion process
188 bool inserted = insertColumn(_cols, v, singularityLimit);
189 if (!inserted) {
190 delIndices.push_back(k);
191 }
192 }
194}
195
201{
202
204
205 PRECICE_ASSERT(k >= 0, k);
206 PRECICE_ASSERT(k < _cols, k, _cols);
207
208 // maintain decomposition and orthogonalization by application of givens rotations
209
210 for (int l = k; l < _cols - 1; l++) {
212 computeReflector(grot, _R(l, l + 1), _R(l + 1, l + 1));
213 Eigen::VectorXd Rr1 = _R.row(l);
214 Eigen::VectorXd Rr2 = _R.row(l + 1);
215 applyReflector(grot, l + 2, _cols, Rr1, Rr2);
216 _R.row(l) = Rr1;
217 _R.row(l + 1) = Rr2;
218 Eigen::VectorXd Qc1 = _Q.col(l);
219 Eigen::VectorXd Qc2 = _Q.col(l + 1);
220 applyReflector(grot, 0, _rows, Qc1, Qc2);
221 _Q.col(l) = Qc1;
222 _Q.col(l + 1) = Qc2;
223 }
224 // copy values and resize R and Q
225 for (int j = k; j < _cols - 1; j++) {
226 for (int i = 0; i <= j; i++) {
227 _R(i, j) = _R(i, j + 1);
228 }
229 }
230 _R.conservativeResize(_cols - 1, _cols - 1);
231 //_Q.conservativeResize(Eigen::NoChange_t, _cols-1);
232 _Q.conservativeResize(_rows, _cols - 1);
233 _cols--;
234
235 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
236 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
237 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
238 // PRECICE_ASSERT(_R.rows() == _cols, _Q.rows(), _cols);
239}
240
241// ATTENTION: This method works on the memory of vector v, thus changes the vector v.
242bool QRFactorization::insertColumn(int k, const Eigen::VectorXd &vec, double singularityLimit)
243{
244 PRECICE_TRACE(k);
245
246 Eigen::VectorXd v(vec);
247
248 if (_cols == 0)
249 _rows = v.size();
250
251 bool applyFilter = (singularityLimit > 0.0);
252
253 PRECICE_ASSERT(k >= 0, k);
254 PRECICE_ASSERT(k <= _cols, k, _cols);
255 PRECICE_ASSERT(v.size() == _rows, v.size(), _rows);
256
257 _cols++;
258
259 // orthogonalize v to columns of Q
260 Eigen::VectorXd u(_cols);
261 double rho_orth = 0., rho0 = 0.;
262 if (applyFilter)
263 rho0 = utils::IntraComm::l2norm(v);
264
265 int err = orthogonalize(v, u, rho_orth, _cols - 1);
266
267 // on of the following is true
268 // - either ||v_orth|| / ||v|| <= 0.7 was true and the re-orthogonalization process failed 4 times
269 // - or the system is quadratic, thus no further column can be orthogonalized (||v_orth|| = rho_orth = 0)
270 // - or ||v_orth|| = rho_orth extremely small (almost zero), thus the column v is not very orthogonal to Q, discard
271 if (rho_orth <= std::numeric_limits<double>::min() || err < 0) {
272 PRECICE_DEBUG("The ratio ||v_orth|| / ||v|| is extremely small and either the orthogonalization process of column v failed or the system is quadratic.");
273
274 // necessary for applyFilter with the QR-2 filter. In this case, the new column is not inserted, but discarded.
275 _cols--;
276 _computeQR2Filter = true;
277 return false;
278 }
279
280 // QR2-filter based on the new information added to the orthogonal system.
281 // if the new column incorporates less new information to the system than a
282 // prescribed threshold, the column is discarded
283 // rho_orth: the norm of the orthogonalized (but not normalized) column
284 // rho0: the norm of the initial column that is to be inserted
285 if (applyFilter && (rho0 * singularityLimit > rho_orth)) {
286 PRECICE_DEBUG("discarding column as it is filtered out by the QR2-filter: rho0*eps > rho_orth: {} > {}", rho0 * singularityLimit, rho_orth);
287 _cols--;
288 _computeQR2Filter = true;
289 return false;
290 }
291
292 // resize R(1:m, 1:m) -> R(1:m+1, 1:m+1)
293 _R.conservativeResize(_cols, _cols);
294 _R.col(_cols - 1) = Eigen::VectorXd::Zero(_cols);
295 _R.row(_cols - 1) = Eigen::VectorXd::Zero(_cols);
296
297 for (int j = _cols - 2; j >= k; j--) {
298 for (int i = 0; i <= j; i++) {
299 _R(i, j + 1) = _R(i, j);
300 }
301 }
302
303 for (int j = k + 1; j < _cols; j++) {
304 _R(j, j) = 0.;
305 }
306
307 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
308 // PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
309
310 // resize Q(1:n, 1:m) -> Q(1:n, 1:m+1)
311 _Q.conservativeResize(_rows, _cols);
312 _Q.col(_cols - 1) = v;
313
314 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
315 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
316
317 // maintain decomposition and orthogonalization by application of givens rotations
318 for (int l = _cols - 2; l >= k; l--) {
320 computeReflector(grot, u(l), u(l + 1));
321 Eigen::VectorXd Rr1 = _R.row(l);
322 Eigen::VectorXd Rr2 = _R.row(l + 1);
323 applyReflector(grot, l + 1, _cols, Rr1, Rr2);
324 _R.row(l) = Rr1;
325 _R.row(l + 1) = Rr2;
326 Eigen::VectorXd Qc1 = _Q.col(l);
327 Eigen::VectorXd Qc2 = _Q.col(l + 1);
328 applyReflector(grot, 0, _rows, Qc1, Qc2);
329 _Q.col(l) = Qc1;
330 _Q.col(l + 1) = Qc2;
331 }
332 for (int i = 0; i <= k; i++) {
333 _R(i, k) = u(i);
334 }
335
336 return true;
337}
338
351 Eigen::VectorXd &v,
352 Eigen::VectorXd &r,
353 double &rho,
354 int colNum)
355{
357
360 }
361
362 bool null = false;
363 bool termination = false;
364 double rho0 = 0., rho1 = 0.;
365 Eigen::VectorXd u = Eigen::VectorXd::Zero(_rows);
366 Eigen::VectorXd s = Eigen::VectorXd::Zero(colNum);
367 r = Eigen::VectorXd::Zero(_cols);
368
369 rho = utils::IntraComm::l2norm(v); // distributed l2norm
370 rho0 = rho;
371 int k = 0;
372 while (!termination) {
373
374 // take a gram-schmidt iteration
375 u = Eigen::VectorXd::Zero(_rows);
376 for (int j = 0; j < colNum; j++) {
377
378 // dot-product <_Q(:,j), v >
379 Eigen::VectorXd Qc = _Q.col(j);
380
381 // dot product <_Q(:,j), v> =: r_ij
382 double r_ij = utils::IntraComm::dot(Qc, v);
383 // save r_ij in s(j) = column of R
384 s(j) = r_ij;
385 // u is the sum of projections r_ij * _Q(:,j) = _Q(:,j) * <_Q(:,j), v>
386 u += _Q.col(j) * r_ij;
387 }
388 // add the furier coefficients over all orthogonalize iterations
389 for (int j = 0; j < colNum; j++) {
390 r(j) = r(j) + s(j);
391 }
392 // subtract projections from v, v is now orthogonal to columns of _Q
393 for (int i = 0; i < _rows; i++) {
394 v(i) = v(i) - u(i);
395 }
396 // rho1 = norm of orthogonalized new column v_tilde (though not normalized)
397 rho1 = utils::IntraComm::l2norm(v); // distributed l2norm
398
399 // t = norm of r_(:,j) with j = colNum-1
400 double norm_coefficients = utils::IntraComm::l2norm(s); // distributed l2norm
401 k++;
402
403 // treat the special case m=n
404 // Attention (intra-participant communication): Here, we need to compare the global _rows with colNum and NOT the local
405 // rows on the processor.
406 if (_globalRows == colNum) {
407 PRECICE_WARN("The least-squares system matrix is quadratic, i.e., the new column cannot be orthogonalized (and thus inserted) to the LS-system.\nOld columns need to be removed.");
408 v = Eigen::VectorXd::Zero(_rows);
409 rho = 0.;
410 return k;
411 }
412
413 // take correct action if v_orth is null
414 if (rho1 <= std::numeric_limits<double>::min()) {
415 PRECICE_DEBUG("The norm of v_orthogonal is almost zero, i.e., failed to orthogonalize column v; discard.");
416 null = true;
417 rho1 = 1;
418 termination = true;
419 }
420
433 if (rho1 * _theta <= rho0 + _omega * norm_coefficients) {
434 // exit to fail if too many iterations
435 if (k >= 4) {
436 PRECICE_WARN("Matrix Q is not sufficiently orthogonal. Failed to orthogonalize new column after 4 iterations. New column will be discarded. The least-squares system is very bad conditioned and the quasi-Newton will most probably fail to converge.");
437 return -1;
438 }
439 rho0 = rho1;
440
441 // termination, i.e., (rho0 + _omega * t < _theta *rho1)
442 } else {
443 termination = true;
444 }
445 }
446
447 // normalize v
448 v /= rho1;
449 rho = null ? 0 : rho1;
450 r(colNum) = rho;
451 return k;
452}
453
466 Eigen::VectorXd &v,
467 Eigen::VectorXd &r,
468 double &rho,
469 int colNum)
470{
472
473 // serial case
476 }
477
478 bool restart = false;
479 bool null = false;
480 bool termination = false;
481 double rho0 = 0., rho1 = 0.;
482 double t = 0;
483 Eigen::VectorXd u = Eigen::VectorXd::Zero(_rows);
484 Eigen::VectorXd s = Eigen::VectorXd::Zero(colNum);
485 r = Eigen::VectorXd::Zero(_cols);
486
487 rho = utils::IntraComm::l2norm(v); // distributed l2norm
488 rho0 = rho;
489 int k = 0;
490 while (!termination) {
491 // take a gram-schmidt iteration, ignoring r on later steps if previous v was null
492 u = Eigen::VectorXd::Zero(_rows);
493 for (int j = 0; j < colNum; j++) {
494
495 /*
496 * dot-product <_Q(:,j), v >
497 */
498 Eigen::VectorXd Qc = _Q.col(j);
499
500 // dot product <_Q(:,j), v> =: r_ij
501 double ss = utils::IntraComm::dot(Qc, v);
502 t = ss;
503 // save r_ij in s(j) = column of R
504 s(j) = t;
505 // u is the sum of projections r_ij * _Q(i,:) = _Q(i,:) * <_Q(:,j), v>
506 for (int i = 0; i < _rows; i++) {
507 u(i) = u(i) + _Q(i, j) * t;
508 }
509 }
510 if (!null) {
511 // add over all runs: r_ij = r_ij_prev + r_ij
512 for (int j = 0; j < colNum; j++) {
513 r(j) = r(j) + s(j);
514 }
515 }
516 // subtract projections from v, v is now orthogonal to columns of _Q
517 for (int i = 0; i < _rows; i++) {
518 v(i) = v(i) - u(i);
519 }
520 // rho1 = norm of orthogonalized new column v_tilde (though not normalized)
521 rho1 = utils::IntraComm::l2norm(v); // distributed l2norm
522
523 // t = norm of r_(:,j) with j = colNum-1
524 t = utils::IntraComm::l2norm(s); // distributed l2norm
525 k++;
526
527 // treat the special case m=n
528 // Attention (intra-participant communication): Here, we need to compare the global _rows with colNum and NOT the local
529 // rows on the processor.
530 if (_globalRows == colNum) {
531 PRECICE_WARN("The least-squares system matrix is quadratic, i.e., the new column cannot be orthogonalized (and thus inserted) to the LS-system.\nOld columns need to be removed.");
532 v = Eigen::VectorXd::Zero(_rows);
533 rho = 0.;
534 return k;
535 }
536
549 if (rho1 * _theta <= rho0 + _omega * t) {
550 // exit to fail if too many iterations
551 if (k >= 4) {
553 << "\ntoo many iterations in orthogonalize, termination failed\n";
554 PRECICE_WARN("Matrix Q is not sufficiently orthogonal. Failed to orthogonalize new column after 4 iterations. New column will be discarded. The least-squares system is very bad conditioned and the quasi-Newton will most probably fail to converge.");
555 return -1;
556 }
557
558 // if ||v_orth|| / ||v|| is extremely small (numeric limit)
559 // discard information from column, use any unit vector orthogonal to Q
560 if (!restart && rho1 <= rho * _sigma) {
561 PRECICE_WARN("The new column is in the range of Q, thus not possible to orthogonalize. Try to insert a unit vector that is orthogonal to the columns space of Q.");
562 // PRECICE_DEBUG("[QR-dec] - reorthogonalization");
563 if (_fstream_set)
564 (*_infostream) << "[QR-dec] - reorthogonalization\n";
565
566 restart = true;
567
575 u = Eigen::VectorXd::Zero(_rows);
576 for (int j = 0; j < colNum; j++) {
577 for (int i = 0; i < _rows; i++) {
578 u(i) = u(i) + _Q(i, j) * _Q(i, j);
579 }
580 }
581 t = 2;
582
583 // ATTENTION: maybe in the following is something wrong @todo: fix this comment
584
585 for (int i = 0; i < _rows; i++) {
586 if (u(i) < t) {
587 k = i;
588 t = u(k);
589 }
590 }
591
592 int global_k = k;
593 int local_k = 0;
594 double local_uk = 0.;
595 double global_uk = 0.;
596 int rank = 0;
597
600 utils::IntraComm::getCommunication()->send(u(k), 0);
601 }
602
604 global_uk = u(k);
605 for (Rank secondaryRank : utils::IntraComm::allSecondaryRanks()) {
606 utils::IntraComm::getCommunication()->receive(local_k, secondaryRank);
607 utils::IntraComm::getCommunication()->receive(local_uk, secondaryRank);
608 if (local_uk < global_uk) {
609 rank = secondaryRank;
610 global_uk = local_uk;
611 global_k = local_k;
612 }
613 }
614 if (_fstream_set)
615 (*_infostream) << " global u(k):" << global_uk << ", global k: " << global_k << ", rank: " << rank << '\n';
616 }
617
618 // take correct action if v is null
619 if (rho1 == 0) {
620 null = true;
621 rho1 = 1;
622 }
623 // reinitialize v and k
624 v = Eigen::VectorXd::Zero(_rows);
625
626 // insert rho1 at position k with smallest u(i) = Q(i,:) * Q(i,:)
628 v(k) = rho1;
629 } else {
630 if (utils::IntraComm::getRank() == rank)
631 v(global_k) = rho1;
632 }
633 k = 0;
634 }
635 rho0 = rho1;
636
637 // termination, i.e., (rho0 + _omega * t < _theta *rho1)
638 } else {
639 termination = true;
640 }
641 }
642
643 // normalize v
644 v /= rho1;
645 rho = null ? 0 : rho1;
646 r(colNum) = rho;
647 return k;
648}
649
655 double &x,
656 double &y)
657{
658 double u = x;
659 double v = y;
660 if (v == 0) {
661 grot.sigma = 0;
662 grot.gamma = 1;
663 } else {
664 double mu = std::max(std::fabs(u), std::fabs(v));
665 double t = mu * std::sqrt(std::pow(u / mu, 2) + std::pow(v / mu, 2));
666 t *= (u < 0) ? -1 : 1;
667 grot.gamma = u / t;
668 grot.sigma = v / t;
669 x = t;
670 y = 0;
671 }
672}
673
679 const QRFactorization::givensRot &grot,
680 int k,
681 int l,
682 Eigen::VectorXd &p,
683 Eigen::VectorXd &q)
684{
685 double nu = grot.sigma / (1. + grot.gamma);
686 for (int j = k; j < l; j++) {
687 double u = p(j);
688 double v = q(j);
689 double t = u * grot.gamma + v * grot.sigma;
690 p(j) = t;
691 q(j) = (t + u) * nu - v;
692 }
693}
694
696{
697 _globalRows = gr;
698}
699
700Eigen::MatrixXd &QRFactorization::matrixQ()
701{
702 return _Q;
703}
704
705Eigen::MatrixXd &QRFactorization::matrixR()
706{
707 return _R;
708}
709
711{
712 return _cols;
713}
714
716{
717 return _rows;
718}
719
724
726{
727 _Q.resize(0, 0);
728 _R.resize(0, 0);
729 _cols = 0;
730 _rows = 0;
731 _globalRows = 0;
732}
733
735 Eigen::MatrixXd const &Q,
736 Eigen::MatrixXd const &R,
737 int rows,
738 int cols,
739 double omega,
740 double theta,
741 double sigma)
742{
743 _Q = Q;
744 _R = R;
745 _rows = rows;
746 _cols = cols;
747 _omega = omega;
748 _theta = theta;
749 _sigma = sigma;
751 PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
752 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
753 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
754 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
755}
756
758 Eigen::MatrixXd const &A,
759 int globalRows,
760 double omega,
761 double theta,
762 double sigma)
763{
765 _Q.resize(0, 0);
766 _R.resize(0, 0);
767 _cols = 0;
768 _rows = A.rows();
769 _omega = omega;
770 _theta = theta;
771 _sigma = sigma;
772 _globalRows = globalRows;
773
774 int m = A.cols();
775 int col = 0, k = 0;
776 for (; col < m; k++, col++) {
777 Eigen::VectorXd v = A.col(col);
778 bool inserted = insertColumn(k, v);
779 if (not inserted) {
780 k--;
781 PRECICE_DEBUG("column {} has not been inserted in the QR-factorization, failed to orthogonalize.", col);
782 }
783 }
784 PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
785 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
786 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
787 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
788 PRECICE_ASSERT(_cols == m, _cols, m);
789}
790
791void QRFactorization::pushFront(const Eigen::VectorXd &v)
792{
793 insertColumn(0, v);
794}
795
796void QRFactorization::pushBack(const Eigen::VectorXd &v)
797{
799}
800
805
807{
808 deleteColumn(_cols - 1);
809}
810
812{
813 _infostream = stream;
814 _fstream_set = true;
815}
816
818{
819 _filter = filter;
820}
821
822} // namespace precice::acceleration::impl
#define PRECICE_WARN(...)
Definition LogMacros.hpp:12
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:61
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:92
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
T begin(T... args)
int orthogonalize_stable(Eigen::VectorXd &v, Eigen::VectorXd &r, double &rho, int colNum)
assuming Q(1:n,1:m) has nearly orthonormal columns, this procedure orthogonlizes v(1:n) to the column...
bool insertColumn(int k, const Eigen::VectorXd &v, double singularityLimit=0)
inserts a new column at arbitrary position and updates the QR factorization This function works on th...
int orthogonalize(Eigen::VectorXd &v, Eigen::VectorXd &r, double &rho, int colNum)
assuming Q(1:n,1:m) has nearly orthonormal columns, this procedure orthogonlizes v(1:n) to the column...
Eigen::MatrixXd & matrixR()
returns a matrix representation of the upper triangular matrix R
void applyFilter(double singularityLimit, std::vector< int > &delIndices, Eigen::MatrixXd &V)
filters the least squares system, i.e., the decomposition Q*R = V according to the defined filter tec...
void computeReflector(givensRot &grot, double &x, double &y)
computes parameters for givens matrix G for which (x,y)G = (z,0). replaces (x,y) by (z,...
void resetFilter(double singularityLimit, std::vector< int > &delIndices, Eigen::MatrixXd &V)
Performs a reset of A = QR using the QR2 Filter. This eliminates columns during the reconstruction of...
void pushBack(const Eigen::VectorXd &v)
inserts a new column at position _cols-1, i.e., appends a column at the end and updates the QR factor...
void reset()
resets the QR factorization zo zero Q(0:0, 0:0)R(0:0, 0:0)
void popBack()
deletes the column at position _cols-1, i.e., deletes the last column and updates the QR factorizatio...
void pushFront(const Eigen::VectorXd &v)
inserts a new column at position 0, i.e., shifts right and inserts at first position and updates the ...
QRFactorization(int filter=0, double omega=0, double theta=1./0.7, double sigma=std::numeric_limits< double >::min())
Constructor.
void applyReflector(const givensRot &grot, int k, int l, Eigen::VectorXd &p, Eigen::VectorXd &q)
this procedure replaces the two column matrix [p(k:l-1), q(k:l-1)] by [p(k:l), q(k:l)]*G,...
Eigen::MatrixXd & matrixQ()
returns a matrix representation of the orthogonal matrix Q
void popFront()
deletes the column at position 0, i.e., deletes and shifts columns to the left and updates the QR fac...
void deleteColumn(int k)
updates the factorization A=Q[1:n,1:m]R[1:m,1:n] when the kth column of A is deleted....
static double l2norm(const Eigen::VectorXd &vec)
The l2 norm of a vector is calculated on distributed data.
Definition IntraComm.cpp:67
static Rank getRank()
Current rank.
Definition IntraComm.cpp:42
static double dot(const Eigen::VectorXd &vec1, const Eigen::VectorXd &vec2)
static bool isPrimary()
True if this process is running the primary rank.
Definition IntraComm.cpp:52
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
Definition IntraComm.hpp:37
static bool isParallel()
True if this process is running in parallel.
Definition IntraComm.cpp:62
static bool isSecondary()
True if this process is running a secondary rank.
Definition IntraComm.cpp:57
static com::PtrCommunication & getCommunication()
Intra-participant communication.
Definition IntraComm.hpp:31
T end(T... args)
T fabs(T... args)
T max(T... args)
T min(T... args)
int Rank
Definition Types.hpp:37
STL namespace.
T pow(T... args)
T push_back(T... args)
T resize(T... args)
T size(T... args)
T sort(T... args)
T sqrt(T... args)