
jcm_optimizer_path = '<JCM_OPTIMIZER_PATH>';
addpath(fullfile(jcm_optimizer_path, 'interface', 'matlab'));
 
server = jcmoptimizer.Server();
client = jcmoptimizer.Client(server.host);

 % Definition of the search domain
design_space = { ...
  struct('name', 'b1', 'type', 'continuous', 'domain', [0,10]), ... 
  struct('name', 'b2', 'type', 'continuous', 'domain', [0.1,4]), ...
  struct('name', 'b3', 'type', 'continuous', 'domain', [-4,-0.1]), ...
  struct('name', 'b4', 'type', 'continuous', 'domain', [0.05,1]), ...
  struct('name', 'b5', 'type', 'continuous', 'domain', [0.05,1]) ...
};
constraints = { ...
    struct('name', 'test', 'expression', 'b2 + b3 <= 1.0') ...
};

 % Creation of the study object with study_id 'scipy_least_squares'
study = client.create_study( ...
    'design_space', design_space, ...
    'constraints', constraints,...
    'driver','ScipyLeastSquares',...
    'name','Solution of a non-expensive least-square problem based on a scipy implementation',...
    'study_id', 'scipy_least_squares');
%The vectorial model function of the MGH17 problem
function val = model(x)
    s = 0:32;
    val = x(1) + x(2)*exp(-s.*x(4)) + x(3)*exp(-s.*x(5));
end

%Target vector of the MGH17
target=[8.44E-01, 9.08E-01, 9.32E-01, 9.36E-01, 9.25E-01, ...
 9.08E-01, 8.81E-01, 8.50E-01, 8.18E-01, 7.84E-01, ...
 7.51E-01, 7.18E-01, 6.85E-01, 6.58E-01, 6.28E-01, ...
 6.03E-01, 5.80E-01, 5.58E-01, 5.38E-01, 5.22E-01, ...
 5.06E-01, 4.90E-01, 4.78E-01, 4.67E-01, 4.57E-01, ...
 4.48E-01, 4.38E-01, 4.31E-01, 4.24E-01, 4.20E-01, ...
 4.14E-01, 4.11E-01, 4.06E-01];

study.configure( ...
    'target_vector', target, ...
    'max_iter', 300, ...
    'num_initial', 1, ...
    'method', 'trf' ...
);

% Evaluation of the black-box function for specified design parameters
function observation = evaluate(study, sample)

    observation = study.new_observation();
     %tensor of design values to reconstruct
    x = [sample.b1, sample.b2, sample.b3, sample.b4, sample.b5];    
    observation.add(model(x));
    
end  

% Run the minimization
study.set_evaluator(@evaluate);
study.run(); 

best_sample = study.driver.best_sample;
min_chisq = study.driver.min_objective;
uncertainties = study.driver.uncertainties;
fprintf("Reconstructed parameters with chi-squared value %e\n", min_chisq);
fns = fieldnames(best_sample);
for i = 1:length(fns)
    fprintf("  %s = %f +/- %f\n", fns{i}, ...
            best_sample.(fns{i}), uncertainties.(fns{i})); 
end

