Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | #include <openvdb/openvdb.h> | ||
5 | #include <openvdb/version.h> | ||
6 | #include <openvdb/math/ConjGradient.h> | ||
7 | |||
8 | #include <gtest/gtest.h> | ||
9 | |||
10 | |||
11 | 3 | class TestConjGradient: public ::testing::Test | |
12 | { | ||
13 | }; | ||
14 | |||
15 | |||
16 | //////////////////////////////////////// | ||
17 | |||
18 | |||
19 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | TEST_F(TestConjGradient, testJacobi) |
20 | { | ||
21 | using namespace openvdb; | ||
22 | |||
23 | typedef math::pcg::SparseStencilMatrix<double, 7> MatrixType; | ||
24 | |||
25 | const math::pcg::SizeType rows = 5; | ||
26 | |||
27 | 2 | MatrixType A(rows); | |
28 | 1 | A.setValue(0, 0, 24.0); | |
29 | 1 | A.setValue(0, 2, 6.0); | |
30 | 1 | A.setValue(1, 1, 8.0); | |
31 | 1 | A.setValue(1, 2, 2.0); | |
32 | 1 | A.setValue(2, 0, 6.0); | |
33 | 1 | A.setValue(2, 1, 2.0); | |
34 | 1 | A.setValue(2, 2, 8.0); | |
35 | 1 | A.setValue(2, 3, -6.0); | |
36 | 1 | A.setValue(2, 4, 2.0); | |
37 | 1 | A.setValue(3, 2, -6.0); | |
38 | 1 | A.setValue(3, 3, 24.0); | |
39 | 1 | A.setValue(4, 2, 2.0); | |
40 | 1 | A.setValue(4, 4, 8.0); | |
41 | |||
42 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(A.isFinite()); |
43 | |||
44 | MatrixType::VectorType | ||
45 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | x(rows, 0.0), |
46 |
2/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1 | b(rows, 1.0), |
47 | expected(rows); | ||
48 | |||
49 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | expected[0] = 0.0104167; |
50 | 1 | expected[1] = 0.09375; | |
51 | 1 | expected[2] = 0.125; | |
52 | 1 | expected[3] = 0.0729167; | |
53 | 1 | expected[4] = 0.09375; | |
54 | |||
55 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | math::pcg::JacobiPreconditioner<MatrixType> precond(A); |
56 | |||
57 | // Solve A * x = b for x. | ||
58 | math::pcg::State result = math::pcg::solve( | ||
59 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | A, b, x, precond, math::pcg::terminationDefaults<double>()); |
60 | |||
61 |
1/16✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
1 | EXPECT_TRUE(result.success); |
62 |
1/16✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
1 | EXPECT_TRUE(result.iterations <= 20); |
63 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(x.eq(expected, 1.0e-5)); |
64 | 1 | } | |
65 | |||
66 | |||
67 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | TEST_F(TestConjGradient, testIncompleteCholesky) |
68 | { | ||
69 | using namespace openvdb; | ||
70 | |||
71 | typedef math::pcg::SparseStencilMatrix<double, 7> MatrixType; | ||
72 | typedef math::pcg::IncompleteCholeskyPreconditioner<MatrixType> CholeskyPrecond; | ||
73 | |||
74 | const math::pcg::SizeType rows = 5; | ||
75 | |||
76 | 2 | MatrixType A(5); | |
77 | 1 | A.setValue(0, 0, 24.0); | |
78 | 1 | A.setValue(0, 2, 6.0); | |
79 | 1 | A.setValue(1, 1, 8.0); | |
80 | 1 | A.setValue(1, 2, 2.0); | |
81 | 1 | A.setValue(2, 0, 6.0); | |
82 | 1 | A.setValue(2, 1, 2.0); | |
83 | 1 | A.setValue(2, 2, 8.0); | |
84 | 1 | A.setValue(2, 3, -6.0); | |
85 | 1 | A.setValue(2, 4, 2.0); | |
86 | 1 | A.setValue(3, 2, -6.0); | |
87 | 1 | A.setValue(3, 3, 24.0); | |
88 | 1 | A.setValue(4, 2, 2.0); | |
89 | 1 | A.setValue(4, 4, 8.0); | |
90 | |||
91 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(A.isFinite()); |
92 | |||
93 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CholeskyPrecond precond(A); |
94 | { | ||
95 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | const CholeskyPrecond::TriangularMatrix lower = precond.lowerMatrix(); |
96 | |||
97 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CholeskyPrecond::TriangularMatrix expected(5); |
98 | 1 | expected.setValue(0, 0, 4.89898); | |
99 | 1 | expected.setValue(1, 1, 2.82843); | |
100 | 1 | expected.setValue(2, 0, 1.22474); | |
101 | 1 | expected.setValue(2, 1, 0.707107); | |
102 | 1 | expected.setValue(2, 2, 2.44949); | |
103 | 1 | expected.setValue(3, 2, -2.44949); | |
104 | 1 | expected.setValue(3, 3, 4.24264); | |
105 | 1 | expected.setValue(4, 2, 0.816497); | |
106 | 1 | expected.setValue(4, 4, 2.70801); | |
107 | |||
108 | #if 0 | ||
109 | std::cout << "Expected:\n"; | ||
110 | for (int i = 0; i < 5; ++i) { | ||
111 | std::cout << " " << expected.getConstRow(i).str() << std::endl; | ||
112 | } | ||
113 | std::cout << "Actual:\n"; | ||
114 | for (int i = 0; i < 5; ++i) { | ||
115 | std::cout << " " << lower.getConstRow(i).str() << std::endl; | ||
116 | } | ||
117 | #endif | ||
118 | |||
119 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(lower.eq(expected, 1.0e-5)); |
120 | } | ||
121 | { | ||
122 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | const CholeskyPrecond::TriangularMatrix upper = precond.upperMatrix(); |
123 | |||
124 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CholeskyPrecond::TriangularMatrix expected(5); |
125 | { | ||
126 | 1 | expected.setValue(0, 0, 4.89898); | |
127 | 1 | expected.setValue(0, 2, 1.22474); | |
128 | 1 | expected.setValue(1, 1, 2.82843); | |
129 | 1 | expected.setValue(1, 2, 0.707107); | |
130 | 1 | expected.setValue(2, 2, 2.44949); | |
131 | 1 | expected.setValue(2, 3, -2.44949); | |
132 | 1 | expected.setValue(2, 4, 0.816497); | |
133 | 1 | expected.setValue(3, 3, 4.24264); | |
134 | 1 | expected.setValue(4, 4, 2.70801); | |
135 | } | ||
136 | |||
137 | #if 0 | ||
138 | std::cout << "Expected:\n"; | ||
139 | for (int i = 0; i < 5; ++i) { | ||
140 | std::cout << " " << expected.getConstRow(i).str() << std::endl; | ||
141 | } | ||
142 | std::cout << "Actual:\n"; | ||
143 | for (int i = 0; i < 5; ++i) { | ||
144 | std::cout << " " << upper.getConstRow(i).str() << std::endl; | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(upper.eq(expected, 1.0e-5)); |
149 | } | ||
150 | |||
151 | MatrixType::VectorType | ||
152 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | x(rows, 0.0), |
153 |
2/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1 | b(rows, 1.0), |
154 | expected(rows); | ||
155 | |||
156 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | expected[0] = 0.0104167; |
157 | 1 | expected[1] = 0.09375; | |
158 | 1 | expected[2] = 0.125; | |
159 | 1 | expected[3] = 0.0729167; | |
160 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | expected[4] = 0.09375; |
161 | |||
162 | // Solve A * x = b for x. | ||
163 | math::pcg::State result = math::pcg::solve( | ||
164 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | A, b, x, precond, math::pcg::terminationDefaults<double>()); |
165 | |||
166 |
1/16✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
1 | EXPECT_TRUE(result.success); |
167 |
1/16✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
1 | EXPECT_TRUE(result.iterations <= 20); |
168 |
2/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1 | EXPECT_TRUE(x.eq(expected, 1.0e-5)); |
169 | 1 | } | |
170 | |||
171 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | TEST_F(TestConjGradient, testVectorDotProduct) |
172 | { | ||
173 | using namespace openvdb; | ||
174 | |||
175 | typedef math::pcg::Vector<double> VectorType; | ||
176 | |||
177 | // Test small vector - runs in series | ||
178 | { | ||
179 | const size_t length = 1000; | ||
180 | 1 | VectorType aVec(length, 2.0); | |
181 |
1/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1 | VectorType bVec(length, 3.0); |
182 | |||
183 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | VectorType::ValueType result = aVec.dot(bVec); |
184 | |||
185 |
2/16✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
1 | EXPECT_NEAR(result, 6.0 * length, 1.0e-7); |
186 | } | ||
187 | // Test long vector - runs in parallel | ||
188 | { | ||
189 | const size_t length = 10034502; | ||
190 | 1 | VectorType aVec(length, 2.0); | |
191 |
1/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1 | VectorType bVec(length, 3.0); |
192 | |||
193 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | VectorType::ValueType result = aVec.dot(bVec); |
194 | |||
195 |
2/16✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
1 | EXPECT_NEAR(result, 6.0 * length, 1.0e-7); |
196 | } | ||
197 | 1 | } | |
198 |