function classify_equal_samples()
    % Signal parameters
    Fs = 1000; % Sampling frequency
    t = linspace(0, 1, Fs); % Time vector

    % Define modulation types
    modTypes = {'AM', 'FM', 'PSK', 'ASK', 'FSK'};

    % Number of samples to generate for each modulation type
    n_samples_per_type = 500; 

    % Generate dataset
    [X, y] = generate_dataset(Fs, t, modTypes, n_samples_per_type);

    % Extract features from the signals
    X_features = extract_features(X);

    % Classify signals based on features
    y_pred = classify_signals_refined(X_features);

    % Remove any unknown predictions for consistency
    valid_indices = y_pred > 0;
    y_pred = y_pred(valid_indices);
    y = y(valid_indices);

    % Calculate accuracy
    accuracy = sum(y == y_pred) / length(y) * 100;
    fprintf('Total Accuracy: %.2f%%\n', accuracy);

    % Show the name of given and classified signal for each test case
    fprintf('Signal classification results:\n');
    for i = 1:length(y)
        given_name = get_modulation_name(y(i), modTypes);
        classified_name = get_modulation_name(y_pred(i), modTypes);
        fprintf('Test %d: Given - %s, Classified - %s\n', i, given_name, classified_name);
    end

    % Create the confusion matrix and display it
    cm = confusionmat(y, y_pred);
    figure;
    % Use the modTypes order to label confusion chart
    confusionchart(cm, modTypes, 'Title', 'Confusion Matrix for Equal Sample Test');
end

function signal = generate_am(frequency, modulation_index, carrier_freq, t)
    % Generate Amplitude Modulated signal
    signal = (1 + modulation_index * cos(2 * pi * frequency * t)) .* cos(2 * pi * carrier_freq * t);
end

function signal = generate_fm(frequency, modulation_index, carrier_freq, t)
    % Generate Frequency Modulated signal
    signal = cos(2 * pi * carrier_freq * t + modulation_index * sin(2 * pi * frequency * t));
end

function signal = generate_psk(frequency, phase_shift, t)
    % Generate Phase Shift Keying signal
    signal = cos(2 * pi * frequency * t + phase_shift);
end

function signal = generate_ask(data, carrier_freq, t)
    % Generate Amplitude Shift Keying signal
    signal = (1 + data) .* cos(2 * pi * carrier_freq * t);
end

function signal = generate_fsk(data, f1, f2, t)
    % Generate Frequency Shift Keying signal
    signal = cos(2 * pi * (f1 + (f2 - f1) * data) .* t);
end

function [X, y] = generate_dataset(Fs, t, modTypes, n_samples_per_type)
    X = [];
    y = [];
    for modId = 1:length(modTypes)
        for j = 1:n_samples_per_type
            frequency = rand * (100 - 10) + 10;
            carrier_freq = rand * (200 - 100) + 100;
            switch modTypes{modId}
                case 'AM'
                    mod_index = rand * (1.5 - 0.5) + 0.5;
                    signal = generate_am(frequency, mod_index, carrier_freq, t);
                    label = 1;
                case 'FM'
                    mod_index = rand * (2 - 0.5) + 0.5;
                    signal = generate_fm(frequency, mod_index, carrier_freq, t);
                    label = 2;
                case 'PSK'
                    phase_shift = rand * pi;
                    signal = generate_psk(frequency, phase_shift, t);
                    label = 3;
                case 'ASK'
                    data = randi([0 1], 1, length(t));
                    signal = generate_ask(data, carrier_freq, t);
                    label = 4;
                case 'FSK'
                    data = randi([0 1], 1, length(t));
                    f1 = carrier_freq;
                    f2 = carrier_freq + 50;
                    signal = generate_fsk(data, f1, f2, t);
                    label = 5;
            end
            X = [X; signal];
            y = [y; label];
        end
    end
end

function features = extract_features(X)
    features = zeros(size(X, 1), 6);
    for i = 1:size(X, 1)
        signal = X(i, :);

        % Basic features
        features(i, 1) = mean(signal);
        features(i, 2) = var(signal);
        features(i, 3) = max(abs(signal));

        % Amplitude Envelope
        x_envelope = abs(hilbert(signal));
        features(i, 4) = std(x_envelope);

        % Phase statistics
        phase = unwrap(angle(hilbert(signal)));
        features(i, 5) = std(phase);

        % Frequency statistics
        freqDiff = diff(unwrap(phase));
        features(i, 6) = std(freqDiff);
    end
end

function y_pred = classify_signals_refined(X_features)
    n_samples = size(X_features, 1);
    y_pred = zeros(n_samples, 1);

    for i = 1:n_samples
        sigma_ap = X_features(i, 4);
        sigma_dp = X_features(i, 5);
        sigma_af = X_features(i, 6);

        if sigma_ap > 0.7 && sigma_af > 1.0 && sigma_dp < 200
            y_pred(i) = 1; % AM
        elseif sigma_ap < 0.1 && sigma_dp > 350
            y_pred(i) = 2; % FM
        elseif sigma_ap < 0.1 && sigma_dp < 60
            y_pred(i) = 3; % PSK
        elseif sigma_ap > 0.35 && sigma_ap < 0.45 && sigma_af < 0.3 && sigma_dp < 240
            y_pred(i) = 4; % ASK
        elseif sigma_ap < 0.4 && sigma_af > 0.9
            y_pred(i) = 5; % FSK
        else
            y_pred(i) = -1; % Unknown
        end
    end
end

function mod_name = get_modulation_name(label, modTypes)
    mod_name = modTypes{label};
end

All kinds of signals should be equal in number to 500 also display confusion matrix