preCICE v3.2.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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),
40 _infostream(),
41 _fstream_set(false),
42 _globalRows(rows)
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),
67 _infostream(),
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),
99 _infostream(),
100 _fstream_set(false),
101 _globalRows(0)
102{
103}
104
105void QRFactorization::applyFilter(double singularityLimit, std::vector<int> &delIndices, Eigen::MatrixXd &V)
106{
108 delIndices.resize(0);
110 bool linearDependence = true;
111 std::vector<int> delFlag(_cols, 0);
112 int delCols = 0;
113 while (linearDependence) {
114 linearDependence = false;
115 int index = 0; // actual index of checked column, \in [0, _cols] and _cols is decreasing
116 if (_cols > 1) {
117 for (size_t i = 0; i < delFlag.size(); i++) {
118 // index is not incremented, if columns has been deleted in previous rounds
119 if (delFlag[i] > 0)
120 continue;
121
122 // QR1-filter
123 if (index >= cols())
124 break;
126 double factor = (_filter == Acceleration::QR1FILTER_ABS) ? 1.0 : _R.norm();
127 if (std::fabs(_R(index, index)) < singularityLimit * factor) {
128
129 linearDependence = true;
131 delFlag[i]++;
132 delIndices.push_back(i);
133 delCols++;
134 // break;
135 index--; // check same column index, as cols are shifted left
136 }
137 PRECICE_ASSERT(delCols + _cols == (int) delFlag.size(), (delCols + _cols), delFlag.size());
138 index++;
139 }
140 }
141 }
142 } else if (_filter == Acceleration::QR2FILTER) {
143 resetFilter(singularityLimit, delIndices, V);
144
145 } else if (_filter == Acceleration::QR3FILTER) {
146 int index = cols() - 1;
147 // Iterate from the last column to the 2nd column from the left
148 for (size_t i = index; i > 0; i--) {
149 Eigen::VectorXd v = V.col(i);
150 double rho0 = utils::IntraComm::l2norm(v);
151 if (std::fabs(_R(i, i)) < rho0 * singularityLimit) {
152 _computeQR2Filter = true;
153 break;
154 }
155 }
156 if (_computeQR2Filter) {
157 PRECICE_DEBUG("Pre-scaling weights were reset. Reverting to QR2 and rebuilding QR.");
158 resetFilter(singularityLimit, delIndices, V);
159 }
160 _computeQR2Filter = false;
161 PRECICE_DEBUG("Deleting {} columns in QR3 Filter", delIndices.size());
162 }
163 std::sort(delIndices.begin(), delIndices.end());
164}
165
171void QRFactorization::resetFilter(double singularityLimit, std::vector<int> &delIndices, Eigen::MatrixXd &V)
172{
173 _Q.resize(0, 0);
174 _R.resize(0, 0);
175 _cols = 0;
176 _rows = V.rows();
177 // starting with the most recent input/output information, i.e., the latest column
178 // which is at position 0 in _matrixV (latest information is never filtered out!)
179 for (int k = 0; k < V.cols(); k++) {
180 Eigen::VectorXd v = V.col(k);
181 // this is the same as pushBack(v) as _cols grows within the insertion process
182 bool inserted = insertColumn(_cols, v, singularityLimit);
183 if (!inserted) {
184 delIndices.push_back(k);
185 }
186 }
188}
189
195{
196
198
199 PRECICE_ASSERT(k >= 0, k);
200 PRECICE_ASSERT(k < _cols, k, _cols);
201
202 // maintain decomposition and orthogonalization by application of givens rotations
203
204 for (int l = k; l < _cols - 1; l++) {
206 computeReflector(grot, _R(l, l + 1), _R(l + 1, l + 1));
207 Eigen::VectorXd Rr1 = _R.row(l);
208 Eigen::VectorXd Rr2 = _R.row(l + 1);
209 applyReflector(grot, l + 2, _cols, Rr1, Rr2);
210 _R.row(l) = Rr1;
211 _R.row(l + 1) = Rr2;
212 Eigen::VectorXd Qc1 = _Q.col(l);
213 Eigen::VectorXd Qc2 = _Q.col(l + 1);
214 applyReflector(grot, 0, _rows, Qc1, Qc2);
215 _Q.col(l) = Qc1;
216 _Q.col(l + 1) = Qc2;
217 }
218 // copy values and resize R and Q
219 for (int j = k; j < _cols - 1; j++) {
220 for (int i = 0; i <= j; i++) {
221 _R(i, j) = _R(i, j + 1);
222 }
223 }
224 _R.conservativeResize(_cols - 1, _cols - 1);
225 //_Q.conservativeResize(Eigen::NoChange_t, _cols-1);
226 _Q.conservativeResize(_rows, _cols - 1);
227 _cols--;
228
229 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
230 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
231 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
232 // PRECICE_ASSERT(_R.rows() == _cols, _Q.rows(), _cols);
233}
234
235// ATTENTION: This method works on the memory of vector v, thus changes the vector v.
236bool QRFactorization::insertColumn(int k, const Eigen::VectorXd &vec, double singularityLimit)
237{
238 PRECICE_TRACE(k);
239
240 Eigen::VectorXd v(vec);
241
242 if (_cols == 0)
243 _rows = v.size();
244
245 bool applyFilter = (singularityLimit > 0.0);
246
247 PRECICE_ASSERT(k >= 0, k);
248 PRECICE_ASSERT(k <= _cols, k, _cols);
249 PRECICE_ASSERT(v.size() == _rows, v.size(), _rows);
250
251 _cols++;
252
253 // orthogonalize v to columns of Q
254 Eigen::VectorXd u(_cols);
255 double rho_orth = 0., rho0 = 0.;
256 if (applyFilter)
257 rho0 = utils::IntraComm::l2norm(v);
258
259 int err = orthogonalize(v, u, rho_orth, _cols - 1);
260
261 // on of the following is true
262 // - either ||v_orth|| / ||v|| <= 0.7 was true and the re-orthogonalization process failed 4 times
263 // - or the system is quadratic, thus no further column can be orthogonalized (||v_orth|| = rho_orth = 0)
264 // - or ||v_orth|| = rho_orth extremely small (almost zero), thus the column v is not very orthogonal to Q, discard
265 if (rho_orth <= std::numeric_limits<double>::min() || err < 0) {
266 PRECICE_DEBUG("The ratio ||v_orth|| / ||v|| is extremely small and either the orthogonalization process of column v failed or the system is quadratic.");
267
268 // necessary for applyFilter with the QR-2 filter. In this case, the new column is not inserted, but discarded.
269 _cols--;
270 _computeQR2Filter = true;
271 return false;
272 }
273
274 // QR2-filter based on the new information added to the orthogonal system.
275 // if the new column incorporates less new information to the system than a
276 // prescribed threshold, the column is discarded
277 // rho_orth: the norm of the orthogonalized (but not normalized) column
278 // rho0: the norm of the initial column that is to be inserted
279 if (applyFilter && (rho0 * singularityLimit > rho_orth)) {
280 PRECICE_DEBUG("discarding column as it is filtered out by the QR2-filter: rho0*eps > rho_orth: {} > {}", rho0 * singularityLimit, rho_orth);
281 _cols--;
282 _computeQR2Filter = true;
283 return false;
284 }
285
286 // resize R(1:m, 1:m) -> R(1:m+1, 1:m+1)
287 _R.conservativeResize(_cols, _cols);
288 _R.col(_cols - 1) = Eigen::VectorXd::Zero(_cols);
289 _R.row(_cols - 1) = Eigen::VectorXd::Zero(_cols);
290
291 for (int j = _cols - 2; j >= k; j--) {
292 for (int i = 0; i <= j; i++) {
293 _R(i, j + 1) = _R(i, j);
294 }
295 }
296
297 for (int j = k + 1; j < _cols; j++) {
298 _R(j, j) = 0.;
299 }
300
301 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
302 // PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
303
304 // resize Q(1:n, 1:m) -> Q(1:n, 1:m+1)
305 _Q.conservativeResize(_rows, _cols);
306 _Q.col(_cols - 1) = v;
307
308 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
309 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
310
311 // maintain decomposition and orthogonalization by application of givens rotations
312 for (int l = _cols - 2; l >= k; l--) {
314 computeReflector(grot, u(l), u(l + 1));
315 Eigen::VectorXd Rr1 = _R.row(l);
316 Eigen::VectorXd Rr2 = _R.row(l + 1);
317 applyReflector(grot, l + 1, _cols, Rr1, Rr2);
318 _R.row(l) = Rr1;
319 _R.row(l + 1) = Rr2;
320 Eigen::VectorXd Qc1 = _Q.col(l);
321 Eigen::VectorXd Qc2 = _Q.col(l + 1);
322 applyReflector(grot, 0, _rows, Qc1, Qc2);
323 _Q.col(l) = Qc1;
324 _Q.col(l + 1) = Qc2;
325 }
326 for (int i = 0; i <= k; i++) {
327 _R(i, k) = u(i);
328 }
329
330 return true;
331}
332
345 Eigen::VectorXd &v,
346 Eigen::VectorXd &r,
347 double &rho,
348 int colNum)
349{
351
354 }
355
356 bool null = false;
357 bool termination = false;
358 double rho0 = 0., rho1 = 0.;
359 Eigen::VectorXd u = Eigen::VectorXd::Zero(_rows);
360 Eigen::VectorXd s = Eigen::VectorXd::Zero(colNum);
361 r = Eigen::VectorXd::Zero(_cols);
362
363 rho = utils::IntraComm::l2norm(v); // distributed l2norm
364 rho0 = rho;
365 int k = 0;
366 while (!termination) {
367
368 // take a gram-schmidt iteration
369 u = Eigen::VectorXd::Zero(_rows);
370 for (int j = 0; j < colNum; j++) {
371
372 // dot-product <_Q(:,j), v >
373 Eigen::VectorXd Qc = _Q.col(j);
374
375 // dot product <_Q(:,j), v> =: r_ij
376 double r_ij = utils::IntraComm::dot(Qc, v);
377 // save r_ij in s(j) = column of R
378 s(j) = r_ij;
379 // u is the sum of projections r_ij * _Q(:,j) = _Q(:,j) * <_Q(:,j), v>
380 u += _Q.col(j) * r_ij;
381 }
382 // add the furier coefficients over all orthogonalize iterations
383 for (int j = 0; j < colNum; j++) {
384 r(j) = r(j) + s(j);
385 }
386 // subtract projections from v, v is now orthogonal to columns of _Q
387 for (int i = 0; i < _rows; i++) {
388 v(i) = v(i) - u(i);
389 }
390 // rho1 = norm of orthogonalized new column v_tilde (though not normalized)
391 rho1 = utils::IntraComm::l2norm(v); // distributed l2norm
392
393 // t = norm of r_(:,j) with j = colNum-1
394 double norm_coefficients = utils::IntraComm::l2norm(s); // distributed l2norm
395 k++;
396
397 // treat the special case m=n
398 // Attention (intra-participant communication): Here, we need to compare the global _rows with colNum and NOT the local
399 // rows on the processor.
400 if (_globalRows == colNum) {
401 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.");
402 v = Eigen::VectorXd::Zero(_rows);
403 rho = 0.;
404 return k;
405 }
406
407 // take correct action if v_orth is null
408 if (rho1 <= std::numeric_limits<double>::min()) {
409 PRECICE_DEBUG("The norm of v_orthogonal is almost zero, i.e., failed to orthogonalize column v; discard.");
410 null = true;
411 rho1 = 1;
412 termination = true;
413 }
414
427 if (rho1 * _theta <= rho0 + _omega * norm_coefficients) {
428 // exit to fail if too many iterations
429 if (k >= 4) {
430 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.");
431 return -1;
432 }
433 rho0 = rho1;
434
435 // termination, i.e., (rho0 + _omega * t < _theta *rho1)
436 } else {
437 termination = true;
438 }
439 }
440
441 // normalize v
442 v /= rho1;
443 rho = null ? 0 : rho1;
444 r(colNum) = rho;
445 return k;
446}
447
460 Eigen::VectorXd &v,
461 Eigen::VectorXd &r,
462 double &rho,
463 int colNum)
464{
466
467 // serial case
470 }
471
472 bool restart = false;
473 bool null = false;
474 bool termination = false;
475 double rho0 = 0., rho1 = 0.;
476 double t = 0;
477 Eigen::VectorXd u = Eigen::VectorXd::Zero(_rows);
478 Eigen::VectorXd s = Eigen::VectorXd::Zero(colNum);
479 r = Eigen::VectorXd::Zero(_cols);
480
481 rho = utils::IntraComm::l2norm(v); // distributed l2norm
482 rho0 = rho;
483 int k = 0;
484 while (!termination) {
485 // take a gram-schmidt iteration, ignoring r on later steps if previous v was null
486 u = Eigen::VectorXd::Zero(_rows);
487 for (int j = 0; j < colNum; j++) {
488
489 /*
490 * dot-product <_Q(:,j), v >
491 */
492 Eigen::VectorXd Qc = _Q.col(j);
493
494 // dot product <_Q(:,j), v> =: r_ij
495 double ss = utils::IntraComm::dot(Qc, v);
496 t = ss;
497 // save r_ij in s(j) = column of R
498 s(j) = t;
499 // u is the sum of projections r_ij * _Q(i,:) = _Q(i,:) * <_Q(:,j), v>
500 for (int i = 0; i < _rows; i++) {
501 u(i) = u(i) + _Q(i, j) * t;
502 }
503 }
504 if (!null) {
505 // add over all runs: r_ij = r_ij_prev + r_ij
506 for (int j = 0; j < colNum; j++) {
507 r(j) = r(j) + s(j);
508 }
509 }
510 // subtract projections from v, v is now orthogonal to columns of _Q
511 for (int i = 0; i < _rows; i++) {
512 v(i) = v(i) - u(i);
513 }
514 // rho1 = norm of orthogonalized new column v_tilde (though not normalized)
515 rho1 = utils::IntraComm::l2norm(v); // distributed l2norm
516
517 // t = norm of r_(:,j) with j = colNum-1
518 t = utils::IntraComm::l2norm(s); // distributed l2norm
519 k++;
520
521 // treat the special case m=n
522 // Attention (intra-participant communication): Here, we need to compare the global _rows with colNum and NOT the local
523 // rows on the processor.
524 if (_globalRows == colNum) {
525 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.");
526 v = Eigen::VectorXd::Zero(_rows);
527 rho = 0.;
528 return k;
529 }
530
543 if (rho1 * _theta <= rho0 + _omega * t) {
544 // exit to fail if too many iterations
545 if (k >= 4) {
547 << "\ntoo many iterations in orthogonalize, termination failed\n";
548 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.");
549 return -1;
550 }
551
552 // if ||v_orth|| / ||v|| is extremely small (numeric limit)
553 // discard information from column, use any unit vector orthogonal to Q
554 if (!restart && rho1 <= rho * _sigma) {
555 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.");
556 // PRECICE_DEBUG("[QR-dec] - reorthogonalization");
557 if (_fstream_set)
558 (*_infostream) << "[QR-dec] - reorthogonalization\n";
559
560 restart = true;
561
569 u = Eigen::VectorXd::Zero(_rows);
570 for (int j = 0; j < colNum; j++) {
571 for (int i = 0; i < _rows; i++) {
572 u(i) = u(i) + _Q(i, j) * _Q(i, j);
573 }
574 }
575 t = 2;
576
577 // ATTENTION: maybe in the following is something wrong @todo: fix this comment
578
579 for (int i = 0; i < _rows; i++) {
580 if (u(i) < t) {
581 k = i;
582 t = u(k);
583 }
584 }
585
586 int global_k = k;
587 int local_k = 0;
588 double local_uk = 0.;
589 double global_uk = 0.;
590 int rank = 0;
591
594 utils::IntraComm::getCommunication()->send(u(k), 0);
595 }
596
598 global_uk = u(k);
599 for (Rank secondaryRank : utils::IntraComm::allSecondaryRanks()) {
600 utils::IntraComm::getCommunication()->receive(local_k, secondaryRank);
601 utils::IntraComm::getCommunication()->receive(local_uk, secondaryRank);
602 if (local_uk < global_uk) {
603 rank = secondaryRank;
604 global_uk = local_uk;
605 global_k = local_k;
606 }
607 }
608 if (_fstream_set)
609 (*_infostream) << " global u(k):" << global_uk << ", global k: " << global_k << ", rank: " << rank << '\n';
610 }
611
612 // take correct action if v is null
613 if (rho1 == 0) {
614 null = true;
615 rho1 = 1;
616 }
617 // reinitialize v and k
618 v = Eigen::VectorXd::Zero(_rows);
619
620 // insert rho1 at position k with smallest u(i) = Q(i,:) * Q(i,:)
622 v(k) = rho1;
623 } else {
624 if (utils::IntraComm::getRank() == rank)
625 v(global_k) = rho1;
626 }
627 k = 0;
628 }
629 rho0 = rho1;
630
631 // termination, i.e., (rho0 + _omega * t < _theta *rho1)
632 } else {
633 termination = true;
634 }
635 }
636
637 // normalize v
638 v /= rho1;
639 rho = null ? 0 : rho1;
640 r(colNum) = rho;
641 return k;
642}
643
649 double &x,
650 double &y)
651{
652 double u = x;
653 double v = y;
654 if (v == 0) {
655 grot.sigma = 0;
656 grot.gamma = 1;
657 } else {
658 double mu = std::max(std::fabs(u), std::fabs(v));
659 double t = mu * std::sqrt(std::pow(u / mu, 2) + std::pow(v / mu, 2));
660 t *= (u < 0) ? -1 : 1;
661 grot.gamma = u / t;
662 grot.sigma = v / t;
663 x = t;
664 y = 0;
665 }
666}
667
673 const QRFactorization::givensRot &grot,
674 int k,
675 int l,
676 Eigen::VectorXd &p,
677 Eigen::VectorXd &q)
678{
679 double nu = grot.sigma / (1. + grot.gamma);
680 for (int j = k; j < l; j++) {
681 double u = p(j);
682 double v = q(j);
683 double t = u * grot.gamma + v * grot.sigma;
684 p(j) = t;
685 q(j) = (t + u) * nu - v;
686 }
687}
688
690{
691 _globalRows = gr;
692}
693
694Eigen::MatrixXd &QRFactorization::matrixQ()
695{
696 return _Q;
697}
698
699Eigen::MatrixXd &QRFactorization::matrixR()
700{
701 return _R;
702}
703
705{
706 return _cols;
707}
708
710{
711 return _rows;
712}
713
718
720{
721 _Q.resize(0, 0);
722 _R.resize(0, 0);
723 _cols = 0;
724 _rows = 0;
725 _globalRows = 0;
726}
727
729 Eigen::MatrixXd const &Q,
730 Eigen::MatrixXd const &R,
731 int rows,
732 int cols,
733 double omega,
734 double theta,
735 double sigma)
736{
737 _Q = Q;
738 _R = R;
739 _rows = rows;
740 _cols = cols;
741 _omega = omega;
742 _theta = theta;
743 _sigma = sigma;
745 PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
746 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
747 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
748 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
749}
750
752 Eigen::MatrixXd const &A,
753 int globalRows,
754 double omega,
755 double theta,
756 double sigma)
757{
759 _Q.resize(0, 0);
760 _R.resize(0, 0);
761 _cols = 0;
762 _rows = A.rows();
763 _omega = omega;
764 _theta = theta;
765 _sigma = sigma;
766 _globalRows = globalRows;
767
768 int m = A.cols();
769 int col = 0, k = 0;
770 for (; col < m; k++, col++) {
771 Eigen::VectorXd v = A.col(col);
772 bool inserted = insertColumn(k, v);
773 if (not inserted) {
774 k--;
775 PRECICE_DEBUG("column {} has not been inserted in the QR-factorization, failed to orthogonalize.", col);
776 }
777 }
778 PRECICE_ASSERT(_R.rows() == _cols, _R.rows(), _cols);
779 PRECICE_ASSERT(_R.cols() == _cols, _R.cols(), _cols);
780 PRECICE_ASSERT(_Q.cols() == _cols, _Q.cols(), _cols);
781 PRECICE_ASSERT(_Q.rows() == _rows, _Q.rows(), _rows);
782 PRECICE_ASSERT(_cols == m, _cols, m);
783}
784
785void QRFactorization::pushFront(const Eigen::VectorXd &v)
786{
787 insertColumn(0, v);
788}
789
790void QRFactorization::pushBack(const Eigen::VectorXd &v)
791{
793}
794
799
801{
802 deleteColumn(_cols - 1);
803}
804
806{
807 _infostream = stream;
808 _fstream_set = true;
809}
810
812{
813 _filter = filter;
814}
815
816} // 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
unsigned int index
#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)
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)