44template <
typename CoeffGetter>
45double evaluateFunction1d(CoeffGetter g,
double x,
std::size_t size) {
46 double b_kp2 = 0.0, b_kp1 = 0.0;
48 double b_k = g[k] + 2 *
x * b_kp1 - b_kp2;
52 return g[0] +
x * b_kp1 - b_kp2;
60struct RecursionArrayImitator {
61 double operator[](Eigen::Index i)
const {
62 return evaluateFunction1d(coefficients[i], x,
coefficients.getSize<1>());
65 RecursionArrayImitator(ndarray::Array<double const, 2, 2>
const &coefficients_,
double x_)
77 -(2.0 *
bbox.getCenterY()) /
bbox.getHeight()));
81ndarray::Array<double, 2, 2> _initializeChebyshev(
size_t order,
bool identity) {
82 ndarray::Array<double, 2, 2> coeffs = ndarray::allocate(ndarray::makeVector(
order + 1,
order + 1));
94 _toChebyshevRange(makeChebyshevRangeTransform(
bbox)),
95 _coefficients(_initializeChebyshev(
order, identity)),
102 _toChebyshevRange(makeChebyshevRangeTransform(
bbox)),
105 _nParameters((_order + 1) * (_order + 2) / 2) {}
109 Eigen::VectorXd::Index k = 0;
110 for (ndarray::Size j = 0; j <= _order; ++j) {
111 ndarray::Size
const iMax = _order - j;
112 for (ndarray::Size i = 0; i <= iMax; ++i, ++k) {
113 _coefficients[j][i] -= delta[k];
121double integrateTn(
int n) {
125 return 2.0 / (1.0 -
static_cast<double>(n * n));
136Eigen::VectorXd computeIntegralTn(ndarray::Size
order,
double x) {
138 Eigen::VectorXd Tn(
order + 2);
143 for (ndarray::Size i = 2; i <=
order + 1; ++i) {
144 Tn[i] = 2 *
x * Tn[i - 1] - Tn[i - 2];
148 Eigen::VectorXd integralTn(
order + 1);
151 integralTn[1] = 0.5 *
x *
x;
153 for (ndarray::Size i = 2; i <=
order; ++i) {
155 integralTn[i] = i * Tn[i + 1] / (i * i - 1) -
x * Tn[i] / (i - 1);
163double PhotometryTransformChebyshev::oneIntegral(
double x,
double y)
const {
166 auto integralTnx = computeIntegralTn(_order, point.getX());
167 auto integralTmy = computeIntegralTn(_order, point.getY());
172 for (ndarray::Size j = 0; j <= _order; ++j) {
173 ndarray::Size
const iMax = _order - j;
174 for (ndarray::Size i = 0; i <= iMax; ++i) {
175 result += _coefficients[j][i] * integralTnx[i] * integralTmy[j];
195 double determinant = _bbox.
getArea() / 4.0;
196 for (ndarray::Size j = 0; j < _coefficients.getSize<0>(); j++) {
197 for (ndarray::Size i = 0; i < _coefficients.getSize<1>(); i++) {
198 result += _coefficients[j][i] * integrateTn(i) * integrateTn(j);
201 return result * determinant;
211 Eigen::VectorXd parameters(_nParameters);
213 Eigen::VectorXd::Index k = 0;
214 for (ndarray::Size j = 0; j <= _order; ++j) {
215 ndarray::Size
const iMax = _order - j;
216 for (ndarray::Size i = 0; i <= iMax; ++i, ++k) {
217 parameters[k] = _coefficients[j][i];
226 return evaluateFunction1d(RecursionArrayImitator(_coefficients, p.getX()), p.getY(),
227 _coefficients.getSize<0>());
231 double x,
double y, Eigen::Ref<Eigen::VectorXd> derivatives)
const {
235 Eigen::VectorXd Tnx(_order + 1);
236 Eigen::VectorXd Tmy(_order + 1);
243 for (ndarray::Size i = 2; i <= _order; ++i) {
244 Tnx[i] = 2 * p.getX() * Tnx[i - 1] - Tnx[i - 2];
245 Tmy[i] = 2 * p.getY() * Tmy[i - 1] - Tmy[i - 2];
249 Eigen::VectorXd::Index k = 0;
250 for (ndarray::Size j = 0; j <= _order; ++j) {
251 ndarray::Size
const iMax = _order - j;
252 for (ndarray::Size i = 0; i <= iMax; ++i, ++k) {
253 derivatives[k] = Tmy[j] * Tnx[i];
ndarray::Array< double const, 2, 2 > coefficients
A floating-point coordinate rectangle geometry.
double getArea() const noexcept
1-d interval accessors