%% ===== Pack & SAVE all results (models + metrics) =====
% Destination (edit as you like)
out_dir  = fullfile('E:\Lorenzo\Final_results_thesis', 'cp_rank_results');
if ~exist(out_dir,'dir'), mkdir(out_dir); end
stamp    = datestr(now,'yyyymmdd_HHMMSS');
out_name = sprintf('cp_rank_noCV_pairwiseMedoid_%s.mat', stamp);
out_path = fullfile(out_dir, out_name);

% Package results in one struct to avoid workspace clutter
results = struct();

% Meta/config for reproducibility
if exist('BASE_SEED','var'), results.meta.BASE_SEED = BASE_SEED; else, results.meta.BASE_SEED = []; end
results.meta.timestamp   = datestr(now);
results.meta.solver      = solver;
results.meta.opts        = opts;            % struct with tol, maxiters, printitn
results.meta.n_restarts  = n_restarts;
results.meta.R_range     = R_range;

% Fits across restarts
results.train_fit.best = train_fit_best;
results.train_fit.mean = train_fit_mean;
results.train_fit.std  = train_fit_std;

% Stability (FMS to medoid) per rank
results.stability.FMS_mean   = fms_mean;
results.stability.FMS_median = fms_median;
results.stability.FMS_std    = fms_std;
results.stability.FMS_min    = fms_min;
results.stability.FMS_p25    = fms_p25;
results.stability.FMS_p75    = fms_p75;
results.stability.FMS_max    = fms_max;
results.stability.FMS_matrix    = FMS_matrix;     % cell: SxS per R
results.stability.FMS_to_medoid = FMS_to_medoid;  % cell: Sx1 per R

% Diagnostics on medoid
results.collinearity.maxA = collinear_maxA;   results.collinearity.medA = collinear_medA;
results.collinearity.maxB = collinear_maxB;   results.collinearity.medB = collinear_medB;
results.collinearity.maxC = collinear_maxC;   results.collinearity.medC = collinear_medC;
results.duplicate_score   = dup_score;

% Residual structure on medoid
results.residual.frac1_mode1 = res_frac1_mode1;
results.residual.frac1_mode2 = res_frac1_mode2;
results.residual.frac1_mode3 = res_frac1_mode3;
results.residual.time_autoc  = res_time_autoc;

% Representatives and top-10 models per rank
results.models.medoid_per_R = medoid_per_R;   % cell of ktensor
results.models.best10_per_R = best10_per_R;   % cell of 1x<=10 ktensor
results.models.best10_fits  = best10_fits;    % cell of 1x<=10 double

% Save (v7.3 to handle object arrays / big cells)
save(out_path, 'results', '-v7.3');

fprintf('\nSaved all results to:\n  %s\n', out_path);
