72 for (
int k = 0; k < m; k++) {
73 Eigen::VectorXd v = A.col(k);
110 bool linearDependence =
true;
113 while (linearDependence) {
114 linearDependence =
false;
117 for (
size_t i = 0; i < delFlag.
size(); i++) {
129 linearDependence =
true;
148 for (
size_t i =
index; i > 0; i--) {
149 Eigen::VectorXd v = V.col(i);
151 if (
std::fabs(
_R(i, i)) < rho0 * singularityLimit) {
157 PRECICE_DEBUG(
"Pre-scaling weights were reset. Reverting to QR2 and rebuilding QR.");
179 for (
int k = 0; k < V.cols(); k++) {
180 Eigen::VectorXd v = V.col(k);
204 for (
int l = k; l <
_cols - 1; l++) {
207 Eigen::VectorXd Rr1 =
_R.row(l);
208 Eigen::VectorXd Rr2 =
_R.row(l + 1);
212 Eigen::VectorXd Qc1 =
_Q.col(l);
213 Eigen::VectorXd Qc2 =
_Q.col(l + 1);
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);
240 Eigen::VectorXd v(vec);
254 Eigen::VectorXd u(
_cols);
255 double rho_orth = 0., rho0 = 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.");
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);
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);
297 for (
int j = k + 1; j <
_cols; j++) {
312 for (
int l =
_cols - 2; l >= k; l--) {
315 Eigen::VectorXd Rr1 =
_R.row(l);
316 Eigen::VectorXd Rr2 =
_R.row(l + 1);
320 Eigen::VectorXd Qc1 =
_Q.col(l);
321 Eigen::VectorXd Qc2 =
_Q.col(l + 1);
326 for (
int i = 0; i <= k; i++) {
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);
366 while (!termination) {
369 u = Eigen::VectorXd::Zero(
_rows);
370 for (
int j = 0; j < colNum; j++) {
373 Eigen::VectorXd Qc =
_Q.col(j);
380 u +=
_Q.col(j) * r_ij;
383 for (
int j = 0; j < colNum; j++) {
387 for (
int i = 0; i <
_rows; i++) {
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);
409 PRECICE_DEBUG(
"The norm of v_orthogonal is almost zero, i.e., failed to orthogonalize column v; discard.");
427 if (rho1 *
_theta <= rho0 +
_omega * norm_coefficients) {
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.");
443 rho = null ? 0 : rho1;
472 bool restart =
false;
474 bool termination =
false;
475 double rho0 = 0., rho1 = 0.;
477 Eigen::VectorXd u = Eigen::VectorXd::Zero(
_rows);
478 Eigen::VectorXd s = Eigen::VectorXd::Zero(colNum);
479 r = Eigen::VectorXd::Zero(
_cols);
484 while (!termination) {
486 u = Eigen::VectorXd::Zero(
_rows);
487 for (
int j = 0; j < colNum; j++) {
492 Eigen::VectorXd Qc =
_Q.col(j);
500 for (
int i = 0; i <
_rows; i++) {
501 u(i) = u(i) +
_Q(i, j) * t;
506 for (
int j = 0; j < colNum; j++) {
511 for (
int i = 0; i <
_rows; i++) {
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);
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.");
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.");
558 (*_infostream) <<
"[QR-dec] - reorthogonalization\n";
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);
579 for (
int i = 0; i <
_rows; i++) {
588 double local_uk = 0.;
589 double global_uk = 0.;
602 if (local_uk < global_uk) {
603 rank = secondaryRank;
604 global_uk = local_uk;
609 (*_infostream) <<
" global u(k):" << global_uk <<
", global k: " << global_k <<
", rank: " << rank <<
'\n';
618 v = Eigen::VectorXd::Zero(
_rows);
639 rho = null ? 0 : rho1;
660 t *= (u < 0) ? -1 : 1;
680 for (
int j = k; j < l; j++) {
685 q(j) = (t + u) * nu - v;
729 Eigen::MatrixXd
const &Q,
730 Eigen::MatrixXd
const &R,
752 Eigen::MatrixXd
const &A,
770 for (; col < m; k++, col++) {
771 Eigen::VectorXd v = A.col(col);
775 PRECICE_DEBUG(
"column {} has not been inserted in the QR-factorization, failed to orthogonalize.", col);
#define PRECICE_WARN(...)
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_ASSERT(...)
static const int QR1FILTER_ABS
static const int QR3FILTER
static const int QR2FILTER
static const int QR1FILTER
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...
void setGlobalRows(int gr)
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 setfstream(std::fstream *stream)
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 ...
size_t _resetFilterCounter
std::fstream * _infostream
size_t getResetFilterCounter() const
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,...
void setFilter(int filter)
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.
static Rank getRank()
Current rank.
static double dot(const Eigen::VectorXd &vec1, const Eigen::VectorXd &vec2)
static bool isPrimary()
True if this process is running the primary rank.
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
static bool isParallel()
True if this process is running in parallel.
static bool isSecondary()
True if this process is running a secondary rank.
static com::PtrCommunication & getCommunication()
Intra-participant communication.