Hello, I am trying to model a tricky optimization problem using JuMP.
Exposition:
I am trying to manufacture something a bit like a Fresnel lens.
I have a continuous function of height vs x & y position, but we can only manufacture it at 16 discrete levels, and the height of our function is much greater than the highest level we can manufacture.
Thankfully, we are illuminating the surface with monochromatic light of exactly one wavelength. This means, we can “wrap” the surface up and down in increments of one wavelength and it will work identically.
What I tried:
My first approach was to create a matrix variable in jump, and create a cost function using mod
:
model = Model(COSMO.Optimizer)
@variable(model, z[1:21, 1:21], lower_bound=0, upper_bound=16)
periodic_euclidean_cost(z,z′) = sum(@.(
min(
mod((z - z′)^2, 16),
16 - mod((z - z′)^2, 16)
)^2))
@objective(model, Min, periodic_euclidean_cost(z, z′))
My goal was to treat each variable as periodic, and find the closest value modulo 16.
The Error I Encountered
Attempting to add that objective to the model leads to No method matching mod(::QuadExpr, ::Int64)
.
I guess this is not surprising that JuMP can’t optimize through mod
.
Is there another way I can specify this problem that JuMP will understand?
Thanks!
N.B. I know it would be easy to just wrap our matrix ourselves and not use JuMP, but I have some additional constraints I need JuMP to optimize e.g. the height of the layers.