%% Clear + Global Data 
clear, close all, clc;

% Load Data
load('data\total_data\conditioned.mat');
load('data\total_data\meta_data.mat');

%% Evaluate All Data for our different types

% Tailored
% ddbd w/ dict          irls
% rand w/ wavelet       bp
% bernoulli w/ dct      bp
% gaussian w/ dct ?     irls



size_subset = 10000;
subset = randperm(size(beats,1), size_subset);
beats_sub = beats(subset, :);
meanBeat = mean(beats_sub,1);

percent_training = 0.50;
use_pod = false;
do_parallel = true;


cr_vals = [2, 3, 4, 5, 7, 10, 15, 20, 25, 50, 60, 100]; % 11/28/22 got through 5
cr_vals = [100];

for i=1:length(cr_vals)

   

    cr = cr_vals(i);
    results.cr = cr;
    results.subset = subset;
    results.size_subset = size_subset;

    fprintf("CR [%d]\n", cr);

    
    tic
    tailored = tailored_sensing(beats_sub', percent_training, cr, meanBeat, use_pod, do_parallel);
    prd = [tailored.eval_stats.prd];
    prd1 = [tailored.eval_stats.prd1];
    fprintf("    Tailored --> Mean/Min/Max PRD/PRD1:   [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
    results.tailored = tailored;
    clear tailored;

    ddbd_dict = compressed_sensing(beats_sub, cr, meanBeat, 'ddbd', 'dict', 'bp', true);
    prd = [ddbd_dict.eval_stats.prd];
    prd1 = [ddbd_dict.eval_stats.prd1];
    fprintf("    DDBD Dict --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
    results.ddbd_dict = ddbd_dict;
    clear ddbd_dict;

    
    ddbd_wave = compressed_sensing(beats_sub, cr, meanBeat, 'ddbd', 'wavlet', 'bp', true);
    prd = [ddbd_wave.eval_stats.prd];
    prd1 = [ddbd_wave.eval_stats.prd1];
    fprintf("    DDBD Wave --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
    results.ddbd_wave = ddbd_wave;
    clear ddbd_wave;

    bern_dct = compressed_sensing(beats_sub, cr, meanBeat, 'bernoulli', 'dct', 'bp', true);
    prd = [bern_dct.eval_stats.prd];
    prd1 = [bern_dct.eval_stats.prd1];
    fprintf("    Bern Dct --> Mean/Min/Max PRD/PRD1:   [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
    results.bern_dct = bern_dct;
    clear bern_dct;

    gauss_dct = compressed_sensing(beats_sub, cr, meanBeat, 'gauss', 'dct', 'bp', true);
    prd = [gauss_dct.eval_stats.prd];
    prd1 = [gauss_dct.eval_stats.prd1];
    fprintf("    Gauss Dct --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
    results.gauss_dct = gauss_dct;
    clear gauss_dct;

    save(strcat('data\results\', num2str(cr), '.mat'), 'results');

    clear results;


    clear prd;
    clear prd1;

    toc

end

%% Perform for each beat type

load('data\total_data\per_beat\beat_map.mat')

cr_vals = [2, 3, 4, 5, 7, 10, 15, 20, 25, 50, 60, 100];
percent_training = 0.50;
use_pod = false;
do_parallel = true;

% start_j = 1;
start_j = 16;     % Completed all but the last one

for j=start_j:length(beat_map)

    cur_beat = load(strcat(beat_map(j).path, '\conditioned.mat'));
    cur_beat = cur_beat.filt_beats;

    beat_str = get_beat_type(beat_map(j).type);
    fprintf("[%s]\n", beat_str);

    if(size(cur_beat, 1) < 200)
        fprintf('    Too Few Beats for [%s] --> [%d]\n', beat_str, size(cur_beat, 1));
    else

        size_subset = min(10000, size(cur_beat, 1));
        subset = randperm(size(cur_beat,1), size_subset);
        beats_sub = cur_beat(subset, :);
        meanBeat = mean(beats_sub,1);

        abbvr = cellfun(@(c) lower(c(1)), strsplit(beat_str));
        res_dir = strcat('data\results\per_beat\', abbvr);
        if ~exist(res_dir, 'dir')
            mkdir(res_dir);
        end

        beat_label_2(j).path = res_dir;
        beat_label_2(j).type = beat_map(j).type;
        beat_label_2(j).abbvr = abbvr;

        for i=1:length(cr_vals)

            cr = cr_vals(i);
            results.cr = cr;
            results.subset = subset;
            results.size_subset = size_subset;
        
            fprintf("    CR [%d]\n", cr);
        
            
            tic
            tailored = tailored_sensing(beats_sub', percent_training, cr, meanBeat, use_pod, do_parallel);
            prd = [tailored.eval_stats.prd];
            prd1 = [tailored.eval_stats.prd1];
            fprintf("    Tailored --> Mean/Min/Max PRD/PRD1:   [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
            results.tailored = tailored;
            clear tailored;
        
            ddbd_dict = compressed_sensing(beats_sub, cr, meanBeat, 'ddbd', 'dict', 'bp', true);
            prd = [ddbd_dict.eval_stats.prd];
            prd1 = [ddbd_dict.eval_stats.prd1];
            fprintf("    DDBD Dict --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
            results.ddbd_dict = ddbd_dict;
            clear ddbd_dict;
        
            
            ddbd_wave = compressed_sensing(beats_sub, cr, meanBeat, 'ddbd', 'wavlet', 'bp', true);
            prd = [ddbd_wave.eval_stats.prd];
            prd1 = [ddbd_wave.eval_stats.prd1];
            fprintf("    DDBD Wave --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
            results.ddbd_wave = ddbd_wave;
            clear ddbd_wave;
        
            bern_dct = compressed_sensing(beats_sub, cr, meanBeat, 'bernoulli', 'dct', 'bp', true);
            prd = [bern_dct.eval_stats.prd];
            prd1 = [bern_dct.eval_stats.prd1];
            fprintf("    Bern Dct --> Mean/Min/Max PRD/PRD1:   [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
            results.bern_dct = bern_dct;
            clear bern_dct;
        
            gauss_dct = compressed_sensing(beats_sub, cr, meanBeat, 'gauss', 'dct', 'bp', true);
            prd = [gauss_dct.eval_stats.prd];
            prd1 = [gauss_dct.eval_stats.prd1];
            fprintf("    Gauss Dct --> Mean/Min/Max PRD/PRD1:  [%f] [%f] [%f] - [%f] [%f] [%f]\n", mean(prd), min(prd), max(prd), mean(prd1), min(prd1), max(prd1));
            results.gauss_dct = gauss_dct;
            clear gauss_dct;

            
            % Save Results
            res_file = strcat(res_dir, '\', num2str(cr), '.mat');
            save(res_file, "results");

            toc

            clear results;
        end
        clear size_subset;
        clear subset;
        clear beats_sub; 
        clear meanBeat;
    end
    clear cur_beat;
end

save('data\results\per_beat\beat_label.mat', 'abbvr');



