OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
cpp_python_sampling.h File Reference
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <limits>
#include <iomanip>
#include <set>
#include <utility>
#include <numeric>

Go to the source code of this file.

Functions

std::vector< double > linear_spacing (double start, double end, size_t n, bool include_start)
std::vector< double > initial_sampling (double x_max, size_t n)
double safe_cast_to_double (long double d)
void clean_values (std::vector< double > &X, std::vector< double > &Y)
long double compute_curvature (const double &F_im1, const double &F_i, const double &F_ip1, const double &h1, const double &h2)
std::vector< double > select_points (const std::vector< double > &x, const std::vector< double > &F_values, size_t n_points)

Function Documentation

◆ clean_values()

void clean_values ( std::vector< double > & X,
std::vector< double > & Y )

Definition at line 94 of file cpp_python_sampling.h.

94 {
95 // initial size
96 size_t N = X.size();
97 // Remove non-finite values
98 std::vector<double> XX;
99 std::vector<double> YY;
100 for (size_t i = 0; i < X.size(); i++)
101 {
102 if (std::isfinite(Y[i]))
103 {
104 if(i > 0)
105 {
106 if (fabs(Y[i] - Y[i-1]) > 1e-10)
107 {
108 XX.push_back(X[i]);
109 YY.push_back(Y[i]);
110 }
111 } else {
112 XX.push_back(X[i]);
113 YY.push_back(Y[i]);
114 }
115 }
116 }
117 if(XX.size() == 0) {
118 return;
119 }
120 X = XX;
121 Y = YY;
122 const size_t new_size = X.size();
123 double Xlast = X[new_size - 1];
124 double Ylast = Y[new_size - 1];
125 for(size_t i = new_size ; i < N; i++){
126 X.push_back(Xlast + 1.0);
127 Y.push_back(Ylast);
128 }
129}
#define N

◆ compute_curvature()

long double compute_curvature ( const double & F_im1,
const double & F_i,
const double & F_ip1,
const double & h1,
const double & h2 )

Definition at line 132 of file cpp_python_sampling.h.

132 {
133 // Cast inputs to long double for higher precision
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);
139
140 // First derivative using non-uniform spacing
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);
142
143 // Second derivative using non-uniform spacing
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);
145
146 // Curvature formula
147 long double denom = std::pow(1 + F_prime * F_prime, 1.5L);
148 if (denom == 0.0L) return 0.0; // Avoid division by zero
149 long double curvature = std::abs(F_double_prime) / denom;
150 // Cast the result back to double
151 // if NaN or Inf return 0.0
152 if (std::isnan(curvature) || std::isinf(curvature)) {
153 return 0.0L;
154 }
155 return curvature;
156}

◆ initial_sampling()

std::vector< double > initial_sampling ( double x_max,
size_t n )

Definition at line 45 of file cpp_python_sampling.h.

45 {
46 // Define the ranges
47 n = n / 5;
48 std::vector<double> range_starts = {0, 1, 10, 100, 1000};
49 std::vector<double> range_ends = {1, 10, 100, 1000, 10000};
50
51 std::vector<double> X;
52 X.reserve(5 * n); // Reserve space for efficiency
53 // Generate points for each range
54 for (size_t i = 0; i < range_starts.size(); ++i) {
55 bool include_start = (i == 0); // Only include start for the first range
56 std::vector<double> range_points = linear_spacing(
57 range_starts[i], range_ends[i], n, include_start
58 );
59 X.insert(X.end(), range_points.begin(), range_points.end());
60 }
61 // scale the points to 0 xmax
62 double x_min_right = 0;
63// for (size_t i = 0; i < X.size(); i++) {
64// X[i] = x_min_right + X[i] * (x_max - x_min_right) / 10000;
65// }
66 X[0] = (X[0] + X[1]) / 2.0;
67 return X;
68}
std::vector< double > linear_spacing(double start, double end, size_t n, bool include_start)
n

◆ linear_spacing()

std::vector< double > linear_spacing ( double start,
double end,
size_t n,
bool include_start )

Definition at line 34 of file cpp_python_sampling.h.

