9 #include <vtestbed/config/real_type.hh> 10 #include <vtestbed/core/arma.hh> 11 #include <vtestbed/core/convolution.hh> 12 #include <vtestbed/core/debug.hh> 13 #include <vtestbed/base/for_loop.hh> 14 #include <vtestbed/core/polynomial.hh> 15 #include <vtestbed/profile/profile.hh> 21 template <
class T,
int N>
22 inline blitz::Array<T,N>
25 const blitz::TinyVector<T,N>& alpha
27 const auto& delta = grid.
delta();
30 [&grid,&delta,alpha] (
const blitz::TinyVector<int,N>& idx) {
35 return exp(-(sum(abs(grid(idx, delta) * alpha))));
40 template <
class T,
int N>
43 blitz::Array<T,N>& surface,
45 const blitz::TinyVector<T,N>& alpha
50 const T old_variance =
variance(surface);
51 surface *= exponential_decay(grid, alpha);
52 const T new_variance =
variance(surface);
53 const T a =
sqrt(old_variance / new_variance);
62 template <
class T,
int N>
65 VTB_PROFILE_BLOCK(__func__);
68 const int n = phi.numElements();
70 std::copy_n(phi.data(), n, characteristic_polynomial.begin());
71 characteristic_polynomial.coefficients() =
72 -characteristic_polynomial.coefficients();
73 characteristic_polynomial.coefficients(0) = 1;
76 if (num_bad_roots > 0) {
81 template <
class T,
int N>
84 VTB_PROFILE_BLOCK(__func__);
90 blitz::Array<C,N> tmp(rhs.shape());
95 const int n = rhs.numElements();
96 return blitz::Array<T,N>(real(tmp) / n / n);
99 template <
class T,
int N>
101 vtb::core::covariance(
102 blitz::Array<T,N> lhs,
103 blitz::Array<T,N> rhs,
106 VTB_PROFILE_BLOCK(__func__);
108 using namespace blitz;
109 if (!all(lhs.shape() == rhs.shape())) {
112 blitz::Array<C,N> f1(lhs.shape());
115 blitz::Array<C,N> f2(rhs.shape());
120 const int n = rhs.numElements();
121 return blitz::Array<T,N>(real(f1) / n / n);
125 template <
class T,
int N>
131 clock_type::now().time_since_epoch().count(),
132 clock_type::rep(dev())
134 this->_prng.seed(seq);
137 template <
class T,
int N>
142 VTB_PROFILE_BLOCK(__func__);
143 const T stdev = std::sqrt(this->white_noise_variance());
145 for (
auto& x : result) { x = normal(this->_prng); }
148 template <
class T,
int N>
151 if (this->has_acf_generator()) {
152 grid_type grid = this->_acf_generator->acf_grid();
153 array_type surface(grid.shape());
154 this->_acf_generator->generate(grid, surface);
155 #if defined(VTB_DEBUG_ARMA) 156 dbg::write_animated_surface(
"base_surface", surface);
158 exponential_decay(surface, grid, this->decay());
159 #if defined(VTB_DEBUG_ARMA) 160 dbg::write_animated_surface(
"base_surface_exp", surface);
163 tmp.resizeAndPreserve(tmp.shape()/2);
164 #if defined(VTB_DEBUG_ARMA) 165 dbg::write_animated_surface(
"acf", tmp);
167 this->_acf.reference(tmp);
169 this->_coefficients.reference(this->_solver->solve(this->acf()));
170 #if defined(VTB_DEBUG_ARMA) 171 dbg::write_animated_surface(
"coefficients", this->_coefficients);
174 this->_whitenoisevariance = this->_solver->white_noise_variance();
175 if (this->_whitenoisevariance <= T{0}) {
176 std::cerr <<
"white noise variance = " << _whitenoisevariance << std::endl;
181 template <
class T,
int N>
184 const grid_type& grid_txy,
187 typedef blitz::TinyVector<int,N> index;
188 const auto& phi = this->coefficients();
189 auto& buffer = this->_buffer;
190 auto& offset = this->_offset;
191 if (buffer.extent(1) != grid_txy.extent(1) ||
192 buffer.extent(2) != grid_txy.extent(2) ||
193 buffer.extent(0) < phi.extent(0) + grid_txy.extent(0)) {
195 std::max(phi.extent(0) + 1, phi.extent(0) + grid_txy.extent(0)),
202 const auto nt = grid_txy.extent(0);
203 if (offset + nt >= buffer.extent(0)) {
204 int shift = offset + nt - buffer.extent(0);
205 int slice_size = buffer.extent(1)*buffer.extent(2);
208 buffer.data() + shift*slice_size,
209 (offset-shift)*slice_size*
sizeof(T)
213 index r0{offset,0,0};
214 index r1{offset+grid_txy.extent(0), buffer.extent(1), buffer.extent(2)};
215 blitz::RectDomain<N> r{r0,r1-1};
216 this->generate_white_noise(buffer(r));
219 [&] (
const index& idx) {
221 index shape{blitz::min(idx+1, phi.shape())};
224 [&] (
const index& idx2) {
225 sum += phi(idx2) * buffer(index{idx-idx2});
233 auto m = blitz::minmax(result);
234 std::clog <<
"m.min=" << m.min << std::endl;
235 std::clog <<
"m.max=" << m.max << std::endl;
238 template <
class T,
int N>
241 const grid_type& grid,
244 this->generate_white_noise(result);
246 typedef blitz::Array<C,N> carray_type;
248 const auto& theta = this->coefficients();
249 carray_type
signal(result.shape()), kernel(theta.shape());
254 Convolution<C,N> convolve(result.shape(), theta.shape());
255 result = real(convolve(signal, kernel));
261 template blitz::Array<VTB_REAL_TYPE,3>
264 template blitz::Array<VTB_REAL_TYPE,1>
265 vtb::core::covariance(
266 blitz::Array<VTB_REAL_TYPE,1> lhs,
267 blitz::Array<VTB_REAL_TYPE,1> rhs,
271 template blitz::Array<VTB_REAL_TYPE,3>
272 vtb::core::covariance(
273 blitz::Array<VTB_REAL_TYPE,3> lhs,
274 blitz::Array<VTB_REAL_TYPE,3> rhs,
282 #if defined(VTB_REAL_TYPE_FLOAT)
Based on autoregerssive model.
void validate_process(blitz::Array< T, N > phi)
Check AR (MA) process stationarity (invertibility).
T variance(const Array< T, N > &rhs)
Sample variance.
New and missing Blitz++ functions.
blitz::Array< T, N > auto_covariance(const blitz::Array< T, N > &rhs)
Computes autocovariance function of three-dimensional field.
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.
Based on moving-average model.
int num_roots_inside_unit_disk(Polynomial< T > p)
Finds the number of polynomial roots inside the unit disk.