Potential variants - ObjectVision/GeoDMS GitHub Wiki

Grid functions potential variants

syntax

  • potential64(grid_data_item, kernel)
  • potentialRaw64(grid_data_item, kernel)
  • potentialSlow(grid_data_item, kernel)
  • potential32(grid_data_item, kernel)
  • potentialRaw32(grid_data_item, kernel)

definition

The potential function is available in a set of explicitly named variants. All variants have the same two arguments (a grid_data_item and a kernel) and calculate the same convolution sum; they differ in the algorithm used, the precision the calculation runs in and whether a smoothing step is applied to the result.

The plain potential function is a synonym for the fastest full-precision variant, currently potential64.

variants

function algorithm precision smoothing applies to
potential FFT (same as potential64) float64 yes float32, float64
potential64 FFT float64 yes float32, float64
potentialRaw64 FFT float64 no float32, float64
potentialSlow direct (four nested loops) value type of arguments no float32, float64
potential32 FFT float32 yes float32
potentialRaw32 FFT float32 no float32
  • potential64: the default implementation. The convolution is calculated with a Fast Fourier Transformation (FFT); kernel and intermediate buffers are widened to float64, also for float32 arguments, to give a more precise result. A smoothing step is applied afterwards.
  • potentialRaw64: same as potential64, but without the smoothing step.
  • potentialSlow: the classic reference implementation with four nested loops, without FFT. It calculates the sums directly in the value type of the arguments. As no FFT is used, no oscillation artifacts occur and no smoothing is applied. It requires O(n*m*k*j) operations for an n*m grid and a k*j kernel and is therefore much slower for large kernels; it is primarily meant for verifying and benchmarking the FFT-based variants.
  • potential32: the same FFT, but calculated in single precision throughout: the kernel, the intermediate buffers and the transform itself all stay in float32. That roughly halves the memory the convolution needs and lets the processor do twice as much per vector instruction, at the cost of precision. Only available for float32 arguments.
  • potentialRaw32: same as potential32, but without the smoothing step.

description

precision: the FFT-based variants come in a float64 and a float32 flavour, and the suffix in the name is exactly that choice. Both accept float32 arguments; only the float64 flavour also accepts float64 ones. Working in float64 on float32 data costs about twice the memory and processing time of the convolution but returns a result that is exact to float32; working in float32 is cheaper but leaves a relative error in the order of 10^-7 to 10^-6. As an indication, on a 33x33 grid with a 5x5 kernel and result values up to 1088, potential32 deviates from potential by 3.7*10^-4, where the (non-FFT) potentialSlow deviates by 1.2*10^-4.

smoothing: an FFT can result in small oscillations: values very close to zero, sometimes even slightly negative, in regions where the exact result is zero. The smoothing step resets those to zero. The threshold is relative to the square root of the sum of the squared result values, and follows the precision the transform ran in: a factor 10^-9 for the float64 variants and 10^-6 for the float32 ones, because the oscillations of a float32 transform are the larger of the two. The raw variants (potentialRaw64 and potentialRaw32) skip this step and return the FFT output as is.

which variant to use: for regular use, apply potential. Use potentialRaw64 if near-zero result values are meaningful and must not be reset to zero by the smoothing step. Use potentialSlow to verify results of the FFT-based variants on small grids. Use potential32 for large float32 grids where the memory or the processing time of the convolution is a limiting factor and a relative error in the order of 10^-6 is acceptable.

applies to

  • attribute grid_data_item with float32 or float64 value type (potential32 and potentialRaw32: float32 only)

conditions

The domain unit of grid_data_item must be a Point value type of the group CanBeDomainUnit.

since version

20.13.0, in which the port of the FFT-based variants from the Intel Performance Primitives library to FFTW3 was completed:

  • The single-precision variants were renamed from potentialPacked and potentialRawPacked to potential32 and potentialRaw32, and now use FFTW's single-precision transform. From 20.0.0 up to and including 20.12.0 they ran a double-precision transform whose pre-calculated kernel was read as if it were float64 while it was written as float32, which made them return values that underflowed to zero on small grids and null values on larger grids. See issue 1174.
  • potentialIpps64 was renamed to potential64. Its results are unchanged.

The names potentialIpps64, potentialPacked and potentialRawPacked are no longer recognized; configurations that use them must be updated.

example

attribute<float32> potgrid_raw (GridDomain) := potentialRaw64(float32(sourcegrid), pot3Range/RelWeight);

see also

⚠️ **GitHub.com Fallback** ⚠️