## -*- texinfo -*-
## @deftypefn {Function File} {} placet_optimize_constraint (@var{beamline}, @var{user_function}, @var{correctors}, @var{leverages}, @var{initial_guess}, @var{constraints})
## Optimize 'user_function' using selected 'correctors', respective 'leverages', 'initial_guess'
##
## Example of user_function:
##
## @verbatim
## function m=final_emittance(beamline)
##  e=placet_test_no_correction(beamline, "beam0", "None");
##  m=e(end,6);
## endfunction
##
## optimum = placet_optimize_constraint("electron", "final_emittance", [ 1 2 3], [ "y"; "strength_y"; "y" ], [0, 0; 0, 1; 0, 0]);
##
## @end verbatim
## @end deftypefn

function [retval,merit] = placet_optimize_constraint(beamline, user_function, correctors, leverages, constraints)
  if nargin==5 && ischar(beamline) && ischar(user_function) && isvector(correctors) && ismatrix(constraints)
    initial_state=zeros(size(correctors));
    if rows(leverages)==1
      initial_state=placet_element_get_attribute(beamline, correctors, leverages);
    else
      for i=1:length(correctors)
        x = placet_element_get_attribute(beamline, correctors(i), deblank(leverages(i,:)));
        a = constraints(i,1);
        b = constraints(i,2);
        if a != b
          _a = min(constraints(i,:));
          _b = max(constraints(i,:));
          x = sigmoid_inv(max(_a, min(x, _b)), a ,b);
        end
        initial_state(i) = x;
      end
    endif
    retval=fmins("__merit_function_constraint__", initial_state, [], [], beamline, user_function, correctors, leverages, constraints, initial_state);
    if nargout==2
      merit=__merit_function_constraint__(retval, beamline, user_function, correctors, leverages, constraints, initial_state)
    end
    # apply the constraints on the result
    for i=1:length(correctors)
      a=constraints(i,1);
      b=constraints(i,2);
      if a != b
        retval(i)=sigmoid(retval(i), a, b);
      endif
    endfor
    if rows(leverages)==1
      placet_element_set_attribute(beamline, correctors(i), leverages, retval);
    else
      for i=1:length(correctors)
        placet_element_set_attribute(beamline, correctors(i), deblank(leverages(i,:)), retval(i));
      end
    endif
  else  
    help placet_optimize
  endif
endfunction
