17 unsigned num_points) {
18 LF_ASSERT_MSG(num_points > 0,
"num_points must be positive.");
21 boost::multiprecision::number<boost::multiprecision::cpp_bin_float<
22 57, boost::multiprecision::digit_base_2>>;
24 static const scalar_t kPi = boost::math::constants::pi<scalar_t>();
26 Eigen::VectorXd points(num_points);
27 Eigen::VectorXd weights(num_points);
31 const unsigned int m = (num_points + 1) / 2;
34 for (
unsigned int i = 0; i < m; ++i) {
36 scalar_t z = cos(kPi * (i + 0.75) / (num_points + 0.5));
47 for (
unsigned int j = 0; j < num_points; ++j) {
50 p1 = ((2.0 * j + 1.) * z * p2 - j * p3) / (j + 1.);
56 pp = num_points * (z * p1 - p2) / (z * z - 1.0);
60 }
while (abs(z - z1) > 1e-17);
62 points(i) = (0.5 * (1 - z)).convert_to<
double>();
63 points(num_points - 1 - i) = (0.5 * (1 + z)).convert_to<
double>();
64 weights(i) = (1. / ((1.0 - z * z) * pp * pp)).convert_to<double>();
65 weights(num_points - 1 - i) = weights(i);
68 return {std::move(points), std::move(weights)};
74 LF_ASSERT_MSG(num_points > 0,
"num_points must be positive.");
75 LF_ASSERT_MSG(alpha > -1,
"alpha > -1 required");
76 LF_ASSERT_MSG(beta > -1,
"beta > -1 required.");
78 using boost::math::lgamma;
80 boost::multiprecision::number<boost::multiprecision::cpp_bin_float<
81 57, boost::multiprecision::digit_base_2>>;
83 const int MAX_IT = 10;
102 std::vector<scalar_t> points(num_points);
103 Eigen::VectorXd weights(num_points);
109 an = alpha / num_points;
110 bn = beta / num_points;
112 (2.78 / (4.0 + num_points * num_points) + 0.768 * an / num_points);
113 r2 = 1.0 + 1.48 * an + 0.96 * bn + 0.452 * an * an + 0.83 * an * bn;
117 r1 = (4.1 + alpha) / ((1.0 + alpha) * (1.0 + 0.156 * alpha));
118 r2 = 1.0 + 0.06 * (num_points - 8.0) * (1.0 + 0.12 * alpha) / num_points;
119 r3 = 1.0 + 0.012 * beta * (1.0 + 0.25 * std::abs(alpha)) / num_points;
120 z -= (1.0 - z) * r1 * r2 * r3;
123 r1 = (1.67 + 0.28 * alpha) / (1.0 + 0.37 * alpha);
124 r2 = 1.0 + 0.22 * (num_points - 8.0) / num_points;
125 r3 = 1.0 + 8.0 * beta / ((6.28 + beta) * num_points * num_points);
126 z -= (points[0] - z) * r1 * r2 * r3;
127 }
else if (i == num_points - 2) {
129 r1 = (1.0 + 0.235 * beta) / (0.766 + 0.119 * beta);
130 r2 = 1.0 / (1.0 + 0.639 * (num_points - 4.0) /
131 (1.0 + 0.71 * (num_points - 4.0)));
133 (1.0 + 20.0 * alpha / ((7.5 + alpha) * num_points * num_points));
134 z += (z - points[num_points - 4]) * r1 * r2 * r3;
135 }
else if (i == num_points - 1) {
137 r1 = (1.0 + 0.37 * beta) / (1.67 + 0.28 * beta);
138 r2 = 1.0 / (1.0 + 0.22 * (num_points - 8.0) / num_points);
140 (1.0 + 8.0 * alpha / ((6.28 + alpha) * num_points * num_points));
141 z += (z - points[num_points - 3]) * r1 * r2 * r3;
144 z = 3.0 * points[i - 1] - 3.0 * points[i - 2] + points[i - 3];
146 alfbet = alpha + beta;
148 for (its = 1; its <= MAX_IT; ++its) {
154 p1 = (alpha - beta + temp * z) / 2.0;
159 temp = 2 * j + alfbet;
160 a = 2 * j * (j + alfbet) * (temp - 2.0);
162 (alpha * alpha - beta * beta + temp * (temp - 2.0) * z);
163 c = 2.0 * (j - 1 + alpha) * (j - 1 + beta) * temp;
164 p1 = (b * p2 - c * p3) / a;
166 pp = (num_points * (alpha - beta - temp * z) * p1 +
167 2.0 * (num_points + alpha) * (num_points + beta) * p2) /
168 (temp * (1.0 - z * z));
174 if (abs(z - z1) <= 1e-17) {
178 LF_VERIFY_MSG(its <= MAX_IT,
"too many iterations.");
182 weights(i) = (exp(lgamma(alpha + num_points) + lgamma(beta + num_points) -
183 lgamma(num_points + 1.) -
184 lgamma(
static_cast<double>(num_points) + alfbet + 1.0)) *
185 temp * pow(2.0, alfbet) / (pp * p2))
186 .convert_to<
double>();
189 Eigen::VectorXd points_result(num_points);
191 points_result(i) = points[i].convert_to<
double>();
195 return {points_result, weights};