45 poly._xCoeffs(1, 0) += 1;
46 poly._yCoeffs(0, 1) += 1;
55 poly._xCoeffs(1, 0) += 1;
56 poly._yCoeffs(0, 1) += 1;
66 _xCoeffs = ndarray::allocate(
order + 1,
order + 1);
67 _yCoeffs = 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)),
78 _u(_xCoeffs.getSize<0>()),
79 _v(_xCoeffs.getSize<0>()) {
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.getSize<1>() != _xCoeffs.getSize<0>()) {
90 (boost::format(
"Coefficient matrices must be triangular, not trapezoidal: "
92 _xCoeffs.getSize<0>() % _xCoeffs.getSize<1>())
98 : _xCoeffs(
ndarray::copy(other.getXCoeffs())),
99 _yCoeffs(
ndarray::copy(other.getYCoeffs())),
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)));
218 result._xCoeffs.deep() = t2._xCoeffs * t1[AT::XX] + t2._yCoeffs * t1[AT::XY];
219 result._yCoeffs.deep() = t2._xCoeffs * t1[AT::YX] + t2._yCoeffs * t1[AT::YY];
220 result._xCoeffs(0, 0) += t1[AT::X];
221 result._yCoeffs(0, 0) += t1[AT::Y];
230 t1a._xCoeffs(0, 0) = t1._xCoeffs(0, 0);
231 t1a._yCoeffs(0, 0) = t1._yCoeffs(0, 0);
243 for (
int p = 0; p <=
order; ++p) {
244 for (
int m = 0;
m <= p; ++
m) {
245 for (
int j = 0; j <=
m; ++j) {
246 for (
int q = 0; p + q <=
order; ++q) {
247 for (
int n = 0; n <= q; ++n) {
248 for (
int k = 0; k <= n; ++k) {
249 double z = binomial(p,
m) * t2u[p -
m] * binomial(
m, j) * t2uu[j] * t2uv[
m - j] *
250 binomial(q, n) * t2v[q - n] * binomial(n, k) * t2vu[k] * t2vv[n - k];
251 result._xCoeffs(j + k,
m + n - j - k) += t1._xCoeffs(p, q) *
z;
252 result._yCoeffs(j + k,
m + n - j - k) += t1._yCoeffs(p, q) *
z;
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
A class that computes binomial coefficients up to a certain power.
Reports attempts to exceed implementation-defined length limits for some classes.
Low-level polynomials (including special polynomials) in C++.
Point< double, 2 > Point2D
void computePowers(Eigen::VectorXd &r, double x)
Fill an array with integer powers of x, so .
PolynomialTransform compose(geom::AffineTransform const &t1, PolynomialTransform const &t2)
Return a PolynomialTransform that is equivalent to the composition t1(t2())