Hello James,
I understand that you're looking to determine the bandwidth of a signal using various definitions. However, there are a few corrections needed in your code.
The signal `Gx` should be evaluated across a spectrum of frequencies, not solely at `f = 446000`. Therefore, the way `Gx(f)` is defined in your code does not align with MATLAB's syntax. You'll need to define `Gx` as an anonymous function or within a function file to cover the desired frequency range. Moreover, the `power_bw` function is intended to identify both the lower and upper frequency limits that encompass a specified percentage of the signal's power. Additionally, when calculating `null_to_null_bw`, searching for exact zeros in `Gf` may lead to inaccuracies due to the discrete nature of the data. It's more reliable to detect zero crossings by observing sign changes in `Gf`.
Below, I've provided a revised version of the code that addresses these issues and assists you in accurately calculating the bandwidth.
clc
clear all
% Define the frequency range
f = linspace(0, 2e6, 10000); % 0 to 2 MHz with 10000 points
% Define Gx as an anonymous function
Gx = @(f) 10^-4 * (sin(pi*(f-10^6)*10^-4) ./ (pi*(f-10^6)*10^-4));
% Evaluate Gx over the frequency range
Gf = Gx(f);
hp_bw = half_power_bw(f, Gf);
nn_bw = null_to_null_bw(f, Gf);
p99_bw = power_bw(f, Gf, 0.99);
att35_bw = attenuation_bw(f, Gf, 35);
% Display the results
fprintf('Half-power bandwidth: %f Hz\n', hp_bw);
fprintf('Null-to-null bandwidth: %f Hz\n', nn_bw);
fprintf('99%% of power bandwidth: %f Hz\n', p99_bw);
fprintf('Bandwidth beyond which the attenuation is 35 dB: %f Hz\n', att35_bw);
% Local function definitions:
function Bw = half_power_bw(f, Gf)
[~,imax] = max(abs(Gf));
i_half_lower = find(abs(Gf(1:imax)) < abs(Gf(imax))/sqrt(2), 1, 'last');
i_half_upper = find(abs(Gf(imax:end)) < abs(Gf(imax))/sqrt(2), 1, 'first') + imax - 1;
Bw = f(i_half_upper) - f(i_half_lower);
end
function Bw = null_to_null_bw(f, Gf)
% Find sign changes in Gf which indicate a null has been crossed
sign_changes = find(diff(sign(Gf)) ~= 0);
% If there are no sign changes, then there are no nulls
if isempty(sign_changes)
Bw = 0;
return;
end
% Assuming the first and last sign changes correspond to the first and last nulls
i_null_lower = sign_changes(1);
i_null_upper = sign_changes(end);
% Calculate the null-to-null bandwidth
Bw = f(i_null_upper) - f(i_null_lower);
end
function Bw = power_bw(f, Gf, power_fraction)
total_power = trapz(f, abs(Gf).^2);
power_integral = cumtrapz(f, abs(Gf).^2);
lower_idx = find(power_integral >= total_power*(1-power_fraction)/2, 1, 'first');
upper_idx = find(power_integral >= total_power*(1+power_fraction)/2, 1, 'first');
Bw = f(upper_idx) - f(lower_idx);
end
function Bw = attenuation_bw(f, Gf, attenuation_dB)
attenuation_linear = 10^(-attenuation_dB/20);
i_attenuation = find(abs(Gf) < abs(max(Gf))*attenuation_linear, 1, 'first');
Bw = f(i_attenuation);
end
Kindly have a look at the following documentation links to have more information on:
- 'functions' in MATLAB: https://www.mathworks.com/help/matlab/ref/function.html
- 'trapz' function: https://www.mathworks.com/help/matlab/ref/trapz.html
Hope this helps!
Balavignesh