Skip to content

Commit 830cea1

Browse files
Test: add xUNBDB6 tests for LAPACK issue Reference-LAPACK#634
1 parent 1ad359a commit 830cea1

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

TESTING/cpp/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ add_cxx_test(tools_tests tools_tests.cpp)
4747
add_cxx_test(xGGQRCS_tests xGGQRCS_tests.cpp)
4848
add_cxx_test(xLASRTI_tests xLASRTI_tests.cpp)
4949
add_cxx_test(xLASRTR_tests xLASRTR_tests.cpp)
50+
add_cxx_test(xUNBDB6_tests xUNBDB6_tests.cpp)
5051
add_cxx_test(xUNCSD2BY1_tests xUNCSD2BY1_tests.cpp)
5152

5253

TESTING/cpp/xUNBDB6_tests.cpp

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (c) 2021 Christoph Conrads
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the copyright holders nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#include "config.hpp"
30+
#include "tools.hpp"
31+
32+
#include <cstddef>
33+
34+
#include <limits>
35+
#include <vector>
36+
37+
#include <boost/assert.hpp>
38+
#include <boost/numeric/ublas/matrix.hpp>
39+
#include <boost/numeric/ublas/vector.hpp>
40+
#include <boost/test/unit_test.hpp>
41+
42+
using Integer = lapack::integer_t;
43+
44+
namespace ublas = boost::numeric::ublas;
45+
namespace tools = lapack::tools;
46+
47+
48+
// test if xUNBDB6 respects vector increments
49+
template<
50+
typename Number,
51+
typename std::enable_if<std::is_fundamental<Number>::value, int>::type* =
52+
nullptr>
53+
void vector_increments_impl(Number) {
54+
using Matrix = ublas::matrix<Number, ublas::column_major>;
55+
56+
auto m1 = std::size_t{2};
57+
auto n = std::size_t{4};
58+
auto m2 = std::size_t{3};
59+
auto ldq = m1 + m2;
60+
auto Q = Matrix(ublas::identity_matrix<Number>(m1 + m2, n));
61+
62+
auto increments = std::vector<int>{+1, +2, +5};
63+
for(auto incx1 : increments) {
64+
for(auto incx2 : increments) {
65+
BOOST_REQUIRE(incx1 != 0);
66+
BOOST_REQUIRE(incx2 != 0);
67+
68+
constexpr auto nan = tools::not_a_number<Number>::value;
69+
70+
auto ldx1 = m1 * std::abs(incx1);
71+
auto x1 = ublas::vector<Number>(ldx1, nan);
72+
for(auto i = std::size_t{0}; i < m1; ++i) {
73+
x1(i * std::abs(incx1)) = 1;
74+
}
75+
76+
auto ldx2 = m2 * std::abs(incx2);
77+
auto x2 = ublas::vector<Number>(ldx2, nan);
78+
for(auto i = std::size_t{0}; i < m2; ++i) {
79+
x2(i * std::abs(incx2)) = 1;
80+
}
81+
82+
auto work = ublas::vector<Number>(n, nan);
83+
auto info = lapack::xUNBDB6(
84+
m1, m2, n, &x1(0), incx1, &x2(0), incx2, &Q(0, 0), ldq,
85+
&Q(m1, 0), ldq, &work(0), work.size());
86+
87+
BOOST_REQUIRE_EQUAL(info, 0);
88+
for(auto i = std::size_t{0}; i < m1; ++i) {
89+
std::printf("%zu %16.10e\n", i, x1(i * std::abs(incx1)));
90+
BOOST_CHECK(tools::finite_p(x1(i * std::abs(incx1))));
91+
}
92+
}
93+
}
94+
}
95+
96+
BOOST_AUTO_TEST_CASE_TEMPLATE(
97+
vector_increments, Number, lapack::supported_real_types) {
98+
vector_increments_impl(Number{});
99+
}
100+
101+
102+
// test if xUNBDB6 returns a zero vector if the vector lies in the
103+
// column span of the matrix
104+
template<
105+
typename Number,
106+
typename std::enable_if<std::is_fundamental<Number>::value, int>::type* =
107+
nullptr>
108+
void require_zero_output_impl(Number) {
109+
using Real = typename tools::real_from<Number>::type;
110+
using Matrix = ublas::matrix<Number, ublas::column_major>;
111+
112+
auto m = std::size_t{1};
113+
auto n = std::size_t{1};
114+
auto p = std::size_t{1};
115+
auto ldq = m + p;
116+
117+
for(auto i = std::size_t{0}; i < m + p; ++i) {
118+
constexpr auto mu = std::numeric_limits<Real>::denorm_min();
119+
auto Q = Matrix(ldq, n, Number{});
120+
auto x = ublas::vector<Number>(m + p, Number{});
121+
Q(i, 0) = 1;
122+
Q(m + p - i - 1, 0) = mu;
123+
x(i) = 1;
124+
BOOST_VERIFY(tools::is_almost_isometric(Q));
125+
126+
auto lwork = n;
127+
constexpr auto nan = tools::not_a_number<Number>::value;
128+
auto work = ublas::vector<Number>(lwork, nan);
129+
auto ret = lapack::xUNBDB6(
130+
m, p, n, &x(0), 1, &x(m), 1, &Q(0, 0), ldq, &Q(m, 0), ldq, &work(0),
131+
lwork);
132+
133+
BOOST_TEST_CONTEXT("index=" << i) {
134+
BOOST_REQUIRE_EQUAL(ret, 0);
135+
BOOST_CHECK_EQUAL(Real{ublas::norm_inf(x)}, 0);
136+
}
137+
}
138+
}
139+
140+
BOOST_AUTO_TEST_CASE_TEMPLATE(
141+
require_zero_output, Number, lapack::supported_real_types) {
142+
require_zero_output_impl(Number{});
143+
}

0 commit comments

Comments
 (0)