45 poly._xCoeffs(1, 0) += 1;
46 poly._yCoeffs(0, 1) += 1;
55 poly._xCoeffs(1, 0) += 1;
56 poly._yCoeffs(0, 1) += 1;
58 compose(poly, other._cdInverse));
66 _xCoeffs.reset(ndarray::Array<double, 2, 2>(ndarray::allocate(order + 1, order + 1)));
67 _yCoeffs.reset(ndarray::Array<double, 2, 2>(ndarray::allocate(order + 1, order + 1)));
70 _u = Eigen::VectorXd(order + 1);
71 _v = Eigen::VectorXd(order + 1);
75 ndarray::Array<double const, 2, 0>
const& yCoeffs)
76 : _xCoeffs(
ndarray::copy(xCoeffs)),
77 _yCoeffs(
ndarray::copy(yCoeffs)),
80 if (xCoeffs.getShape() != yCoeffs.getShape()) {
83 (boost::format(
"X and Y coefficient matrices must have the same shape: " 84 " (%d,%d) != (%d,%d)") %
85 xCoeffs.getSize<0>() % xCoeffs.getSize<1>() % yCoeffs.getSize<0>() % yCoeffs.getSize<1>())
88 if (_xCoeffs.cols() != _xCoeffs.rows()) {
90 (boost::format(
"Coefficient matrices must be triangular, not trapezoidal: " 92 _xCoeffs.rows() % _xCoeffs.cols())
101 _v(other._v.size()) {}
108 if (&other !=
this) {
116 if (&
other !=
this) {
123 _xCoeffs.swap(other._xCoeffs);
124 _yCoeffs.swap(other._yCoeffs);
130 double xu = 0.0, xv = 0.0, yu = 0.0, yv = 0.0,
x = 0.0,
y = 0.0;
134 for (
int p = 0; p <= order; ++p) {
135 for (
int q = 0; q <= order; ++q) {
137 xu += _xCoeffs(p, q) * p * _u[p - 1] * _v[q];
138 yu += _yCoeffs(p, q) * p * _u[p - 1] * _v[q];
141 xv += _xCoeffs(p, q) * q * _u[p] * _v[q - 1];
142 yv += _yCoeffs(p, q) * q * _u[p] * _v[q - 1];
144 x += _xCoeffs(p, q) * _u[p] * _v[q];
145 y += _yCoeffs(p, q) * _u[p] * _v[q];
163 for (
int p = 0; p <= order; ++p) {
164 for (
int q = 0; q <= order; ++q) {
165 x += _xCoeffs(p, q) * _u[p] * _v[q];
166 y += _yCoeffs(p, q) * _u[p] * _v[q];
182 result._poly._xCoeffs(1, 0) += 1;
183 result._poly._yCoeffs(0, 1) += 1;
190 result._poly._xCoeffs(1, 0) += 1;
191 result._poly._yCoeffs(0, 1) += 1;
198 : _poly(poly), _inputScaling(inputScaling), _outputScalingInverse(outputScalingInverse) {}
201 _poly.
swap(other._poly);
202 std::swap(_inputScaling, other._inputScaling);
203 std::swap(_outputScalingInverse, other._outputScalingInverse);
207 return _outputScalingInverse * _poly.
linearize(_inputScaling(in)) * _inputScaling;
211 return _outputScalingInverse(_poly(_inputScaling(in)));
217 result._xCoeffs = t2._xCoeffs * t1[AT::XX] + t2._yCoeffs * t1[AT::XY];
218 result._yCoeffs = t2._xCoeffs * t1[AT::YX] + t2._yCoeffs * t1[AT::YY];
219 result._xCoeffs(0, 0) += t1[AT::X];
220 result._yCoeffs(0, 0) += t1[AT::Y];
229 t1a._xCoeffs(0, 0) = t1._xCoeffs(0, 0);
230 t1a._yCoeffs(0, 0) = t1._yCoeffs(0, 0);
242 for (
int p = 0; p <= order; ++p) {
243 for (
int m = 0;
m <= p; ++
m) {
244 for (
int j = 0; j <=
m; ++j) {
245 for (
int q = 0; p + q <= order; ++q) {
246 for (
int n = 0; n <= q; ++n) {
247 for (
int k = 0; k <= n; ++k) {
248 double z = binomial(p,
m) * t2u[p -
m] * binomial(
m, j) * t2uu[j] * t2uv[
m - j] *
249 binomial(q, n) * t2v[q - n] * binomial(n, k) * t2vu[k] * t2vv[n - k];
250 result._xCoeffs(j + k,
m + n - j - k) += t1._xCoeffs(p, q) * z;
251 result._yCoeffs(j + k,
m + n - j - k) += t1._yCoeffs(p, q) * z;
A class that computes binomial coefficients up to a certain power.
PolynomialTransform compose(geom::AffineTransform const &t1, PolynomialTransform const &t2)
Return a PolynomialTransform that is equivalent to the composition t1(t2())
ItemVariant const * other
Point< double, 2 > Point2D
std::unique_ptr< SchemaItem< U > > result
#define LSST_EXCEPT(type,...)
void computePowers(Eigen::VectorXd &r, double x)
Fill an array with integer powers of x, so .