├── .gitignore ├── ECDF.m ├── include ├── Distributions │ ├── MEX │ │ ├── my_tinv.mexw32 │ │ ├── my_tinv.mexw64 │ │ ├── dmvgt_mex.mexw32 │ │ ├── dmvgt_mex.mexw64 │ │ ├── my_norminv.mexw32 │ │ ├── my_norminv.mexw64 │ │ ├── my_norminv.c │ │ ├── my_tinv.c │ │ └── dmvgt_mex.c │ ├── t_dens_uni.m │ ├── fn_partition_ends.m │ ├── skewed_t.m │ ├── correl_mat.m │ ├── duvt.m │ ├── t_mv_pdf.m │ ├── bi_copula_n_rnd.m │ ├── bi_copula_t_rnd.m │ ├── duvt_garch.m │ ├── rmvt.m │ ├── rmvgt2.m │ ├── rmvgt.m │ ├── dmvt.m │ ├── dmvgt.m │ └── fn_rmvgt_robust.m ├── Data │ ├── data note.txt │ └── GSPC_ret_updated.csv ├── Models │ ├── MEX │ │ ├── loglik_gen_gas_mex.mexa64 │ │ ├── loglik_gen_gas_mex.mexw32 │ │ ├── loglik_gen_gas_mex.mexw64 │ │ ├── posterior_gen_gas_mex.mexa64 │ │ ├── posterior_gen_gas_mex.mexw32 │ │ ├── volatility_t_gas_mex.mexa64 │ │ ├── volatility_t_gas_mex.mexw32 │ │ ├── volatility_t_gas_mex.mexw64 │ │ ├── loglik_gen_copula_gas_mex.mexa64 │ │ ├── loglik_gen_copula_gas_mex.mexw32 │ │ ├── loglik_gen_copula_gas_mex.mexw64 │ │ ├── posterior_t_gas_hyper_mex.mexa64 │ │ ├── posterior_t_gas_hyper_mex.mexw32 │ │ ├── posterior_t_gas_hyper_mex.mexw64 │ │ ├── volatility_t_garch_noS_mex.mexa64 │ │ ├── volatility_t_garch_noS_mex.mexw32 │ │ ├── volatility_t_garch_noS_mex.mexw64 │ │ ├── loglik_t_gas_hyper_init_mex.mexa64 │ │ ├── loglik_t_gas_hyper_init_mex.mexw32 │ │ ├── loglik_t_gas_hyper_init_mex.mexw64 │ │ ├── posterior_t_garch_noS_hyper_mex.mexa64 │ │ ├── posterior_t_garch_noS_hyper_mex.mexw32 │ │ ├── posterior_t_garch_noS_hyper_mex.mexw64 │ │ ├── posterior_t_gas_hyper_init_mex.mexa64 │ │ ├── posterior_t_gas_hyper_init_mex.mexw32 │ │ ├── posterior_t_gas_hyper_init_mex.mexw64 │ │ ├── loglik_t_garch_noS_hyper_init_mex.mexa64 │ │ ├── loglik_t_garch_noS_hyper_init_mex.mexw32 │ │ ├── loglik_t_garch_noS_hyper_init_mex.mexw64 │ │ ├── posterior_t_garch_noS_hyper_init_mex.mexa64 │ │ ├── posterior_t_garch_noS_hyper_init_mex.mexw32 │ │ ├── posterior_t_garch_noS_hyper_init_mex.mexw64 │ │ ├── volatility_t_garch_noS_mex.c │ │ ├── volatility_t_gas_mex.c │ │ ├── loglik_t_garch_noS_hyper_init_mex.c │ │ ├── loglik_t_gas_hyper_init_mex.c │ │ ├── posterior_t_gas_hyper_mex.c │ │ ├── posterior_t_gas_hyper_init_mex.c │ │ ├── loglik_gen_gas_mex.c │ │ ├── posterior_t_garch_noS_hyper_mex.c │ │ ├── posterior_t_garch_noS_hyper_init_mex.c │ │ ├── posterior_gen_gas_mex.c │ │ └── loglik_gen_copula_gas_mex.c │ ├── transformation │ │ ├── jacobian_gas_copula.m │ │ ├── jacobian_garch.m │ │ ├── jacobian_gas.m │ │ ├── transform_param_gas_copula.m │ │ ├── transform_param_garch.m │ │ └── transform_param_gas.m │ ├── posterior_gas_init.m │ ├── volatility_t_garch_noS.m │ ├── predict_t_garch_noS.m │ ├── predict_t_gas.m │ ├── volatility_copula_gas.m │ ├── loglik_copula_gas2.m │ ├── posterior_gas.m │ ├── loglik_copula_gas.m │ ├── loglik_copula_t_gas.m │ ├── loglik_copula_t_gas2.m │ ├── posterior_t_garch_noS.m │ ├── loglik_t_gas.m │ ├── posterior_t_gas.m │ └── loglik_gen_gas.m └── MitISEM │ ├── Mit_MH.m │ ├── fn_initopt.m │ └── fn_MH.m ├── skewed_t_sampling.m ├── Exercises ├── Correl_mat.m ├── t_mv_pdf.m ├── Combining_arbitrary_marignals3.m ├── Combining_arbitrary_marignals2.m ├── Contour_plots.m └── Combining_arbitrary_marignals.m ├── estimate.m ├── README.md ├── loglik_t_copula.m ├── speed_check.m ├── simulate_copula_implicit.m ├── Grouped_t_copula.m ├── simulate_copula_ss.m ├── simulate_copula_gas.m ├── copula_gas.m └── marginals.m /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | *.png 3 | *.mat 4 | *.jpg 5 | *.fig 6 | *.doc 7 | *.eps 8 | RL_code/ 9 | KLS/ -------------------------------------------------------------------------------- /ECDF.m: -------------------------------------------------------------------------------- 1 | function p = ECDF(y) 2 | [~, ind] = sort(y); 3 | [~,p] = sort(ind); 4 | p = p/(T+1); 5 | end -------------------------------------------------------------------------------- /include/Distributions/MEX/my_tinv.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/my_tinv.mexw32 -------------------------------------------------------------------------------- /include/Distributions/MEX/my_tinv.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/my_tinv.mexw64 -------------------------------------------------------------------------------- /include/Distributions/MEX/dmvgt_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/dmvgt_mex.mexw32 -------------------------------------------------------------------------------- /include/Distributions/MEX/dmvgt_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/dmvgt_mex.mexw64 -------------------------------------------------------------------------------- /include/Data/data note.txt: -------------------------------------------------------------------------------- 1 | Daily returns on IBM and Coca Cola from January 1990 to December 1999, from A. Patton's copula toolbox for Matlab -------------------------------------------------------------------------------- /include/Distributions/MEX/my_norminv.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/my_norminv.mexw32 -------------------------------------------------------------------------------- /include/Distributions/MEX/my_norminv.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Distributions/MEX/my_norminv.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_gas_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_gas_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_gas_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_gas_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_gas_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_gas_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_gen_gas_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_gen_gas_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_gen_gas_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_gen_gas_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_gas_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_gas_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_gas_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_gas_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_gas_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_gas_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_copula_gas_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_copula_gas_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_copula_gas_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_copula_gas_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_gen_copula_gas_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_gen_copula_gas_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_garch_noS_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_garch_noS_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_garch_noS_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_garch_noS_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_garch_noS_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/volatility_t_garch_noS_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_gas_hyper_init_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_gas_hyper_init_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_gas_hyper_init_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_gas_hyper_init_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_gas_hyper_init_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_gas_hyper_init_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_init_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_init_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_init_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_init_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_init_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_gas_hyper_init_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.mexw64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexa64 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexw32 -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborowska/Copulas/HEAD/include/Models/MEX/posterior_t_garch_noS_hyper_init_mex.mexw64 -------------------------------------------------------------------------------- /include/Distributions/t_dens_uni.m: -------------------------------------------------------------------------------- 1 | function d = t_dens_uni(x,nu) 2 | c1 = gamma((nu+1)/2); 3 | c2 = sqrt(nu*pi); 4 | c3 = gamma(nu/2); 5 | e = -(nu+1)/2; 6 | c = c1/(c2*c3); 7 | d = c.*(1 + (x.^2)./nu).^e; 8 | end -------------------------------------------------------------------------------- /include/Distributions/fn_partition_ends.m: -------------------------------------------------------------------------------- 1 | function [s1, s2] = fn_partition_ends(partition, d, s) 2 | s1 = partition(s); 3 | S = length(partition); 4 | if s < S 5 | s2 = partition(s+1)-1; 6 | else 7 | s2 = d; 8 | end 9 | end -------------------------------------------------------------------------------- /skewed_t_sampling.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | N = 2000; 4 | d = 2; 5 | rho = 0.8; 6 | Sigma = correl_mat(rho); 7 | df = 5; 8 | gam = [0.8 0]; 9 | 10 | C = chol(Sigma); 11 | X = randn(N,d); 12 | X = X*C; 13 | 14 | W = df./chi2rnd(df,N,1); 15 | X = bsxfun(@times,X,sqrt(W)); 16 | Xsk = bsxfun(@plus,X,gam*W); 17 | hold on 18 | scatter(X(:,1),X(:,2),'.') 19 | scatter(Xsk(:,1),Xsk(:,2),'r.') 20 | hold off -------------------------------------------------------------------------------- /include/Distributions/skewed_t.m: -------------------------------------------------------------------------------- 1 | function val = skewed_t(z,nu,lambda) 2 | % z = -2:0.01:2; 3 | % nu = 3; 4 | % lambda = 0; 5 | C = gamma((nu+1)/2)/(gamma(nu/2)*sqrt(pi*(nu-2))); 6 | A = 4*lambda*C*(nu-2)/(nu-1); 7 | B = sqrt(1+3*lambda^2-A^2); 8 | 9 | val = ((B.*z+A)./(1+sign(z+A/B).*lambda)).^2; 10 | val = val./(nu-2); 11 | val = B*C*(1+val).^(-(nu+1)/2); 12 | end 13 | 14 | figure(11) 15 | plot(z,val) 16 | 17 | hold on 18 | plot(z,tpdf(z,nu),'r') 19 | hold off 20 | -------------------------------------------------------------------------------- /Exercises/Correl_mat.m: -------------------------------------------------------------------------------- 1 | function Rho = Correl_mat(rhos) 2 | % create a dxd correlation matrix from a (d*(d-1)/2)x1 vector 3 | [m,n] = size(rhos); 4 | rhos = reshape(rhos,m*n,1); 5 | m = m*n; 6 | d = (1 + sqrt(1+8*m))/2; 7 | if mod(d,1)~=0 % not an integer 8 | error('Input vecor of inccorect size.') 9 | else 10 | Rho = triu(ones(d),1)'; 11 | Rho(Rho==1) = rhos; 12 | Rho = Rho + Rho' + diag(ones(d,1)); 13 | end 14 | end -------------------------------------------------------------------------------- /include/Distributions/correl_mat.m: -------------------------------------------------------------------------------- 1 | function Rho = correl_mat(rhos) 2 | % create a dxd correlation matrix from a (d*(d-1)/2)x1 vector 3 | [m,n] = size(rhos); 4 | rhos = reshape(rhos,m*n,1); 5 | m = m*n; 6 | d = (1 + sqrt(1+8*m))/2; 7 | if mod(d,1)~=0 % not an integer 8 | error('Input vecor of inccorect size.') 9 | else 10 | Rho = triu(ones(d),1)'; 11 | Rho(Rho==1) = rhos; 12 | Rho = Rho + Rho' + diag(ones(d,1)); 13 | end 14 | end -------------------------------------------------------------------------------- /include/Models/transformation/jacobian_gas_copula.m: -------------------------------------------------------------------------------- 1 | function jaco_inv = jacobian_gas_copula(param_trans) 2 | d = size(param_trans,2); 3 | 4 | if (d == 3) 5 | jaco_inv = diag([1/exp(param_trans(1,1)), 1, ... 6 | (1+exp(param_trans(1,3)))*(1+exp(-param_trans(1,3)))]); 7 | else 8 | jaco_inv = diag([1/exp(param_trans(1,1)), 1, ... 9 | (1+exp(param_trans(1,3)))*(1+exp(-param_trans(1,3))), 1/(exp(param_trans(1,4)))]); 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /estimate.m: -------------------------------------------------------------------------------- 1 | function [theta, hessian, hessian_tr, signal_smooth] = estimate(kernel,theta_init,fn_trans_param,fn_jacobian,options) 2 | theta_init_trans = fn_trans_param(theta_init, 'opt'); 3 | 4 | [theta_trans,~,~,~,~, hessian]= fminunc(kernel, theta_init_trans, options); 5 | 6 | jaco_inv = fn_jacobian(theta_trans); 7 | hessian_tr = jaco_inv*hessian*jaco_inv; 8 | 9 | if (nargout == 4) 10 | [~, signal_smooth] = kernel(theta_trans); 11 | end 12 | 13 | theta = fn_trans_param(theta_trans,'back'); 14 | end -------------------------------------------------------------------------------- /include/Distributions/duvt.m: -------------------------------------------------------------------------------- 1 | function ep = duvt(eps, nu, hp, L) 2 | % density of the univariate t distribution 3 | % calculated at matrix eps, with hp columns 4 | % df of each row are in the nu vector 5 | c = gamma((nu+1)/2)./(sqrt(pi*nu).*gamma(nu/2)); 6 | c = repmat(c, 1, hp); 7 | e = -(nu+1)/2; 8 | e = repmat(e, 1, hp); 9 | ep = c.*((1 + (eps.^2)./repmat(nu, 1, hp)).^e); 10 | 11 | if L 12 | ep = log(ep); 13 | ep = sum(ep,2); 14 | else 15 | ep = prod(ep,2); 16 | end 17 | end -------------------------------------------------------------------------------- /include/Models/transformation/jacobian_garch.m: -------------------------------------------------------------------------------- 1 | function jaco_inv = jacobian_garch(param_trans) 2 | d = size(param_trans,2); 3 | 4 | if (d == 4) 5 | jaco_inv = diag([1/exp(param_trans(1,1)), (1+exp(param_trans(1,2)))*(1+exp(-param_trans(1,2))),... 6 | (1+exp(param_trans(1,3)))*(1+exp(-param_trans(1,3))), 1]); 7 | else 8 | jaco_inv = diag([1/exp(param_trans(1,1)), (1+exp(param_trans(1,2)))*(1+exp(-param_trans(1,2))), ... 9 | (1+exp(param_trans(1,3)))*(1+exp(-param_trans(1,3))), 1, 1/(exp(param_trans(1,5)))]); 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Exercises/t_mv_pdf.m: -------------------------------------------------------------------------------- 1 | function pdf = t_mv_pdf(x,mu,Sigma,nu) 2 | [~, d] = size(x); 3 | 4 | pdf = log(gamma((nu+d)/2)) - log(gamma(nu/2)) - 0.5*d*log(pi*nu); 5 | if isempty(mu) 6 | mu = zeros(1,d); 7 | end 8 | 9 | if (d == 1) 10 | pdf = pdf - 0.5*log(Sigma); 11 | elseif (d ==2) 12 | pdf = pdf - 0.5*log(Sigma(1,1)*Sigma(2,2) - Sigma(2,1)*Sigma(1,2)); 13 | else 14 | pdf = pdf - 0.5*log(det(Sigma)); 15 | end 16 | pdf = pdf - ((nu+d)/2)*log(1 + sum((bsxfun(@minus,x,mu)/Sigma).*bsxfun(@minus,x,mu),2)/nu); 17 | 18 | pdf = exp(pdf); 19 | end -------------------------------------------------------------------------------- /include/Distributions/t_mv_pdf.m: -------------------------------------------------------------------------------- 1 | function pdf = t_mv_pdf(x,mu,Sigma,nu) 2 | [~, d] = size(x); 3 | 4 | pdf = log(gamma((nu+d)/2)) - log(gamma(nu/2)) - 0.5*d*log(pi*nu); 5 | if isempty(mu) 6 | mu = zeros(1,d); 7 | end 8 | 9 | if (d == 1) 10 | pdf = pdf - 0.5*log(Sigma); 11 | elseif (d ==2) 12 | pdf = pdf - 0.5*log(Sigma(1,1)*Sigma(2,2) - Sigma(2,1)*Sigma(1,2)); 13 | else 14 | pdf = pdf - 0.5*log(det(Sigma)); 15 | end 16 | pdf = pdf - ((nu+d)/2)*log(1 + sum((bsxfun(@minus,x,mu)/Sigma).*bsxfun(@minus,x,mu),2)/nu); 17 | 18 | pdf = exp(pdf); 19 | end -------------------------------------------------------------------------------- /include/Models/posterior_gas_init.m: -------------------------------------------------------------------------------- 1 | function d = posterior_gas_init(theta, y) 2 | mu = theta(:,1); 3 | omega = exp(theta(:,2)); 4 | A = theta(:,3); 5 | B = logsig(theta(:,4)); 6 | 7 | T = size(y,1); 8 | 9 | f = zeros(T,1); 10 | f(1,1) = omega/(1-B); % unconditional variance to initialize h_1 11 | for t = 2:T 12 | scaled_score = (y(t-1,1)-mu).^2 - f(t-1,1); 13 | f(t,1) = omega + A*scaled_score + B*f(t-1,1); 14 | end 15 | pdf = -0.5*(log(2*pi) + log(f) + ((y - mu).^2)./f); 16 | d = sum(pdf)/T; 17 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Copulas 2 | 3 | Just the first attempt to modelling time-varying copulas. So far, only for observation driven models (GAS of Creal et al., 2013, and ACM, in the parlance of Koopman et al., 2016). And only for eliptical copulas (Gaussian and Student's _t_). 4 | 5 | 6 | ### References 7 | Creal, D., S. J. Koopman and A. Lucas (2013), "Generalized Autoregressive Score Models with Applications", _Journal of Applied Econometrics_, 28(5), 777-795. 8 | 9 | Koopman, S. J., A. Lucas and M. Scharth (2016), "Predicting Time-Varying Parameters with Parameter-Driven and Observation-Driven Models", _Review of Economics and Statistics_, 98, 97-110. 10 | -------------------------------------------------------------------------------- /include/Distributions/bi_copula_n_rnd.m: -------------------------------------------------------------------------------- 1 | function u_sim = bi_copula_n_rnd(rho) 2 | % drawing from bivariate Gaussian copula 3 | % with time varying correlation rho 4 | T = size(rho,2); 5 | Rho = ones(2,2,T); 6 | Rho(1,2,:) = rho; 7 | Rho(2,1,:) = rho; 8 | draw = mvnrnd([0,0],Rho); 9 | % SIGMA is a D-by-D symmetric positive semi-definite matrix, 10 | % or a D-by-D-by-N array. 11 | % If SIGMA is an array, MVNRND generates each row of draw using the 12 | % corresponding page of SIGMA, i.e., MVNRND computes R(I,:) using MU(I,:) 13 | % and SIGMA(:,:,I). 14 | 15 | % u_sim = normcdf(draw); 16 | u_sim = 0.5 * erfc(-draw ./ sqrt(2)); 17 | end 18 | -------------------------------------------------------------------------------- /loglik_t_copula.m: -------------------------------------------------------------------------------- 1 | function loglik = loglik_t_copula(u,theta) 2 | N = size(u,1); 3 | nu = theta(:,1); 4 | rho = theta(:,2); 5 | 6 | % transform parameters 7 | nu = 2 + exp(nu); 8 | rho = exp(rho)/(1+exp(rho)); 9 | 10 | u = tinv(nu,nu); 11 | 12 | % t-copula 13 | t_copula_pdf = log(gamma((nu+2)/2)) + log(gamma(nu/2)) - 2*log(gamma((nu+1)/2))... 14 | - 0.5*log(1 - rho^2)... 15 | - ((nu+2)/2)*log(1 + (u(:,1).^2 + u(:,2).^2 - 2*rho*u(:,1).*u(:,2))/(nu*(1-rho^2))) ... 16 | + ((nu+1)/2)*log(1 + (u(:,1).^2)/nu) ... 17 | + ((nu+1)/2)*log(1 + (u(:,2).^2)/nu); 18 | 19 | % average minus loglik 20 | loglik = -sum(t_copula_pdf)/N; 21 | 22 | end -------------------------------------------------------------------------------- /include/Distributions/bi_copula_t_rnd.m: -------------------------------------------------------------------------------- 1 | function u_sim = bi_copula_t_rnd(rho, df) 2 | % drawing from bivariate Student's copula 3 | % with time varying correlation rho 4 | T = size(rho,2); 5 | Rho = ones(2,2,T); 6 | Rho(1,2,:) = rho; 7 | Rho(2,1,:) = rho; 8 | draw = mvnrnd([0,0],Rho); 9 | % SIGMA is a D-by-D symmetric positive semi-definite matrix, 10 | % or a D-by-D-by-N array. 11 | % If SIGMA is an array, MVNRND generates each row of draw using the 12 | % corresponding page of SIGMA, i.e., MVNRND computes R(I,:) using MU(I,:) 13 | % and SIGMA(:,:,I). 14 | R = df./chi2rnd(df,T,1); 15 | R = sqrt(R); 16 | draw = bsxfun(@times, draw, R); 17 | 18 | u_sim = tcdf(draw,df); 19 | end 20 | -------------------------------------------------------------------------------- /include/Models/volatility_t_garch_noS.m: -------------------------------------------------------------------------------- 1 | function h_T = volatility_t_garch_noS(theta, data, S) 2 | % function h_T = volatility_t_garch(theta, data, S) 3 | 4 | [N ,~] = size(theta); 5 | omega = theta(:,1); 6 | alpha = theta(:,2); 7 | beta = theta(:,3); 8 | mu = theta(:,4); 9 | 10 | T = size(data,1); 11 | % ind = 2:T; 12 | data = data'; 13 | 14 | h = zeros(N,T); 15 | h(:,1) = S*ones(N,1); 16 | 17 | % h(:,ind) = repmat(omega(:,1),1,T-1) + repmat(alpha(:,1),1,T-1).*(repmat(data(1,ind-1),N,1)-repmat(mu(:,1),1,T-1)).^2; 18 | for jj = 2:T 19 | h(:,jj) = omega(:,1) + alpha(:,1).*(data(1,jj-1) - mu(:,1)).^2 + beta(:,1).*h(:,jj-1) ; 20 | end 21 | h_T = h(:,T); 22 | end -------------------------------------------------------------------------------- /include/Models/transformation/jacobian_gas.m: -------------------------------------------------------------------------------- 1 | function jaco_inv = jacobian_gas(param_trans, link) 2 | d = size(param_trans,2); 3 | 4 | if (d == 4) 5 | if link 6 | jaco_inv = diag([1, 1/exp(param_trans(1,2)), 1, (1+exp(param_trans(1,4)))*(1+exp(-param_trans(1,4)))]); 7 | else 8 | jaco_inv = diag([1, 1, 1, (1+exp(param_trans(1,4)))*(1+exp(-param_trans(1,4)))]); 9 | end 10 | else 11 | if link 12 | jaco_inv = diag([1, 1/exp(param_trans(1,2)), 1, (1+exp(param_trans(1,4)))*(1+exp(-param_trans(1,4))), 1/(exp(param_trans(1,5)))]); 13 | else 14 | jaco_inv = diag([1, 1, 1, (1+exp(param_trans(1,4)))*(1+exp(-param_trans(1,4))), 1/(exp(param_trans(1,5)))]); 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /include/Distributions/duvt_garch.m: -------------------------------------------------------------------------------- 1 | function dens = duvt_garch(x, mu, Sigma, df, GamMat) 2 | % location/scale univariate student t distribution 3 | 4 | % c1 = gamma((df+1)/2); 5 | % c2 = gamma(df/2); 6 | c0 = df+1; 7 | if c0 < 200 8 | c1 = GamMat(floor(c0*50000)); 9 | else 10 | c1 = gamma(c0/2); 11 | end 12 | 13 | if df < 200 14 | c2 = GamMat(round(df*50000)); % read the correponding value of th gamma 15 | else 16 | c2 = gamma(df/2); 17 | end 18 | 19 | % c3 = (pi*df)^(d/2); 20 | % c = c1/(c2*c3*sqrt(det(Sigma))); 21 | % c = c1/(c2*c3*tmp); 22 | c = c1/(c2*sqrt(pi*df*Sigma)); 23 | % e = -(d+df)/2; 24 | e = -(df+1)/2; 25 | % dens = c*(1+(x-mu)*inv(Sigma)*(x-mu)'/df)^e; 26 | tmp = (x-mu)*(x-mu)/Sigma; 27 | 28 | dens = c*(1+tmp/df)^e; 29 | end -------------------------------------------------------------------------------- /include/Distributions/rmvt.m: -------------------------------------------------------------------------------- 1 | function draw = rmvt(mu,Sigma,df,n) 2 | % location/scale multivariate student t distribution 3 | [N_mu,d] = size(mu); 4 | % mu_n = zeros(1,d); 5 | % Z = mvnrnd(mu_n,Sigma,n); 6 | % % R2 = chi2rnd(df,n,1); 7 | % % R2 = R2/df; 8 | % % R2 = repmat(R2,1,d); 9 | % % % draw = repmat(mu,n,1) + Z./sqrt(R2); 10 | % % R2 = chi2rnd(df,n,1); 11 | % % df = df*ones(n,1); 12 | % % R2 = df./R2; 13 | % R2 = random('gam',df/2,2/df,n,1); % shape scale 14 | % R2 = repmat(R2,1,d); 15 | % draw = repmat(mu,n,1) + Z.*sqrt(R2); 16 | 17 | % R = chol(Sigma); 18 | % Y = mvtrnd(eye(d), df, n); 19 | Y = mvnrnd(zeros(1,d),Sigma,n); 20 | R = df./chi2rnd(df,n,1); 21 | R = repmat(R,1,d); 22 | if (N_mu == 1) 23 | draw = repmat(mu,n,1) + Y.*sqrt(R); 24 | else 25 | draw = mu + Y.*sqrt(R); 26 | end 27 | end -------------------------------------------------------------------------------- /include/Distributions/rmvgt2.m: -------------------------------------------------------------------------------- 1 | function theta = rmvgt2(N,mu,Sigma,df,p) 2 | % Random sampling from mixture of t densitites 3 | % N - number of draws 4 | % mit - list with parameters of mixture of t density 5 | [H, d] = size(mu); % number of components, dimension of t distribution 6 | 7 | % sample membership 8 | memb = randsample(1:H,N,true,p); 9 | % randsample(1:3,10,true,[0.1 0.3 0.6]) 10 | theta = zeros(N, d); 11 | for h=1:H 12 | ind_h = (memb == h); 13 | n_h = sum(ind_h); 14 | if (n_h>0) 15 | mu_h = mu(h,:); 16 | Sigma_h = Sigma(h,:); 17 | Sigma_h = reshape(Sigma_h,d,d); 18 | df_h = df(h); 19 | % draw_h = mvtrnd(Sigma_h,df_h,n_h); 20 | draw_h = rmvt(mu_h,Sigma_h,df_h,n_h); 21 | % draw_h = draw_h + repmat(mu_h,n_h,1); 22 | theta(ind_h,:) = draw_h; 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /include/MitISEM/Mit_MH.m: -------------------------------------------------------------------------------- 1 | function [theta, accept] = Mit_MH(N, kernel, mit, GamMat) 2 | % perform independence MH sampling using mixture of t densities as the 3 | % candidate density 4 | % input: 5 | % N - lenght of the generated chain 6 | % kernel - function which computes the kernel 7 | % mit - mixture of t's 8 | % output: 9 | % theta - [Nxk] matrix of samples generated by the independence MH 10 | % accept - acceptance rate in the independence MH 11 | 12 | resampl_on = false; 13 | 14 | [theta, lnk, ~] = fn_rmvgt_robust(N, mit, kernel, resampl_on); 15 | ind_real = ((imag(lnk)==0) & ~isnan(lnk)); 16 | lnk(~ind_real) = -Inf; 17 | 18 | lnd = dmvgt(theta, mit, true, GamMat); 19 | % norm = false; 20 | % lnw = fn_ISwgts(lnk, lnd, norm); 21 | % lnw = log(lnw); %log weights 22 | lnw = lnk - lnd; 23 | lnw = lnw - max(lnw); 24 | 25 | [ind, a] = fn_MH(lnw); 26 | theta = theta(ind,:); 27 | accept = a/N; 28 | end -------------------------------------------------------------------------------- /include/Models/predict_t_garch_noS.m: -------------------------------------------------------------------------------- 1 | function [y_hp, eps_hp, h] = predict_t_garch_noS(theta, y_T, h_T, hp, eps) 2 | [N ,~] = size(theta); 3 | omega = theta(:,1); 4 | alpha = theta(:,2); 5 | beta = theta(:,3); 6 | mu = theta(:,4); 7 | nu = theta(:,5); 8 | 9 | rho = (nu-2)./nu; 10 | 11 | if (nargin == 4) 12 | % fprintf('hp = %i \n',hp); 13 | eps_hp = trnd(repmat(nu,1,hp)); 14 | else %(with given eps) 15 | eps_hp = eps; 16 | end 17 | 18 | y_hp = zeros(N,hp+1); 19 | y_hp(:,1) = y_T.*ones(N,1); 20 | 21 | h = zeros(N,hp+1); 22 | h(:,1) = h_T; 23 | 24 | for jj = 2:(hp+1) 25 | h(:,jj) = omega(:,1) + alpha(:,1).*(y_hp(:,jj-1)-mu(:,1)).^2 + beta(:,1).*h(:,jj-1); 26 | y_hp(:,jj) = mu(:,1) + sqrt(rho(:,1).*h(:,jj)).*eps_hp(:,jj-1); 27 | end 28 | y_hp = y_hp(:,2:hp+1); 29 | h = h(:,2:hp+1); 30 | % y_hp = predict_t_garch_noS_mex(theta, y_T, h_T, eps_hp); 31 | end -------------------------------------------------------------------------------- /include/Distributions/rmvgt.m: -------------------------------------------------------------------------------- 1 | function [theta, t] = rmvgt(N,mit) 2 | % Random sampling from mixture of t densitites 3 | % N - number of draws 4 | % mit - list with parameters of mixture of t density 5 | tic 6 | [H,d] = size(mit.mu); % number of components, dimension of t distribution 7 | % sample membership 8 | memb = randsample(1:H,N,true,mit.p); 9 | % randsample(1:3,10,true,[0.1 0.3 0.6]) 10 | theta = zeros(N, d); 11 | for h=1:H 12 | ind_h = (memb == h); 13 | n_h = sum(ind_h); 14 | if (n_h>0) 15 | mu_h = mit.mu(h,:); 16 | Sigma_h = mit.Sigma(h,:); 17 | Sigma_h = reshape(Sigma_h,d,d); 18 | df_h = mit.df(h); 19 | % draw_h = mvtrnd(Sigma_h,df_h,n_h); 20 | draw_h = rmvt(mu_h,Sigma_h,df_h,n_h); 21 | % draw_h = draw_h + repmat(mu_h,n_h,1); 22 | theta(ind_h,:) = draw_h; 23 | end 24 | end 25 | if (nargout > 1) 26 | t = toc; 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /include/MitISEM/fn_initopt.m: -------------------------------------------------------------------------------- 1 | function [mu, Sigma, val] = fn_initopt(kernel, mu0, fn_delta) % , options) 2 | d = length(mu0); 3 | % options = optimset('TolX', 0.0001, 'Display', 'iter', 'Maxiter', 5000, 'MaxFunEvals', 5000, 'LargeScale', 'off', 'HessUpdate', 'bfgs'); 4 | 5 | options = optimset('display','iter','TolFun',1e-5,'LargeScale','off',... 6 | 'TolX',1e-5,'HessUpdate','bfgs','FinDiffType','central',... 7 | 'maxiter',5000,'MaxFunEvals',5000); 8 | 9 | [mu,val,~,~,~,hessian] = fminunc(kernel, mu0, options); 10 | % options = optimset('Display','iter'); 11 | % x = fminsearch(kernel_init,mu_init, options); 12 | % x = fminsearch(kernel_init,mu_hl), options); 13 | % [x,~,~,~,~,hessian] = fminunc(kernel,mu0,options) 14 | if nargin > 2 15 | hessian = fn_delta(mu, hessian); 16 | end 17 | try 18 | [~, T] = kernel(mu0); 19 | Sigma = inv(T*hessian); 20 | catch 21 | Sigma = inv(hessian); 22 | end 23 | Sigma = reshape(Sigma,1,d^2); 24 | end -------------------------------------------------------------------------------- /include/MitISEM/fn_MH.m: -------------------------------------------------------------------------------- 1 | function [ind, a] = fn_MH(lnw) 2 | % Run the independence Metropolis-Hastings algorithm on the vector of log weights lnw 3 | % to return the index indicating the corresponding draws 4 | % a - counter for accepted draws 5 | [N,~] = size(lnw); 6 | a = 0; 7 | % initialize the chain 8 | ind = zeros(N,1); 9 | ind(1,:) = 1; 10 | 11 | ind_old = 1; 12 | fprintf('\nMH running...') 13 | 14 | % h = waitbar(0,'MH in progress...'); 15 | % iterate over the chain 16 | for ii = 2:N 17 | u = rand; % draw from uniform 18 | % e = min(1,w(ii)/w(ind_old)); % min between the ratio and 1 19 | e = min(1, exp(lnw(ii)-lnw(ind_old))); % min between the ratio and 1 20 | if (u <= e) 21 | ind(ii,:) = ii; 22 | a = a + 1; % increase the counter for acceptance rate 23 | ind_old = ii; % move the old position 24 | else 25 | ind(ii,:) = ind_old; 26 | end 27 | % waitbar(ii/N) 28 | end 29 | % close(h) 30 | fprintf(' done! \n') 31 | end -------------------------------------------------------------------------------- /include/Models/transformation/transform_param_gas_copula.m: -------------------------------------------------------------------------------- 1 | function param_trans = transform_param_gas_copula(param, mode) 2 | param_trans = param; 3 | d = size(param,2); 4 | 5 | switch mode 6 | % case 'est_opt' % transformation for optimization --> unbounded 7 | case 'opt' % transformation for optimization --> unbounded 8 | param_trans(1,1) = log(param(1,1)); 9 | param_trans(1,3) = log(param(1,3)/(1-param(1,3))); 10 | if (d == 4) 11 | param_trans(1,4) = log(param(1,4) - 2); 12 | end 13 | 14 | % case 'est_back'% if mode == 'back' (transform back) 15 | case 'back'% if mode == 'back' (transform back) 16 | param_trans(1,1) = exp(param(1,1)); 17 | param_trans(1,3) = exp(param(1,3))/(1+exp(param(1,3))); 18 | param_trans(1,3) = min(0.998, param_trans(1,3)); 19 | if (d == 4) 20 | param_trans(1,4) = 2 + exp(param(1,4)); 21 | param_trans(1,4) = min(200, param_trans(1,4)); 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /include/Models/predict_t_gas.m: -------------------------------------------------------------------------------- 1 | function [y_hp, eps_hp, f] = predict_t_gas(theta, y_T, f_T, hp, eps) 2 | [N ,~] = size(theta); 3 | mu = theta(:,1); 4 | omega = theta(:,2); 5 | A = theta(:,3); 6 | B = theta(:,4); 7 | nu = theta(:,5); 8 | 9 | rho = (nu-2)./nu; 10 | nu_con = (nu+1)./(nu-2); 11 | A = A.*((nu+3)./nu); 12 | 13 | if (nargin == 4) 14 | eps_hp = trnd(repmat(nu,1,hp)); 15 | else %(with given eps) 16 | eps_hp = eps; 17 | end 18 | 19 | y_hp = zeros(N,hp+1); 20 | y_hp(:,1) = y_T.*ones(N,1); 21 | 22 | f = zeros(N,hp+1); 23 | f(:,1) = f_T; 24 | 25 | for jj = 2:(hp+1) 26 | C = 1 + ((y_hp(:,jj-1)-mu).^2)./((nu-2).*f(:,jj-1)); 27 | f(:,jj) = omega + A.*(nu_con.*((y_hp(:,jj-1)-mu).^2)./C - f(:,jj-1)) + B.*f(:,jj-1); 28 | % f(:,jj) = omega(:,1) + alpha(:,1).*(y_hp(:,jj-1)-mu(:,1)).^2 + beta(:,1).*h(:,jj-1); 29 | y_hp(:,jj) = mu(:,1) + sqrt(rho(:,1).*f(:,jj)).*eps_hp(:,jj-1); 30 | end 31 | y_hp = y_hp(:,2:hp+1); 32 | f = f(:,2:hp+1); 33 | end -------------------------------------------------------------------------------- /include/Models/transformation/transform_param_garch.m: -------------------------------------------------------------------------------- 1 | function param_trans = transform_param_garch(param, mode) 2 | param_trans = param; 3 | d = size(param,2); 4 | 5 | switch mode 6 | % case 'est_opt' % transformation for optimization --> unbounded 7 | case 'opt' % transformation for optimization --> unbounded 8 | param_trans(1,1) = log(param(1,1)); 9 | param_trans(1,2) = log(param(1,2)/(1-param(1,2))); 10 | param_trans(1,3) = log(param(1,3)/(1-param(1,3))); 11 | if (d == 5) 12 | param_trans(1,5) = log(param(1,5) - 2); 13 | end 14 | 15 | % case 'est_back'% if mode == 'back' (transform back) 16 | case 'back'% if mode == 'back' (transform back) 17 | param_trans(1,1) = exp(param(1,1)); 18 | param_trans(1,2) = exp(param(1,2))/(1+exp(param(1,2))); 19 | param_trans(1,3) = exp(param(1,3))/(1+exp(param(1,3))); 20 | param_trans(1,3) = min(0.998, param_trans(1,3)); 21 | if (d == 5) 22 | param_trans(1,5) = 2 + exp(param(1,5)); 23 | param_trans(1,5) = min(200, param_trans(1,5)); 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /include/Models/volatility_copula_gas.m: -------------------------------------------------------------------------------- 1 | function [f, rho] = volatility_copula_gas(theta, y) 2 | [N,~] = size(theta); 3 | T = size(y, 1); 4 | 5 | omega = theta(:,1); 6 | A = theta(:,2); 7 | B = theta(:,3); 8 | 9 | z = norminv(y); 10 | 11 | f = zeros(N,T); % alpha in the paper, time-varying parameter following GAS recursion 12 | f(:,1) = omega./(1-B); 13 | transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 14 | rho = zeros(N,T); % the time-varying parameter tranfsormed by the trnasf function --> rho, i.e. the correlation 15 | rho(:,1) = transf(f(:,1)); 16 | 17 | scoref = @(z1, z2, r) ((1 + r.^2).*(z1.*z2 - r) - r.*(z1.^2 + z2.^2 - 2))./((1 - r.^2).^2); 18 | inff = @(r) (1 + r.^2)./((1 - r.^2).^2); 19 | 20 | for jj = 2:T 21 | s = scoref(z(jj-1,1), z(jj-1,2), rho(:,jj-1)); 22 | scscore = s./sqrt(inff(rho(:,jj-1))); 23 | f(:,jj) = omega + A.*scscore + B.*f(:,jj-1); 24 | rho(:,jj) = transf(f(:,jj)); 25 | end 26 | % f_T = f(:,T); 27 | % rho_T = rho(:,T); 28 | end 29 | 30 | % function scaled_score = scaled_score_copula_gas(y1, y2, rho) 31 | % score = ((1 + rho.^2).*(y1.*y2 - rho) - rho.(y1.^2 + y2.^2 - 2))./((1 - rho.^2).^2); 32 | % I = (1 + rho.^2)./((1 - rho.^2).^2); 33 | % scaled_score = score./sqrt(I); 34 | % end -------------------------------------------------------------------------------- /Exercises/Combining_arbitrary_marignals3.m: -------------------------------------------------------------------------------- 1 | % START WITH BIVARIATE T 2 | clear all 3 | close all 4 | 5 | m = 2; 6 | N = 2000; 7 | Sigma = [1, 0.8; 0.8, 1]; 8 | C = chol(Sigma); 9 | df1 = 3; 10 | df2 = 10; 11 | 12 | X = randn(N,m); 13 | X = X*C; 14 | 15 | W1 = df1./chi2rnd(df1,N,1); 16 | X1 = bsxfun(@times,X,sqrt(W1)); 17 | U1 = tcdf(X1,df1); % t copula with df1 df 18 | 19 | W2 = df2./chi2rnd(df2,N,1); 20 | X2 = bsxfun(@times,X,sqrt(W1)); 21 | U2 = tcdf(X2,df2); % t copoula with df2 df 22 | 23 | Y1 = zeros(N,m); 24 | Y2 = zeros(N,m); 25 | Y3 = zeros(N,m); 26 | Y4 = zeros(N,m); 27 | Y5 = zeros(N,m); 28 | Y6 = zeros(N,m); 29 | 30 | Y1(:,1) = tinv(U1(:,1),df1); 31 | Y1(:,2) = tinv(U1(:,2),df1); 32 | 33 | Y2(:,1) = tinv(U1(:,1),df1); 34 | Y2(:,2) = tinv(U1(:,2),df2); 35 | 36 | Y3(:,1) = tinv(U1(:,1),df2); 37 | Y3(:,2) = tinv(U1(:,2),df2); 38 | 39 | Y4(:,1) = tinv(U2(:,1),df1); 40 | Y4(:,2) = tinv(U2(:,2),df1); 41 | 42 | Y5(:,1) = tinv(U2(:,1),df1); 43 | Y5(:,2) = tinv(U2(:,2),df2); 44 | 45 | Y6(:,1) = tinv(U2(:,1),df2); 46 | Y6(:,2) = tinv(U2(:,2),df2); 47 | 48 | subplot(2,3,1) 49 | scatter(Y1(:,1),Y1(:,2)) 50 | subplot(2,3,2) 51 | scatter(Y2(:,1),Y2(:,2)) 52 | subplot(2,3,3) 53 | scatter(Y3(:,1),Y3(:,2)) 54 | subplot(2,3,4) 55 | scatter(Y4(:,1),Y4(:,2)) 56 | subplot(2,3,5) 57 | scatter(Y5(:,1),Y5(:,2)) 58 | subplot(2,3,6) 59 | scatter(Y6(:,1),Y6(:,2)) -------------------------------------------------------------------------------- /include/Distributions/dmvt.m: -------------------------------------------------------------------------------- 1 | function dens = dmvt(x, mu, Sigma, df, GamMat) 2 | % location/scale multivariate student t distribution 3 | 4 | [~,d] = size(mu); 5 | % % % % c1 = gamma((df+d)/2); 6 | % % % % c2 = gamma(df/2); 7 | %% 8 | % global GamMat 9 | 10 | % tmp = (df+d)/2; 11 | % tmp = round((df+d)*100000); % round to the 4th decimal number 12 | % c1 = GamMat(tmp); % read the correponding value of th gamma 13 | c0 = df+d; 14 | if c0 < 100 15 | c1 = GamMat(floor(c0*50000)); 16 | else 17 | c1 = gamma(c0/2); 18 | end 19 | % tmp = df/2; 20 | % tmp = round(tmp*100000); 21 | % c2 = GamMat(tmp); % read the correponding value of th gamma 22 | 23 | if df < 100 24 | c2 = GamMat(round(df*50000)); % read the correponding value of th gamma 25 | else 26 | c2 = gamma(df/2); 27 | end 28 | 29 | %% 30 | % c3 = (pi*df)^(d/2); 31 | % c = c1/(c2*c3*sqrt(det(Sigma))); 32 | if d == 1 33 | tmp = sqrt(Sigma); 34 | else 35 | tmp = sqrt(det(Sigma)); 36 | end 37 | % c = c1/(c2*c3*tmp); 38 | c = c1/(c2*((pi*df)^(d/2))*tmp); 39 | % e = -(d+df)/2; 40 | e = -c0/2; 41 | % dens = c*(1+(x-mu)*inv(Sigma)*(x-mu)'/df)^e; 42 | tmp = (x-mu)/Sigma; 43 | tmp = sum(tmp.*(x-mu)); 44 | dens = exp(log(c) + log((1+tmp/df)^e)); 45 | end -------------------------------------------------------------------------------- /Exercises/Combining_arbitrary_marignals2.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | m = 2; 5 | N = 5000; 6 | Sigma = [1, 0.5; 0.5, 1]; 7 | C = chol(Sigma); 8 | df = 4; 9 | 10 | % % Important: multiply a vector by the lower triangular! 11 | % x = randn(m,1); 12 | % x = C'*x; %!!! 13 | 14 | %% 15 | Z = randn(N,m); 16 | Z = Z*C; 17 | 18 | W = df./chi2rnd(df,N,1); 19 | X = bsxfun(@times,Z,sqrt(W)); 20 | 21 | 22 | %% 23 | Z_pit = normcdf(Z); % normal copula 24 | X_pit = tcdf(X,df); % t copula 25 | 26 | corrcoef(Z) 27 | corrcoef(X) 28 | corrcoef(Z_pit) 29 | corrcoef(X_pit) 30 | 31 | scatter(Z(:,1),Z(:,2)) 32 | scatter(X(:,1),X(:,2)) 33 | scatter(Z_pit(:,1),Z_pit(:,2)) 34 | scatter(X_pit(:,1),X_pit(:,2)) 35 | 36 | %% 37 | X_meta_n = tinv(Z_pit,df); % t marginas + normal copula = X_meta_n 38 | Z_meta_t = norminv(X_pit); % n marginas + t copula = Z_meta_t 39 | 40 | %% 41 | figure(1) 42 | subplot(2,2,1) 43 | scatter(Z(:,1),Z(:,2),'.') 44 | subplot(2,2,2) 45 | scatter(X_meta_n(:,1),X_meta_n(:,2),'g.') 46 | subplot(2,2,3) 47 | scatter(Z_meta_t(:,1),Z_meta_t(:,2),'r.') 48 | subplot(2,2,4) 49 | scatter(X(:,1),X(:,2),'.') 50 | 51 | 52 | figure(2) 53 | subplot(2,3,1) 54 | scatter(X_meta_n(:,1),X_meta_n(:,2),'g.') 55 | subplot(2,3,2) 56 | hist(X_meta_n(:,1)) 57 | subplot(2,3,3) 58 | hist(X_meta_n(:,2)) 59 | 60 | 61 | subplot(2,3,4) 62 | scatter(Z_meta_t(:,1),Z_meta_t(:,2),'r.') 63 | subplot(2,3,5) 64 | hist(Z_meta_t(:,1)) 65 | subplot(2,3,6) 66 | hist(Z_meta_t(:,2)) 67 | 68 | 69 | -------------------------------------------------------------------------------- /include/Distributions/dmvgt.m: -------------------------------------------------------------------------------- 1 | function dens = dmvgt(theta, mit, L, GamMat) 2 | % density of a mixture of multivariate t distributions 3 | % L (log) - return log-density values if L=true 4 | % % MATLAB 5 | % [H,d] = size(mit.mu); % number of components, dimension of t distribution 6 | % [N,~] = size(theta); 7 | % dcoms = zeros(N,H); 8 | % for h = 1:H 9 | % mu_h = mit.mu(h,:); 10 | % Sigma_h = mit.Sigma(h,:); 11 | % Sigma_h = reshape(Sigma_h,d,d); 12 | % df_h = mit.df(h); 13 | % for ii = 1:N 14 | % dcoms(ii,h) = dmvt(theta(ii,:), mu_h, Sigma_h, df_h, GamMat); 15 | % end 16 | % end 17 | % tmp = log(repmat(mit.p,N,1)) + log(dcoms); 18 | % dens = sum(exp(tmp),2); 19 | % if (L == true) 20 | % dens = log(dens); 21 | % end 22 | 23 | % % C-MEX 24 | L = double(L); 25 | dens = dmvgt_mex(theta, mit.mu, mit.Sigma, mit.df, mit.p, GamMat, L); 26 | 27 | % % comparison of the MATLAB and C-MEX kernel evaluation functions 28 | % lnd_mex = dmvgt_mex(theta, mit.mu, mit.Sigma, mit.df, mit.p, GamMat, 1); 29 | % fprintf('\n *** sum(abs(lnd_mex-lnd)> eps) = %6.4f ***\n', sum(abs(lnd_mex-dens)>eps) ); 30 | % fprintf(' *** sum(abs(lnd_mex-lnd)) = %16.14f ***\n\n', sum(abs(lnd_mex-dens))); 31 | % if (sum(abs(lnd_mex-dens)) > 1e-4 ) 32 | % keyboard 33 | % [val, MM] = max(abs(lnd_mex-dens)); % lnd_mex(MM)-dens(MM) 34 | % end 35 | 36 | end -------------------------------------------------------------------------------- /speed_check.m: -------------------------------------------------------------------------------- 1 | %% Gaussian 2 | % With anonymous functions 3 | mu_init = [0.02, 0.10, 0.98]; 4 | kernel_init = @(xx) loglik_copula_gas(fn_trans_param(xx,'back'), u); 5 | tic 6 | % profile on 7 | [mu_copula, ~, Hessian, signal_copula] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 8 | % profile off 9 | % profile viewer 10 | toc %Elapsed time is 18.795089 seconds. 11 | 12 | 13 | 14 | % With subfunction 15 | mu_init = [0.02, 0.10, 0.98]; 16 | kernel_init = @(xx) loglik_copula_gas2(fn_trans_param(xx,'back'), u); 17 | % tic 18 | profile on 19 | [mu_copula2, ~, Hessian2, signal_copula2] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 20 | profile off 21 | profile viewer 22 | % toc %Elapsed time is 8.523910 seconds. 23 | 24 | %% Student's t 25 | % With anonymous functions 26 | mu_init = [0.02, 0.10, 0.98, 8]; 27 | kernel_init = @(xx) loglik_copula_t_gas(fn_trans_param(xx,'back'), u); 28 | % tic 29 | profile on 30 | [mu_copula, ~, Hessian, signal_copula] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 31 | profile off 32 | profile viewer 33 | % toc %Elapsed time is 7.028290 sseconds. 34 | 35 | 36 | 37 | % With subfunction 38 | mu_init = [0.02, 0.10, 0.98, 8]; 39 | kernel_init = @(xx) loglik_copula_t_gas2(fn_trans_param(xx,'back'), u); 40 | % tic 41 | % profile on 42 | [mu_copula2, ~, Hessian2, signal_copula2] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 43 | % profile off 44 | % profile viewer 45 | toc %Elapsed time is 23.376660 seconds. 46 | 47 | -------------------------------------------------------------------------------- /simulate_copula_implicit.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | d = 2; 5 | N = 1000; 6 | 7 | Rho = [1,0.5; 0.5,1]; 8 | 9 | df = 4; 10 | 11 | 12 | %% Bivariate 13 | % Normal 14 | X_b_n = mvnrnd([0,0], Rho, N); 15 | 16 | % Student's t 17 | % t is normal variance mixture: X = sqrt(W)*Z, W indep Z, Z~N, nu/W~chi2(nu) [equiv.: W~IG(nu/2,nu/2)] 18 | X_b_t4 = mvnrnd([0,0],Rho, N); 19 | W = df./chi2rnd(df,N,1); 20 | W = sqrt(W); 21 | X_b_t4 = bsxfun(@times, X_b_t4, W); 22 | 23 | % Elliptical implied copulas with correlation 0.5 24 | 25 | figure(1) 26 | subplot(3,2,1) 27 | scatter(X_b_n(:,1),X_b_n(:,2),'.') 28 | corrcoef(X_b_n) % 0.4921 29 | subplot(3,2,2) 30 | scatter(X_b_t4(:,1),X_b_t4(:,2),'.') 31 | corrcoef(X_b_t4) % 0.5174 32 | 33 | %% Margins 34 | % Normal 35 | X_n_marg = randn(N,d); 36 | 37 | % Student's t 38 | X_t4_marg = trnd(df,N,d); 39 | 40 | %% Copulas: elliptical 41 | % Normal 42 | X_n = norminv(normcdf(X_n_marg)); 43 | 44 | % Student's t 45 | X_t4 = tinv(tcdf(X_t4_marg,df),df); 46 | 47 | figure(1) 48 | subplot(3,2,3) 49 | scatter(X_n(:,1),X_n(:,2),'.') 50 | corrcoef(X_n) % 0.4921 51 | subplot(3,2,4) 52 | scatter(X_t4(:,1),X_t4(:,2),'.') 53 | corrcoef(X_t4) % 0.5174 54 | 55 | %% Copulas: non-elliptical 56 | % Normal 57 | X_meta_n = norminv(tcdf(X_t4_marg,df)); 58 | 59 | % Student's t 60 | X_meta_t4 = tinv(normcdf(X_n_marg),df); 61 | 62 | figure(1) 63 | subplot(2,2,5) 64 | scatter(X_meta_n(:,1),X_meta_n(:,2),'r.') 65 | corrcoef(X_meta_n(all(isfinite(X_meta_n),2),:)) 66 | 67 | subplot(2,2,6) 68 | scatter(X_meta_t4(:,1),X_meta_t4(:,2),'.') 69 | corrcoef(X_meta_t4) 70 | 71 | -------------------------------------------------------------------------------- /include/Models/loglik_copula_gas2.m: -------------------------------------------------------------------------------- 1 | function [LL, f, rho] = loglik_copula_gas2(theta, y) 2 | [N,~] = size(theta); 3 | T = size(y, 1); 4 | 5 | omega = theta(:,1); 6 | A = theta(:,2); 7 | B = theta(:,3); 8 | 9 | z = norminv(y); 10 | 11 | f = zeros(N,T); % alpha in the paper, time-varying parameter following GAS recursion 12 | f(:,1) = omega./(1-B); 13 | % transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 14 | rho = zeros(N,T); % the time-varying parameter tranfsormed by the trnasf function --> rho, i.e. the correlation 15 | rho(:,1) = transf(f(:,1)); 16 | 17 | % scoref = @(z1, z2, r) ((1 + r.^2).*(z1.*z2 - r) - r.*(z1.^2 + z2.^2 - 2))./((1 - r.^2).^2); 18 | % inff = @(r) (1 + r.^2)./((1 - r.^2).^2); 19 | 20 | for jj = 2:T 21 | s = scoref(z(jj-1,1), z(jj-1,2), rho(:,jj-1)); 22 | scscore = s./sqrt(inff(rho(:,jj-1))); 23 | f(:,jj) = omega + A.*scscore + B.*f(:,jj-1); 24 | rho(:,jj) = transf(f(:,jj)); 25 | end 26 | 27 | Z1 = repmat(z(:,1)',N,1); 28 | Z2 = repmat(z(:,2)',N,1); 29 | LL = - 0.5*log(1-rho.^2) - 0.5*(Z1.^2 + Z2.^2 - 2*rho.*Z1.*Z2)./(1-rho.^2) ... 30 | + 0.5*Z1.^2 + 0.5*Z2.^2; 31 | LL = -sum(LL,2)/T; 32 | 33 | % f_T = f(:,T); 34 | % rho_T = rho(:,T); 35 | end 36 | 37 | function s = scoref(z1, z2, r) 38 | s = ((1 + r.^2).*(z1.*z2 - r) - r.*(z1.^2 + z2.^2 - 2))./((1 - r.^2).^2); 39 | end 40 | 41 | function invf = inff(r) 42 | invf = (1 + r.^2)./((1 - r.^2).^2); 43 | end 44 | 45 | function aa = transf(aa) 46 | aa = (1 - exp(-aa))./(1 + exp(-aa)); 47 | end -------------------------------------------------------------------------------- /include/Models/posterior_gas.m: -------------------------------------------------------------------------------- 1 | function d = posterior_gas(theta, y, L) 2 | % theta is Nx4, matrix of draws 3 | [N ,~] = size(theta); 4 | mu = theta(:,1); 5 | omega = theta(:,2); 6 | A = theta(:,3); 7 | B = theta(:,4); 8 | 9 | prior = prior_gas(N, omega, B); 10 | 11 | T = size(y,1); 12 | 13 | d = -Inf*ones(N,1); 14 | 15 | for ii = 1:N 16 | if mod(ii,1000) == 0 17 | fprintf('posterior ii = %d\n',ii); 18 | end 19 | 20 | f = zeros(T,1); 21 | if (prior(ii,1)) % when all the parameter constraints are satisfied 22 | f(1,1) = omega(ii,1)/(1-B(ii,1)); % unconditional variance to initialize h_1 23 | for jj = 2:T 24 | scaled_score = (y(jj-1,1)-mu(ii,1)).^2 - f(jj-1,1); 25 | f(jj,1) = omega(ii,1) + A(ii,1)*scaled_score + B(ii,1)*f(jj-1,1); 26 | end 27 | pdf = -0.5*(log(2*pi) + log(f) + ((y - mu(ii,1)).^2)./f); 28 | d(ii,1) = sum(pdf) + prior(ii,2); 29 | end 30 | end 31 | 32 | if (~L) 33 | d = exp(d); 34 | end 35 | end 36 | 37 | 38 | function R = prior_gas(N, omega, B) 39 | % uniform priors 40 | 41 | % prior is an Nx2 matrix: 42 | % 1 col - constraint satisfied? 43 | % 2 col - prior val an the corresponding point 44 | 45 | c1 = (omega > 0); 46 | c3 = ((B >= 0) & (B < 1)); 47 | 48 | r1 = (c1 & c3); 49 | r2 = -Inf*ones(N,1); 50 | r2(r1==true) = 1; 51 | 52 | R = [r1, r2]; 53 | end 54 | -------------------------------------------------------------------------------- /Grouped_t_copula.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | addpath(genpath('include/')); 4 | 5 | d = 4; % Dimension 6 | partition = [1,3]; % subsets indicators 7 | S = length(partition); % no of groups 8 | df = [5,10]; % df of groups 9 | 10 | 11 | N = 2000; 12 | % rhos = [0.8 0.7 0.6 0.4 0.3 0.2]; 13 | rhos = [0.8 0.8 0.8 0.8 0.8 0.8]; 14 | Sigma = correl_mat(rhos); 15 | C = chol(Sigma); 16 | 17 | X = randn(N,d); 18 | X = X*C; % sample from N(0,Sigma) 19 | U = zeros(N,d); 20 | 21 | Uw = rand(N,1); 22 | W = zeros(N,S); 23 | 24 | for s = 1:S 25 | W(:,s) = df(s)./chi2inv(Uw,df(s)); 26 | end 27 | 28 | for s = 1:S 29 | [s1, s2] = fn_partition_ends(partition, d, s); 30 | X(:,s1:s2) = bsxfun(@times,X(:,s1:s2),sqrt(W(1,s))); 31 | U(:,s1:s2) = tcdf(X(:,s1:s2),df(s)); 32 | end 33 | 34 | Z = norminv(U); 35 | 36 | subplot(4,4,1) 37 | hist(Z(:,1)) 38 | 39 | subplot(4,4,6) 40 | hist(Z(:,2)) 41 | 42 | subplot(4,4,11) 43 | hist(Z(:,3)) 44 | 45 | subplot(4,4,16) 46 | hist(Z(:,4)) 47 | 48 | %% Estimate t copula 49 | N = 2000; 50 | rho = 0.2; 51 | Rho = correl_mat(rho); 52 | C = chol(Rho); 53 | df = 3; 54 | 55 | X = randn(N,2); 56 | X = X*C; 57 | 58 | W = df./chi2rnd(df,N,1); 59 | X = bsxfun(@times,X,sqrt(W)); 60 | U = tcdf(X,df); % t copula with df 61 | Z = norminv(U); 62 | u = norcdf(Z); 63 | 64 | theta = [10,0.5]; 65 | theta(:,1) = log(theta(:,1) - 2); 66 | theta(:,2) = log(theta(:,2)/(1-theta(:,2))); 67 | 68 | f_opt = @(xx) loglik_t_copula(u,xx); 69 | f_opt(theta) 70 | 71 | theta = fminunc(f_opt,theta); 72 | 73 | nu = 2 + exp(theta(1,1)); 74 | rho = exp(theta(1,2))/(1+exp(theta(1,2))); -------------------------------------------------------------------------------- /include/Models/loglik_copula_gas.m: -------------------------------------------------------------------------------- 1 | function [LL, f, rho] = loglik_copula_gas(theta, y, link) 2 | [N,~] = size(theta); 3 | T = size(y, 1); 4 | 5 | if (nargin == 2) 6 | link = 1; 7 | end 8 | 9 | omega = theta(:,1); 10 | A = theta(:,2); 11 | B = theta(:,3); 12 | 13 | z = norminv(y); 14 | 15 | f = zeros(N,T); % alpha in the paper, time-varying parameter following GAS recursion 16 | f(:,1) = omega./(1-B); 17 | 18 | if link 19 | transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 20 | else 21 | transf = @(aa) (exp(2*aa)-1)./(exp(2*aa)+1); 22 | end 23 | rho = zeros(N,T); % the time-varying parameter tranfsormed by the trnasf function --> rho, i.e. the correlation 24 | rho(:,1) = transf(f(:,1)); 25 | 26 | scoref = @(z1, z2, r) ((1 + r.^2).*(z1.*z2 - r) - r.*(z1.^2 + z2.^2 - 2))./((1 - r.^2).^2); 27 | inff = @(r) (1 + r.^2)./((1 - r.^2).^2); 28 | 29 | for jj = 2:T 30 | s = scoref(z(jj-1,1), z(jj-1,2), rho(:,jj-1)); 31 | scscore = s./sqrt(inff(rho(:,jj-1))); 32 | f(:,jj) = omega + A.*scscore + B.*f(:,jj-1); 33 | rho(:,jj) = transf(f(:,jj)); 34 | end 35 | 36 | Z1 = repmat(z(:,1)',N,1); 37 | Z2 = repmat(z(:,2)',N,1); 38 | LL = - 0.5*log(1-rho.^2) - 0.5*(Z1.^2 + Z2.^2 - 2*rho.*Z1.*Z2)./(1-rho.^2) ... 39 | + 0.5*Z1.^2 + 0.5*Z2.^2; 40 | LL = -sum(LL,2)/T; 41 | 42 | % f_T = f(:,T); 43 | % rho_T = rho(:,T); 44 | end 45 | 46 | % function scaled_score = scaled_score_copula_gas(y1, y2, rho) 47 | % score = ((1 + rho.^2).*(y1.*y2 - rho) - rho.(y1.^2 + y2.^2 - 2))./((1 - rho.^2).^2); 48 | % I = (1 + rho.^2)./((1 - rho.^2).^2); 49 | % scaled_score = score./sqrt(I); 50 | % end -------------------------------------------------------------------------------- /include/Distributions/MEX/my_norminv.c: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "math.h" 3 | #include "matrix.h" 4 | 5 | /******************************************************************* */ 6 | 7 | void my_norminv(double *ninv, double *y, mwSignedIndex T, mwSignedIndex D) 8 | { 9 | mxArray *in_array_ptr, *out_array_ptr; // mxArray * - a pointer to a struct (A POINTER TO A POINTER??) 10 | 11 | in_array_ptr = mxCreateDoubleMatrix(T, D, mxREAL); 12 | 13 | memcpy(mxGetPr(in_array_ptr), y, T*D*sizeof(double)); // start copying at the double returned by mxGetPr(array_ptr) 14 | 15 | mexCallMATLAB(1, &out_array_ptr, 1, &in_array_ptr, "norminv"); // & turns a value into a pointer --> call a MATLAB function with pointer to real matrices 16 | memcpy(ninv, mxGetPr(out_array_ptr), T*D*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 17 | 18 | mxDestroyArray(in_array_ptr); 19 | mxDestroyArray(out_array_ptr); 20 | } 21 | 22 | /******************************************************************* */ 23 | 24 | /* The gateway function */ 25 | void mexFunction( int nlhs, mxArray *plhs[], 26 | int nrhs, const mxArray *prhs[]) 27 | { 28 | mwSignedIndex N, k, T, D; /* size of matrix */ 29 | double *y; /* input*/ 30 | double *ninv; /* output */ 31 | 32 | /* Getting the inputs */ 33 | y = mxGetPr(prhs[0]); 34 | 35 | T = mxGetM(prhs[0]); /* no. of observations */ 36 | D = mxGetN(prhs[0]); /* no. of series */ 37 | 38 | 39 | /* create the output matrix */ 40 | plhs[0] = mxCreateDoubleMatrix(T,D,mxREAL); /* log posterior */ 41 | 42 | /* get a pointer to the real data in the output matrix */ 43 | ninv = mxGetPr(plhs[0]); 44 | 45 | /* call the function */ 46 | my_norminv(ninv, y, T, D); 47 | } 48 | -------------------------------------------------------------------------------- /simulate_copula_ss.m: -------------------------------------------------------------------------------- 1 | function [u_sim, f_true, rho_true] = simulate_copula_ss(mu_true, T, N, link) 2 | d = size(mu_true,2); 3 | 4 | c = mu_true(:,1); 5 | sigma_nu = mu_true(:,2); 6 | phi = mu_true(:,3); 7 | a1 = c./(1-phi); 8 | P1 = sigma_nu.^2./(1-phi.^2); 9 | if (d == 4) 10 | nu = mu_true(:,4); 11 | end 12 | if link 13 | transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 14 | else 15 | transf = @(aa) (exp(2*aa)-1)./(exp(2*aa)+1); 16 | end 17 | f_true = zeros(N,T); 18 | u_sim = zeros(T,2,N); 19 | 20 | f_true(:,1) = a1 + sqrt(P1).*randn(N,1); 21 | 22 | for ii = 2:T 23 | f_true(:,ii) = c + phi.*f_true(:,ii-1) + sigma_nu.*randn(N,1); 24 | end 25 | rho_true = transf(f_true); 26 | if (d == 3) 27 | for jj = 1:N 28 | u_sim(:,:,jj) = bi_copula_n_rnd(rho_true(jj,:)); 29 | end 30 | else 31 | for jj = 1:N 32 | u_sim(:,:,jj) = bi_copula_t_rnd(rho_true(jj,:), nu); 33 | end 34 | end 35 | 36 | if (N == 1) 37 | u_sim = squeeze(u_sim); 38 | end 39 | % tic 40 | % u_sim = zeros(3000,2); 41 | % for ii=1:T 42 | % u_sim(ii,:) = copularnd('t',rho_true(1,ii),mu_true(1,4),1); 43 | % end 44 | % toc%3.895109 45 | 46 | % tic 47 | % toc%0.371761 48 | 49 | end 50 | 51 | % rho_true=[0.99*ones(1,1000),0.5*ones(1,1000),zeros(1,1000)];% 52 | % figure(1) 53 | % subplot(2,3,1) 54 | % scatter(u_sim(1:1000,1),u_sim(1:1000,2)) 55 | % subplot(2,3,2) 56 | % scatter(u_sim(1001:2000,1),u_sim(1001:2000,2)) 57 | % subplot(2,3,3) 58 | % scatter(u_sim(2001:3000,1),u_sim(2001:3000,2)) 59 | % subplot(2,3,4) 60 | % scatter(u_sim2(1:1000,1),u_sim2(1:1000,2),'r') 61 | % subplot(2,3,5) 62 | % scatter(u_sim2(1001:2000,1),u_sim2(1001:2000,2),'r') 63 | % subplot(2,3,6) 64 | % scatter(u_sim2(2001:3000,1),u_sim2(2001:3000,2),'r') 65 | -------------------------------------------------------------------------------- /Exercises/Contour_plots.m: -------------------------------------------------------------------------------- 1 | % contour plots 2 | M = 100; 3 | OO = ones(1,M); 4 | xx = linspace(-4,4,M)'; 5 | vv = (0.02:0.02:0.28); 6 | 7 | t_uv_pdf = @(x,mu,Sigma,nu) exp(log(gamma((nu+1)/2)) - log(gamma(nu/2)) - 0.5*log(pi*nu) - 0.5*log(Sigma)... 8 | - ((nu+1)/2)*log(1 + ((x-mu).^2)/(Sigma*nu))); 9 | t_copula_pdf = @(u,R,nu) t_mv_pdf(tinv(u,nu),[],R,nu)./prod(t_uv_pdf(tinv(u,nu),0,1,nu),2); 10 | 11 | rho = 0.8; 12 | Rho = Correl_mat(rho); 13 | 14 | DF = [3,10]; 15 | figure(1) 16 | for pp = 1:6 17 | % margins: 18 | if (mod(pp,3) == 0) 19 | df1 = DF(2); 20 | else 21 | df1 = DF(1); 22 | end 23 | if (mod(pp,3) == 1) 24 | df2 = DF(1); 25 | else 26 | df2 = DF(2); 27 | end 28 | xx1 = tpdf(xx,df1); 29 | xx2 = tpdf(xx,df2); 30 | 31 | % feeds to copula: 32 | uu1 = tcdf(xx,df1); 33 | uu2 = tcdf(xx,df2); 34 | 35 | % copula common evaualtion 36 | if (pp <= 3) 37 | df = DF(1); 38 | else 39 | df = DF(2); 40 | end 41 | zz1 = tinv(uu1,df); 42 | zz2 = tinv(uu2,df); 43 | 44 | tt1 = t_uv_pdf(zz1,0,1,df); 45 | tt2 = t_uv_pdf(zz2,0,1,df); 46 | 47 | % copula pdf 48 | CPDF = zeros(M,M); 49 | for ii = 1:M 50 | u_in = [uu1(ii)*OO', uu2]; 51 | CPDF(:,ii) = t_copula_pdf(u_in,Rho,df); 52 | % uu's are distinct feeds to copula 53 | % z_in is their common evaluation 54 | % z_in = [tinv(uu1,df),tinv(uu2(ii),df)*ones(M,1)]; 55 | % CPDF(:,ii) = t_mv_pdf(z_in,[],Rho,df); 56 | % CPDF(:,ii) = CPDF(:,ii)./prod(t_uv_pdf(z_in,0,1,df),2); 57 | % % CPDF(:,ii) = CPDF(:,ii)./(tt1*tt2(ii)); 58 | end 59 | % surf(CPDF) 60 | % contour(xx,xx,CPDF) 61 | 62 | % joint pdf = prod(margins pdf)*copula pdf 63 | Y = (OO'*xx1') .* (xx2*OO) .* CPDF; 64 | % surf(Y) 65 | subplot(2,3,pp) 66 | contour(xx,xx,Y,vv); 67 | title(sprintf('df1 = %i, df2 = %i, df = %i ',df1,df2,df)); 68 | end -------------------------------------------------------------------------------- /include/Models/transformation/transform_param_gas.m: -------------------------------------------------------------------------------- 1 | function param_trans = transform_param_gas(param, mode, link) 2 | param_trans = param; 3 | d = size(param,2); 4 | 5 | switch mode 6 | % case 'sim_opt' % transformation for optimization --> unbounded 7 | % param(1,2) = param(1,2)/2 + 0.5; 8 | % param_trans(1,2) = log(param(1,2)/(1-param(1,2))); 9 | % param_trans(1,3) = log(param(1,3)); 10 | % if (d == 4) 11 | % param_trans(1,4) = log(param(1,4) - 2); 12 | % end 13 | % 14 | % case 'sim_back' % if mode == 'back' (transform back) 15 | % param_trans(1,2) = exp(param(1,2))/(1+exp(param(1,2))); 16 | % param_trans(1,2) = 2*(param_trans(1,2) - 0.5); 17 | % param_trans(1,3) = exp(param(1,3)); 18 | % if (d == 4) 19 | % param_trans(1,4) = 2 + exp(param(1,4)); 20 | % end 21 | 22 | % case 'est_opt' % transformation for optimization --> unbounded 23 | case 'opt' % transformation for optimization --> unbounded 24 | if link 25 | param_trans(1,2) = log(param(1,2)); 26 | end 27 | param_trans(1,4) = log(param(1,4)/(1-param(1,4))); 28 | if (d == 5) 29 | param_trans(1,5) = log(param(1,5) - 2); 30 | end 31 | 32 | % case 'est_back'% if mode == 'back' (transform back) 33 | case 'back'% if mode == 'back' (transform back) 34 | if link 35 | param_trans(1,2) = exp(param(1,2)); 36 | end 37 | param_trans(1,4) = exp(param(1,4))/(1+exp(param(1,4))); 38 | param_trans(1,4) = min(0.998, param_trans(1,4)); 39 | if (d == 5) 40 | param_trans(1,5) = 2 + exp(param(1,5)); 41 | param_trans(1,5) = min(200, param_trans(1,5)); 42 | end 43 | end 44 | end -------------------------------------------------------------------------------- /include/Distributions/fn_rmvgt_robust.m: -------------------------------------------------------------------------------- 1 | function [theta, lnk, ind_red, x, lng_y, lnw_x, eps_bar, eps_sim, C_T, lnp_T, RND] = fn_rmvgt_robust(N, mit, kernel, resampl_on, extended) 2 | % robust sampling from mixture of multivariate t densities 3 | % when resampl_on == 1 samples are redrawn from mit if they correspond to a bad region with zero 4 | % kernel density (i.e. these with -Inf weights) 5 | % "Standard" kernel evaluation is modified to account for the state space models 6 | % (in that case there are five inputs and additional outputs) 7 | 8 | % Mixtue of t (mit) parameters: 9 | mu = mit.mu; 10 | Sigma = mit.Sigma; 11 | df = mit.df; 12 | p = mit.p; 13 | 14 | theta = rmvgt2(N, mu, Sigma, df, p); % Sampling from the mixture of t 15 | 16 | % lnk - N vector of log-kernel evaluations at draws 17 | fprintf('\nKernel computation \n') 18 | 19 | if (nargin == 4) % not Extended version (an observation driven model) 20 | lnk = kernel(theta); 21 | else % Extedned version (a parametric model) 22 | [lnk, x, lng_y, lnw_x, eps_bar, eps_sim, C_T, lnp_T, RND] = kernel(theta); 23 | end 24 | 25 | ind_red = 0; 26 | if resampl_on % Perform resampling to consturct the required mixture 27 | while any(lnk == -Inf) 28 | ind_red = ind_red + 1; 29 | ind = find(lnk == -Inf); 30 | n_resamp = length(ind); 31 | % fprintf('resampling %d draws.\n', n_resamp) 32 | draw_new = rmvgt2(n_resamp, mu, Sigma, df, p); 33 | theta(ind,:) = draw_new; 34 | 35 | if (nargin == 4) % not Extedned version (an observation driven model) 36 | lnk(ind) = kernel(draw_new); 37 | else % Extedned version (a parametric model) 38 | % [lnk(ind), x(ind,:), lng_y(ind), lnw_x(ind), x_smooth(:,ind)] = kernel(draw_new); 39 | [lnk(ind), x(ind,:), lng_y(ind), lnw_x(ind)] = kernel(draw_new); 40 | end 41 | end 42 | end 43 | end -------------------------------------------------------------------------------- /include/Models/MEX/volatility_t_garch_noS_mex.c: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "math.h" 3 | 4 | void volatility_t_garch(double *y, mwSignedIndex N, mwSignedIndex T, double *S, 5 | double *theta, double *h) 6 | { 7 | // double *omega; 8 | mwSignedIndex i, j; 9 | 10 | /* Variable size arrays */ 11 | // omega = malloc((N)*sizeof(double)); 12 | 13 | /* Initialise */ 14 | for (i=0; i call a MATLAB function with pointer to real matrices 22 | memcpy(tinv, mxGetPr(out_array_ptr), T*D*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 23 | 24 | mxDestroyArray(in_array_ptr); 25 | mxDestroyArray(out_array_ptr); 26 | } 27 | 28 | /******************************************************************* */ 29 | 30 | /* The gateway function */ 31 | void mexFunction( int nlhs, mxArray *plhs[], 32 | int nrhs, const mxArray *prhs[]) 33 | { 34 | mwSignedIndex N, k, T, D; /* size of matrix */ 35 | double *y, *nu; /* input*/ 36 | double *tinv; /* output */ 37 | 38 | /* Getting the inputs */ 39 | nu = mxGetPr(prhs[0]); 40 | y = mxGetPr(prhs[1]); 41 | 42 | N = mxGetM(prhs[0]); /* no of parameter draws */ 43 | T = mxGetM(prhs[1]); /* no. of observations */ 44 | D = mxGetN(prhs[1]); /* no. of series */ 45 | 46 | 47 | /* create the output matrix */ 48 | plhs[0] = mxCreateDoubleMatrix(T,D,mxREAL); /* log posterior */ 49 | 50 | /* get a pointer to the real data in the output matrix */ 51 | tinv = mxGetPr(plhs[0]); 52 | 53 | /* call the function */ 54 | my_tinv(tinv, y, nu, T, D); 55 | } 56 | -------------------------------------------------------------------------------- /simulate_copula_gas.m: -------------------------------------------------------------------------------- 1 | function [u_sim, f_true, rho_true] = simulate_copula_gas(mu_true, T, N, link) 2 | d = size(mu_true,2); 3 | 4 | omega = mu_true(:,1); 5 | A = mu_true(:,2); 6 | B = mu_true(:,3); 7 | if (d == 4) 8 | nu = mu_true(:,4); 9 | end 10 | if link 11 | transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 12 | else 13 | transf = @(aa) (exp(2*aa)-1)./(exp(2*aa)+1); 14 | end 15 | f_true = zeros(N,T); 16 | rho_true = zeros(N,T); 17 | u_sim = zeros(T,2,N); 18 | 19 | 20 | f(:,1) = omega./(1-B); 21 | rho_true(:,1) = transf(f(:,1)); 22 | if (d == 3) 23 | scoref = @(z1, z2, r) ((1 + r.^2).*(z1.*z2 - r) - r.*(z1.^2 + z2.^2 - 2))./((1 - r.^2).^2); 24 | inff = @(r) (1 + r.^2)./((1 - r.^2).^2); 25 | 26 | for jj = 2:T 27 | u_sim(jj-1,:,ii) = bi_copula_n_rnd(rho_true(jj-1,:)); 28 | z = norminv(u_sim(jj-1,:,ii)); 29 | s = scoref(z(1,1), z(1,2), rho_true(:,jj-1)); 30 | scscore = s./sqrt(inff(rho_true(:,jj-1))); 31 | f_true(:,jj) = omega + A.*scscore + B.*f_true(:,jj-1); 32 | rho_true(:,jj) = transf(f_true(:,jj)); 33 | end 34 | else 35 | scoref = @(z1, z2, r, w) ((1 + r.^2).*(w.*z1.*z2 - r) - r.*(w.*z1.^2 + w.*z2.^2 - 2))./((1 - r.^2).^2); 36 | inff = @(r, v) (v + 2 + v.* r.^2)./((v+4).*(1 - r.^2).^2); 37 | wf = @(z1, z2, r, v) (v + 2)./(v + (z1.^2 + z2.^2 - 2*r.*z1.*z2)./(1 - r.^2)) ; 38 | 39 | for ii = 1:N 40 | z = tinv(y,nu(ii,1)); 41 | 42 | for jj = 2:T 43 | u_sim(:,:,jj) = bi_copula_n_rnd(rho_true(jj,:)); 44 | 45 | u_sim(jj-1,:) = bi_copula_t_rnd(rho_true(jj-1,:), nu); 46 | z = tinv(u_sim(jj-1,:),nu); 47 | 48 | w = wf(z(1,1), z(1,2), rho_true(ii,jj-1), nu(ii,1)); 49 | s = scoref(z(1,1), z(1,2), rho_true(ii,jj-1), w); 50 | scscore = s./sqrt(inff(rho_true(ii,jj-1), nu(ii,1))); 51 | 52 | f_true(ii,jj) = omega(ii,1) + A(ii,1).*scscore + B(ii,1).*f_true(ii,jj-1); 53 | rho_true(ii,jj) = transf(f_true(ii,jj)); 54 | end 55 | end 56 | end 57 | 58 | if (N == 1) 59 | u_sim = squeeze(u_sim); 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /include/Models/loglik_copula_t_gas.m: -------------------------------------------------------------------------------- 1 | function [LL, f, rho] = loglik_copula_t_gas(theta, y) 2 | [N,~] = size(theta); 3 | T = size(y, 1); 4 | 5 | if (nargin == 2) 6 | link = 1; 7 | end 8 | 9 | omega = theta(:,1); 10 | A = theta(:,2); 11 | B = theta(:,3); 12 | nu = theta(:,4); 13 | 14 | f = zeros(N,T); % alpha in the paper, time-varying parameter following GAS recursion 15 | f(:,1) = omega./(1-B); 16 | if link 17 | transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 18 | else 19 | transf = @(aa) (exp(2*aa)-1)./(exp(2*aa)+1); 20 | end 21 | rho = zeros(N,T); % the time-varying parameter tranfsormed by the trnasf function --> rho, i.e. the correlation 22 | rho(:,1) = transf(f(:,1)); 23 | 24 | LL = zeros(N,1); 25 | 26 | scoref = @(z1, z2, r, w) ((1 + r.^2).*(w.*z1.*z2 - r) - r.*(w.*z1.^2 + w.*z2.^2 - 2))./((1 - r.^2).^2); 27 | inff = @(r, v) (v + 2 + v.* r.^2)./((v+4).*(1 - r.^2).^2); 28 | wf = @(z1, z2, r, v) (v + 2)./(v + (z1.^2 + z2.^2 - 2*r.*z1.*z2)./(1 - r.^2)) ; 29 | 30 | for ii = 1:N 31 | z = tinv(y,nu(ii,1)); 32 | for jj = 2:T 33 | w = wf(z(jj-1,1), z(jj-1,2), rho(ii,jj-1), nu(ii,1)); 34 | % fprintf('w = %6.4f\n', w); 35 | s = scoref(z(jj-1,1), z(jj-1,2), rho(ii,jj-1), w); 36 | scscore = s./sqrt(inff(rho(ii,jj-1), nu(ii,1))); 37 | f(ii,jj) = omega(ii,1) + A(ii,1).*scscore + B(ii,1).*f(ii,jj-1); 38 | rho(ii,jj) = transf(f(ii,jj)); 39 | end 40 | 41 | Z1 = z(:,1)'; 42 | Z2 = z(:,2)'; 43 | 44 | L = log(gamma((nu(ii,1)+2)/2)) + log(gamma(nu(ii,1)/2)) - 2*log(gamma((nu(ii,1)+1)/2)) ... 45 | - 0.5*log(1-rho(ii,:).^2) ... 46 | - 0.5*(nu(ii,1)+2).*log(1 + (Z1.^2 + Z2.^2 - 2*rho(ii,:).*Z1.*Z2)./(nu(ii,1).*(1 - rho(ii,:).^2))) ... 47 | + 0.5*(nu(ii,1)+1).*log(1 + (Z1.^2)./nu(ii,1)) ... 48 | + 0.5*(nu(ii,1)+1).*log(1 + (Z2.^2)./nu(ii,1)); 49 | LL(ii,1) = -sum(L,2)/T; 50 | end 51 | % f_T = f(:,T); 52 | % rho_T = rho(:,T); 53 | end 54 | 55 | % function scaled_score = scaled_score_copula_gas(y1, y2, rho) 56 | % score = ((1 + rho.^2).*(y1.*y2 - rho) - rho.(y1.^2 + y2.^2 - 2))./((1 - rho.^2).^2); 57 | % I = (1 + rho.^2)./((1 - rho.^2).^2); 58 | % scaled_score = score./sqrt(I); 59 | % end -------------------------------------------------------------------------------- /include/Models/loglik_copula_t_gas2.m: -------------------------------------------------------------------------------- 1 | function [LL, f, rho] = loglik_copula_t_gas2(theta, y) 2 | [N,~] = size(theta); 3 | T = size(y, 1); 4 | 5 | omega = theta(:,1); 6 | A = theta(:,2); 7 | B = theta(:,3); 8 | nu = theta(:,4); 9 | 10 | f = zeros(N,T); % alpha in the paper, time-varying parameter following GAS recursion 11 | f(:,1) = omega./(1-B); 12 | % transf = @(aa) (1 - exp(-aa))./(1 + exp(-aa)); 13 | rho = zeros(N,T); % the time-varying parameter tranfsormed by the trnasf function --> rho, i.e. the correlation 14 | rho(:,1) = transf(f(:,1)); 15 | 16 | LL = zeros(N,1); 17 | 18 | % scoref = @(z1, z2, r, w) ((1 + r.^2).*(w.*z1.*z2 - r) - r.*(w.*z1.^2 + w.*z2.^2 - 2))./((1 - r.^2).^2); 19 | % inff = @(r, v) (v + 2 + v.* r.^2)./((v+4).*(1 - r.^2).^2); 20 | % wf = @(z1, z2, r, v) (v + 2)./(v + (z1.^2 + z2.^2 - 2*r.*z1.*z2)./(1 - r.^2)) ; 21 | 22 | for ii = 1:N 23 | z = tinv(y,nu(ii,1)); 24 | for jj = 2:T 25 | w = wf(z(jj-1,1), z(jj-1,2), rho(ii,jj-1), nu(ii,1)); 26 | % fprintf('w = %6.4f\n', w); 27 | s = scoref(z(jj-1,1), z(jj-1,2), rho(ii,jj-1), w); 28 | scscore = s./sqrt(inff(rho(ii,jj-1), nu(ii,1))); 29 | f(ii,jj) = omega(ii,1) + A(ii,1).*scscore + B(ii,1).*f(ii,jj-1); 30 | rho(ii,jj) = transf(f(ii,jj)); 31 | end 32 | 33 | Z1 = z(:,1)'; 34 | Z2 = z(:,2)'; 35 | 36 | L = log(gamma((nu(ii,1)+2)/2)) + log(gamma(nu(ii,1)/2)) - 2*log(gamma((nu(ii,1)+1)/2)) ... 37 | - 0.5*log(1-rho(ii,:).^2) ... 38 | - 0.5*(nu(ii,1)+2).*log(1 + (Z1.^2 + Z2.^2 - 2*rho(ii,:).*Z1.*Z2)./(nu(ii,1).*(1 - rho(ii,:).^2))) ... 39 | + 0.5*(nu(ii,1)+1).*log(1 + (Z1.^2)./nu(ii,1)) ... 40 | + 0.5*(nu(ii,1)+1).*log(1 + (Z2.^2)./nu(ii,1)); 41 | LL(ii,1) = -sum(L,2)/T; 42 | end 43 | % f_T = f(:,T); 44 | % rho_T = rho(:,T); 45 | end 46 | 47 | function w = wf(z1, z2, r, v) 48 | w = (v + 2)./(v + (z1.^2 + z2.^2 - 2*r.*z1.*z2)./(1 - r.^2)) ; 49 | end 50 | 51 | function s = scoref(z1, z2, r, w) 52 | s = ((1 + r.^2).*(w.*z1.*z2 - r) - r.*(w.*z1.^2 + w.*z2.^2 - 2))./((1 - r.^2).^2); 53 | end 54 | 55 | function invf = inff(r, v) 56 | invf = (v + 2 + v.* r.^2)./((v+4).*(1 - r.^2).^2); 57 | end 58 | 59 | function aa = transf(aa) 60 | aa = (1 - exp(-aa))./(1 + exp(-aa)); 61 | end -------------------------------------------------------------------------------- /include/Models/posterior_t_garch_noS.m: -------------------------------------------------------------------------------- 1 | function d = posterior_t_garch_noS(theta, data, S, L, hyper, GamMat) 2 | % theta is Nx5, matrix of draws 3 | [N ,~] = size(theta); 4 | omega = theta(:,1); 5 | alpha = theta(:,2); 6 | beta = theta(:,3); 7 | mu = theta(:,4); 8 | nu = theta(:,5); 9 | 10 | prior = prior_t_garch(N, omega, alpha, beta, mu, nu, L, hyper); 11 | T = size(data,1); 12 | ind = 1:T-1; 13 | 14 | d = -Inf*ones(N,1); 15 | h = zeros(T,1); 16 | h(1,1) = S; 17 | % omega = S*(1-alpha-beta); % variance targeting constraint 18 | rho = (nu-2)./nu; 19 | 20 | for ii = 1:N 21 | if mod(ii,1000) == 0 22 | fprintf('posterior ii = %d\n',ii); 23 | end 24 | 25 | pdf = zeros(T,1); 26 | if (prior(ii,1)) % when all the parameter constraints are satisfied 27 | % h(1,1) = omega(ii,1)/(1-alpha(ii,1)-beta(ii,1)); % unconditional variance to initialize h_1 28 | % pdf(1,1) = dmvt(data(1,1), mu(ii,1), rho(ii,1)*h(1,1), nu(ii,1), GamMat); 29 | % pdf(1,1) = log(pdf(1,1)); 30 | h(2:T) = omega(ii,1) + alpha(ii,1)*(data(ind,1)-mu(ii,1)).^2; 31 | for jj = 2:T 32 | h(jj,1) = h(jj,1) + beta(ii,1)*h(jj-1,1); 33 | % eps = (data(jj,1) - mu(ii,1))/sqrt(rho(ii,1)*h(jj,1)); 34 | % tmp = tpdf(eps, nu(ii,1)); 35 | pdf(jj,1) = dmvt(data(jj,1), mu(ii,1), rho(ii,1)*h(jj,1), nu(ii,1), GamMat); 36 | pdf(jj,1)= log(pdf(jj,1)); 37 | % pdf(jj,1) = log(tmp); 38 | end 39 | d(ii,1) = sum(pdf) + prior(ii,2); 40 | end 41 | end 42 | if (~L) 43 | d = exp(d); 44 | end 45 | end 46 | 47 | 48 | function R = prior_t_garch(N, omega, alpha, beta, mu, nu, L, hyper) 49 | % uniform prior on alpha and beta on (0,1) 50 | % with restriction alpha + beta < 1 51 | % uniform prior on mu on [-1,1] 52 | % exponential uninformative prior on nu with hyperparam hyper 53 | % prior is an Nx2 matrix: 54 | % 1 col - constraint satisfied? 55 | % 2 col - prior val an the corresponding point 56 | 57 | c1 = ((alpha >= 0) & (alpha < 1) & (beta >= 0) & (beta < 1)); 58 | c2 = (alpha + beta < 1); 59 | c3 = (omega > 0); 60 | % c3 = ((mu > -1) & (mu < 1)); 61 | c4 = (nu > 2); 62 | 63 | r1 = (c1 & c2 & c3 & c4); 64 | % r1 = (c1 & c2 & c4); 65 | 66 | r2 = -Inf*ones(N,1); 67 | r2(r1==true) = log(hyper) - hyper*( nu(r1==true) - 2); % exponential prior: nu~exp(1) --> p(nu)=exp(-nu) from 2 to inf 68 | if (~L) 69 | r2 = exp(r2); 70 | end 71 | R = [r1, r2]; 72 | end 73 | -------------------------------------------------------------------------------- /include/Models/loglik_t_gas.m: -------------------------------------------------------------------------------- 1 | function [LL, f, sigma2] = loglik_t_gas(theta, y, link, scale, GamMat) 2 | % theta is Nx5, matrix of draws 3 | [N ,~] = size(theta); 4 | mu = theta(:,1); 5 | omega = theta(:,2); 6 | A = theta(:,3); 7 | B = theta(:,4); 8 | nu = theta(:,5); 9 | 10 | rho = (nu-2)./nu; 11 | 12 | % nu_con1 = (nu+1)./(nu-2); 13 | nu_con2 = 2*((nu+3)./nu); 14 | 15 | if link 16 | fn_link = @(xx) xx; 17 | fn_chain_rule = @(xx) 1; 18 | else 19 | fn_link = @(xx) exp(xx); 20 | fn_chain_rule = @(xx) xx; 21 | end 22 | 23 | if scale 24 | fn_scale = @(xx) xx; 25 | else 26 | fn_scale = @(xx) sqrt(xx); 27 | end 28 | 29 | T = size(y,1); 30 | 31 | d = -Inf*ones(N,1); 32 | LL = -Inf*ones(N,1); 33 | 34 | for ii = 1:N 35 | if mod(ii,1000) == 0 36 | fprintf('loglik ii = %d\n',ii); 37 | end 38 | 39 | f = zeros(T,1); 40 | sigma2 = zeros(T,1); 41 | 42 | pdf = zeros(T,1); 43 | L = zeros(T,1); 44 | 45 | f(1,1) = omega(ii,1)/(1-B(ii,1)); % unconditional variance to initialize h_1 46 | sigma2(1,1) = fn_link(f(1,1)); 47 | 48 | % % pdf(1,1) = dmvt(y(1,1), mu(ii,1), rho(ii,1)*sigma2(1,1), nu(ii,1), GamMat); 49 | pdf(1,1) = duvt_garch(y(1,1), mu(ii,1), rho(ii,1)*sigma2(1,1), nu(ii,1), GamMat); 50 | pdf(1,1) = log(pdf(1,1)); 51 | y2 = ((y(1,1)-mu(ii,1)).^2)./((nu(ii,1)-2)*sigma2(1,1)); 52 | L(1,1) = log(gamma((nu(ii,1)+1)/2))-log(gamma(nu(ii,1)/2))-0.5*log(nu(ii,1)-2) - 0.5*log(pi) ... 53 | - 0.5*log(sigma2(1,1))-((nu(ii,1)+1)/2)*log(1+y2); 54 | 55 | for jj = 2:T 56 | inv_fisher = nu_con2(ii,1).*(sigma2(jj-1,1).^2)./(fn_chain_rule(sigma2(jj-1,1).^2)); 57 | scale = fn_scale(inv_fisher); 58 | w = (nu(ii,1)+1)./(nu(ii,1) - 2 + ((y(jj-1,1)-mu(ii,1)).^2)./sigma2(jj-1,1)); 59 | score = (w.*((y(jj-1,1)-mu(ii,1)).^2)./sigma2(jj-1,1) - 1)./(2*sigma2(jj-1,1)); 60 | score = fn_chain_rule(sigma2(jj-1,1)).*score; 61 | scaled_score = scale.*score; 62 | 63 | f(jj,1) = omega(ii,1) + A(ii,1)*scaled_score + B(ii,1)*f(jj-1,1); 64 | sigma2(jj,1) = fn_link(f(jj,1)); 65 | 66 | % % pdf(jj,1) = dmvt(y(jj,1), mu(ii,1), rho(ii,1)*f(jj,1), nu(ii,1), GamMat); 67 | pdf(jj,1) = duvt_garch(y(jj,1), mu(ii,1), rho(ii,1)*sigma2(jj,1), nu(ii,1), GamMat); 68 | pdf(jj,1) = log(pdf(jj,1)); 69 | y2 = ((y(jj,1)-mu(ii,1)).^2)./((nu(ii,1)-2)*sigma2(jj,1)); 70 | L(jj,1) = log(gamma((nu(ii,1)+1)/2))-log(gamma(nu(ii,1)/2))-0.5*log(nu(ii,1)-2)- 0.5*log(pi) ... 71 | - 0.5*log(sigma2(jj,1))-((nu(ii,1)+1)/2)*log(1+y2); 72 | end 73 | d(ii,1) = -sum(pdf)/T; 74 | LL(ii,1) = -sum(L)/T; 75 | fprintf('d(%i,1) = %8.6f, LL(%i,1) = %8.6f, DIFF = %8.6f\n', ii, d(ii,1), ii, LL(ii,1), d(ii,1)-LL(ii,1)); 76 | end 77 | end -------------------------------------------------------------------------------- /include/Models/posterior_t_gas.m: -------------------------------------------------------------------------------- 1 | function d = posterior_t_gas(theta, y, hyper, GamMat, link, scale) 2 | % theta is Nx5, matrix of draws 3 | [N ,~] = size(theta); 4 | mu = theta(:,1); 5 | omega = theta(:,2); 6 | A = theta(:,3); 7 | B = theta(:,4); 8 | nu = theta(:,5); 9 | 10 | rho = (nu-2)./nu; 11 | 12 | % nu_con1 = (nu+1)./(nu-2); 13 | nu_con2 = 2*((nu+3)./nu); 14 | % A = A.*((nu+3)./nu); 15 | 16 | if link 17 | fn_link = @(xx) xx; 18 | fn_chain_rule = @(xx) 1; 19 | else 20 | fn_link = @(xx) exp(xx); 21 | fn_chain_rule = @(xx) xx; 22 | end 23 | 24 | if scale 25 | fn_scale = @(xx) xx; 26 | else 27 | fn_scale = @(xx) sqrt(xx); 28 | end 29 | prior = prior_t_gas(N, omega, B, nu, hyper); 30 | 31 | T = size(y,1); 32 | 33 | d = -Inf*ones(N,1); 34 | 35 | for ii = 1:N 36 | if mod(ii,1000) == 0 37 | fprintf('posterior ii = %d\n',ii); 38 | end 39 | 40 | f = zeros(T,1); 41 | theta = zeros(T,1); 42 | pdf = zeros(T,1); 43 | 44 | if (prior(ii,1)) % when all the parameter constraints are satisfied 45 | f(1,1) = omega(ii,1)/(1-B(ii,1)); % unconditional variance to initialize h_1 46 | theta(1,1) = fn_link(f(1,1)); 47 | 48 | pdf(1,1) = dmvt(y(1,1), mu(ii,1), rho(ii,1)*theta(1,1), nu(ii,1), GamMat); 49 | pdf(1,1) = log(pdf(1,1)); 50 | 51 | for jj = 2:T 52 | % C = 1 + ((y(jj-1,1)-mu(ii,1)).^2)/((nu(ii,1)-2)*theta(jj-1,1)); 53 | inv_fisher = nu_con2(ii,1).*(theta(jj-1,1).^2)./(fn_chain_rule(theta(jj-1,1).^2)); 54 | scale = fn_scale(inv_fisher); 55 | w = (nu(ii,1)+1)./(nu(ii,1) - 2 + ((y(jj-1,1)-mu(ii,1)).^2)./theta(jj-1,1)); 56 | score = (w.*((y(jj-1,1)-mu(ii,1)).^2)./theta(jj-1,1) - 1)./(2*theta(jj-1,1)); 57 | score = fn_chain_rule(theta(jj-1,1)).*score; 58 | scaled_score = scale.*score; 59 | % scaled_score = ((nu+3)./nu).*(nu_con1(ii,1)*((y(jj-1,1)-mu(ii,1)).^2)/C - theta(jj-1,1)); 60 | 61 | f(jj,1) = omega(ii,1) + A(ii,1)*scaled_score + B(ii,1)*f(jj-1,1); 62 | theta(jj,1) = fn_link(f(jj,1)); 63 | 64 | % pdf(jj,1) = dmvt(y(jj,1), mu(ii,1), rho(ii,1)*f(jj,1), nu(ii,1), GamMat); 65 | pdf(jj,1) = dmvt(y(jj,1), mu(ii,1), rho(ii,1)*theta(jj,1), nu(ii,1), GamMat); 66 | pdf(jj,1) = log(pdf(jj,1)); 67 | end 68 | d(ii,1) = sum(pdf) + prior(ii,2); 69 | end 70 | end 71 | end 72 | 73 | function R = prior_t_gas(N, omega, B, nu, hyper) 74 | % uniform priors 75 | 76 | % prior is an Nx2 matrix: 77 | % 1 col - constraint satisfied? 78 | % 2 col - prior val an the corresponding point 79 | 80 | c1 = (omega > 0); 81 | c3 = ((B >= 0) & (B < 1)); 82 | c4 = (nu > 2); 83 | 84 | r1 = (c1 & c3 & c4); 85 | r2 = -Inf*ones(N,1); 86 | r2(r1==true) = log(hyper) - hyper*( nu(r1==true) - 2); % exponential prior: nu~exp(1) --> p(nu)=exp(-nu) from 2 to inf 87 | 88 | R = [r1, r2]; 89 | end -------------------------------------------------------------------------------- /include/Models/MEX/loglik_t_garch_noS_hyper_init_mex.c: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "math.h" 3 | #include "matrix.h" 4 | 5 | #define PI 3.1415926535897932; 6 | 7 | void duvt_garch(double x, double mu, double sigma, double df, double *GamMat, mwSignedIndex G, double *pdf) 8 | { 9 | double c0, c1, c2, c, e, tmp, etmp, df5; 10 | int ind; 11 | 12 | c0 = df+1; 13 | 14 | if (c0 <= 100) 15 | { 16 | ind = floor(c0*50000) - 1; 17 | c1 = GamMat[ind]; 18 | } 19 | else 20 | { 21 | c1 = GamMat[G-1]; 22 | } 23 | 24 | if (df <= 100) 25 | { 26 | df5 = df*50000; 27 | if ((df5 - floor(df5)) < (floor(df5+1) - df5)) 28 | { 29 | ind = floor(df5); 30 | } 31 | else 32 | { 33 | ind = floor(df5 + 1); 34 | } 35 | ind = ind - 1; 36 | c2 = GamMat[ind]; 37 | } 38 | else 39 | { 40 | c2 = GamMat[G-1]; 41 | } 42 | 43 | c = df*PI; 44 | c = pow(c,0.5); 45 | c2 = c2*c; 46 | c2 = c2*pow(sigma,0.5); 47 | c = c1/c2; 48 | e = -0.5*c0; 49 | 50 | tmp = (x-mu)*(x-mu)/sigma; 51 | tmp = 1 + tmp/df; 52 | etmp = pow(tmp,e); 53 | pdf[0] = exp(log(c) + log(etmp)); 54 | } 55 | 56 | void loglik_t_garch_noS_hyper_init_mex(double *y, mwSignedIndex N, mwSignedIndex T, double *S, 57 | double *theta, double *hyper, double *GamMat, mwSignedIndex G, double *d, 58 | double *Td) 59 | { 60 | double *rho; 61 | double h, *pdf; 62 | double rhoh; 63 | mwSignedIndex i, j; 64 | 65 | /* Variable size arrays */ 66 | rho = mxMalloc((N)*sizeof(double)); 67 | pdf = mxMalloc((1)*sizeof(double)); 68 | 69 | Td[0] = (double)(T); 70 | 71 | /* Initialise */ 72 | for (i=0; i normal errors 4 | % k == 5 --> stundent's t errors, with nu degrees of freedom 5 | % (l)ink: 1 - linear link, sigma2(f)=f; 0 - exp link, sigma2(f)=exp(f); 6 | % if exp link, nontrivial chain rule required, dsigma2/df = exp(f) = sigma2: 7 | % (s)cale: 1 - inv fisher; 0 - sqrt inv fisher 8 | % Note: (l,s) == (1,1) was discussed in the original GAS paper (Creal et al. 2013) 9 | % Note: (l,s) == (0,0) cancels out so the updating step has a constant unit variance 10 | % and is invariant under any nondegenerate parameter transformation (cf. Koopman et al. 2016) 11 | [N, k] = size(theta); 12 | mu = theta(:,1); 13 | omega = theta(:,2); 14 | A = theta(:,3); 15 | B = theta(:,4); 16 | 17 | if (k == 5) 18 | nu = theta(:,5); 19 | % rho = (nu-2)./nu; 20 | % nu_con1 = (nu+1)./(nu-2); 21 | nu_con2 = 2*((nu+3)./nu); 22 | end 23 | 24 | if link 25 | fn_link = @(xx) xx; 26 | fn_chain_rule = @(xx) 1; 27 | else 28 | fn_link = @(xx) exp(xx); 29 | fn_chain_rule = @(xx) xx; 30 | end 31 | 32 | if scale 33 | fn_scale = @(xx) xx; 34 | else 35 | fn_scale = @(xx) sqrt(xx); 36 | end 37 | 38 | T = size(y,1); 39 | 40 | % d = -Inf*ones(N,1); 41 | LL = -Inf*ones(N,1); 42 | 43 | for ii = 1:N 44 | if mod(ii,1000) == 0 45 | fprintf('loglik ii = %d\n',ii); 46 | end 47 | 48 | f = zeros(T,1); 49 | sigma2 = zeros(T,1); 50 | 51 | % pdf = zeros(T,1); 52 | L = zeros(T,1); 53 | 54 | f(1,1) = omega(ii,1)/(1-B(ii,1)); % unconditional variance to initialize f_1 55 | sigma2(1,1) = fn_link(f(1,1)); 56 | 57 | % pdf(1,1) = duvt_garch(y(1,1), mu(ii,1), rho(ii,1)*sigma2(1,1), nu(ii,1), GamMat); 58 | % pdf(1,1) = log(pdf(1,1)); 59 | % y2 = ((y(1,1)-mu(ii,1)).^2)./((nu(ii,1)-2)*sigma2(1,1)); 60 | % L(1,1) = log(gamma((nu(ii,1)+1)/2))-log(gamma(nu(ii,1)/2))-0.5*log(nu(ii,1)-2) - 0.5*log(pi) ... 61 | % - 0.5*log(sigma2(1,1))-((nu(ii,1)+1)/2)*log(1+y2); 62 | 63 | y2 = ((y(1,1)-mu(ii,1)).^2)./sigma2(1,1); 64 | 65 | if (k == 5) 66 | % pdf(1,1) = duvt_garch(y(1,1), mu(ii,1), rho(ii,1)*sigma2(1,1), nu(ii,1), GamMat); 67 | % pdf(1,1) = log(pdf(1,1)); 68 | y2 = y2./(nu(ii,1)-2); 69 | L(1,1) = log(gamma((nu(ii,1)+1)/2)) - log(gamma(nu(ii,1)/2))... 70 | - 0.5*(log(nu(ii,1)-2) + log(pi) + log(sigma2(1,1)) + (nu(ii,1)+1)*log(1+y2)); 71 | else 72 | L(1,1) = -0.5*(log(2*pi) + log(sigma2(1,1)) + y2); 73 | end 74 | 75 | for jj = 2:T 76 | if (k == 5) 77 | inv_fisher = nu_con2(ii,1).*(sigma2(jj-1,1).^2)./(fn_chain_rule(sigma2(jj-1,1).^2)); 78 | w = (nu(ii,1)+1)./(nu(ii,1) - 2 + ((y(jj-1,1)-mu(ii,1)).^2)./sigma2(jj-1,1)); 79 | score = (w.*((y(jj-1,1)-mu(ii,1)).^2)./sigma2(jj-1,1) - 1)./(2*sigma2(jj-1,1)); 80 | else 81 | inv_fisher = 2*(sigma2(jj-1,1).^2)./(fn_chain_rule(sigma2(jj-1,1).^2)); 82 | score = (((y(jj-1,1)-mu(ii,1)).^2)./sigma2(jj-1,1) - 1)./(2*sigma2(jj-1,1)); 83 | end 84 | S = fn_scale(inv_fisher); 85 | score = fn_chain_rule(sigma2(jj-1,1)).*score; 86 | scaled_score = S.*score; 87 | 88 | f(jj,1) = omega(ii,1) + A(ii,1)*scaled_score + B(ii,1)*f(jj-1,1); 89 | sigma2(jj,1) = fn_link(f(jj,1)); 90 | 91 | y2 = ((y(jj,1)-mu(ii,1)).^2)./sigma2(jj,1); 92 | 93 | if (k == 5) 94 | % pdf(jj,1) = duvt_garch(y(jj,1), mu(ii,1), rho(ii,1)*sigma2(jj,1), nu(ii,1), GamMat); 95 | % pdf(jj,1) = log(pdf(jj,1)); 96 | y2 = y2./(nu(ii,1)-2); 97 | L(jj,1) = log(gamma((nu(ii,1)+1)/2)) - log(gamma(nu(ii,1)/2))... 98 | - 0.5*(log(nu(ii,1)-2) + log(pi) + log(sigma2(jj,1)) + (nu(ii,1)+1)*log(1+y2)); 99 | else 100 | L(jj,1) = -0.5*(log(2*pi) + log(sigma2(jj,1)) + y2); 101 | end 102 | end 103 | LL(ii,1) = -sum(L)/T; 104 | % if (k == 5) 105 | % d(ii,1) = - sum(pdf)/T; 106 | % fprintf('d(%i,1) = %8.6f, LL(%i,1) = %8.6f, DIFF = %8.6f\n', ii, d(ii,1), ii, LL(ii,1), d(ii,1)-LL(ii,1)); 107 | % end 108 | end 109 | end -------------------------------------------------------------------------------- /copula_gas.m: -------------------------------------------------------------------------------- 1 | addpath(genpath('include/')); 2 | addpath(genpath('KLS/')); 3 | 4 | model = 'copula_t_gas'; 5 | 6 | options = optimset('display','iter','TolFun',1e-5,'LargeScale','off','TolX',1e-5,'HessUpdate','bfgs','FinDiffType','central',... 7 | 'maxiter',5000,'MaxFunEvals',5000); %display iter 8 | plot_on = false; 9 | 10 | %% EMPIRICAL 11 | % Given the estimation results for the marginals 12 | y = load('ibm_ccola_rets.txt'); 13 | T = size(y,1); 14 | ibm = y(:,1); 15 | ccola = y(:,2); 16 | 17 | load('Results/ibm_ccola_results.mat'); 18 | 19 | if link 20 | fn_link = @(xx) xx; 21 | else 22 | fn_link = @(xx) exp(xx); 23 | end 24 | 25 | % Standardized residuals, ~t(0,1,nu) (zero mean, unit variance) 26 | z_ibm = (ibm'-mu_ibm(1,1))./sqrt(fn_link(f_ibm)*(mu_ibm(1,5)-2)/mu_ibm(1,5)); 27 | z_ccola = (ccola'-mu_ccola(1,1))./sqrt(fn_link(f_ccola)*(mu_ccola(1,5)-2)/mu_ccola(1,5)); 28 | 29 | if plot_on 30 | hold on 31 | plot(z_ibm,'b') 32 | plot(z_ccola,'r') 33 | hold off 34 | end 35 | % cdf transforms of the residuals 36 | u_ibm = tcdf(z_ibm, mu_ibm(1,5)); 37 | u_ccola = tcdf(z_ccola, mu_ccola(1,5)); 38 | if plot_on 39 | hold on 40 | plot(u_ibm,'b') 41 | plot(u_ccola,'r') 42 | hold off 43 | end 44 | 45 | u = [u_ibm; u_ccola]'; 46 | mu_init = [0.02, 0.10, 0.98]; 47 | [f, rho] = volatility_copula_gas(mu_init, u); 48 | 49 | if plot_on 50 | hold on 51 | % plot(f_ibm,'b') 52 | % plot(f_ccola,'r') 53 | plot(rho,'k') 54 | plot(rho*0,'k:') 55 | hold off 56 | end 57 | 58 | %% SIMULATION 59 | mu_init = [0.02, 0.10, 0.98, 5]; 60 | mu_true = mu_init; 61 | T = 2500; 62 | N = 1; 63 | link = 1; 64 | [u, f, rho] = simulate_copula_ss(mu_true, T, N, link); 65 | % [u, f, rho] = simulate_copula_gas(mu_true, T, N, link); 66 | 67 | 68 | %% Normal Copula estimation 69 | 70 | fn_trans_param = @(xx, mm) transform_param_gas_copula(xx, mm); 71 | fn_jacobian = @(xx) jacobian_gas_copula(xx); 72 | link = 1; % 1: 2*(logsig-0.5) (KLS); 0: inv Fisher transform (Hafner & Manner 2012); 73 | scale = 0; % 1 - inv fisher; 0 - sqrt inv fisher 74 | 75 | mu_init = [0.02, 0.10, 0.98]; 76 | kernel_init = @(xx) loglik_copula_gas(fn_trans_param(xx,'back'), u); 77 | tic 78 | [mu_copula, ~, Hessian, signal_copula] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 79 | toc %Elapsed time is 18.795089 seconds. 80 | 81 | Sigma_copula = inv(T*Hessian); 82 | [f_copula, rho_copula] = volatility_copula_gas(mu_copula, u); 83 | 84 | 85 | kernel_init = @(xx) loglik_gen_copula_gas_mex(fn_trans_param(xx,'back'), u, link, scale); 86 | tic 87 | [mu_copula_mex, ~, Hessian_mex, signal_copula_mex] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 88 | toc %Elapsed time is 0.388792 seconds. 89 | 90 | if plot_on 91 | hold on 92 | % plot(f_ibm,'b') 93 | % plot(f_ccola,'r') 94 | plot(rho,'b') 95 | plot(rho_copula,'k') 96 | plot(rho*0,'k:') 97 | hold off 98 | end 99 | 100 | 101 | 102 | %% Student's t Copula estimation 103 | 104 | mu_init = [0.02, 0.10, 0.98, 8]; 105 | fn_trans_param = @(xx, mm) transform_param_gas_copula(xx, mm); 106 | fn_jacobian = @(xx) jacobian_gas_copula(xx); 107 | kernel_init = @(xx) loglik_copula_t_gas(fn_trans_param(xx,'back'), u); 108 | tic 109 | [mu_copula_t, ~, Hessian, signal_copula_t] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 110 | toc %Elapsed time is 7.022134 seconds. 111 | 112 | Sigma_copula_t = inv(T*Hessian); 113 | [~, f_copula_t, rho_copula_t] = loglik_copula_t_gas(mu_copula_t, u); 114 | 115 | 116 | link = 1; % 1: 2*(logsig-0.5) (KLS); 0: inv Fisher transform (Hafner & Manner 2012); 117 | scale = 0; % 1 - inv fisher; 0 - sqrt inv fisher 118 | kernel_init = @(xx) loglik_gen_copula_gas_mex(fn_trans_param(xx,'back'), u, link, scale); 119 | tic 120 | [mu_copula_t_mex, ~, Hessian_mex, signal_copula_t_mex] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 121 | toc %Elapsed time is 5.247818 seconds. 122 | 123 | 124 | if plot_on 125 | hold on 126 | % plot(f_ibm,'b') 127 | % plot(f_ccola,'r') 128 | plot(rho_copula,'b') 129 | plot(rho_copula_t,'k') 130 | plot(rho*0,'k:') 131 | hold off 132 | end 133 | 134 | %% Save 135 | save('Results/ibm_ccola_copula_gas_results.mat', 'link', 'scale', 'u', 'z_ibm', 'z_ccola', 'f_ibm', 'f_ccola', ... 136 | 'mu_copula', 'Sigma_copula', 'f_copula', 'rho_copula', 'mu_copula_t', 'Sigma_copula_t', 'f_copula_t', 'rho_copula_t'); 137 | 138 | %% Different link functions: 139 | link = 0; % 1: 2*(logsig-0.5) (KLS); 0: inv Fisher transform (Hafner & Manner 2012); 140 | scale = 0; % 1 - inv fisher; 0 - sqrt inv fisher 141 | kernel_init = @(xx) loglik_gen_copula_gas_mex(fn_trans_param(xx,'back'), u, link, scale); 142 | mu_init = [0.02, 0.10, 0.98]; 143 | 144 | tic 145 | [mu_copula_mex2, ~, Hessian_mex2, signal_copula_mex2] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 146 | toc 147 | 148 | mu_init = [0.02, 0.10, 0.98, 8]; 149 | 150 | tic 151 | [mu_copula_t_mex2, ~, Hessian_mex2, signal_copula_t_mex2] = estimate(kernel_init, mu_init, fn_trans_param, fn_jacobian, options); 152 | toc -------------------------------------------------------------------------------- /include/Models/MEX/posterior_t_gas_hyper_mex.c: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "math.h" 3 | #include "matrix.h" 4 | 5 | #define PI 3.1415926535897932; 6 | 7 | /******************************************************************* */ 8 | 9 | void duvt_garch(double x, double mu, double sigma, double df, double *GamMat, mwSignedIndex G, double *pdf) 10 | { 11 | double c0, c1, c2, c, e, tmp, etmp, df5; 12 | int ind; 13 | 14 | c0 = df+1; 15 | 16 | if (c0 <= 100) 17 | { 18 | ind = floor(c0*50000) - 1; 19 | c1 = GamMat[ind]; 20 | } 21 | else 22 | { 23 | c1 = GamMat[G-1]; 24 | } 25 | 26 | if (df <= 100) 27 | { 28 | df5 = df*50000; 29 | if ((df5 - floor(df5)) < (floor(df5+1) - df5)) 30 | { 31 | ind = floor(df5); 32 | } 33 | else 34 | { 35 | ind = floor(df5 + 1); 36 | } 37 | ind = ind - 1; 38 | c2 = GamMat[ind]; 39 | } 40 | else 41 | { 42 | c2 = GamMat[G-1]; 43 | } 44 | 45 | c = df*PI; 46 | c = pow(c,0.5); 47 | c2 = c2*c; 48 | c2 = c2*pow(sigma,0.5); 49 | c = c1/c2; 50 | e = -0.5*c0; 51 | 52 | tmp = (x-mu)*(x-mu)/sigma; 53 | tmp = 1 + tmp/df; 54 | etmp = pow(tmp,e); 55 | pdf[0] = exp(log(c) + log(etmp)); 56 | } 57 | 58 | /******************************************************************* */ 59 | 60 | 61 | void prior_t_gas_hyper(double *theta, double *hyper, 62 | mwSignedIndex N, mwSignedIndex *r1, double *r2) 63 | { 64 | mwSignedIndex i; 65 | 66 | /* Variable size arrays */ 67 | 68 | for (i=0; i0 74 | { 75 | r1[i] = 0; 76 | } 77 | if ((theta[i+3*N] < 0) || (theta[i+3*N] >= 1)) // 0<=B<1 78 | { 79 | r1[i] = 0; 80 | } 81 | if (theta[i+4*N] <= 2) //nu>2 82 | { 83 | r1[i] = 0; 84 | } 85 | if (r1[i] == 1) 86 | { 87 | r2[i] = log(hyper[0]) - hyper[0]*(theta[i+4*N] - 2); 88 | } 89 | } 90 | } 91 | 92 | /******************************************************************* */ 93 | 94 | 95 | void posterior_t_gas_hyper_mex(double *y, mwSignedIndex N, mwSignedIndex T, 96 | double *theta, double *hyper, double *GamMat, mwSignedIndex G, double *d) 97 | { 98 | mwSignedIndex *r1; 99 | double *r2; 100 | double *rho, *A, *nu_con; 101 | double h, *pdf; 102 | double rhoh, tmp; 103 | mwSignedIndex i, j; 104 | 105 | /* Variable size arrays */ 106 | r1 = mxMalloc((N)*sizeof(mwSignedIndex)); 107 | r2 = mxMalloc((N)*sizeof(double)); 108 | rho = mxMalloc((N)*sizeof(double)); 109 | A = mxMalloc((N)*sizeof(double)); 110 | nu_con = mxMalloc((N)*sizeof(double)); 111 | 112 | pdf = mxMalloc((1)*sizeof(double)); 113 | 114 | prior_t_gas_hyper(theta, hyper, N, r1, r2); 115 | 116 | /* Initialise */ 117 | for (i=0; i0 74 | { 75 | r1[i] = 0; 76 | } 77 | if ((theta[i+3*N] < 0) || (theta[i+3*N] >= 1)) // 0<=B<1 78 | { 79 | r1[i] = 0; 80 | } 81 | if (theta[i+4*N] <= 2) //nu>2 82 | { 83 | r1[i] = 0; 84 | } 85 | if (r1[i] == 1) 86 | { 87 | r2[i] = log(hyper[0]) - hyper[0]*(theta[i+4*N] - 2); 88 | } 89 | } 90 | } 91 | 92 | /******************************************************************* */ 93 | 94 | 95 | void posterior_t_gas_hyper_init_mex(double *y, mwSignedIndex N, mwSignedIndex T, 96 | double *theta, double *hyper, double *GamMat, mwSignedIndex G, double *d, 97 | double *Td) 98 | { 99 | mwSignedIndex *r1; 100 | double *r2; 101 | double *rho, *A, *nu_con; 102 | double h, *pdf; 103 | double rhoh, tmp; 104 | mwSignedIndex i, j; 105 | 106 | /* Variable size arrays */ 107 | r1 = mxMalloc((N)*sizeof(mwSignedIndex)); 108 | r2 = mxMalloc((N)*sizeof(double)); 109 | rho = mxMalloc((N)*sizeof(double)); 110 | A = mxMalloc((N)*sizeof(double)); 111 | nu_con = mxMalloc((N)*sizeof(double)); 112 | 113 | pdf = mxMalloc((1)*sizeof(double)); 114 | 115 | Td[0] = (double)(T); 116 | 117 | prior_t_gas_hyper(theta, hyper, N, r1, r2); 118 | 119 | /* Initialise */ 120 | for (i=0; i call a MATLAB function with pointer to real matrices 18 | memcpy(gam, mxGetPr(out_array_ptr), 2*N*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 19 | 20 | mxDestroyArray(in_array_ptr); 21 | mxDestroyArray(out_array_ptr); 22 | } 23 | 24 | /******************************************************************* */ 25 | void loglik_gen_gas_mex(double *y, mwSignedIndex N, mwSignedIndex k, mwSignedIndex T, 26 | double *theta, double *link, double *scale, 27 | double *d, double *f) 28 | { 29 | 30 | double *nu_con, *gam, *gam2; 31 | double y2, sigma2, pdf; 32 | double tmp, S, scaled_score; 33 | mwSignedIndex i, j; 34 | 35 | /* Variable size arrays */ 36 | if (k == 5) 37 | { 38 | nu_con = mxMalloc((N)*sizeof(double)); 39 | gam = mxMalloc(2*(N)*sizeof(double)); 40 | } 41 | 42 | /* Initialise */ 43 | if (k == 5) 44 | { 45 | for (i=0; i0 73 | { 74 | r1[i] = 0; 75 | } 76 | if ((theta[i+N] <0 ) || (theta[i+N] >= 1)) // 0<=alpha<1 77 | { 78 | r1[i] = 0; 79 | } 80 | if ((theta[i+2*N] < 0) || (theta[i+2*N] >= 1)) // 0<=beta<1 81 | { 82 | r1[i] = 0; 83 | } 84 | if (theta[i+N] + theta[i+2*N] >= 1) //alpha+beta<1 85 | { 86 | r1[i] = 0; 87 | } 88 | if (theta[i+4*N] <= 2) //nu>2 89 | { 90 | r1[i] = 0; 91 | } 92 | if (r1[i] == 1) 93 | { 94 | r2[i] = log(hyper[0]) - hyper[0]*(theta[i+4*N] - 2); 95 | } 96 | } 97 | } 98 | 99 | void posterior_t_garch_noS_hyper_mex(double *y, mwSignedIndex N, mwSignedIndex T, double *S, 100 | double *theta, double *hyper, double *GamMat, mwSignedIndex G, double *d) 101 | { 102 | mwSignedIndex *r1; 103 | double *r2; 104 | // double *omega, *rho; 105 | double *rho; 106 | double h, *pdf; 107 | double rhoh; 108 | mwSignedIndex i, j; 109 | 110 | /* Variable size arrays */ 111 | r1 = mxMalloc((N)*sizeof(mwSignedIndex)); 112 | r2 = mxMalloc((N)*sizeof(double)); 113 | // omega = mxMalloc((N)*sizeof(double)); 114 | rho = mxMalloc((N)*sizeof(double)); 115 | pdf = mxMalloc((1)*sizeof(double)); 116 | 117 | prior_t_garch_hyper(theta, hyper, N, r1, r2); 118 | 119 | /* Initialise */ 120 | for (i=0; i0 73 | { 74 | r1[i] = 0; 75 | } 76 | if ((theta[i+N] <0 ) || (theta[i+N] >= 1)) // 0<=alpha<1 77 | { 78 | r1[i] = 0; 79 | } 80 | if ((theta[i+2*N] < 0) || (theta[i+2*N] >= 1)) // 0<=beta<1 81 | { 82 | r1[i] = 0; 83 | } 84 | if (theta[i+N] + theta[i+2*N] >= 1) //alpha+beta<1 85 | { 86 | r1[i] = 0; 87 | } 88 | if (theta[i+4*N] <= 2) //nu>2 89 | { 90 | r1[i] = 0; 91 | } 92 | if (r1[i] == 1) 93 | { 94 | r2[i] = log(hyper[0]) - hyper[0]*(theta[i+4*N] - 2); 95 | } 96 | } 97 | } 98 | 99 | void posterior_t_garch_noS_hyper_init_mex(double *y, mwSignedIndex N, mwSignedIndex T, double *S, 100 | double *theta, double *hyper, double *GamMat, mwSignedIndex G, double *d, 101 | double *Td) 102 | { 103 | mwSignedIndex *r1; 104 | double *r2; 105 | // double *omega, *rho; 106 | double *rho; 107 | double h, *pdf; 108 | double rhoh; 109 | mwSignedIndex i, j; 110 | 111 | /* Variable size arrays */ 112 | r1 = mxMalloc((N)*sizeof(mwSignedIndex)); 113 | r2 = mxMalloc((N)*sizeof(double)); 114 | // omega = mxMalloc((N)*sizeof(double)); 115 | rho = mxMalloc((N)*sizeof(double)); 116 | pdf = mxMalloc((1)*sizeof(double)); 117 | 118 | Td[0] = (double)(T); 119 | 120 | prior_t_garch_hyper(theta, hyper, N, r1, r2); 121 | 122 | /* Initialise */ 123 | for (i=0; i0 74 | { 75 | r1[i] = 0; 76 | } 77 | if ((theta[i+3*N] < 0) || (theta[i+3*N] >= 1)) // 0<=B<1 78 | { 79 | r1[i] = 0; 80 | } 81 | if (k == 5) 82 | { 83 | if (theta[i+4*N] <= 2) //nu>2 84 | { 85 | r1[i] = 0; 86 | } 87 | if (r1[i] == 1) 88 | { 89 | r2[i] = log(hyper[0]) - hyper[0]*(theta[i+4*N] - 2); 90 | } 91 | } 92 | else 93 | { 94 | if (r1[i] == 1) 95 | { 96 | r2[i] = 1; 97 | } 98 | } 99 | 100 | } 101 | } 102 | 103 | /******************************************************************* */ 104 | 105 | 106 | void posterior_gen_gas_mex(double *y, mwSignedIndex N, mwSignedIndex k, mwSignedIndex T, 107 | double *theta, double *hyper, double *link, double *scale, double *GamMat, mwSignedIndex G, 108 | double *d, double *f) 109 | { 110 | mwSignedIndex *r1; 111 | double *r2; 112 | double *rho, *nu_con; 113 | double sigma2, *pdf; 114 | double rhos, tmp, S, scaled_score; 115 | mwSignedIndex i, j; 116 | 117 | /* Variable size arrays */ 118 | r1 = mxMalloc((N)*sizeof(mwSignedIndex)); 119 | r2 = mxMalloc((N)*sizeof(double)); 120 | rho = mxMalloc((N)*sizeof(double)); 121 | nu_con = mxMalloc((N)*sizeof(double)); 122 | 123 | pdf = mxMalloc((1)*sizeof(double)); 124 | 125 | prior_gen_gas(theta, hyper, N, k, r1, r2); 126 | 127 | /* Initialise */ 128 | if (k == 5) 129 | { 130 | for (i=0; i call a MATLAB function with pointer to real matrices 16 | memcpy(ninv, mxGetPr(out_array_ptr), T*2*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 17 | 18 | mxDestroyArray(in_array_ptr); 19 | mxDestroyArray(out_array_ptr); 20 | } 21 | 22 | /******************************************************************* */ 23 | 24 | void my_tinv(double *tinv, double *u, double *nu, mwSignedIndex T) 25 | { 26 | mxArray *in_array_ptr[2], *out_array_ptr; // mxArray * - a pointer to a struct (A POINTER TO A POINTER??) 27 | 28 | in_array_ptr[0] = mxCreateDoubleMatrix(T, 2, mxREAL); 29 | in_array_ptr[1] = mxCreateDoubleMatrix(1, 1, mxREAL); 30 | 31 | memcpy(mxGetPr(in_array_ptr[0]), u, T*2*sizeof(double)); // start copying at the double returned by mxGetPr(array_ptr) 32 | memcpy(mxGetPr(in_array_ptr[1]), nu, sizeof(double)); // start copying at the double returned by mxGetPr(array_ptr) 33 | 34 | mexCallMATLAB(1, &out_array_ptr, 2, in_array_ptr, "tinv"); // & turns a value into a pointer --> call a MATLAB function with pointer to real matrices 35 | memcpy(tinv, mxGetPr(out_array_ptr), T*2*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 36 | 37 | mxDestroyArray(in_array_ptr); 38 | mxDestroyArray(out_array_ptr); 39 | } 40 | 41 | /******************************************************************* */ 42 | 43 | void my_gamma(double *gam, mwSignedIndex N) 44 | { 45 | mxArray *in_array_ptr, *out_array_ptr; // mxArray * - a pointer to a struct (A POINTER TO A POINTER??) 46 | 47 | in_array_ptr = mxCreateDoubleMatrix(3*N, 1, mxREAL); 48 | 49 | memcpy(mxGetPr(in_array_ptr), gam, 3*N*sizeof(double)); // start copying at the double returned by mxGetPr(array_ptr) 50 | mexCallMATLAB(1, &out_array_ptr, 1, &in_array_ptr, "gamma"); // & turns a value into a pointer --> call a MATLAB function with pointer to real matrices 51 | memcpy(gam, mxGetPr(out_array_ptr), 3*N*sizeof(double)); // start copying at the double returned by d=mxGetPr(plhs[0]) 52 | 53 | mxDestroyArray(in_array_ptr); 54 | mxDestroyArray(out_array_ptr); 55 | } 56 | 57 | /******************************************************************* */ 58 | void loglik_gen_copula_gas_mex(double *y, mwSignedIndex N, mwSignedIndex k, mwSignedIndex T, 59 | double *theta, double *link, double *scale, 60 | double *d, double *f, double *rho) 61 | { 62 | 63 | double *z, *gam; 64 | double pdf; /*,rho;*/ 65 | double tmp, rr, S, scaled_score; 66 | mwSignedIndex i, j; 67 | 68 | /* Variable size arrays */ 69 | z = mxMalloc(2*(T)*sizeof(double)); 70 | if (k == 4) 71 | { 72 | gam = mxMalloc(3*(N)*sizeof(double)); 73 | } 74 | 75 | /* Initialise */ 76 | if (k == 4) /* Get the constants for Student's distribution */ 77 | { 78 | for (i=0; i