// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

// Benchmarks for the implicit Kronecker sum A (+) B = A (x) I + I (x) B and its
// BartelsStewart solver on finite-difference operators: the 2-D Laplacian
// Dy (+) Dx and the 3-D Laplacian Dz (+) Dy (+) Dx of tridiagonal 1-D factors,
// and a nonsymmetric 2-D convection-diffusion operator, against the
// materialized sparse matrix and SparseLU. The products cost
// O(n1 nnz(B) + n2 nnz(A)) either way; the direct solve costs one O(n^3)
// decomposition per factor and O(N sum_k n_k) per right-hand side, against the
// fill-in of a sparse LU of the N x N matrix.

#include <benchmark/benchmark.h>
#include <Eigen/Eigenvalues>
#include <Eigen/Sparse>
#include <Eigen/SparseLU>
#include <contrib/Eigen/StructuredMatrices>

using namespace Eigen;

using Vec = VectorXd;
using SpMat = SparseMatrix<double>;

// tridiag(-1 - c, 2, -1 + c): the negated second difference plus c times a
// centered first difference, SPD for c = 0.
static SpMat tridiagonal(Index n, double c = 0.0) {
  SpMat A(n, n);
  A.reserve(VectorXi::Constant(n, 3));
  for (Index j = 0; j < n; ++j) {
    if (j > 0) A.insert(j - 1, j) = -1.0 + c;
    A.insert(j, j) = 2.0;
    if (j + 1 < n) A.insert(j + 1, j) = -1.0 - c;
  }
  A.makeCompressed();
  return A;
}

// --- y = (Dy (+) Dx) x on an n x n grid ---
static void BM_KroneckerSumProduct2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto L = makeKroneckerSum(tridiagonal(n), tridiagonal(n));
  Vec x = Vec::Random(n * n), y(n * n);
  for (auto _ : state) {
    y.noalias() = L * x;
    benchmark::DoNotOptimize(y.data());
  }
}
BENCHMARK(BM_KroneckerSumProduct2D)->Arg(64)->Arg(256)->Arg(1024);

static void BM_KroneckerSumProduct2DMaterialized(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat L;
  L = makeKroneckerSum(tridiagonal(n), tridiagonal(n));
  Vec x = Vec::Random(n * n), y(n * n);
  for (auto _ : state) {
    y.noalias() = L * x;
    benchmark::DoNotOptimize(y.data());
  }
}
BENCHMARK(BM_KroneckerSumProduct2DMaterialized)->Arg(64)->Arg(256)->Arg(1024);

// --- y = ((Dz (+) Dy) (+) Dx) x on an n^3 grid: a left-nested sum, applied
// from the right inside the outer sum ---
static void BM_KroneckerSumProduct3DLeftNested(benchmark::State& state) {
  const Index n = state.range(0);
  const KroneckerSum<KroneckerSum<SpMat, SpMat>, SpMat> L(makeKroneckerSum(tridiagonal(n), tridiagonal(n)),
                                                          tridiagonal(n));
  Vec x = Vec::Random(n * n * n), y(n * n * n);
  for (auto _ : state) {
    y.noalias() = L * x;
    benchmark::DoNotOptimize(y.data());
  }
}
BENCHMARK(BM_KroneckerSumProduct3DLeftNested)->Arg(32)->Arg(64)->Arg(128);

// --- Implicit Euler step (I + tau D) u = b, D = -L the SPD negated Laplacian,
// decompositions set up once. Symmetric factors: the fast diagonalization path.
static auto heatStep2D(Index n, double tau) {
  SpMat I(n, n);
  I.setIdentity();
  const SpMat D = tridiagonal(n);
  return makeKroneckerSum(SpMat(I + tau * D), SpMat(tau * D));
}

static void BM_KroneckerSumSolveHeat2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = heatStep2D(n, 0.25);
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = solver.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveHeat2D)->Arg(64)->Arg(128)->Arg(256);

