Help simplify this code? JuMP constraints

for i in 1:Y, j in 1:X
	s = sum(x[max(1, i - 1):min(Y, i + 1), max(1, j - 1):min(X, j + 1)])
	s -= x[i, j]

	@constraint(model, 2a[i, j] <= s)
	@constraint(model, 5a[i, j] <= 8 - s)
	@constraint(model, 4b[i, j] <= s)
	@constraint(model, 4b[i, j] <= 8 - s)
	@constraint(model, 5c[i, j] <= s)
end

I’m using JuMP. I’m trying to make it so that:

  • a[i,j] = 1 iff the sum of elements around x[i, j] (3x3, without it, up to 8 elements in total) is between 2-3.
  • b[i, j] = 1 iff the sum = 4
  • c[i, j] == 1 iff the sum >= 5.

I don’t like how this code looks, but it was the cleanest I could think of.

x[max(1, i - 1):min(Y, i + 1), max(1, j - 1):min(X, j + 1)] selects the 3x3 submatrix of x around x[i, j].

Some ideas I had to simplify it were:

  • Maybe there is some function to choose the submatrix without having to do the bound checking manually?
  • Preferable, I tried to do a convolution:
mask = centered(ones(3, 3))
mask[0, 0] = 0
S = imfilter(x, mask, Fill(zero(VariableRef)))
#S = imfilter(x, mask, Fill(zero(AffExpr)))

But both of these convolutions fail:

ERROR: LoadError: ArgumentError: Cannot convert elements of border=Fill{AffExpr, 2}(0, (1, 1), (1, 1)) to eltype(inner)=VariableRef.
[...]
caused by: MethodError: Cannot `convert` an object of type AffExpr to an object of type VariableRef

Any ideas?
Thanks