2D harmonic stencil a.k.a Laplace operator
Compute harmonic weights on regular grids (Laplacian) - 09/2023 - #Jumble
Related notes on biharmonic weights for grids
1D harmonic stencil:
(1 -2 1)
The 2D harmonic stencil (a.k.a the Laplace operator) is:
\[ \Delta f(x,y) \approx \frac{f(x-h,y) + f(x+h,y) + f(x,y-h) + f(x,y+h) - 4f(x,y)}{h^2}, \]1 1 -4 1 1
Diffusion algorithm on a 2D grid that will converge to harmonic weights:
/// @param grid : grid of values/vectors you want to diffuse /// @param mask : values to '0' are not diffused /// @tparam T : must implement constructor T( double ) and overload /// 'T operator/(double)' 'T operator+(T)' /// @note: diffusing is equivalent to solving Lx=b using Gauss Seidel iterations. /// (L is the laplacian of our grid) template< typename T> void diffuse_laplacian(Grid2_ref<T> grid, Grid2_const_ref<int> mask, int nb_iter = 128*16) { tbx_assert( grid.size() == mask.size()); Vec2_i neighs[4] = {Vec2_i( 1, 0), Vec2_i( 0, 1), Vec2_i(-1, 0), Vec2_i( 0,-1)}; // First we store every grid elements that need to be diffused according // to 'mask' int mask_nb_elts = mask.size().product(); std::vector<int> idx_list; idx_list.reserve( mask_nb_elts ); for(Idx2 idx(mask.size(), 0); idx.is_in(); ++idx) { if( mask( idx ) == 1 ) idx_list.push_back( idx.to_linear() ); } // Diffuse values with a Gauss-seidel like scheme for(int j = 0; j < nb_iter; ++j) { // Look up grid elements to be diffused for(unsigned i = 0; i < idx_list.size(); ++i) { Idx2 idx(grid.size(), idx_list[i]); T sum(0.); int nb_neigh = 0; for(int i = 0; i < 4; ++i) { Idx2 idx_neigh = idx + neighs[i]; if( idx_neigh.is_in() /*check if inside grid*/ ){ sum = sum + grid( idx_neigh ); nb_neigh++; } } sum = sum / (T)( nb_neigh ); grid( idx ) = sum; } } }
Recall that one iteration of Guauss seidel to solve a linear system \(\mathbf {Ax} = \mathbf{b}\) is:
$$ x_i^{k+1}=\frac{ \overbrace{\sum \limits_{j=1}^{i-1} {a_{ij}.x_j^{k+1}}}^{ \text{already computed value} \\ \text{in previous iteration} }+ (b_i-\sum \limits_{j=i+1}^{n}a_{ij}.x_j^k) }{a_{ii}} $$No comments