mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add boundary test coverage: stableNorm, LinSpaced, complex GEMV, triangular solve
libeigen/eigen!2291 Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
@@ -569,6 +569,88 @@ void product_custom_scalar_types() {
|
||||
}
|
||||
}
|
||||
|
||||
// Test complex GEMV with all conjugation combinations at sizes that
|
||||
// exercise full, half, and quarter packet code paths.
|
||||
// The GEMV kernels in GeneralMatrixVector.h use conj_helper at three
|
||||
// packet levels. The existing product_extra tests cover conjugation
|
||||
// but only at random sizes, never systematically at packet boundaries.
|
||||
template <int>
|
||||
void gemv_complex_conjugate() {
|
||||
typedef std::complex<float> Scf;
|
||||
typedef std::complex<double> Scd;
|
||||
const Index PS_f = internal::packet_traits<Scf>::size;
|
||||
const Index PS_d = internal::packet_traits<Scd>::size;
|
||||
|
||||
// Sizes chosen to exercise packet boundaries for both float and double.
|
||||
const Index sizes[] = {1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33};
|
||||
|
||||
for (int si = 0; si < 14; ++si) {
|
||||
Index m = sizes[si];
|
||||
// Test complex<float> GEMV with all conjugation combos.
|
||||
{
|
||||
typedef Matrix<Scf, Dynamic, Dynamic> Mat;
|
||||
typedef Matrix<Scf, Dynamic, 1> Vec;
|
||||
Mat A = Mat::Random(m, m);
|
||||
Vec v = Vec::Random(m);
|
||||
Vec res(m);
|
||||
|
||||
// A * v (no conjugation)
|
||||
res.noalias() = A * v;
|
||||
VERIFY_IS_APPROX(res, (A.eval() * v.eval()).eval());
|
||||
|
||||
// A.conjugate() * v
|
||||
res.noalias() = A.conjugate() * v;
|
||||
VERIFY_IS_APPROX(res, (A.conjugate().eval() * v.eval()).eval());
|
||||
|
||||
// A * v.conjugate()
|
||||
res.noalias() = A * v.conjugate();
|
||||
VERIFY_IS_APPROX(res, (A.eval() * v.conjugate().eval()).eval());
|
||||
|
||||
// A.conjugate() * v.conjugate()
|
||||
res.noalias() = A.conjugate() * v.conjugate();
|
||||
VERIFY_IS_APPROX(res, (A.conjugate().eval() * v.conjugate().eval()).eval());
|
||||
|
||||
// A.adjoint() * v (transpose + conjugate of lhs)
|
||||
Vec res2(m);
|
||||
res2.noalias() = A.adjoint() * v;
|
||||
VERIFY_IS_APPROX(res2, (A.adjoint().eval() * v.eval()).eval());
|
||||
|
||||
// Row-major complex GEMV
|
||||
typedef Matrix<Scf, Dynamic, Dynamic, RowMajor> RMat;
|
||||
RMat B = A;
|
||||
res.noalias() = B * v;
|
||||
VERIFY_IS_APPROX(res, (A.eval() * v.eval()).eval());
|
||||
|
||||
res.noalias() = B.conjugate() * v;
|
||||
VERIFY_IS_APPROX(res, (A.conjugate().eval() * v.eval()).eval());
|
||||
}
|
||||
|
||||
// Test complex<double> GEMV with conjugation.
|
||||
{
|
||||
typedef Matrix<Scd, Dynamic, Dynamic> Mat;
|
||||
typedef Matrix<Scd, Dynamic, 1> Vec;
|
||||
Mat A = Mat::Random(m, m);
|
||||
Vec v = Vec::Random(m);
|
||||
Vec res(m);
|
||||
|
||||
res.noalias() = A.conjugate() * v;
|
||||
VERIFY_IS_APPROX(res, (A.conjugate().eval() * v.eval()).eval());
|
||||
|
||||
res.noalias() = A * v.conjugate();
|
||||
VERIFY_IS_APPROX(res, (A.eval() * v.conjugate().eval()).eval());
|
||||
|
||||
// Non-square: wide matrix × vector (exercises different cols path).
|
||||
Mat C = Mat::Random(m, m + 3);
|
||||
Vec w = Vec::Random(m + 3);
|
||||
Vec res3(m);
|
||||
res3.noalias() = C.conjugate() * w;
|
||||
VERIFY_IS_APPROX(res3, (C.conjugate().eval() * w.eval()).eval());
|
||||
}
|
||||
}
|
||||
(void)PS_f;
|
||||
(void)PS_d;
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(product_extra) {
|
||||
for (int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1(product_extra(
|
||||
@@ -593,4 +675,7 @@ EIGEN_DECLARE_TEST(product_extra) {
|
||||
CALL_SUBTEST_8(aliasing_with_resize<void>());
|
||||
CALL_SUBTEST_9(product_custom_scalar_types<0>());
|
||||
CALL_SUBTEST_10(test_small_block_correctness<0>());
|
||||
|
||||
// Complex GEMV conjugation at varied sizes (deterministic, outside g_repeat).
|
||||
CALL_SUBTEST_11(gemv_complex_conjugate<0>());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user