## 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.

### Produce frml by procedure

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)?
jonasdovern

Posts: 68
Joined: Sat Apr 11, 2009 10:30 am

### Re: Produce frml by procedure

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)
TomDoan

Posts: 2724
Joined: Wed Nov 01, 2006 5:36 pm

### Re: Produce frml by procedure

Thanks a lot. That's what I need.
jonasdovern

Posts: 68
Joined: Sat Apr 11, 2009 10:30 am

### Re: Produce frml by procedure

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: 68
Joined: Sat Apr 11, 2009 10:30 am

### Re: Produce frml by procedure

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)
jonasdovern

Posts: 68
Joined: Sat Apr 11, 2009 10:30 am