48 std::vector<double> range_starts = {0, 1, 10, 100, 1000};
49 std::vector<double> range_ends = {1, 10, 100, 1000, 10000};
51 std::vector<double> X;
54 for (
size_t i = 0; i < range_starts.size(); ++i) {
55 bool include_start = (i == 0);
57 range_starts[i], range_ends[i],
n, include_start
59 X.insert(X.end(), range_points.begin(), range_points.end());
62 double x_min_right = 0;
66 X[0] = (X[0] + X[1]) / 2.0;
132long double compute_curvature(
const double & F_im1,
const double & F_i,
const double &F_ip1,
const double & h1,
const double & h2) {
134 long double F_im1_ld =
static_cast<long double>(F_im1);
135 long double F_i_ld =
static_cast<long double>(F_i);
136 long double F_ip1_ld =
static_cast<long double>(F_ip1);
137 long double h1_ld =
static_cast<long double>(h1);
138 long double h2_ld =
static_cast<long double>(h2);
141 long double F_prime = (h2_ld * (F_i_ld - F_im1_ld) + h1_ld * (F_ip1_ld - F_i_ld)) / (h1_ld * h2_ld);
144 long double F_double_prime = 2 * ((F_ip1_ld - F_i_ld) / h2_ld - (F_i_ld - F_im1_ld) / h1_ld) / (h1_ld + h2_ld);
147 long double denom = std::pow(1 + F_prime * F_prime, 1.5L);
148 if (denom == 0.0L)
return 0.0;
149 long double curvature = std::abs(F_double_prime) / denom;
152 if (std::isnan(curvature) || std::isinf(curvature)) {
159std::vector<double>
select_points(
const std::vector<double>&
x,
const std::vector<double>& F_values,
size_t n_points) {
167 std::vector<long double> curvature(
n, 0.0);
168 for (
size_t i = 1; i <
n - 1; ++i) {
169 double h1 =
x[i] -
x[i - 1];
170 double h2 =
x[i + 1] -
x[i];
171 if (h1 == 0.0 || h2 == 0.0) {
176 if (!std::isfinite(F_values[i]) || !std::isfinite(F_values[i - 1]) || !std::isfinite(F_values[i + 1])) {
180 curvature[i] =
compute_curvature(F_values[i - 1], F_values[i], F_values[i + 1], h1, h2);
184 long double curvature_sum = std::accumulate(curvature.begin(), curvature.end(), 0.0);
185 std::vector<long double> density(
n, 0.0L);
187 density[0] = sqrt(curvature[0] * (2*(
x[1] -
x[0])));
188 density[
n-1] = sqrt(curvature[
n-1] * (2*(
x[
n-1] -
x[
n-2])));
189 for (
size_t i = 0; i <
n-1; ++i) {
190 density[i] = std::sqrt(curvature[i] * (
x[i+1] -
x[i]));
193 long double max_density = *std::max_element(density.begin(), density.end());
195 for (
size_t i = 0; i <
n; ++i) {
196 density[i] += 0.001L * max_density;
198 long double density_sum = std::accumulate(density.begin(), density.end(), 0.0);
199 for (
auto& d : density) {
204 std::vector<long double> cdf(
n, 0.0L);
205 std::partial_sum(density.begin(), density.end(), cdf.begin());
208 std::vector<double> selected_points;
209 selected_points.reserve(n_points);
210 double step = 1.0 / (n_points - 1);
213 for (
size_t i = 0; i < n_points; ++i) {
214 auto it = std::lower_bound(cdf.begin(), cdf.end(), target);
215 size_t idx = std::distance(cdf.begin(), it);
216 selected_points.push_back(
x[std::min(idx,
n - 1)]);
221 if (std::find(selected_points.begin(), selected_points.end(),
x.front()) == selected_points.end()) {
222 selected_points[0] =
x.front();
224 if (std::find(selected_points.begin(), selected_points.end(),
x.back()) == selected_points.end()) {
225 selected_points[n_points - 1] =
x.back();
228 return selected_points;
end[inform, rinform, sol, inst, schur, redrhs, pivnul_list, sym_perm, uns_perm, icntl, cntl, colsca_out, rowsca_out, keep_out, dkeep_out]