Small shift in frequency in FFT
Your vector

t = linspace(0, T, num_samples);

is the problem. It should be

t = (0:num_samples-1)/fs;

Note that, even though you claim it in a comment in the code, in the current version, dt = t(2) - t(1); is not equal to 1/f_s.