preCICE v3.1.2
Loading...
Searching...
No Matches
QRFactorizationTest.cpp
Go to the documentation of this file.
1#include <Eigen/Core>
2#include <math.h>
9#include "testing/Testing.hpp"
10
11BOOST_AUTO_TEST_SUITE(AccelerationTests)
12
13using namespace precice;
14using namespace precice::acceleration;
15using namespace precice::acceleration::impl;
16
18 Eigen::MatrixXd &Q,
19 Eigen::MatrixXd &R,
20 Eigen::MatrixXd &A)
21{
22 Eigen::MatrixXd A_prime = Q * R;
23
24 for (int i = 0; i < A.rows(); i++) {
25 for (int j = 0; j < A.cols(); j++) {
26 BOOST_TEST(testing::equals(A_prime(i, j), A(i, j)));
27 }
28 }
29}
30
31void testQTQequalsIdentity(Eigen::MatrixXd &Q)
32{
33 Eigen::MatrixXd QTQ = Q.transpose() * Q;
34
35 // test if Q^TQ equals identity
36 for (int i = 0; i < QTQ.rows(); i++) {
37 for (int j = 0; j < QTQ.cols(); j++) {
38 if (i == j) {
39 BOOST_TEST(testing::equals(QTQ(i, j), 1.0, 1e-12));
40 } else {
41 BOOST_TEST(testing::equals(QTQ(i, j), 0.0, 1e-12));
42 }
43 }
44 }
45}
46
47BOOST_AUTO_TEST_CASE(testQRFactorization)
48{
49 PRECICE_TEST(1_rank);
50 int m = 6, n = 8;
51 int filter = BaseQNAcceleration::QR1FILTER;
52 Eigen::MatrixXd A(n, m);
53
54 // Set values according to Hilbert matrix.
55 for (int i = 0; i < n; i++) {
56 for (int j = 0; j < m; j++) {
57 double entry = 1.0 / static_cast<double>(i + j + 1);
58 A(i, j) = entry;
59 }
60 }
61
62 // compute QR factorization of A via successive inserting of columns
63 QRFactorization qr_1(A, filter);
64
65 // test if Q^TQ equals identity
67 // test if QR equals A
68 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A);
69
74 // ----------- delete last column ---------------
75 Eigen::MatrixXd A_prime1 = A;
76 Eigen::VectorXd col6 = A.col(m - 1);
77 A_prime1.conservativeResize(n, m - 1);
78 qr_1.deleteColumn(m - 1);
79
80 // test if Q^TQ equals identity
82 // test if QR equals A
83 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A_prime1);
84
85 // ----------- delete first column ---------------
86 Eigen::MatrixXd A_prime2 = A_prime1;
87 Eigen::VectorXd col1 = A.col(0);
88 for (int i = 0; i < A_prime2.rows(); i++)
89 for (int j = 0; j < A_prime2.cols() - 1; j++)
90 A_prime2(i, j) = A_prime2(i, j + 1);
91 A_prime2.conservativeResize(n, A_prime2.cols() - 1);
92 qr_1.deleteColumn(0);
93
94 // test if Q^TQ equals identity
96 // test if QR equals A
97 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A_prime2);
98
99 // ----------- add first column -----------------
100 qr_1.insertColumn(0, col1);
101
102 // test if Q^TQ equals identity
104 // test if QR equals A
105 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A_prime1);
106
107 // ----------- add last column -----------------
108 qr_1.insertColumn(qr_1.cols(), col6); // ??
109 // test if Q^TQ equals identity
111 // test if QR equals A
112 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A);
113
114 // ----------- delete middle column ---------------
115 int k = 3;
116 Eigen::MatrixXd A_prime3 = A;
117 Eigen::VectorXd colk = A.col(k);
118 for (int i = 0; i < A_prime3.rows(); i++)
119 for (int j = k; j < A_prime3.cols() - 1; j++)
120 A_prime3(i, j) = A_prime3(i, j + 1);
121 A_prime3.conservativeResize(n, A_prime3.cols() - 1);
122 qr_1.deleteColumn(k);
123
124 // test if Q^TQ equals identity
126 // test if QR equals A
127 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A_prime3);
128
129 // ----------- add middle column -----------------
130 qr_1.insertColumn(k, colk);
131
132 // test if Q^TQ equals identity
134 // test if QR equals A
135 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A);
136
137 // ------------ reset ----------------------------
138 qr_1.reset();
139 qr_1.reset(A, A.rows());
141 // test if QR equals A
142 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A);
143
144 Eigen::MatrixXd q = qr_1.matrixQ();
145 Eigen::MatrixXd r = qr_1.matrixR();
146 qr_1.reset();
147 qr_1.reset(q, r, q.rows(), q.cols());
149 // test if QR equals A
150 testQRequalsA(qr_1.matrixQ(), qr_1.matrixR(), A);
151}
152
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
void testQTQequalsIdentity(Eigen::MatrixXd &Q)
void testQRequalsA(Eigen::MatrixXd &Q, Eigen::MatrixXd &R, Eigen::MatrixXd &A)
BOOST_AUTO_TEST_CASE(testQRFactorization)
#define PRECICE_TEST(...)
Definition Testing.hpp:27
Class that provides functionality for a dynamic QR-decomposition, that can be updated in O(mn) flops ...
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...
Eigen::MatrixXd & matrixR()
returns a matrix representation of the upper triangular matrix R
void reset()
resets the QR factorization zo zero Q(0:0, 0:0)R(0:0, 0:0)
Eigen::MatrixXd & matrixQ()
returns a matrix representation of the orthogonal matrix Q
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....
contains implementations of acceleration schemes.
boost::test_tools::predicate_result equals(const std::vector< float > &VectorA, const std::vector< float > &VectorB, float tolerance)
equals to be used in tests. Compares two std::vectors using a given tolerance. Prints both operands o...
Definition Testing.cpp:65
Main namespace of the precice library.