'==================================================================================================
'==================================================================================================
'==================================================================================================
'
'	Temporal disaggregation soubroutines, help procedures
'
'==================================================================================================
'==================================================================================================
'==================================================================================================

subroutine local aggreg (matrix AGG, scalar op1, scalar N, scalar s, scalar n_up, scalar n_dn)

' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	PURPOSE:	Generate a temporal aggregation matrix
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	SYNTAX:		matrix AGG
'					call aggreg (AGG, op1, N, s, n_up, n_dn)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	OUTPUT:		N x sN temporal aggregation matrix AGG(NxsN)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	INPUT:		AGG:		aggreagation matrix name, have to be declared before subroutine
'					op1:		type of temporal aggregation
'					op1=1		sum (flow)
'					op1=2		average (index)
'					op1=3 	last  element (stock) - interpolation
'					op1=4 	first  element (stock) - interpolation
'					N:			number of low frequency data points 
'					s:			number of high frequency points 
'								for each low frequency data points (freq. conversion)
'					s=4		annual to quarterly
'					s=12		annual to monthly
'					s=3		quarterly to monthly
'					n_up		numbre of extrapolated forward high frequency points
'								HF subperiods not subject to temporal aggreagation constraint
'					n_dn		numbre of extrapolated backward high frequency points
'								HF subperiods not subject to temporal aggreagation constraint
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	LIBRARY:		
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	writen by:
'	Slawomir Dudek
'	MOF 
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

'	Checking parameter s

if (s=4 OR s=12 OR s=3) then

'	Generation of aggregation vector cc_vec

if op1=1 then
	rowvector(s) cc_vec = 1
else
	if op1=2 then
		rowvector(s) cc_vec = 1/s
	else
		if op1=3 then
			rowvector(s) cc_vec = 0
			cc_vec(s)=1
		else 
			if op1=4 then
				rowvector(s) cc_vec = 0
				cc_vec(1)=1
			else
			statusline  ERROR!!! AGG() subroutine !!!*** Improper value of option parameter [ta: aggregation type = (1 to 4)] ***!!!
			stop 
			endif
		endif
	endif
endif

' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

'	Generation of aggregation matrix AGG=I(N) kronecker cc_vec

if (n_up=0 AND n_dn=0) then

'	Generation of ordinary aggregation matrix, pure distribution n=N*s

matrix AGG=@kronecker(@identity(N), cc_vec)
else

'	Generation of enhaced aggregation matrix

	if (n_up>0 AND n_dn=0) then
		matrix AGG_temp=@kronecker(@identity(N), cc_vec)
		matrix(N, N*s+n_up) AGG
		matrix(N,  n_up) zeros
		matplace(AGG, AGG_temp,1,1)
		matplace(AGG, zeros, 1, N*s+1)
	else
	
	if (n_up=0 AND n_dn>0) then
		matrix AGG_temp=@kronecker(@identity(N), cc_vec)
		matrix(N, N*s+n_dn) AGG
		matrix(N,  n_dn) zeros
		matplace(AGG, AGG_temp,1,n_dn+1)
		matplace(AGG, zeros, 1, 1)
	else

	if (n_up>0 AND n_dn>0) then
		matrix AGG_temp=@kronecker(@identity(N), cc_vec)
		matrix(N, N*s+n_up+n_dn) AGG
		matrix(N,  n_dn) zeros_dn
		matrix(N,  n_dn) zeros_up
		matplace(AGG, AGG_temp,1,n_dn+1)
		matplace(AGG, zeros_dn, 1, 1)
		matplace(AGG, zeros_up, 1, N*s+1+n_dn)

	else
	statusline   ERROR!!! AGG() subroutine !!!*** Improper value of option parameter [n_up or n_dn: >= 0] ***!!!
	stop 

endif
endif
endif
endif

else
statusline  ERROR!!! AGG() subroutine !!!*** Improper value of option parameter [s: frequency conv. = (3, 4, 12)] ***!!!
stop 
endif


endsub

'==================================================================================================
'==================================================================================================
'==================================================================================================

subroutine local dif (matrix DIF, scalar dd, scalar n, scalar p)

' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	PURPOSE:	Generate a diferentiation matrix DIF(n X n)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	SYNTAX:		matrix DIF
'					call dif (DIF, dd, n, p)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	OUTPUT:		n x n temporal diferentiation matrix DIF(n x n)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	INPUT:		DIF:	temporal diferentiation matrix name, have to be declared before subroutine
'					dd:		order of diferentiation
'					dd=0	levels => DIF=I
'					dd=1	first order diferentiation => DIF=DIF
'					dd=2 	second order diferentiation  => DIF=DIF*DIF
'					n:		number of high frequency data points
'					p:		modified / not modified
'					p=0	not modified (minimization of first correction, x0=y0)
'					p=1	truncted first/second row/third row (x0 <> y0)
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	LIBRARY:		
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'	writen by:
'	Slawomir Dudek
'	MOF 
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'
'	Generation of diferentiation matrix DIF

if p=0 then

if dd=0 then
	matrix DIF=@identity(n)
else
	if dd=1 then
		vector(n-1) diag1=-1
		matrix (n, n) DIF
		DIF=@makediagonal(diag1,-1) + @identity(n)
		delete diag1
	else
		if dd=2 then
			vector(n-1) diag1=-1
			matrix (n, n) DIF
			DIF=@makediagonal(diag1,-1) + @identity(n)
			matrix DIF=DIF*DIF
			else
			statusline   ERROR!!! DIF() subroutine !!!*** Improper value of option parameter [dd: = (0 to 2)] ***!!!
			stop 
		endif
	endif
endif

else

if p=1 then

if dd=0 then
	matrix DIF=@identity(n)
else
	if dd=1 then
		vector(n-1) diag1=-1
		matrix (n, n) DIF_temp
		DIF_temp=@makediagonal(diag1,-1) + @identity(n)
		matrix DIF = @subextract(DIF_temp,2,1, n, n)
		delete diag1 DIF_temp

	else
		if dd=2 then
			vector(n-1) diag1=-1
			matrix (n, n) DIF_temp
			DIF_temp=@makediagonal(diag1,-1) + @identity(n)
			matrix DIF_temp1=DIF_temp*DIF_temp
			matrix DIF = @subextract(DIF_temp1,3,1, n, n)
			delete diag1 DIF_temp DIF_temp1
		else
		statusline   ERROR!!! DIF() subroutine !!!*** Improper value of option parameter [dd: = (0 to 2)] ***!!!
		stop
		endif
	endif
endif

else 
statusline ERROR!!! DIF() subroutine !!!*** Improper value of option parameter [p: = 0/1] ***!!!
stop

endif
endif

endsub

' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

'==================================================================================================
'==================================================================================================
'==================================================================================================

