49 const T& degentol,
const T& r12tol) {
51 "amap2_fitall_gamma requires transcendental arithmetic");
52 using fitdetail::num_sqrt;
61 std::vector<Map<T>> out;
62 if (M1 <= zero)
throw InputError(
"amap2_fitall_gamma: non-positive first moment");
64 const T SCV = (M2 - M1 * M1) / (M1 * M1);
65 bool degenerate =
false;
67 const T d = one - SCV;
68 const T M3lb = three * pw(M1, 3) * (three * SCV - one + num_sqrt(two) * d * num_sqrt(d));
69 if (
num_abs(T(M3 - M3lb)) < degentol) degenerate =
true;
76 three * M1 * M1 * M2 * M2 + two * pw(M2, 3);
77 if (tmp0 < zero)
return out;
80 const T tmp1 = three * num_sqrt(tmp0);
81 const T tmp2 = M3 - three * M1 * M2;
83 if (tmp3 == zero)
throw NumericError(
"amap2_fitall_gamma: degenerate moment set (M2 = 2 M1^2)");
85 const std::size_t n = (tmp0 == zero) ? 1u : 2u;
86 std::vector<T> h1v(n, zero), h2v(n, zero);
91 h2v[0] = (tmp2 + tmp1) / tmp3;
92 h2v[1] = (tmp2 - tmp1) / tmp3;
96 for (std::size_t j = 0; j < n; ++j)
97 if (h2v[j] <= zero)
return out;
100 const T hi = one + r12tol;
102 for (std::size_t j = 0; j < n; ++j) {
106 const T z = M1 * M1 * GAMMA * GAMMA +
107 (two * M1 * h1 + two * M1 * h2 - four * h1 * h2 - two * M1 * M1) * GAMMA +
108 M1 * M1 - two * M1 * h1 - two * M1 * h2 + h1 * h1 + two * h1 * h2 + h2 * h2;
111 if (h1 == zero)
continue;
112 r2v.push_back(T((h1 - M1 + h2 + GAMMA * M1) / (two * h1)));
113 }
else if (z > zero) {
114 if (h1 == zero)
continue;
115 const T s = num_sqrt(z);
116 r2v.push_back(T((h1 - M1 + h2 - s + GAMMA * M1) / (two * h1)));
117 r2v.push_back(T((h1 - M1 + h2 + s + GAMMA * M1) / (two * h1)));
119 for (std::size_t i = 0; i < r2v.size(); ++i) {
121 const T den = h2 - M1 * r2;
122 if (den == zero)
continue;
123 T r1 = (M1 - h1 - M1 * r2 + h1 * r2) / den;
124 if (!(r1 >= lo && r1 <= hi && r2 >= lo && r2 <= hi))
continue;
125 if (r1 > one) r1 = one;
126 if (r1 < zero) r1 = zero;
127 if (r2 > one) r2 = one;
128 if (r2 < zero) r2 = zero;
132 if (h1 == zero)
continue;
133 T r2 = (h1 - M1 + h2 + GAMMA * M1) / h1;
134 if (r2 == one)
continue;
135 T r1 = (r2 + (h1 + h2 - h1 * r2) / M1 - two) / (r2 - one);
136 if (!(r1 >= lo && r1 <= hi && r2 >= lo && r2 <= hi))
continue;
137 if (r1 > one) r1 = one;
138 if (r1 < zero) r1 = zero;
139 if (r2 > one) r2 = one;
140 if (r2 < zero) r2 = zero;
Map< T > amap2_assemble(const T &l1, const T &l2, const T &p1, const T &p2, int form)
AMAP(2) in canonical form 1 (gamma >= 0) or 2 (gamma < 0).
std::vector< Map< T > > amap2_fitall_gamma(const T &M1, const T &M2, const T &M3, const T &GAMMA, const T °entol, const T &r12tol)
Every AMAP(2) matching (M1, M2, M3, GAMMA).