static void BM_KroneckerSumSolveHeat2DSparseLU(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat M;
  M = heatStep2D(n, 0.25);
  SparseLU<SpMat> lu(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = lu.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveHeat2DSparseLU)->Arg(64)->Arg(128)->Arg(256);

// The one-time setup: two n x n eigendecompositions against the sparse LU.
static void BM_KroneckerSumSetupHeat2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = heatStep2D(n, 0.25);
  for (auto _ : state) {
    BartelsStewart<decltype(M)> solver(M);
    benchmark::DoNotOptimize(&solver);
  }
}
BENCHMARK(BM_KroneckerSumSetupHeat2D)->Arg(64)->Arg(128)->Arg(256);

static void BM_KroneckerSumSetupHeat2DSparseLU(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat M;
  M = heatStep2D(n, 0.25);
  for (auto _ : state) {
    SparseLU<SpMat> lu(M);
    benchmark::DoNotOptimize(&lu);
  }
}
BENCHMARK(BM_KroneckerSumSetupHeat2DSparseLU)->Arg(64)->Arg(128)->Arg(256);

// --- 3-D: (I + tau (Dz (+) Dy (+) Dx)) u = b on an n^3 grid ---
static auto heatStep3D(Index n, double tau) {
  SpMat I(n, n);
  I.setIdentity();
  const SpMat D = tridiagonal(n);
  return makeKroneckerSum(SpMat(I + tau * D), SpMat(tau * D), SpMat(tau * D));
}

static void BM_KroneckerSumSolveHeat3D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = heatStep3D(n, 0.25);
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n * n), u(n * n * n);
  for (auto _ : state) {
    u = solver.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveHeat3D)->Arg(16)->Arg(32)->Arg(48);

static void BM_KroneckerSumSolveHeat3DSparseLU(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat M;
  M = heatStep3D(n, 0.25);
  SparseLU<SpMat> lu(M);
  Vec b = Vec::Random(n * n * n), u(n * n * n);
  for (auto _ : state) {
    u = lu.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveHeat3DSparseLU)->Arg(16)->Arg(32)->Arg(48);

// --- Nonsymmetric factors with real eigenvalues (|c| < 1): the real Schur path ---
static void BM_KroneckerSumSolveConvection2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = makeKroneckerSum(tridiagonal(n, 0.5), tridiagonal(n, 0.3));
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = solver.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveConvection2D)->Arg(64)->Arg(128)->Arg(256);

// The transposed system on the same decompositions: a forward substitution on
// the transposed Schur forms.
static void BM_KroneckerSumSolveConvection2DTransposed(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = makeKroneckerSum(tridiagonal(n, 0.5), tridiagonal(n, 0.3));
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = solver.transpose().solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveConvection2DTransposed)->Arg(64)->Arg(128)->Arg(256);

