Mata:使用Mata的机制

Mata:使用Mata的机制

上学期推荐图书馆购买的这本书:《The Mata Book:A Book for Serious Programmers and Those Who Want to Be》,鉴于这么书这么贵(59$),我决定认认真真的看一下。

这让我想起来西虹市首富里面的那段:

下面进入正题,依照惯例,跳过第一章,现在开始看第二章。

什么是Mata?

许多Stata用户认为Mata是一种矩阵语言,正如Stata公司自己对它的定位一样。更准确地说,Mata是一中跨平台的便携式的、编译的编程语言

值得注意的是,Mata是编译的语言,这意味着程序可以运行的很快。而Stata中的另外一种语言——ado则是一种解释语言,也就是说ado很慢。总体上来说,Mata比ado快10~40倍。

Mata看起来更像是C和C++,在C语言中,一个经典的入门程序是下面这个:

C
1
2
3
main(){
printf("hello, world\n");
}

如果用Mata写这个语言,将会是这个样子:

Stata
1
2
3
4
5
6
mata:
void hello(){
printf("hello, world\n");
}
hello()
end

大多数Mata的用户会懒得在printf("hello, world\n");的结尾使用分号,分号在Mata语言中是可选的,意味着,不以分号结尾不会影响程序的运行。

在进行本书的学习之前,你最好准备好本书程序运行所需要的一些材料,在Stata中运行下面的程序即可获得:

Stata
1
copy "http://www.stata-press.com/data/tmb/tmb.zip" .

注意,不要漏掉这个程序结尾的点了!

导论

作为一种编译型语言,Mata会首先编译hello(),然后丢弃掉原始的程序而在内存中执行编译后的代码,这也就是为什么直接输入hello()就能执行这个函数的原因。

交互式的运行很方便教学,但是对于严肃的程序来说是没有意义的,有三种方法可以让Mata程序严肃地运行:

  1. 把Mata程序放置在do文档中,那么你定义的Mata函数就可以被其他的do文档调用;
  2. 把Mata程序放置在ado文档中,那么你定义的Mata函数将能够在ado文件中使用。
  3. Mata程序也可以编译之后放置在系统文件夹里,那么你就可以在任何时候任何地方对它进行调用。

嵌入do文档中的Mata代码

这种做法是不被建议的。建议把Mata代码放置在单独的do文档里面然后保存为mata文件(扩展名为.mata的文件),例如:

Stata
1
2
3
4
5
6
7
8
9
10
version 15.0
mata:
void hello(){
printf("hello world!\n")
}

void goodbye(){
printf("good-bye, world!\n")
}
end

在同一个文件里面的Mata函数往往是相互关联的,相互关联也是它们出现在同一个文件中的原因,通常不同的函数会相互调用。

把上面的代码保存为hello.mata文件之后(放置在工作目录里),就能在do程序中进行调用了。

工作目录的说明:我通常会把Stata的工作目录设置为桌面,工作完成之后再把文件整理起来。所以我的默认工作目录就是我的桌面。

Stata
1
2
3
4
clear all
do hello.mata
mata: hello()
mata: goodbye()

结果:

Stata
1
2
3
4
5
. mata: hello()
hello world!

. mata: goodbye()
good-bye, world!

版本声明可以使下面的程序在所声明的环境中运行,虽然大多数时候不会对程序产出影响,但是可以确保程序在其它版本(主要是只更高版本的Stata)中依然能够正确运行。

嵌入ado文档中的Mata代码

Mata代码可以放置在ado文档中和通常的ado语言一起使用,一般把Mata代码放置在ado文件的结尾。

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
prog hello
version 15.0
mata: hello()
mata: googbye()
end

version 15.0
mata:
void hello(){
printf("hello world!\n")
}

void goodbye(){
printf("good-bye, world!\n")
}
end

把上面的代码保存为hello.ado文件(放置在工作目录里)之后就能使用hello命令了:

Stata
1
2
3
. hello
hello world!
good-bye, world!

编译Mata程序

我们需要把这两个Mata函数编译再把它们保存到一个library里面,编译代码很简单,我们只需要输入do hello.mata,这是因为Mata在读入程序之后就被把程序进行编译然后存储在内存中。
而对于保存代码,我们需要使用lmbuild libraryname命令,libraryname必须以l开头,并且以.mlib结尾,本书中,我们会命名一个叫lmatabook.mlib的library,然后把所有的函数都存储在这个library里面:

Stata
1
2
3
clear all
do hello.mata
lmbuild lmatabook.mlib

结果:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
. clear all

. do hello.mata

. version 15.0

. mata:
------------------------------------------------- mata (type end to exit) ---
: void hello(){
> printf("hello world!\n")
> }

:
: void goodbye(){
> printf("good-bye, world!\n")
> }

: end
-----------------------------------------------------------------------------

.
end of do-file

. lmbuild lmatabook.mlib
(2 functions added)
new library /Users/mr.cheng/Library/Application Support/Stata/ado/personal/lmatabook.mlib created

注意到这个lmatabook.mlib被保存在系统文件夹里的personal文件夹里了。然后你就会发现,这两个函数随处、随时可用了!

Stata
1
2
3
clear all
mata: hello()
mata: goodbye()

结果:

Stata
1
2
3
4
5
6
7
. clear all

. mata: hello()
hello world!

. mata: goodbye()
good-bye, world!

如果你修改了hello.mata的源码,那么你得重新编译构建这个library:

Stata
1
2
3
clear all
do hello.mata
lmbuild lmatabook.mlib, replace

# Mata

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×