1、EViews命令和编程之子程序EViews命令和编程之子程序子程序是用以重复执行给定任务的一组命令的集合,执行时可能存在少许的不同,但它并不是一组实际命令的拷贝。可以从一个程序中运用子程序去执行另一个程序中的相同任务。一、定义子程序(Defining Subroutines)一个子程序由关键字subroutine打头后接子程序名和任意给定的形式参数,而以关键字endsub结束。两个关键字之间可以存在任意数量的命令行。最简单的子程序具有如下的形式:subroutine z_squareseries x = z2endsub这里,关键字subroutine之后仅有一个子程序名。每次调用这类没有形式
2、参数的子程序时,它都表现出相同的行为。这个子程序构造一个已有序列Z的平方,并将平方值保存到新序列X中。运用return命令可在任何时候强制EViews从子程序中退出。如果侦察到了一个不可预知的错误,通常就运用return命令从子程序中退出。下列程序中如果很查到不能计算Durbin_h统计量就从子程序中退出。Durbin_h统计量是检验具有滞后因变量序列相关用的。(参见Greene, 1997, p.596 or Davidson and MacKinnon, 1993, p.360)subroutine durbin_hequation eqn.ls cs c cs(-1) incscalar
3、 test=1-eqn.regobs*eqn.cov(2,2) an error is indicated by test being nonpositive if test=0 thenreturn exit on errorendif compute h statistic if test positivescalar h=(1-eqn.dw/2)*sqr(eqn.regobs/test) endsub二、具有形式参数的子程序(Subroutine with arguments)迄今为止编写的都是使用一组指定变量进行工作的子程序。一般说来,子程序是可以获取形式参数的。如果熟悉其它程序设计语
4、言,或许早就明了,每次调用子程序时运用形式参数可以改变一组命令的行为。即使还没有接触过子程序,对数学中的类似概念总是熟悉的。定义了一个函数,例如其中函数f是有赖于形式参数x的。x只不过是在定义函数时占据了一个位置,而且它实际上并不代表什么。定义了这个函数以后,如果要计算实际数值譬如.7839的函数值时,就可以简单地写成f(.7839)。如果要计算不同数值譬如.50123的函数值,也只不过写成f(.50123)。通过定义函数,使我们免去了计算不同数值的函数值时,要把整个表达式写出来的烦琐。定义具有形式参数的子程序,由subroutine打头,后接一个子程序名,而后是左括号,用逗号间隔的形式参数,
5、最后是右括号。每个形式参数在EViews对象类型名后再列出形式参数名。控制变量作为数值量(scalar)型,字符串变量作为字符型(string)允许出现在形式参数中。例如,subroutine power(series v, series y, scalar p)v=ypendsub这个子程序扩展了subroutine Z_SQUARE子程序的功能。POWER子程序的功能是计算指定序列Y的P次幂,并将结果置于序列V中。调用子程序POWER要分别用两个序列名和一个数值填充到形式参数的位置。如果设V等于X,Y等于Z,P等于2,去调用POWER子程序,将会得到与上述子程序Z_SQUARE等价的结果。
6、三、子程序的布局(Subroutine Placement)定义的子程序可以按任何顺序置于程序开始的位置。但是,这些子程序并不会执行,除非在程序中利用Call语句调用它们,它们才被执行。例如,subroutine z_squareseries x=z2endsub start of program executionload myworkfetch zcall z_square这个程序从load(加载)语句开始执行;而滑过了定义的子程序,仅当在程序的最后一行调用()它时,子程序才被执行。定义子程序的subroutine不能发生交叉。下一个subroutine只能出现在上一个子程序的sunend
7、以后。子程序间可以互相调用,甚至可以调用自身。将经常使用的一些子程序存放在一个单独的文件中并在程序的开头使用一个include语句将它们插入。假设有一个名为POWERS.PRG的程序文件,它包含了Z_SQUARE子程序和POWER子程序的定义文本。那么可以在任何一个需要调用Z_SQUARE或POWER的其它程序中设置一个命令行include powers这样插入的子程序如同它们是内置在EViews程序设计中的一部分。include语句也接受全路径的程序文件,一个程序中可以包括多个include语句。例如,include c:programspowers.prginclude durbin_hl
8、oad myworkcall durbin_hfetch zcall z_square四、调用子程序(Calling Subroutines)一旦在程序中定义了子程序,就可以运用call命令去执行包含在子程序中的命令。调用子程序的方式:Call之后接子程序名,采用的形式参数列表,形式参数置于括号中,用逗号分隔。如果子程序包含了形式参数,调用时必须完全按照申明时相同顺序提供。下面时一个调用子程序的例子:include powers load myworkfetch z gdpseries xseries gdp2 series gdp3call z_squarecall power(gdp2,g
9、dp,2)call power(gdp3,gdp,3)第一个调用用Z的平方填充到序列X。第二个调用建立了序列GDP2,它是GDP的平方。第三个调用序列GDP3,它是GDP的立方。当子程序的形式参数是数值型时,那么可以用一个数值型对象,一个控制变量,一个简单的数(例如10或15.3),一个矩阵元素(例如mat1(1,2)),或一个数值表达式(例如!y+25)调用。接受矩阵和向量作形式参数的子程序,只能用矩阵名调用,如果矩阵不为子程序修改,也可以用矩阵表达式调用。所有其它类型的形式参数必须采用与单个对象类型相关的简单对象(字符串)名传递给子程序。五、全局变量和局域变量(Global and Loc
10、al Variables)子程序中使用的变量和对象分为全局的和局域的两类。全局变量既包括子程序运行时已经存在于工作文件内的对象,也包括子程序运行时为子程序所建立的对象。当子程序运行结束以后全局变量仍然保留在工作文件中。局域变量是仅仅在子程序内才有意义的变量。一旦子程序运行结束,局域变量就从工作文件中被删除。调用子程序的母程序关于局域变量是一无所知的,因为一旦子程序运行结束并返回母程序时局域变量就消失了。全局子程序(Global Subroutines)根据定义,EViews中的子程序是全局的。任意一个全局子程序当它被调用时,都可以引用存在于工作文件中的任何全局对象。于是,如果Z是工作文件中的一
11、个序列,子程序可以引用它,如果需要的话还可以修改它。类似地,如果Y是一个已由另一个子程序建立的全局矩阵,那么当前子程序也可以使用矩阵Y。全局子程序中使用变量的规则:当子程序完成后新建的对象是全局变量,它们应包含在工作文件中。全局变量是子程序中可以使用的并可直接由子程序进行更新。但是,如果一个全局对象与子程序中的形式参数具有相同的名称,那么变量名引用的是形式参数而不是全局变量。与形式参数对应的全局对象可被使用并被引用的形式参数所更新。下面是一个调用全局子程序的简单程序:subroutine z_squareseries x = z2endsubload myworkfetch zcall z_s
12、quareZ_SQUARE是一个全局子程序,它可以读取全局序列Z。新的全局序列X包含了序列Z的平方。当Z_SQUARE运行结束以后X和Y都保留在工作文件中。如果一个子程序的形式参数与全局变量具有相同的名称,那么形式参数名是优先的。在子程序中任何关于这个名称的引用将是对形式参数的引用,而不是对全局变量的引用。例如,subroutine sqseries(series z,string %name)series %name = z2endsubload myworkfetch zfetch ycall sqseries(y,y2)在这个例子中,原工作文件中有一个序列Z,Z也是子程序中的一个形式参数
13、。用Y作为形式参数调用SQSERIES,就是告诉EViews应使用形式参数而不是全局变量Z。当子程序完成以后,一个新序列Y2包含的是Y的平方,而不是序列Z的平方。全局子程序可以调用全局子程序。当在一个子程序内调用另一个子程序时,必须确定地将子程序所要求的一切形式参数传递给它。例如,subroutine wgtols(series y, series wt)equation eq1call ols(eq1, y)equation eq2series temp = y/sqr(wt)call ols(eq2,temp) delete tempendsubsubroutine ols(equatio
14、n eq, series y)eq.ls y c y(-1) y(-1)2 y(-1)3 endsub可以用下列程序来调用上列子程序:load myworkfetch cpifetch cscall wgtols(cs,cpi)在这个例子中,子程序WGTOLS明确地为子程序OLS中的EQ和Y传递了形式参数;否则这些形式参数将不被OLS识别。如果没有给EQ和Y传递形式参数,那么OLS将试图寻找名为Y的全局序列和名为EQ的全局方程,而不是采用EQ1和CS或者EQ2和TEMP。不能运用子程序去修改全局变量的类型。假设采用子程序NEWXY去申明矩阵X和矩阵Y。在这个例子中,申明Y是可行的,但申明矩阵X
15、却是错误的,因为已经有一个名为X的序列存在:subroutine newxymatrix(2,2) x = 0 matrix(2,2) y = 0endsubload myworkseries xcall newxy运行后,EViews将返回一个出错提示,一个与矩阵类型不同的全局序列X已经存在。六、局域子程序(Local Subroutines)全局子程序建立的全部对象都是全局的,当从子程序中退出以后这些对象仍然保留在工作文件中。如果在子程序定义中包含了关键字local,那么就建立了一个局域子程序。局域子程序建立的一切对象是局域的,当从子程序退出时局域对象将从工作文件中消失。在要创建大量的又无
16、须保存的临时对象时,就要编写局域子程序。局域子程序的主要用途也在这里。局域子程序中使用变量的规则:不能使用全局对象和从子程序中直接更新全局对象。可以使用与形式参数对应的全局对象,它们也可被引用的形式参数所更新。在子程序中的所有对象都是局域的,它们在子程序运行完成后将消失。如果要保存局域子程序的结果,那么应当明确地将它们包含在形式参数之中。例如,subroutine local ols(series y, series res, scalar ssr)equation temp_eq.ls y c y(-1) y(-1)2 y(-1)3temp_eq.makeresid resssr = tem
17、p_eq.ssrendsub这个局域子程序将Y作为输入将序列RES和数值SSR作为输出。方程对象TEMP_EQ时局域的,当子程序结束时就消失了。下面时一个调用局域子程序的例子:load myworkfetch hsf equation eq1.ls hsf c hsf(-1) eq1.makeresid rresscalar rssr = eq1.ssrseries uresscalar ussrcall ols(hsf, ures, ussr)注意,在调用子程序前是怎样申明URES和USSR的。这两个对象是全局的,因为它们是在局域子程序之外申明的。当采用全局对象作为形式参数传递给局域子程序时
18、,局域子程序将更新这些全局变量。这是局域子程序一般很难接受全局变量的一个例外。当全局组作为形式参数传递给局域子程序时,组中的任一序列也是可以被局域子程序接受的。局域子程序可以调用全局子程序,反之亦然。全局子程序只能读取全局变量,局域子程序也只能读取局域变量,除非采用形式参数在子程序之间传递信息。例如,又一个子程序:subroutine newols(series y, series res)include olsequation eq1.ls y c y(-1)eq1.makeresid resscalar rssr=eq1.ssrseries uresscalar ussrcall ols(y, ures, ussr)endsub和一个母程序:load myworkfetch hsf series rrescall newols(hsf, rres)将产生一个等价的结果。注意,子程序NEWOLS仍然不能读取局域子程序OLS中的任何临时变量,虽然已经从NEWOLS中调用了OLS。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1