static void BM_KroneckerSumSolveConvection2DSparseLU(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat M;
  M = makeKroneckerSum(tridiagonal(n, 0.5), tridiagonal(n, 0.3));
  SparseLU<SpMat> lu(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = lu.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveConvection2DSparseLU)->Arg(64)->Arg(128)->Arg(256);

// --- Sparse assembly: M = Dz (+) Dy (+) Dx and M = I (x) (Dy (+) Dx) ---
// A Kronecker-sum factor is materialized once, not once per entry of the
// factor it meets.
static void BM_KroneckerSumAssemble3D(benchmark::State& state) {
  const Index n = state.range(0);
  const SpMat D = tridiagonal(n);
  const auto L = makeKroneckerSum(D, D, D);
  SpMat M;
  for (auto _ : state) {
    M = L;
    benchmark::DoNotOptimize(M.valuePtr());
  }
}
BENCHMARK(BM_KroneckerSumAssemble3D)->Arg(32)->Arg(64)->Arg(96);

static void BM_KroneckerSumAssembleIdentityKron(benchmark::State& state) {
  const Index n = state.range(0);
  const SpMat D = tridiagonal(n);
  const auto K = makeKroneckerOperator(MatrixXd::Identity(n, n), makeKroneckerSum(D, D));
  SpMat M;
  for (auto _ : state) {
    M = K;
    benchmark::DoNotOptimize(M.valuePtr());
  }
}
BENCHMARK(BM_KroneckerSumAssembleIdentityKron)->Arg(32)->Arg(64)->Arg(96);

// --- Spectrum of I_2 (x) (A (+) B) with nonsymmetric tridiagonal n x n A, B ---
// One n x n eigenvalue solve per factor of the sum, against the dense
// eigenvalue solve of the materialized n^2 x n^2 sum.
static void BM_KroneckerSumFactorEigenvalues(benchmark::State& state) {
  const Index n = state.range(0);
  const auto K = makeKroneckerOperator(MatrixXd::Identity(2, 2),
                                       makeKroneckerSum(MatrixXd(tridiagonal(n, 0.5)), MatrixXd(tridiagonal(n, 0.3))));
  for (auto _ : state) {
    VectorXcd lambda = K.eigenvalues();
    benchmark::DoNotOptimize(lambda.data());
  }
}
BENCHMARK(BM_KroneckerSumFactorEigenvalues)->Arg(16)->Arg(24);

static void BM_KroneckerSumFactorEigenvaluesMaterialized(benchmark::State& state) {
  const Index n = state.range(0);
  const MatrixXcd S = MatrixXd(makeKroneckerSum(tridiagonal(n, 0.5), tridiagonal(n, 0.3))).cast<std::complex<double>>();
  for (auto _ : state) {
    ComplexEigenSolver<MatrixXcd> es(S, /*computeEigenvectors=*/false);
    benchmark::DoNotOptimize(es.eigenvalues().data());
  }
}
BENCHMARK(BM_KroneckerSumFactorEigenvaluesMaterialized)->Arg(16)->Arg(24);

// Convection-dominated factors, |c| > 1: tridiag(-1 - c, 2, -1 + c) then has
// complex conjugate eigenvalue pairs, the 2x2 blocks of the real Schur form.
static void BM_KroneckerSumSolveAdvection2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = makeKroneckerSum(tridiagonal(n, 1.5), tridiagonal(n, 1.2));
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = solver.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveAdvection2D)->Arg(64)->Arg(128)->Arg(256);

static void BM_KroneckerSumSolveAdvection2DSparseLU(benchmark::State& state) {
  const Index n = state.range(0);
  SpMat M;
  M = makeKroneckerSum(tridiagonal(n, 1.5), tridiagonal(n, 1.2));
  SparseLU<SpMat> lu(M);
  Vec b = Vec::Random(n * n), u(n * n);
  for (auto _ : state) {
    u = lu.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveAdvection2DSparseLU)->Arg(64)->Arg(128)->Arg(256);

static void BM_KroneckerSumSolveAdvection3D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = makeKroneckerSum(tridiagonal(n, 1.5), tridiagonal(n, 1.2), tridiagonal(n, 0.5));
  BartelsStewart<decltype(M)> solver(M);
  Vec b = Vec::Random(n * n * n), u(n * n * n);
  for (auto _ : state) {
    u = solver.solve(b);
    benchmark::DoNotOptimize(u.data());
  }
}
BENCHMARK(BM_KroneckerSumSolveAdvection3D)->Arg(16)->Arg(32);

static void BM_KroneckerSumSetupConvection2D(benchmark::State& state) {
  const Index n = state.range(0);
  auto M = makeKroneckerSum(tridiagonal(n, 0.5), tridiagonal(n, 0.3));
  for (auto _ : state) {
    BartelsStewart<decltype(M)> solver(M);
    benchmark::DoNotOptimize(&solver);
  }
}
BENCHMARK(BM_KroneckerSumSetupConvection2D)->Arg(64)->Arg(128)->Arg(256);
