Produce frml by procedure

Use this forum to post questions about syntax problems or general programming issues. Questions on implementing a particular aspect of econometrics should go in "Econometrics Issues" below.
jonasdovern
Posts: 97
Joined: Sat Apr 11, 2009 10:30 am

Produce frml by procedure

Unread post by jonasdovern »

Hallo,
I have the following problem: I tried to write a procedure that defines a frml which I need for later use. (I want to use a procedure because I have to define a lot such frmls.) It defines a frml that is equal to a trending function over some period and defines a decay of the slope after that end of that period:

Code: Select all

procedure checkcoeffs frmlname1 frmlname2
	type frml *frmlname1 *frmlname2
	option integer start
	option integer end
	option integer row 1
	option integer col 1
	option ser[rec] ioc
	option real decay .5
	*
	local series coeffts
	*
	set coeffts start end = ioc(t)(row,col)
	*
	linreg coeffts start end
	# constant trend
	frml(lastreg) frmlname2
	frml frmlname1 = %if(t<=end,%max(.0,frmlname2(t)),%max(.0,frmlname1(t-1)+decay^(t-end)*(frmlname2(end)-frmlname2(end-1))))
end procedure checkcoeffs
However, the defined frmls somehow seem to be "dynamic", i.e. when I use the procedure several times all defined frmls will always be based on the most recently executed procedure inputs:

Code: Select all

decl frml frml_51_01 frml_54_01
@checkcoeffs(graph,decay=decay,start=2003:1,end=2007:1,ioc=ioc,row=51,col=1) frml_51_01 temp_51_01
@checkcoeffs(graph,decay=decay,start=2003:1,end=2007:1,ioc=ioc,row=54,col=1) frml_54_01 temp_54_01
set test51 = frml_51_01(t)
set test54 = frml_54_01(t)
... will produce to identical series - both based on the parameter values that belong to the second frml.

Is there any way I can produce "static" frmls by a procedure with parameter values that do not change if the procedure is used multiple times (with different names for the frml-output)?
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Produce frml by procedure

Unread post by TomDoan »

That's what the & prefix is for in a FRML definition - it defines the formula using the value at time of execution rather than using the address (which, as you see, gets overwritten by the procedure is invoked again).

Code: Select all

set junk 1 100 = %ran(1.0)
*
procedure definefrml f1
type frml *f1
option integer break
*
frml f1 = %if(t<=&break,t,junk)
end
*
compute b20=20,b50=50
@definefrml(break=b20) breakat20
@definefrml(break=b50) breakat50
set test20 = breakat20(t)
set test50 = breakat50(t)
jonasdovern
Posts: 97
Joined: Sat Apr 11, 2009 10:30 am

Re: Produce frml by procedure

Unread post by jonasdovern »

Thanks a lot. That's what I need.
jonasdovern
Posts: 97
Joined: Sat Apr 11, 2009 10:30 am

Re: Produce frml by procedure

Unread post by jonasdovern »

Unfortunately, one more question: Is there a way to refer also to reals by value rather than address? I have to create a frml in a procedure which is defined using input from a regression.

The following is a simple example of what I want to do but it is not working since the "&"-construction seems to work for integers only; is that right?

Code: Select all

    set junk 1 100 = %ran(1.0)+t*.5
    set trend 1 100 = t
    *
    procedure definefrml f1
    type frml *f1
    option integer break
    local vec beta
    *
    linreg junk 1 break
    # constant trend
    comp beta=%BETA
    frml f1 = %if(t<=&break,t,&beta(1)+t*&beta(2))
    end
    *
    compute b20=20,b50=50
    @definefrml(break=b20) breakat20
    @definefrml(break=b50) breakat50
    set test20 = breakat20(t)
    set test50 = breakat50(t)
If I replace the one line by simply:

Code: Select all

    frml f1 = %if(t<=&break,t,%BETA(1)+t*%BETA(2))
... each frml produced by the procedure is defined by the coefficients from the regression from the last run of the procedure; but that's clear given that %BETA changes its values at each execution of the procedure. How do I avoid that the frmls are changed after the execution of the procedure finished?
jonasdovern
Posts: 97
Joined: Sat Apr 11, 2009 10:30 am

Re: Produce frml by procedure

Unread post by jonasdovern »

For anybody who has the same problem. I found the following way around the problem: I just introduced a new parameter in the procedure that saves the corresponding coefficients of the frml for later use.

Code: Select all

        set junk 1 100 = %ran(1.0)+t*.5
        set trend 1 100 = t
        *
        procedure definefrml f1 coef1
        type frml *f1
        type vec *coef1 
        option integer break
        local int i
        *
        dim coef1(2)
        linreg junk 1 break
        # constant trend
        ewise coef1(i) = %BETA(i)
        frml f1 = %if(t<=&break,t,coef1(1)+t*coef1(2))
        end
        *
        compute b20=20,b50=50
        decl vec[vec] coefs(2)
        @definefrml(break=b20) breakat20 coefs(1)
        @definefrml(break=b50) breakat50 coefs(2)
        set test20 = breakat20(t)
        set test50 = breakat50(t)
Post Reply