| // 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); |