Optimization

Constraint based optimization can be carried out by specifying which surface parameters to vary and which system properties to aim for as well as which third order aberrations to minimize.

# you can specify a vector of integers corresponding to linear indices,
# or a CartesianIndex vector
v = [2:5; [8, 9]] # this varies only the curvatures for the example lens
# maps System fields to desired values
constraints = Dict(:f => system.f)
# the following two are optional,
# if not provided a simple mean over the five Seidel coefficients is taken
aberr = [:W040, :W131, :W222]
weights = [2.0, 2.0, 1.0]
new_system = optimize(system, v, constraints, aberr, weights)
OpticalRayTracing.System{Layout, Spherical}

   f: 50.7885
EBFD: 44.6784
EFFD: -42.3569
   N: 2.8178
 FOV: 45.8882
stop: 5
  EP: D = 18.0240, t = 8.9897
  XP: D = 17.8280, t = -5.5580
julia> new_system.layout9×4 Layout{Spherical}:
   Inf      0.0    1.0     0.0
   15.9155  3.57   1.6116  0.0
 -169.864   1.89   1.0     0.0
  -30.6793  0.81   1.6053  0.0
   14.1617  2.345  1.0     0.0
   Inf      0.905  1.0     0.0
   Inf      2.17   1.5123  0.0
   14.3984  3.96   1.6116  0.0
  -22.748   0.0    1.0     0.0
julia> w = aberrations(new_system)OpticalRayTracing.Aberration{OpticalRayTracing.System{Layout, Spherical}} W040: -0.0000 W131: 0.0000 W222: -0.0000 W220: 41.3365 W311: 74.2330 W020: 0.0000 W111: 0.0000

Note that this employs a rudimentary optimization procedure meant to provide a rough initial numerical solution; as a result the constraint values might not be met exactly.