如何在mata环境中求解高阶方程的最优解

2017-05-22 高金凤 爬虫俱乐部 爬虫俱乐部

Mata是 在 Stata9.0 版本以后新增的执行矩阵计算的矩阵编程语言,在mata环境中,矩阵的运算速度会快速提高,而且也不需要占用很大内存。并且在mata环境中,矩阵程序的 语法会更简化。虽然mata是一种新的语言环境,但是其程序语言仍然写于ado文件中,可以在常规的do.file文件里调用mata程序。

在实际生活中,我们会碰到求解某一问题的最优值。比如,运筹学中经常会求解某个收益最大、风险最小、路径最短等问题的最优解。今天我们介绍如何在mata环境中求解高阶方程的最优解,给出如下例子:

例一

求解一元高阶方程-2113.15x^8+2130.52x^3-21.4x^2-80.2x+1616.91=0的解,我们只需输入如下命令:

mata     //进入mata语言环境

mata  clear     //清空mata内存中的变量和函数

polyroots((1616.91,-80.2,-21.4,2130.52,0,0,0,0,-2113.15))    //将求解方程的系数按照未知参数次幂从低到高输入

end      //退出mata语言环境

结果如下:

说明:该方程有8个解,其中有2个实根1.09222346和-0.827136741;6个共轭虚根-0.818078380.698536949i,0.1547537790.986620132i和0.530781180.672391261i。

例二

多元高阶方程组有两种类型,第一种是齐次方程式,即方程组的等式右边为0;另一种是方程组等式一边是需要求解的未知参数,当然这两种方程组可以相互转化,下面我们分别介绍这两种方程组的求解例子。

首先介绍第一种类型,假设现在我们要求解如下所示方程组的根:

就可以键入下面命令来执行:

mata:      

mata clear       

void function myfun2(real colvector a, real colvector values)  //void指明函数参数是无类型限定的,编写一个函数myfun2,设置两个参数:一个是列向量a代表我们的函 数解,另一个是列向量的维度,就是未知参数的个数。

{

         values[1] = 10 - a[1]*exp(a[2]*1) - a[3]*1

         values[2] = 12 - a[1]*exp(a[2]^2) - a[3]*2

         values[3] = 15 - a[1]*exp(a[2]^3) - a[3]*3      //方程的书写

}

S = solvenl_init()    //方程的初始化求解

solvenl_init_evaluator(S, &myfun2())   //设置一个指针(实函数)指向的函数集myfun2()

solvenl_init_type(S, "zero")    //指明函数方程的类型,"zero"代表方程组的等式右边为0

solvenl_init_technique(S, "newton")  //设置的计算方法为牛顿法

solvenl_init_numeq(S, 3)    //设置当前方程的未知参数为3

solvenl_init_startingvals(S, J(3,1,.3))   //设置初始值是3行1列,且值都为0.3的向量

solvenl_init_iter_log(S, "on")   //按日志格式显示迭代过程,如设置为“off”则不显示

a = solvenl_solve(S)    //调用计算器并返回计算方案,如果出现错误,solvenl_solve() 中止并返回错误提示

a   //输出a的值

end    //退出mata语言环境

结果如下所示:

可以看到,当设置初始值a=(0.3,0.3,0.3)’时,函数值在第五次迭代后接近0,并且求解精度达到0.0004,函数的根为:x=3.17918,y=1.16875,z=-0.23536。当我们修改初始值为:a=(1.3,1.3,1.3)’时:

可以看到:函数值在第四次迭代后接近0,并且求解精度达到0.003,方程的根基本没什么变化。但当我们将初始值设置为a=(2.3,2.3,2.3)’时:

可以发现:系统提示错误,第二次迭代后遇到缺失值而导致程序无法正常进行,说明求解该类型的方程时,初始值的设置非常重要。

接下来介绍第二种高阶方程的求解方法,假设现在我们要求解如下所示方程组的根:

mata:

mata clear

void function myfun(real colvector from, real colvector values)

{

     values[1] =  5/3 - 2/3*from[2]

     values[2] = 10/3 - 2/3*from[1]

}

S = solvenl_init()

solvenl_init_evaluator(S, &myfun())

solvenl_init_type(S, "fixedpoint")  //指明函数方程的类型," fixedpoint "代表方程组的一边是未知参数

solvenl_init_technique(S, "gaussseidel")  //设置的计算方法"gaussseidel" ,注意:方法不能用于右边是0的方程求解中

solvenl_init_numeq(S, 2)  

solvenl_init_iter_log(S, "on")

a = solvenl_solve(S)

a

end

结果如下:

可 以看到,经过53次迭代,函数值接近于0,解得方程的根为:x=-0.9999999981,y=4。该程序中省略了函数的初值的设置,stata默认初 值为0。有时候不设置初始值时,同样也会遇到迭代过程出现缺失值的情况,所以,高阶方程的求解,寻找合适的初始值很重要。



以上就是今天给大家分享的内容了,说得好就赏个铜板呗!有钱的捧个钱场,有人的捧个人场~。

应广大粉丝要求,爬虫俱乐部的推文公众号打赏功能可以开发票啦,累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫。第一批发票已经寄到各位小主的手中,大家快来给小爬虫打赏呀~

                     文字编辑:徐苾雯

技术总编:刘贝贝



往期推文推荐:

1.高校学术大神:你的导师上榜了吗?

2.中国高校财经、管理与综合类期刊灌水排行榜

3.关于RTF你不知道的命令之番外篇

4.免费事件研究,一片片从邮局寄来

5.免费的股价同步性,一片片从邮局寄来

6.Stata叫你回家听音乐了!

7.一言不合就用stata写邮件(Outlook/Foxmail)

8.听说你想知道怎么用stata画地图?

9.I have a Stata, I have a python

10.I have a Stata, I have a Python之二——pdf转word




关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿”+“推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

欢迎关注爬虫俱乐部

微信扫一扫
关注该公众号