## -*- texinfo -*-
## @deftypefn {Function File} {} placet_optimize (@var{beamline}, @var{user_function}, @var{correctors}, @var{leverages}, @var{initial_guess}, @var{initial_step})
## 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("electron", "final_emittance", [ 1 2 3], [ "y"; "strength_y"; "y" ], [1.0 1.0 1.0]);
## @end verbatim
## @end deftypefn

function [retval,merit] = placet_optimize(beamline, user_function, correctors, leverages, initial_step)
  if nargin>=4 && ischar(beamline) && ischar(user_function) && isvector(correctors)
    if nargin==4
      initial_step=ones(size(correctors));
    endif 
    initial_state=zeros(size(correctors));
    if rows(leverages)==1
      initial_state=placet_element_get_attribute(beamline, correctors, leverages);
    else
      for i=1:length(correctors)
        initial_state(i)=placet_element_get_attribute(beamline, correctors(i), deblank(leverages(i,:)));
      end
    endif
    retval=fmins("__merit_function__", zeros(size(correctors)), [], [], beamline, user_function, correctors, leverages, initial_step, initial_state);
    if nargout==2
      merit=__merit_function__(retval, beamline, user_function, correctors, leverages, initial_step, initial_state)
    end
    # apply the correction to the beamline
    if rows(leverages) == 1
      for i=1:length(correctors)
        placet_element_set_attribute(beamline, correctors(i), leverages, initial_state(i) + retval(i) * initial_step(i));
      end
    else
      for i=1:length(correctors)
        placet_element_set_attribute(beamline, correctors(i), deblank(leverages(i,:)), initial_state(i) + retval(i) * initial_step(i));
      end
    endif
  else  
    help placet_optimize
  endif
endfunction
