Bagian penting dalam mendapatkan Filter Kalman agar berfungsi dengan baik adalah menyetel matriks kovariansi gangguan proses Q dan matriks kovariansi gangguan pengukuran R. Tulisan ini adalah tentang memperoleh matriks R, dan tulisan tentang matriks Q akan segera hadir.
Pada postingan terakhir saya tentang versi alternatif filter kalman yang diperluas untuk memodelkan gelombang sinus saya menjelaskan bahwa 4 pengukuran adalah nilai gelombang sinus itu sendiri, dan fase, frekuensi sudut dan amplitudo gelombang sinus. Fase dan frekuensi sudut “diukur” menggunakan output dari indikator gelombang sinus dan amplitudonya dihitung sebagai RMS nilai selama periode yang diukur. “Masalah” dengan ini adalah bahwa keakuratan pengukuran tersebut pada data nyata tidak diketahui, dan oleh karena itu matriks R juga tidak diketahui, karena sifat siklus yang mendasarinya tidak diketahui. Solusi saya untuk ini adalah offline Monte Carlo simulasi.
Sebagai langkah pertama, Oktaf kode di kotak tepat di bawah ini
clear all ;
pkg load statistics ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load data
raw_data = dlmread( 'raw_data_for_indices_and_strengths' ) ;
delete_hkd_crosses = [ 3 9 12 18 26 31 34 39 43 51 61 ] .+ 1 ; % +1 to account for date column
raw_data( : , delete_hkd_crosses ) = [] ;
raw_data( : , 1 ) = [] ; % delete data vector
all_g_c = dlmread( "all_g_mults_c" ) ; % the currency g mults
all_g_c( : , 7 ) = [] ; % delete hkd index
all_g_s = dlmread( "all_g_sv" ) ; % the gold and silver g mults
all_g_c = [ all_g_c all_g_s(:,2:3) ] ; % a combination of the above 2
all_g_c( : , 2 : end ) = cumprod( all_g_c( : , 2 : end) , 1 ) ;
all_g_c( : , 1 ) = [] ; % delete date vector
all_raw_data = [ raw_data all_g_c ] ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% set up recording vectors
amplitude = zeros( size( all_raw_data , 1 ) , 1 ) ;
all_amplitudes = zeros( size( all_raw_data ) ) ;
all_periods = all_amplitudes ;
for ii = 1 : size( all_raw_data , 2 )
price = all_raw_data( : , ii ) ;
period = autocorrelation_periodogram( price ) ;
all_periods( : , ii ) = period ;
[ hp , ~ ] = highpass_filter_basic( price ) ; hp( 1 : 99 ) = 0 ;
for jj = 100 : size( all_raw_data , 1 )
amplitude( jj ) = sqrt( 2 ) * sqrt( mean( hp( round( jj - period( jj ) / 2 ) : jj , 1 ).^2 ) ) ;
endfor
% store information about amplitude changes as a multiplicative constant
all_amplitudes( : , ii ) = amplitude ./ shift( amplitude , 1 ) ;
endfor
% truncate
all_amplitudes( 1 : 101 , : ) = [] ;
all_periods( 1 : 101 , : ) = [] ;
max_period = max( max( all_periods ) ) ;
min_period = min( min( all_periods ) ) ;
% unroll
all_amplitudes = all_amplitudes( : ) ; all_periods = all_periods( : ) ;
amplitude_changes = cell( max_period , 1 ) ;
for ii = min_period : max_period
ix = find( all_periods == ii ) ;
amplitude_changes{ ii , 1 } = all_amplitudes( ix , 1 ) ;
endfor
save all_amplitude_changes amplitude_changes ;
digunakan untuk mendapatkan informasi tentang amplitudo siklus dari data nyata dan menyimpannya dalam array sel.
Kotak berikutnya menunjukkan kode yang menggunakan array sel ini, ditambah kode sebelumnya kode pemodelan markov tersembunyi untuk pemodelan gelombang sinus, untuk menghasilkan data harga sintetis
clear all ;
pkg load signal ;
pkg load statistics ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load data
raw_data = dlmread( 'raw_data_for_indices_and_strengths' ) ;
delete_hkd_crosses = [ 3 9 12 18 26 31 34 39 43 51 61 ] .+ 1 ; % +1 to account for date column
raw_data( : , delete_hkd_crosses ) = [] ;
raw_data( : , 1 ) = [] ; % delete date vector
all_g_c = dlmread( "all_g_mults_c" ) ; % the currency g mults
all_g_c( : , 7 ) = [] ; % delete hkd index
all_g_s = dlmread( "all_g_sv" ) ; % the gold and silver g mults
all_g_c = [ all_g_c all_g_s(:,2:3) ] ; % a combination of the above 2
all_g_c( : , 2 : end ) = cumprod( all_g_c( : , 2 : end) , 1 ) ;
all_g_c( : , 1 ) = [] ; % delete date vector
all_raw_data = [ raw_data all_g_c ] ; clear -x all_raw_data ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
load all_hmm_periods_daily ;
load all_amplitude_changes ;
% choose an ix for all_raw_data
ix = input( "ix? " ) ;
price = all_raw_data( : , ix ) ;
period = autocorrelation_periodogram( price ) ;
[ hp , trend ] = highpass_filter_basic( price ) ;
% estimate variance of cycle noise
hp_filt = sgolayfilt( hp , 2 , 7 ) ;
noise = hp( 101 : end ) .- hp_filt( 101 : end ) ; noise_var = var( noise ) ;
% zero pad beginning of noise vector
noise = [ zeros( 100 , 1 ) ; noise ] ;
% set for plotting purposes
hp( 1 : 50 ) = 0 ; trend( 1 : 50 ) = price( 1 : 50 ) ;
% create sine wave with known phase and period/angular frequency
[ gen_period , ~ ] = hmmgenerate( length( price ) , transprobest , outprobest ) ;
gen_period = gen_period .+ hmm_min_period_add ;
phase = cumsum( ( 2 * pi ) ./ gen_period ) ; phase = mod( phase , 2 * pi ) ;
gen_sine = sin( phase ) ;
% amplitude vector
amp = ones( size( hp ) ) ;
% RMS initial amplitude
amp( 100 ) = sqrt( 2 ) * sqrt( mean( hp( 100 - period( 100 ) : 100 ).^2 ) ) ;
% alter sine wave with known amplitude
for ii = 101 : length( hp )
% get multiple for this period
random_amp_mults = amplitude_changes{ gen_period( ii ) } ;
rand_mult = random_amp_mults( randi( size( random_amp_mults , 1 ) , 1 ) ) ;
amp( ii ) = rand_mult * sqrt( 2 ) * sqrt( mean( hp( ii - 1 - period( ii - 1 ) : ii - 1 ).^2 ) ) ; ;
gen_sine( ii ) = amp( ii ) * gen_sine( ii ) ;
endfor
% estimate variance of generated cycle noise
gen_filt = sgolayfilt( gen_sine , 2 , 7 ) ;
gen_noise = gen_sine( 101 : end ) .- gen_filt( 101 : end ) ; gen_noise_var = var( gen_noise ) ;
% a crude adjustment of generated cycle noise to match "real" noise by adding
% noise
gen_sine = gen_sine' .+ noise ;
% set beginning of gen_sine to real cycle for plotting purposes
gen_sine( 1 : 100 ) = hp( 1 : 100 ) ;
new_price = trend .+ gen_sine ;
% a simple correlation check
correlation_cycle_gen_sine = corr( hp , gen_sine ) ;
correlation_price_gen_price = corr( price , new_price ) ;
figure(1) ; plot( gen_sine , 'k' , 'linewidth' , 2 ) ; grid minor on ; title( 'The Generated Cycle' ) ;
figure(2) ; plot( price , 'b' , 'linewidth' , 2 , trend , 'k' , 'linewidth' , 1 , new_price , 'r' , 'linewidth', 2 ) ;
title( 'Comparison of Real and Generated Prices' ) ; legend( 'Real Price' , 'Real Trend' , 'Generated Price' ) ; grid minor on ;
figure(3) ; plot( hp , 'k' , 'linewidth' , 2 , gen_sine , 'r' , 'linewidth' , 2 ) ; title( 'Generated Cycle compared with Real Cycle' ) ;
legend( 'Real Cycle' , 'Generated Cycle' ) ; grid minor on ;
Beberapa keluaran grafik khas dari kode ini adalah seri harga sintetis berwarna merah dibandingkan dengan seri harga biru sebenarnya
dan siklus yang mendasarinya.
Untuk lari khusus ini, korelasi antara rangkaian harga sintetis dan rangkaian harga riil adalah 0.99331, sementara korelasi antara siklus relevan hanya 0.19988, lebih dari 1500 titik data (tidak semuanya ditunjukkan dalam grafik di atas).
Karena siklus sintetisnya jelas merupakan gelombang sinus (berdasarkan konstruksi) dengan fase, frekuensi sudut, dan amplitudo yang diketahui, saya dapat menjalankan pengukuran sinewave_indicator dan RMS di atas pada harga sintetis, membandingkannya dengan siklus sintetis yang diketahui, dan memperkirakan matriks kovariansi gangguan pengukuran R.
Akan ada informasi lebih lanjut pada waktunya.