119 using fitdetail::num_sqrt;
134 const T r2 = e2 / two;
135 if (r1 == zero)
throw InputError(
"map2_fit: zero first moment");
136 const T h2 = (r2 - r1 * r1) / (r1 * r1);
139 const T scv = (e2 - e1 * e1) / (e1 * e1);
140 const T c32 = three / two;
142 if (one <= scv && scv < three) {
144 const T h3 = h2 - h2 * h2;
145 e3 = twelve * pw(e1, 3) * h2 + six * pw(e1, 3) * h3 +
146 six * pw(e1, 3) * (one + h2 * h2);
150 }
else if (three <= scv) {
152 }
else if (zero < scv && scv < one) {
154 (twelve * pw(e1, 3) * h2 +
155 six * pw(e1, 3) * (h2 * (one - h2 - two * num_sqrt(T(-h2)))) +
156 six * pw(e1, 3) * (one + h2 * h2));
158 }
else if (e3 == -two) {
161 }
else if (zero < scv && scv < one) {
162 const T h3 = h2 * (one - h2 - two * num_sqrt(T(-h2)));
163 e3 = six * pw(e1, 3) * (h2 * h2 + h3);
165 }
else if (e3 == -three) {
168 }
else if (zero < scv && scv < one) {
169 const T h3 = h2 * h2;
170 e3 = six * pw(e1, 3) * (h2 * h2 + h3);
172 }
else if (e3 > -one && e3 < zero) {
177 }
else if (zero < scv && scv < one) {
178 const T h3 = r * h2 * (one - h2 - two * num_sqrt(T(-h2))) + (one - r) * (h2 * h2);
179 e3 = six * pw(e1, 3) * (h2 * h2 + h3);
184 const T r3 = e3 / six;
185 const T h3 = (r3 * r1 - r2 * r2) / pw(r1, 4);
186 const T b = h3 + h2 * h2 - h2;
188 if (crad < zero)
throw NumericError(
"map2_fit: negative discriminant b^2 + 4 h2^3");
189 const T c = num_sqrt(crad);
197 if (h3 == zero && g2 == zero) {
208 const T qhypo_lo = h2 * (one - h2 - two * num_sqrt(T(-h2)));
210 qhypo_lo <= h3 && h3 <= -(h2 * h2));
212 if (h2 > zero && h3 > zero) {
214 if ((b - c) / (b + c) <= g2 && g2 < one) {
215 res.
map = fitdetail::map2_fit_hyper_diag(r1, h2, h3, b, c, g2);
222 if (zero <= g2 && g2 < one) {
223 res.
map = fitdetail::map2_fit_hyper_diag(r1, h2, h3, b, c, g2);
225 }
else if (-(h3 + h2 * h2) / h2 <= g2 && g2 < zero) {
226 const T a = (h3 + h2 * h2) / h2;
227 res.
map = fitdetail::map2_fit_form(r1, h2, h3, b, c, g2, a);
234 }
else if (hypo_region) {
236 const T sq = num_sqrt(T(-h3));
237 if (g2 <= -((h2 + sq) * (h2 + sq)) / h2) {
238 const T a = (two * h2 + b - c) * (h2 + sq) / (two * h2 * sq);
239 res.
map = fitdetail::map2_fit_form(r1, h2, h3, b, T(-c), g2, a);
246 if (g2 >= -(h3 + h2 * h2) / h2) {
247 const T a = (h3 + h2 * h2) / h2;
248 res.
map = fitdetail::map2_fit_form(r1, h2, h3, b, T(-c), g2, a);
256 res.
err = (h2 > zero && h3 < zero) ? 40 : 30;
Map2FitResult< T > map2_fit(const T &e1, const T &e2, const T &e3_in, const T &g2)
Fit an AMAP(2) to (e1, e2, e3, g2); see the header comment for e3 sentinels.