12#include <Eigen/Sparse>
15#include <spdlog/spdlog.h>
16#include <unsupported/Eigen/Splines>
19template <
typename Scalar>
21 : row_(row), col_(col), val_(val) {}
23template <
typename Scalar>
28template <
typename Scalar>
33template <
typename Scalar>
38template <
typename Scalar>
40 Eigen::Spline<real_t, 1> real_spline,
41 Eigen::Spline<real_t, 1> imag_spline)
42 : row_(row), col_(col), real_spline(std::move(real_spline)),
43 imag_spline(std::move(imag_spline)) {}
45template <
typename Scalar>
48 return {real_spline(omega)(0), imag_spline(omega)(0)};
50 return real_spline(omega)(0);
54template <
typename Scalar>
59template <
typename Scalar>
64template <
typename Scalar>
67 const real_t numerical_precision =
68 5 * std::numeric_limits<real_t>::epsilon() * tensor_in_cartesian_coordinates.norm();
70 Eigen::SparseMatrix<complex_t> tensor =
71 (spherical::get_transformator<complex_t>(kappa1) * tensor_in_cartesian_coordinates *
72 spherical::get_transformator<complex_t>(kappa2).adjoint())
73 .sparseView(1, numerical_precision);
75 std::vector<Entry> entries;
76 for (
int k = 0; k < tensor.outerSize(); ++k) {
77 for (
typename Eigen::SparseMatrix<complex_t>::InnerIterator it(tensor, k); it; ++it) {
79 entries.emplace_back(
ConstantEntry(it.row(), it.col(), it.value()));
81 entries.emplace_back(
ConstantEntry(it.row(), it.col(), it.value().real()));
82 assert(abs(it.value().imag()) < numerical_precision);
86 entries_map[{kappa1, kappa2}] = std::move(entries);
89template <
typename Scalar>
91 int kappa1,
int kappa2,
93 const std::vector<double> &omegas) {
95 if (tensors_in_cartesian_coordinates.size() != omegas.size()) {
96 throw std::invalid_argument(
"The number of tensors and omegas must match.");
99 auto num_knots =
static_cast<int>(omegas.size());
100 Eigen::Map<const Eigen::RowVectorXd> knots(omegas.data(), num_knots);
102 constexpr int spline_degree = 3;
105 std::map<std::pair<int, int>, std::pair<Eigen::RowVectorXd, Eigen::RowVectorXd>> temp_map;
106 for (
int idx = 0; idx < num_knots; ++idx) {
107 const real_t numerical_precision = 5 * std::numeric_limits<real_t>::epsilon() *
108 tensors_in_cartesian_coordinates[idx].norm();
110 Eigen::SparseMatrix<complex_t> tensor =
111 (spherical::get_transformator<complex_t>(kappa1) *
112 tensors_in_cartesian_coordinates[idx] *
113 spherical::get_transformator<complex_t>(kappa2).adjoint())
114 .sparseView(1, numerical_precision);
116 for (
int k = 0; k < tensor.outerSize(); ++k) {
117 for (
typename Eigen::SparseMatrix<complex_t>::InnerIterator it(tensor, k); it; ++it) {
118 std::pair<int, int> key{it.row(), it.col()};
119 auto &[vec_real, vec_imag] =
121 .try_emplace(key, Eigen::RowVectorXd::Zero(num_knots),
122 Eigen::RowVectorXd::Zero(num_knots))
124 vec_real(idx) = it.value().real();
126 vec_imag(idx) = it.value().imag();
128 assert(abs(it.value().imag()) < numerical_precision);
135 std::vector<Entry> entries;
136 entries.reserve(temp_map.size());
137 for (
const auto &[key, value] : temp_map) {
138 const auto &[vec_real, vec_imag] = value;
139 const auto &[row, col] = key;
141 Eigen::Spline<real_t, 1> real_spline =
142 Eigen::SplineFitting<Eigen::Spline<real_t, 1>>::Interpolate(vec_real, spline_degree,
145 Eigen::Spline<real_t, 1> imag_spline;
147 imag_spline = Eigen::SplineFitting<Eigen::Spline<real_t, 1>>::Interpolate(
148 vec_imag, spline_degree, knots);
151 entries.emplace_back(
154 entries_map[{kappa1, kappa2}] = std::move(entries);
157template <
typename Scalar>
158const std::vector<typename GreenTensor<Scalar>::Entry> &
160 if (
auto it = entries_map.find({kappa1, kappa2}); it != entries_map.end()) {
163 static const std::vector<Entry> empty_entries;
164 return empty_entries;
ConstantEntry(int row, int col, Scalar val)
Scalar val(double omega) const
OmegaDependentEntry(int row, int col, Eigen::Spline< real_t, 1 > real_spline, Eigen::Spline< real_t, 1 > imag_spline)
typename traits::NumTraits< Scalar >::real_t real_t
const std::vector< Entry > & get_entries(int kappa1, int kappa2) const
void set_entries(int kappa1, int kappa2, const Eigen::MatrixX< Scalar > &tensor_in_cartesian_coordinates)
Matrix< Type, Dynamic, Dynamic > MatrixX
Helper struct to extract types from a numerical type.