global size int N = 8 # grid dimension, default 8 body size getarg(1, N) end global data import size real grid[2][0:N+1,0:N+1] real epsilon = .3 int nxt = 2 int cur = 1 op print() body data grid = ([2] ([N+2] ([N+2] 0.0))) real l=1.0 real t=2.1 real r=3.3 real b= 4.9 for [ i = 0 to N+1 ] { grid[cur][i,0] = l; grid[nxt][i,0] = l } for [ i = 0 to N+1 ] { grid[cur][0,i] = t; grid[nxt][0,i] = t } for [ i = 0 to N+1 ] { grid[cur][i,N+1] = r; grid[nxt][i,N+1] = r } for [ i = 0 to N+1 ] { grid[cur][N+1,i] = b; grid[nxt][N+1,i] = b } proc print() { write() for [ i = 1 to N ] { for [ j = 1 to N ] { printf("%5.3f ",grid[cur][i,j]) } write() } } end resource jacobi() import data, size real diff[1:N,1:N] # differences procedure update(int i, int j) { grid[nxt][i,j] = (grid[cur][i-1,j] + grid[cur][i,j-1] + \ grid[cur][i+1,j] + grid[cur][i,j+1]) / 4 diff[i,j] = abs(grid[nxt][i,j] - grid[cur][i,j]) } procedure check_diffs(int i) { for [ j = 2 to N ] { diff[i,1] = max(diff[i,1], diff[i,j]) } } int iters = 0 real maxdiff while (true) { # iterate until convergence iters++ co [ i = 1 to N, j = 1 to N ] update(i,j) oc nxt :=: cur # swap roles of grids maxdiff = 0.0 co [ i = 1 to N ] check_diffs(i) -> maxdiff = max(maxdiff, diff[i,1]) oc if (maxdiff <= epsilon) { exit } } write("convergence after", iters, "iterations") print() end