1 #include <vtestbed/config/real_type.hh> 2 #include <vtestbed/core/math.hh> 3 #include <vtestbed/core/wave_numbers.hh> 9 same_sign(T lhs, T rhs) {
10 return (lhs > T(0) && rhs >= T(0)) || (lhs < T(0) && rhs <= T(0));
19 for (
const auto& half : halves) {
20 stats.length.update(half.length);
21 stats.number.update(half.number);
22 stats.height.update(half.height);
30 vtb::core::operator<<(
std::ostream& out,
const Wave_half<T>& rhs) {
32 <<
"length=" << rhs.length
33 <<
",wavenumber=" << rhs.number
34 <<
",height=" << rhs.height;
39 vtb::core::operator<<(
std::ostream& out,
const Wave_statistics<T>& rhs) {
40 out <<
"length: " << rhs.length <<
'\n';
41 out <<
"number: " << rhs.number <<
'\n';
42 out <<
"height: " << rhs.height <<
'\n';
50 const int n = func.extent(0);
54 const T dx = grid.
delta(0);
55 for (
int i=1; i<n-1; ++i) {
56 const T y0 = func(i-1);
58 const T y2 = func(i+1);
60 if (same_sign(y1-y0, y1-y2)) {
63 const T x1 = grid(i, 0);
64 const T k = dx*(dx + T(2)*x1);
65 const T a = (y0 - T(2)*y1 + y2) / (T(2)*dx*dx);
66 const T b = (-a*k - y1 + y2) / dx;
67 const T c = -a*(k + x1*x1) - b*(x1 + dx) + y2;
68 const T vx = -b / (T(2)*a);
69 const T vy = c - b*b / (T(4)*a);
70 extrema.emplace_back(vx, vy);
82 const int n = extrema.size();
86 blitz::TinyVector<T,2> p;
89 for (
int i=1; i<n; ++i) {
90 const T y0 = extrema[i-1](1);
91 const T x1 = extrema[i](0);
92 const T y1 = extrema[i](1);
95 if (same_sign(y0, y1)) {
96 if (abs(p(1)) < abs(y1)) {
101 const T
length = T(2)*(x1 - p(0));
102 const T number = pi_times_2 /
length;
103 const T height = abs(y1 - p(1));
104 halves.emplace_back(length, number, height);
119 const int n = halves.size();
120 for (
int i=0; i<n; ++i) {
121 const T wave_number = halves[i].number;
122 if (wave_number < min_wave_number) {
123 min_wave_number = wave_number;
125 if (max_wave_number < wave_number) {
126 max_wave_number = wave_number;
131 template <
class T,
int N>
133 vtb::core::wave_number_grid(
const Wave_statistics_vector<T,N>& waves) {
135 for (
int i=0; i<N; ++i) {
136 wngrid.lbound(i) = waves(i).number.min();
137 wngrid.ubound(i) = waves(i).number.max();
141 for (
int i=0; i<N; ++i) {
142 if (!(wngrid.lbound(i) < wngrid.ubound(i))) {
143 wngrid.lbound(i) = 0, wngrid.ubound(i) = 0;
150 vtb::core::Wave_statistics_vector<T,2>
151 vtb::core::wave_statistics(blitz::Array<T,2> surface,
const Grid<T,2>& grid) {
152 Wave_statistics_vector<T,2> waves;
153 const auto& _ = blitz::Range::all();
154 const int n1 = surface.extent(0);
155 const int n2 = surface.extent(1);
157 for (
int i=0; i<n2; ++i) {
158 const auto& extrema =
find_extrema(surface(_,i), grid.select(0));
162 for (
int i=0; i<n1; ++i) {
163 const auto& extrema =
find_extrema(surface(i,_), grid.select(1));
171 vtb::core::temporal_wave_statistics(
172 blitz::Array<T,1> surface,
173 const Grid<T,1>& grid
175 Wave_statistics<T> waves;
189 const int n1 = surface.extent(0);
190 const int n2 = surface.extent(1);
192 for (
int i=0; i<n2; ++i) {
200 for (
int i=0; i<n1; ++i) {
207 for (
int i=0; i<2; ++i) {
208 if (wngrid.lbound(i) > wngrid.ubound(i)) {
209 wngrid.lbound(i) = T(0);
210 wngrid.ubound(i) = T(0);
218 blitz::Array<VTB_REAL_TYPE, 1> func,
219 const Grid<VTB_REAL_TYPE, 1>& grid
224 const std::vector<blitz::TinyVector<VTB_REAL_TYPE, 2>>& extrema
229 const std::vector<Wave_half<VTB_REAL_TYPE>>& halves,
230 VTB_REAL_TYPE& min_wave_number,
231 VTB_REAL_TYPE& max_wave_number
237 blitz::Array<VTB_REAL_TYPE, 2> surface,
238 const Grid<VTB_REAL_TYPE, 2>& grid
242 vtb::core::wave_number_grid(
const Wave_statistics_vector<VTB_REAL_TYPE,2>&);
245 vtb::core::wave_number_grid(
const Wave_statistics_vector<VTB_REAL_TYPE,3>&);
247 template blitz::TinyVector<vtb::core::Wave_statistics<VTB_REAL_TYPE>,2>
248 vtb::core::wave_statistics(
249 blitz::Array<VTB_REAL_TYPE,2> surface,
250 const Grid<VTB_REAL_TYPE,2>& grid
254 vtb::core::temporal_wave_statistics(
255 blitz::Array<VTB_REAL_TYPE,1> surface,
256 const Grid<VTB_REAL_TYPE,1>& grid
260 vtb::core::operator<<(
std::ostream&,
const Wave_half<VTB_REAL_TYPE>&);
263 vtb::core::operator<<(
std::ostream&,
const Wave_statistics<VTB_REAL_TYPE>&);
A half of the wave with length, number and height of the full wave.
std::vector< blitz::TinyVector< T, 2 > > find_extrema(blitz::Array< T, 1 > func, const Grid< T, 1 > &grid)
Find coordinates of minima and maxima of a function.
std::vector< Wave_half< T > > find_wave_halves(const std::vector< blitz::TinyVector< T, 2 >> &extrema)
Find wave halves from function extrema computed previously.
const T delta(int i) const
The size of the patch (interval) for dimension i.
A region defined by start and end index and lower and upper bound for each dimension.
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
void find_wave_number_range(const std::vector< Wave_half< T >> &halves, T &min_wave_number, T &max_wave_number)
Find minimum and maximum wave number from wave halves computed previously.