blob: e7d384794865e244ffb95e29309399365679135c [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <contrib/Eigen/StructuredMatrices>
using namespace Eigen;
template <typename Scalar>
void BM_KroneckerLeastSquaresMultiRhs(benchmark::State& state) {
using Real = typename NumTraits<Scalar>::Real;
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
const Index n = state.range(0), nrhs = state.range(1);
Mat a = Mat::Random(n + 1, n), b = Mat::Random(n, n);
a.topRows(n).diagonal().array() += Real(2 * n);
b.diagonal().array() += Real(2 * n);
const auto op = makeKroneckerOperator(a, b);
const Mat expected = Mat::Random(n * n, nrhs);
const Mat rhs = op * expected;
Mat x = op.leastSquaresSolve(rhs);
const Real error = (x - expected).norm() / expected.norm();
if (!(error <= Real(100 * n) * NumTraits<Real>::epsilon())) {
state.SkipWithError("incorrect least-squares solution");
return;
}
state.counters["relative_error"] = double(error);
for (auto _ : state) {
x = op.leastSquaresSolve(rhs);
benchmark::DoNotOptimize(x.data());
benchmark::ClobberMemory();
}
}
BENCHMARK_TEMPLATE(BM_KroneckerLeastSquaresMultiRhs, double)->ArgsProduct({{8, 16, 32, 64}, {1, 8, 64}});
BENCHMARK_TEMPLATE(BM_KroneckerLeastSquaresMultiRhs, std::complex<double>)->ArgsProduct({{8, 16}, {1, 8, 64}});
template <typename Scalar>
void BM_KroneckerRank(benchmark::State& state) {
using Real = typename NumTraits<Scalar>::Real;
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
const Index n = state.range(0);
Mat a = Mat::Random(n, n), b = Mat::Random(n, n);
a.diagonal().array() += Real(2 * n);
b.diagonal().array() += Real(2 * n);
const auto op = makeKroneckerOperator(a, b);
if (op.rank() != n * n) {
state.SkipWithError("incorrect rank");
return;
}
for (auto _ : state) benchmark::DoNotOptimize(op.rank());
}
BENCHMARK_TEMPLATE(BM_KroneckerRank, double)->Arg(8)->Arg(16)->Arg(32);
BENCHMARK_TEMPLATE(BM_KroneckerRank, std::complex<double>)->Arg(8)->Arg(16);