34 {
35 std::vector<double> points(n);
36
37 for (size_t i = 0; i < n; ++i) {
38 double factor = include_start ? i : (i + 1);
39 points[i] = start + factor * (end - start) / (n - 1);
40 }
41 return points;
42}
end[inform, rinform, sol, inst, schur, redrhs, pivnul_list, sym_perm, uns_perm, icntl, cntl, colsca_out, rowsca_out, keep_out, dkeep_out]
Definition dmumps.m:40

◆ safe_cast_to_double()

double safe_cast_to_double ( long double d)

Definition at line 73 of file cpp_python_sampling.h.

73 {
74 // Handle NaN cases
75 if (std::isnan(d)) {
76 return 0.0;
77 }
78
79 // Clamp to the maximum representable double if too large
80 if (d > std::numeric_limits<double>::max()) {
81 return std::numeric_limits<double>::max();
82 }
83
84 // Clamp to the minimum representable double (negative) if too small
85 if (d < -std::numeric_limits<double>::max()) {
86 return -std::numeric_limits<double>::max();
87 }
88
89 // Otherwise, cast safely
90 return static_cast<double>(d);
91}

◆ select_points()

std::vector< double > select_points ( const std::vector< double > & x,
const std::vector< double > & F_values,
size_t n_points )

Definition at line 159 of file cpp_python_sampling.h.

159 {
160 size_t n = x.size();
161 if (n_points >= n) {
162 n_points = n;
163 return x;
164 }
165
166 // Step 1: Compute curvature for all 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) {
172 curvature[i] = 0.0;
173 continue;
174 }
175 //if F_values[i] is not finite, curvature is 0
176 if (!std::isfinite(F_values[i]) || !std::isfinite(F_values[i - 1]) || !std::isfinite(F_values[i + 1])) {
177 curvature[i] = 0.0;
178 continue;
179 }
180 curvature[i] = compute_curvature(F_values[i - 1], F_values[i], F_values[i + 1], h1, h2);
181 }
182
183 // Step 2: Normalize curvature to create a density function
184 long double curvature_sum = std::accumulate(curvature.begin(), curvature.end(), 0.0);
185 std::vector<long double> density(n, 0.0L);
186
187 density[0] = sqrt(curvature[0] * (2*(x[1] - x[0]))); // Use sqrt(curvature)
188 density[n-1] = sqrt(curvature[n-1] * (2*(x[n-1] - x[n-2]))); // Use sqrt(curvature)
189 for (size_t i = 0; i < n-1; ++i) {
190 density[i] = std::sqrt(curvature[i] * (x[i+1] - x[i])); // Use sqrt(curvature)
191 }
192 // get the maximum density
193 long double max_density = *std::max_element(density.begin(), density.end());
194 // density = density + 0.001*max_density
195 for (size_t i = 0; i < n; ++i) {
196 density[i] += 0.001L * max_density;
197 }
198 long double density_sum = std::accumulate(density.begin(), density.end(), 0.0);
199 for (auto& d : density) {
200 d /= density_sum; // Normalize
201 }
202
203 // Step 3: Compute cumulative density function (CDF)
204 std::vector<long double> cdf(n, 0.0L);
205 std::partial_sum(density.begin(), density.end(), cdf.begin());
206
207 // Step 4: Select n_points based on the CDF
208 std::vector<double> selected_points;
209 selected_points.reserve(n_points);
210 double step = 1.0 / (n_points - 1);
211 double target = 0.0;
212
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)]); // Ensure idx is within bounds
217 target += step;
218 }
219
220 // Ensure boundary points are included
221 if (std::find(selected_points.begin(), selected_points.end(), x.front()) == selected_points.end()) {
222 selected_points[0] = x.front();
223 }
224 if (std::find(selected_points.begin(), selected_points.end(), x.back()) == selected_points.end()) {
225 selected_points[n_points - 1] = x.back();
226 }
227
228 return selected_points;
229}
long double compute_curvature(const double &F_im1, const double &F_i, const double &F_ip1, const double &h1, const double &h2)