8#ifndef model_PeriodicLatticeInterpolant_cpp_
9#define model_PeriodicLatticeInterpolant_cpp_
12#include <PeriodicLatticeInterpolant.h>
23 const std::vector<Eigen::Matrix<double, dim, 1>> &mirSymm)
25 std::vector<MatrixDim>
temp;
26 for (
int k = 0;
k < rotSymm; ++
k)
28 const double theta(
k * 2.0 * std::numbers::pi / rotSymm);
29 const double c(cos(theta));
30 const double s(sin(theta));
34 for (
const auto &
N : mirSymm)
36 const double nNorm(
N.norm());
37 if (nNorm > FLT_EPSILON)
41 for (
const auto &
m : temp1)
43 temp.push_back(
m * (MatrixDim::Identity() - 2.0 * n * n.transpose()));
60 Eigen::MatrixXd
M(Eigen::MatrixXd::Zero(
f.rows(), 2 *
waveVectors.rows()));
61 Eigen::MatrixXd
V(Eigen::MatrixXd::Zero(
f.rows(), 1));
62 for (
int i = 0;
i <
f.rows();
i++)
67 M(
i, 2 *
j) = sc.first;
68 M(
i, 2 *
j + 1) = sc.second;
74 std::vector<int> nonZcols;
75 for (
int j = 0;
j <
M.cols(); ++
j)
77 if (
M.col(
j).squaredNorm() > FLT_EPSILON)
79 nonZcols.push_back(
j);
83 Eigen::MatrixXd M1(
M.rows(), nonZcols.size());
84 for (
size_t j = 0;
j < nonZcols.size(); ++
j)
86 M1.col(
j) =
M.col(nonZcols[
j]);
89 const Eigen::JacobiSVD<Eigen::MatrixXd> svd(M1);
92 if (M1.rows() == M1.cols() && svd.rank() == M1.rows())
94 const double cond(svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size() - 1));
99 std::cout <<
"rank=" << svd.rank() << std::endl;
100 std::cout <<
"cond=" << cond << std::endl;
101 throw std::runtime_error(
"Bad condition number");
103 const Eigen::VectorXd
x(M1.lu().solve(
V));
105 Eigen::VectorXd x1(Eigen::VectorXd::Zero(
M.cols()));
106 for (
size_t j = 0;
j < nonZcols.size(); ++
j)
108 x1(nonZcols[
j]) =
x(
j);
110 return Eigen::Map<Eigen::MatrixXd>(x1.data(), 2, x1.rows() / 2);
118 std::cout <<
"M1 has size " << M1.rows() <<
"x" << M1.cols() <<
",and rank=" << svd.rank() << std::endl;
119 throw std::runtime_error(
"M1 MUST BE SQUARE AND FULL RANK");
120 return Eigen::MatrixXd::Zero(1, 1);
128 std::pair<double, double> sc(0.0, 0.0);
132 sc.first += sin(KdotX);
133 sc.second += cos(KdotX);
141 const Eigen::Matrix<double, Eigen::Dynamic, dim> &waveVectors_in,
142 const Eigen::Matrix<double, Eigen::Dynamic, dim + 1> &
f,
144 const std::vector<Eigen::Matrix<double, dim, 1>> &
N) :
146,
B(2.0 * std::numbers::pi *
A.inverse().transpose())
147,
waveVectors((
B * waveVectors_in.transpose()).transpose())
function int_R syms a b c u real f
Eigen::Matrix< double, 3, 3 > MatrixDim
Eigen::MatrixXd getSinCosCoeffs(const Eigen::Matrix< double, Eigen::Dynamic, dim+1 > &f) const
Eigen::Matrix< double, dim, dim > MatrixDim
const std::vector< MatrixDim > symMatrices
const Eigen::Matrix< double, Eigen::Dynamic, dim+1 > points
Eigen::Matrix< double, dim, 1 > VectorDim
const Eigen::Matrix< double, Eigen::Dynamic, dim > waveVectors
PeriodicLatticeInterpolant(const MatrixDim &A_in, const Eigen::Matrix< double, Eigen::Dynamic, dim > &waveVectors_in, const Eigen::Matrix< double, Eigen::Dynamic, dim+1 > &f, const int &rotSymm, const std::vector< Eigen::Matrix< double, dim, 1 > > &N)
double operator()(const VectorDim &x) const
const Eigen::Matrix< double, Eigen::Dynamic, 2 > sinCosCoeffs
std::pair< double, double > sinKXcosKX(const int &r, const VectorDim &x) const
static std::vector< MatrixDim > getSymMatrices(const int &rotSymm, const std::vector< Eigen::Matrix< double, dim, 1 > > &mirSymm)