function smoothed_probs = smooth_bin_probabilities_adaptive(bin_probs, window_size, sigma_min, sigma_max)
% Smooths a probability vector using a Gaussian kernel with adaptive sigma.
% 
% Inputs:
%   bin_probs  - Input probability vector (e.g., bin-wise probabilities)
%   window_size - Size of Gaussian kernel (must be odd)
%   sigma_min  - Minimum kernel width (for smooth inputs)
%   sigma_max  - Maximum kernel width (for rough inputs)

    if mod(window_size, 2) == 0
        error('Window size must be odd.');
    end

    % --- Compute roughness: sum of squared second differences ---
    second_diff = diff(bin_probs, 2);              % Approximate second derivative
    roughness = sum(second_diff.^2);               % Total roughness measure

    % --- Normalize roughness to [0,1] scale via soft thresholding ---
    % Use a robust baseline so noise doesn't over-amplify smoothing
    eps = 1e-6;
    norm_rough = (roughness / (roughness + 1e-6))^0.5;%;roughness / (roughness + eps);    % Normalized to [0,1]

    % --- Map normalized roughness to adaptive sigma ---
    sigma = sigma_min + (sigma_max - sigma_min) * norm_rough;

    % --- Create Gaussian kernel with adaptive sigma ---
    half_width = (window_size - 1) / 2;
    x = -half_width:half_width;
    gauss_kernel = exp(-0.5 * (x / sigma).^2);
    gauss_kernel = gauss_kernel / sum(gauss_kernel);  % Normalize

    % --- Smooth via convolution ---
    smoothed_probs = conv(bin_probs, gauss_kernel, 'same');

    % --- Re-normalize to ensure valid probability vector ---
    smoothed_probs = max(smoothed_probs, 0);
    smoothed_probs = smoothed_probs / sum(smoothed_probs);
end