annotate multi_freq_ddm_int_test_1.m @ 4:72c011ed1977 tip

more elaborate example with non-stat. estimate explanation
author smusevic
date Tue, 30 Jul 2013 09:56:27 +0100
parents a4a7e3405062
children
rev   line source
dan@0 1 % multi_freq_ddm_int tests..
dan@0 2 N = 2^10-1;
dan@0 3 N_fft = 2^12-1;
dan@0 4
dan@0 5 fs = 44100;
dan@0 6
dan@0 7 dsc_idxs = ([-(N-1)/2:(N-1)/2]);
dan@0 8
dan@0 9 frqs_fft = [0:N_fft-1]*fs/N_fft;
dan@0 10
dan@0 11 the_frq = 416;
dan@0 12 the_fm1 = 7000;
dan@0 13 the_ph = 0.2;
dan@0 14 the_amp = 0.1;
dan@0 15 pk_offst_rt = 0.01;
dan@0 16 %frqs = [438,442.5] * 2 *pi; % as many frequencies as desired...
dan@0 17 fft_bin_hz = fs/N_fft;
dan@0 18 t = [-(N-1)/2:(N-1)/2]/fs;
dan@0 19 % monomials matlab style...
dan@0 20 ply_len = 2;
dan@0 21 mdl_poly = flipud(diag(ones(ply_len+1,1))); % vector of polynomials
dan@0 22 mdl_poly_der = zeros(size(mdl_poly));% vector of time derivated polynomials
dan@0 23
dan@0 24 % the actual time domain values of time derivated polynomials
dan@0 25 mdl_poly_der_vals = zeros(N,size(mdl_poly,1));
dan@0 26
dan@0 27 % window and time derivated window...
dan@0 28 w = 0.5+0.5*cos(2*pi*dsc_idxs/(N-1));
dan@0 29 w_d = -pi*fs/(N-1)*sin(2*pi*dsc_idxs/(N-1));
dan@0 30 w = w(:);
dan@0 31 w_d = w_d(:);
dan@0 32
dan@0 33 % calculate time domain plys...
dan@0 34 for k = 1:size(mdl_poly,1)
dan@0 35 pp = polyder(mdl_poly(k,:));
dan@0 36 mdl_poly_der(k,:) = [zeros(1,ply_len+1-size(pp,2)) pp ];
dan@0 37 mdl_poly_der_vals(:,k) = polyval( mdl_poly_der(k,:),t);
dan@0 38 end
dan@0 39
dan@0 40 mdl_poly_der_vals = mdl_poly_der_vals(:,2:end);
dan@0 41
dan@0 42 sig_r = real(exp(the_amp+1j*(the_fm1*t.^2 + t*the_frq*2*pi + the_ph*pi))).';
dan@0 43 %sig = hilbert(sig_r);
dan@0 44 sig = sig_r;
dan@0 45
dan@0 46 [id_s id_e ] = zpzh_idxs(N);
dan@0 47 sig_zp = sig .* w;
dan@0 48 sig_zp = [sig_zp(id_s);zeros(N_fft-N,1);sig_zp(id_e)];
dan@0 49
dan@0 50 sig_fft = fft(sig_zp, N_fft);
dan@0 51 [pk_vl,pk_idx] = max(abs(sig_fft));
dan@0 52 pk_frq_hz = (pk_idx - 1) * fs / N_fft;
dan@0 53 %pk_offst_rt = (fft_bin_hz/the_frq);
dan@0 54 %frqs_test = [pk_frq_hz*(1 - pk_offst_rt),pk_frq_hz, pk_frq_hz*(1 + pk_offst_rt)] * 2 *pi; % as many frequencies as desired...
dan@0 55 frqs_test = [pk_idx - 2, pk_idx - 1, pk_idx ] * 2 * pi * fs / N_fft;
dan@0 56 %frqs_test = [pk_idx - 0.5, pk_idx - 1.5, pk_idx ] * 2 * pi * fs / N_fft;
dan@0 57
dan@0 58
dan@0 59 [fks fks_drs] = fourier_kernel_win(frqs_test, N, fs, w, w_d);
dan@0 60 [gdi, A, b,gdi_lns,r_lns] = ...
dan@0 61 gen_ddm_int(fks, fks_drs, mdl_poly_der_vals, sig, N, 0);
dan@0 62
dan@0 63 errs = A(:,1) - sig_fft(pk_idx-1:pk_idx+1);
dan@0 64 assert( sum(errs < (1 + 1j) * 10^(-11)) == 3);
dan@0 65
dan@0 66 %gdi = gdi_lns;
dan@0 67
dan@0 68 err_rel_frq_log = log10(abs((imag(gdi(1)) / 2 / pi - the_frq)/(imag(gdi(1)) / 2 / pi) ));
dan@0 69 err_rel_fm1_log = log10(abs((imag(gdi(2)) - the_fm1) / imag(gdi(2)) ));
dan@0 70 assert(err_rel_frq_log < -3);
dan@0 71 assert(err_rel_fm1_log < -2);
dan@0 72 real(gdi(1))
dan@0 73 real(gdi(2))
dan@0 74 ply_est = fliplr(gdi.');
dan@0 75 frq_est = imag(ply_est(end));
dan@0 76 the_fm1
dan@0 77 imag(ply_est(end-1))
dan@0 78 frq_est/2/pi
dan@0 79 %ply_est(end) = real(ply_est(end)) + 1j*(imag(ply_est(end)) - the_frq);
dan@0 80 ply_est(end) = real(ply_est(end)); % hm....
dan@0 81 wmp = win_mod_poly(N, t, [ply_est 0], w);
dan@0 82
dan@0 83 % this creates a bias but it's fast...
dan@0 84
dan@0 85 krnl_dmd = exp(1j * frq_est * t');
dan@0 86 dtft_dmd = sum(w .* sig .* conj(krnl_dmd),1);
dan@0 87 r0 = dtft_dmd / wmp;
dan@0 88 err_rel_amp_log = log10(abs((abs(r0)*2 - exp(the_amp)) / exp(the_amp)) )
dan@0 89 err_rel_phs_log = log10(abs((angle(r0) / pi - the_ph)/the_ph));
dan@0 90
dan@0 91 assert(err_rel_amp_log < -2);
dan@0 92 sprintf('%15.15f', (angle(r0) / pi-the_ph) )
dan@0 93
dan@0 94
dan@0 95
dan@0 96
dan@0 97
dan@0 98 %% plots
dan@0 99 figure(3);clf;
dan@0 100 subplot(211);
dan@0 101 hold on;
dan@0 102 plot(frqs_fft,abs(sig_fft),'.k-');
dan@0 103 plot(frqs_test'/2/pi,abs(A(:,1)),'r*');
dan@0 104 subplot(212);
dan@0 105 hold on
dan@0 106 plot(frqs_fft,angle(sig_fft),'.k-');
dan@0 107 plot(frqs_test'/2/pi,angle(A(:,1)),'r*');
dan@0 108
dan@0 109 display('tests completed successfully!');
dan@0 110 display('accuracy:');
dan@0 111 display([ ' frq: ' num2str(err_rel_frq_log)]);
dan@0 112 display([ ' amp: ' num2str(err_rel_amp_log)]);
dan@0 113 display([ ' fm1: ' num2str(err_rel_fm1_log)]);
dan@0 114 display([ ' phs: ' num2str(err_rel_phs_log)]);
dan@0 115 display([ ' rcond: ' num2str(r_lns)]);
dan@0 116
dan@0 117