找回密码
 注册
Simdroid-非首页
楼主: wanglu

微分方程参数优化(拟合)问题

[复制链接]
发表于 2009-12-4 16:05:32 | 显示全部楼层 来自 江苏南京
下面我把我的问题发出来,希望大家能帮忙了。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2009-12-5 18:48:18 | 显示全部楼层 来自 黑龙江哈尔滨
Simdroid开发平台
本帖最后由 TBE_Legend 于 2009-12-5 19:31 编辑
感谢messenger 和TBE_Legend 的说明,期待matlab和mmtc的结果。
wanglu 发表于 2009-12-3 18:14


这道题目和http://forum.simwe.com/thread-884975-2-1.html 是一样的,mmtc程序也就是改改方程就行了,不想再做了。

非常感谢wanglu兄出了一系列的题目【积分方程的求解,含有微分方程的拟合】,无论是matlab还是mmtc还是maple都是很好的练手材料,以后希望能看到一些别的类型的
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-6 20:50:47 | 显示全部楼层 来自 山东淄博
本帖最后由 wanglu 于 2009-12-7 17:32 编辑
下面我把我的问题发出来,希望大家能帮忙了。。。
napler821127 发表于 2009-12-4 16:05

napler821127的问题,Forcal的优化效果也不好。经napler821127验证,MatlabODE求解器与Forcal使用的“积分一步的连分式法”对微分方程的计算结果一致,故优化效果不理想可能来自“求n维极值的单形调优法”,但目前Forcal中还没有更好的优化方法。
故我想到使用MatlabFcScriptForcal脚本服务器)混合编程求解:使用Matlab的优化函数进行参数优化,微分方程计算部分由Forcal完成,优化结果由Matlab验证。虽然接口部分效率较低,但Forcal的快速计算速度足以抵消这个不足,故总的解题时间预计可以减少。
FcScript是由ForcalMForcal支持的脚本控件,采用双接口、STA单线程套间模型。目前定义了两种接口:VBMForcal接口(用于VBScript脚本,全部使用VARIANT参数)和CMForcal接口(用于ExcelCAD等各种使用COM对象的地方)。
FcScript下载:http://xoomer.virgilio.it/forcal/xiazai/forcal9/fcscript.rar
napler821127的问题描述:


为进行混合编程,针对本问题,以求解300000时的数据为例,Forcal提供了两组函数,每组函数编译为一个模块,各提供一个函数供Matlab调用。Matlab根据实际情况选择其中的一个即可。模块1中提供了函数optint,该函数根据优化参数用连分式法对微分方程组进行积分模块2中提供了函数opt,直接根据优化参数返回目标函数值。
模块1用连分式法对微分方程组进行积分,获得理论值(可简称为optint

  1. !using["XSLSF"];                //使用命名空间XSLSF
  2. //函数定义,用于计算微分方程组中各方程右端函数值,连分式法对微分方程组积分一步函数pbs1将调用该函数f。
  3. //t为自变量,f1,f2为函数值,df1,df2为右端函数值(即微分方程的值)。
  4. //该函数被调用时将用到参数a1,a2,a3,a4,a5,这5个参数正好是拟合参数,用模块变量传递这5个参数。
  5. f(t,f1,f2,df1,df2 : x : a1,a2,a3,a4,a5)=
  6. {
  7.   x=300000,
  8.   df1=a1*(x-f2)^a2,
  9.   df2=a3*df1-a4*f2^a5
  10. };
  11. //用连分式法对微分方程组进行积分,获得理论值。用编译符“~”输出该函数,供Matlab等客户机程序调用。
  12. //_a1,_a2,_a3,_a4,_a5为优化参数;t1,t2为积分的起点和终点;f1,f2为t1时的初值,返回时存放t2时的积分值。
  13. //函数返回时,t1=t2,或者t1-t2是一个极小值。下一次积分时,用t1,f1,f2作为积分起点比用t2,f1,f2要好。
  14. //h,s为自动变量。Array,free,hf,step,eps为静态变量:Array为工作数组;hf为函数f的句柄;step为积分步长;eps为积分精度。
  15. //专用静态变量free用于销毁表达式前的释放工作(Forcal在销毁表达式前将自动设置free=1,然后自动执行表达式)。
  16. ~optint(_a1,_a2,_a3,_a4,_a5,t1,f1,f2,t2 : h,s,static,Array,free,hf,step,eps : a1,a2,a3,a4,a5)=
  17. {
  18.   if[free,delete(Array),return(0)],  //销毁表达式时,销毁工作数组Array
  19.   if{ !hf,
  20.       hf=HFor("f"),                  //预先用函数HFor获得函数f的句柄hf
  21.       Array=new[rtoi(real_s),rtoi(2*15)], //预先申请工作数组Array
  22.       step=0.1,eps=1e-6              //积分步长step要合适,积分精度eps越小越精确,用于对微分方程组积分一步函数pbs1
  23.   },

  24.   a1=_a1,a2=_a2,a3=_a3,a4=_a4,a5=_a5,//传递优化变量,函数f中要用到a1,a2,a3,a4,a5
  25.   Array.setra(0,f1,f2),        //设置积分初值,通过模块变量Array传递,Array是一个数组
  26.   s=ceil[(t2-t1)/step],        //计算积分步数
  27.   h=(t2-t1)/s,                 //重新计算积分步长
  28.   {   pbs1[hf,t1,Array,h,eps], //对微分方程组积分一步
  29.       t1=t1+h                  //积分步长增加
  30.   }.until[abs(t1-t2)<h/2],     //连续积分至t2
  31.   Array.getra(0,&f1,&f2)       //从数组Array获得t2时的积分值
  32. };
  33. !HFor("optint");               //使函数optint有效
复制代码

    模块2获得优化时目标函数的值(可简称为opt


  1. !using["XSLSF"];                //使用命名空间XSLSF
  2. //函数定义,用于计算微分方程组中各方程右端函数值,连分式法对微分方程组积分一步函数pbs1将调用该函数ff。
  3. //t为自变量,f1,f2为函数值,df1,df2为右端函数值(即微分方程的值)。
  4. //该函数被调用时将用到参数a1,a2,a3,a4,a5,这5个参数正好是拟合参数,用模块变量传递这5个参数。
  5. ff(t,f1,f2,df1,df2 : x : a1,a2,a3,a4,a5)=
  6. {
  7.   x=300000,
  8.   df1=a1*(x-f2)^a2,
  9.   df2=a3*df1-a4*f2^a5
  10. };
  11. //用连分式法对微分方程组进行积分,获得理论值。
  12. //t1,t2为积分的起点和终点。
  13. //h,s为自动变量。
  14. //模块变量:hff为函数ff的句柄,要预先获得该句柄;Array为工作数组;step为积分步长;eps为积分精度。
  15. 积分(t1,t2:h,s:hff,Array,step,eps)=
  16. {
  17.     s=ceil[(t2-t1)/step],        //计算积分步数
  18.     h=(t2-t1)/s,                 //重新计算积分步长
  19.     {   pbs1[hff,t1,Array,h,eps], //对微分方程组积分一步
  20.         t1=t1+h                  //积分步长增加
  21.     }.until[abs(t1-t2)<h/2]      //连续积分至t2
  22. };
  23. //获得优化时目标函数的值。用编译符“~”输出该函数,供Matlab等客户机程序调用。
  24. //_a1,_a2,_a3,_a4,_a5为优化参数;t1,t2,i,s,y,yy,z为自动变量;tArray,free,max为静态变量;hff,Array,step,eps, a1,a2,a3,a4,a5为模块变量。
  25. //数组tArray中存放实验数据;Array为工作数组;hff为函数ff的句柄;step为积分步长;eps为积分精度。
  26. //专用静态变量free用于销毁表达式前的释放工作(Forcal在销毁表达式前将自动设置free=1,然后自动执行表达式)。
  27. ~opt(_a1,_a2,_a3,_a4,_a5 : t1,t2,i,s,y,yy,z, static,tArray,free,max : hff,Array,step,eps, a1,a2,a3,a4,a5)=
  28. {
  29.   if[free,delete(Array),delete(tArray),return(0)],  //销毁表达式时,销毁数组Array和tArray
  30.   if{ !tArray,
  31.       hff=HFor("ff"),                  //预先用函数HFor获得函数ff的句柄hff
  32.       Array=new[rtoi(real_s),rtoi(2*15)], //预先申请工作数组Array
  33.       max=4801,                      //实验数据组数
  34.       tArray=new{rtoi(real_s),rtoi(max),rtoi(2),rtoi(EndType), //存放实验数据ti
  35. 0   ,   0   ,
  36. 0.5 ,   0.000809    ,
  37. 1   ,   0.001182    ,
  38. //其余数据略
  39. 2399.5  ,   0.006192    ,
  40. 2400    ,   0.006192   
  41.       },
  42.       step=0.1,eps=1e-6              //积分步长step要合适,积分精度eps越小越精确,用于对微分方程组积分一步函数pbs1
  43.   },

  44.   a1=_a1,a2=_a2,a3=_a3,a4=_a4,a5=_a5,//传递优化变量,函数ff中要用到a1,a2,a3,a4,a5
  45.   Array.setra(0,0,50000),            //设置积分初值,通过模块变量Array传递,Array是一个数组
  46.   i=1,s=0,t1=0,
  47.   (i<max).while{
  48.     tArray.getra(i*2,&t2,&yy),
  49.     积分(&t1,t2),                    //从t1积分到t2
  50.     Array.getra(0,&y,z),             //从数组Array获得t2时的积分值
  51.     s=s+[y-yy]^2,                    //累加理论值与实验值差的平方
  52.     i++
  53.   },
  54.   s
  55. };
  56. !HFor("opt");                 //使函数opt有效
复制代码

现在的问题是如何在Matlab中调用函数optint或opt?望各位高手帮忙。

以下给出VBScript使用VBMFocal接口的例子及VBA使用CMForcal的例子,供参考。

1VBScript使用VBMFocal的例子(步骤见注释部分):调用模块1中的函数optint

  1. Set obj=CreateObject("FcScript.VBMForcal")
  2.     dim str_optint, nModule, hModule, err1, err2, iErrCode, hHandle, NumPara, xx
  3.     Call obj.CLoadDll("FcData32W","XSLSF32W")  ‘加载需要的Forcal扩展动态库
  4. nModule = 0               ‘设为0
  5.     str_optint=“模块2的代码” ‘用实际代码取代之
  6.    iErrCode=obj.VBComModule (str_optint, nModule, hModule, err1, err2 ) '编译Forcal源程序为一个模块
  7.    If iErrCode=0 Then
  8.       hHandle=obj.VBGetForHandle(CLng(2)," optint ",NumPara)'获得函数optint的句柄
  9.       xx =Array(_a1,_a2,_a3,_a4,_a5,t1,f1,f2,t2)   '用数组xx存放自变量,设为有意义的实际值
  10.       obj.VBCalFor(CLng(2), hHandle, xx) '执行函数optint,结果在xx中,可多次调用该函数
  11.     Else
  12.         MsgBox iErrCode,0,"编译错误代码"
  13.     End If
  14. Set obj=Nothing
复制代码
2VBA使用CMForcal的例子(步骤见注释部分):调用模块2中的函数opt

  1. Dim obj As Object
  2. Dim iCode As Long, theStr As String, nModule As Long, hModule As Long, err1 As Long, err2 As Long
  3. Set obj = CreateObject("FcScript.CMForcal")‘获得接口
  4. Call obj.CLoadDll("FcData32W","XSLSF32W")  ‘加载需要的Forcal扩展动态库
  5. nModule = 0               ‘设为0
  6. theStr = “模块2的代码” ‘用实际代码取代之
  7. iCode = obj.CComModule(theStr, nModule, hModule, err1, err2) ‘编译模块2
  8.     If iCode = 0 Then ‘检查编译是否正确
  9.         ExComModule = "编译正确!" & "模块句柄:" & hModule
  10.     Else
  11.         ExComModule = "编译错误!错误代码:" & iCode & ",出错起始位置:" & err1 & ",出错结束位置:" & err2
  12.     End If
  13. Dim hFor As Long, Para As Long, NumPara As Long
  14. hFor = obj.CGetForHandle(2, “opt”, Para, NumPara) ‘获得函数opt的句柄
  15. Dim d(5) As Double
  16.     d(0) = 0.0   ‘设置优化参数
  17.     d(1) = 1.0
  18.     d(2) = 2.0
  19.     d(3) = 3.0
  20.     d(4) = 4.0
  21. Dim ExCalRFor As Double
  22. ExCalRFor = obj.CCalRFor(hFor, d(0)) ‘传入优化参数,获得目标函数值,可多次调用该函数
  23. Call obj.CDeleteModule(hModule) ‘销毁模块2
  24. Set obj = Nothing
复制代码

以上虽然是用Matlab为例进行说明的,但有优化函数且能使用COM组件的软件均可一试。欢迎大家批评指正。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

1

查看全部评分

回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-6 21:02:54 | 显示全部楼层 来自 山东淄博
这道题目和http://forum.simwe.com/thread-884975-2-1.html 是一样的,mmtc程序也就是改改方程就行了,不想再做了。

非常感谢wanglu兄出了一系列的题目【积分方程的求解,含有微分方程的拟合】,无论是matlab ...
TBE_Legend 发表于 2009-12-5 18:48

TBE_Legend 您好,您给出的是以上帖子的楼主shamohu 的优化题目,不是woshichenjie555 的题目,woshichenjie555 的题目要麻烦一些。关于该题目,可参考我前面的说明。能否再用mmtc试一下?Forcal的优化结果不太好。
回复 不支持

使用道具 举报

发表于 2009-12-6 22:06:04 | 显示全部楼层 来自 江苏南京
23# wanglu
wanglu,你好!非常感谢你的热心帮助。由于Forcal的结果并不理想,现在我正在考虑采用遗传算法和ODE调用的方法进行分析,程序编出来了,也能够运行,但后期在总群变换后总是会出现ODE算法无法继续运行的问题,MATLAB上显示BUSY,强行中断后会出现在ODE算法上可能出现了问题无法运行。我现在的分析是由于我的方程太过复杂,在初始种群没有选取好的时候会出现这种情况,因此,我目前在不断地试初值,但目前而言没有得到好的结果。
不知道谁有这方面编程的经验,希望能指点一二。
回复 不支持

使用道具 举报

发表于 2009-12-6 22:06:07 | 显示全部楼层 来自 浙江杭州
23# wanglu

以前曾经试过将Forcal与Matlab混编,不过没搞明白Forcal的接口,就放弃了。
回复 不支持

使用道具 举报

发表于 2009-12-7 00:08:25 | 显示全部楼层 来自 黑龙江哈尔滨
本帖最后由 TBE_Legend 于 2009-12-7 00:14 编辑
23# wanglu  
wanglu,你好!非常感谢你的热心帮助。由于Forcal的结果并不理想,现在我正在考虑采用遗传算法和ODE调用的方法进行分析,程序编出来了,也能够运行,但后期在总群变换后总是会出现ODE算法无法继续运行 ...
napler821127 发表于 2009-12-6 22:06


wanglu兄:对于mmtc就是改改方程的事情,最近这类题目做多了,有点恶心了。

算了下第一个表格的情况。
{181.906, {0.000027926, {a1 -> 16.1683, a2 -> -1.33701,
   a3 -> -7.39229, a4 -> -3.67127, a5 -> -10.741, a6 -> 0.0040722}}}

分别为:计算时间,目标函数值,最有参数值,a6是f1(0)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2009-12-7 16:14:06 | 显示全部楼层 来自 江苏南京
27# TBE_Legend
TBE_Legend版主,你做出的拟合图形貌似与数据差别挺大的,这是最好的计算拟合结果吗?
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-7 17:23:42 | 显示全部楼层 来自 山东淄博
23# wanglu

以前曾经试过将Forcal与Matlab混编,不过没搞明白Forcal的接口,就放弃了。
messenger 发表于 2009-12-6 22:06

可能接口部分我的说明不太好。
以下是上面用到的几个函数说明(以VBMForcal接口为例说明,CMForcal接口用法与此类似):

1 加载Forcal动态库扩展:VBLoadDll(str)
    FcStr:含有Forcal扩展动态库名称的字符串。
    FcScript允许加载多个Forcal扩展动态库。例如:"FcData32W","XSLSF32W"

2 编译源程序:VBComModule(FcStr,nModule,hModule,err1,err2)
    将源程序中的表达式编译为一个或多个模块。源程序中可以用#MODULE#和#END#定义一个子模块。即#MODULE#和#END#之间的表达式定义为一个子模块。在模块中,以~开头的表达式被编译为公有表达式,能被其他模块访问到,其余的表达式均被编译为私有表达式,其他模块无法访问。
    FcStr:指向源程序的字符串。
    nModule:一般初始化为0,返回多个模块的最小模块号。一般用不到该参数。返回值是32位整数!
    hModule:返回模块的句柄,用于执行该模块。返回值是32位整数!
    err1和err2:返回编译出错位置。返回值是32位整数!
    该函数返回编译代码,若为0表示编译通过。返回值是32位整数!

3 获得Forcal中自定义函数的句柄:VBGetForHandle(ForType,ForName,NumPara)
    ForType:表达式的类型。只能取1(标识整数表达式)、2(标识实数表达式)、3(标识复数表达式);如果名称包含模块命名空间访问符::(如:"A::Fun"),只能取-1(标识整数表达式)、-2(标识实数表达式)、-3(标识复数表达式)。必须是32位整数!
    ForName:自定义函数名,字符串形式。可以包含模块命名空间访问符::(如:"A::Fun")。
    NumPara:返回函数的参数个数。当NumPara=-1时表示有0个自变量,当NumPara=0时表示有1个自变量,当NumPara=1时表示有2个自变量,依次类推。返回值是32位整数!
    该函数返回自定义函数的句柄,若为0表示函数不存在。返回值是32位整数!

4 执行Forcal中的自定义函数并返回运算结果:VBCalFor(ForType,ForHandle,Para)
    ForType:表达式的类型。只能取1(标识整数表达式)、2(标识实数表达式)、3(标识复数表达式,不过尚未启用)。必须是32位整数!
    ForHandle:由VBGetForHandle获得的自定义函数的句柄。必须是32位整数!
    Para:一维数组,存放自定义函数的参数。当ForType=1时数组为64位长整数类型,当ForType=2时数组为实数类型,当ForType=3时数组为复数类型。
    该函数返回运算结果。运算结果的类型与数组Para的类型相同!
    注意:一个函数若要用VBCalFor执行,在Forcal源代码中必须用HFor("函数名",函数类型)获取过该函数的句柄,此句柄与用函数VBGetForHandle获得的句柄相同。

5 删除模块:VBDeleteModule(hModule)
    hModule:编译源程序时得到的模块的句柄。必须是32位整数!
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-7 18:04:09 | 显示全部楼层 来自 山东淄博
本帖最后由 wanglu 于 2009-12-7 20:20 编辑

napler821127 ,你好: “求n维极值的单形调优法”以前设置初值不方便,我刚做了修改,可自由地设置初值,获得初值附近的最优解,若能猜到较合理的初值,可试一下。

从这里下载最新的OpenFC:http://xoomer.virgilio.it/forcal/xiazai/forcal9/openfc32w.rar
附件中是x=300000时的程序。尝试求解时,以下语句加上注释:

//验证(t1,t2,t3,t4,t5),                            //验证计算结果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2009-12-7 21:53:11 | 显示全部楼层 来自 北京
对napler821127 的问题,仅对第一种情况即x=300000,用4阶龙格库塔法,1stOpt可得结果:

a1          25.5520227720909
a2          -0.786190381371164
a3          0.0205170666095595
a4          3309759.84736165
a5          0

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-8 10:15:37 | 显示全部楼层 来自 山东淄博
对napler821127 的问题,仅对第一种情况即x=300000,用4阶龙格库塔法,1stOpt可得结果:

a1          25.5520227720909
a2          -0.786190381371164
a3          0.0205170666095595
a4          3309759. ...
shamohu 发表于 2009-12-7 21:53

使用shamohu 版主的结果作为初值,我用OpenFC又做了优化,我用的数据量比较大,共4801组,即前面附件中的数据。

结果:


  1. 实际迭代次数=1000, a1=681.52958448460708, a2=-0.91941243078497648, a3=-7.1433104048155016, a4=5328682.4584386265, a5=0., 目标函数终值=3.1732047140044418e-005
  2.                t           f1实验值           f1模拟值         f2模拟值
  3.                0.5         8.09e-004    9.4573333e-004        -2614341.2
  4.                 1.        1.182e-003    1.2286697e-003        -5278682.5
  5.                1.5        1.431e-003     1.406059e-003        -7943023.7
  6.                 2.        1.616e-003    1.5367946e-003         -10607365
  7.                2.5        1.762e-003    1.6408816e-003         -13271706
  8.                 3.         1.88e-003    1.7276293e-003         -15936047
  9. ... ...
  10.              1380.        5.532e-003    5.5806154e-003   -7.3535318e+009
  11.             1380.5         5.53e-003    5.5809045e-003   -7.3561961e+009
  12.              1381.        5.531e-003    5.5811934e-003   -7.3588605e+009
  13.             1381.5        5.532e-003    5.5814823e-003   -7.3615248e+009
  14.              1382.        5.532e-003    5.5817711e-003   -7.3641892e+009
  15. ... ...
  16.              1700.        5.744e-003    5.7484276e-003   -9.0587102e+009
  17.             1700.5        5.746e-003    5.7486662e-003   -9.0613745e+009
  18.              1701.        5.747e-003    5.7489048e-003   -9.0640389e+009
  19.             1701.5        5.746e-003    5.7491433e-003   -9.0667032e+009
  20.              1702.        5.747e-003    5.7493818e-003   -9.0693675e+009
  21.             1702.5        5.746e-003    5.7496201e-003   -9.0720319e+009
  22. ... ...
  23.             2397.5         6.19e-003    6.0313096e-003   -1.2775466e+010
  24.              2398.         6.19e-003    6.0314836e-003   -1.2778131e+010
  25.             2398.5         6.19e-003    6.0316575e-003   -1.2780795e+010
  26.              2399.        6.191e-003    6.0318314e-003   -1.2783459e+010
  27.             2399.5        6.192e-003    6.0320053e-003   -1.2786124e+010
  28.              2400.        6.192e-003    6.0321792e-003   -1.2788788e+010

复制代码


结果大家验证一下,似乎不错,但仍不是最优的,OpenFC仅迭代了1000次,已经半个多小时了。记得napler821127 说过f2的值应该是增加的。这似乎是优化过程中的一个常见问题,大家讨论一下?
回复 不支持

使用道具 举报

发表于 2009-12-10 02:05:19 | 显示全部楼层 来自 浙江杭州
29# wanglu

研究了一下,最简单的方法应该是以Matlab调用一般动态链接库的方法来调用Forcal。好象Forcal不能将一段Forcal程序自己编译成一般动态链接库,供其他语言调用。

所以只能用Matlab调用Forcal32.dll这个动态链接库,不过这样功能会逊色很多。

下面有2个问题:

1、Forcal的一般动态链接库是否是,\forcal32\Forcal动态库版本,这个目录下的Forcal32.dll这个文件?

2、Matlab调用其他语言的一般动态链接库,还要有一个相应的C语言头文件,与Forcal32.dll这个文件对应的C语言头文件是否是\forcal32目录下的Forcal32.h这个文件?
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-10 11:46:06 | 显示全部楼层 来自 山东淄博
29# wanglu

研究了一下,最简单的方法应该是以Matlab调用一般动态链接库的方法来调用Forcal。好象Forcal不能将一段Forcal程序自己编译成一般动态链接库,供其他语言调用。

所以只能用Matlab调用Forcal32.dll ...
messenger 发表于 2009-12-10 02:05

感谢messenger 版主关注Forcal。

Matlab用调用一般动态链接库的方法来调用Forcal,效率似乎是最高的。用C/C++这样调用Forcal有最高的效率。OpenFC就是VC++程序。Matlab来调用时,效率也应该最高吧?我感觉,用COM组件倒是损失一些效率。

Forcal确实不能将一段Forcal程序自己编译成一般动态链接库,供其他语言调用。但Forcal编译Forcal程序后返回一个句柄,用Forcal32W.dll的输出函数(以实数函数为例,用RealCal函数)调用即可:

double _stdcall RealCal(void *hFor,double *d);  //hFor是句柄,数组d中存放自变量

问题:
1、Forcal的一般动态链接库是否是,\forcal32\Forcal动态库版本,这个目录下的Forcal32.dll这个文件?

  Forcal32.dll是旧版本(Forcal8)的动态库,新版本(Forcal9)是Forcal32W.dll。

  Forcal9下载1:http://xiazai.zol.com.cn/detail/27/262790.shtml
  Forcal9下载2:http://xoomer.virgilio.it/forcal/xiazai/forcal9/forcal32w.rar

2、Matlab调用其他语言的一般动态链接库,还要有一个相应的C语言头文件,与Forcal32.dll这个文件对应的C语言头文件是否是\forcal32目录下的Forcal32.h这个文件?

  新版本(Forcal9)中是Forcal32W.h。

盼望messenger 版主能给出Matlab与Forcal混编的例子。我感觉似乎用COM组件更简单?

步骤:
1、获得FcScript的VBMForcal接口或CMForcal接口,以下以VBMForcal接口为例说明。
2、用VBLoadDll加载需要的Forcal动态库扩展。
3、用VBComModule编译字符串源程序为一组模块。
4、用VBGetForHandle获得Forcal中自定义函数的句柄。
5、用VBCalFor执行Forcal中的自定义函数并返回运算结果。

FcScript会自动回收垃圾,当然也可以自己管理,例如用VBDeleteModule删除一个模块。

特别注意的就是:一个函数若要用VBCalFor执行,在Forcal源代码中必须用HFor("函数名",函数类型)获取过该函数的句柄,此句柄与用函数VBGetForHandle获得的句柄相同。
在我的例子中,HFor("函数名",函数类型)的使用很频繁,见前面。
回复 不支持

使用道具 举报

 楼主| 发表于 2009-12-13 20:01:33 | 显示全部楼层 来自 山东淄博
本帖最后由 wanglu 于 2009-12-13 20:12 编辑

拟合了napler821127 的300000的数据,需重新下载OpenFC:
OpenFC下载:http://xoomer.virgilio.it/forcal/xiazai/forcal9/openfc32w.rar

代码见附件。

拟合步骤及说明:
1、用刚刚写的一个拟合函数OptMin拟合出初值,该函数将尽可能全局搜索极小值,但运行较慢。由于该例子运算量较大,故应小心地选取初值及区间等参数。各参数意义见该函数的说明。
2、用OptMin拟合时,对返回的结果分析,调整参数,获得认可的初值,如本例,结果应是t2增加。找准方向后调整初值及区间。
3、因OptMin太慢了,故找到较合理的初值后,再用“求n维极值的单形调优法”拟合即可。该函数我也做了修改,可输入初始参数。请参考说明。

部分结果:

实际迭代次数=851, a1=1.1802093322304931e-032, a2=5.3663167363872217, a3=40897666.810447931, a4=24.964895923033364, a5=1.0297136829719293e-002, 目标函数终值=7.1036616830449218e-006
               t           f1实验值           f1模拟值         f2模拟值
               0.5         8.09e-004    4.4479131e-004         68176.948
                1.        1.182e-003    7.5738428e-004          80947.26
               1.5        1.431e-003    9.9531853e-004         90664.184
                2.        1.616e-003    1.1857309e-003         98437.562
               2.5        1.762e-003    1.3434578e-003         104874.17
                3.         1.88e-003    1.4774444e-003         110339.84
               3.5        1.981e-003    1.5934748e-003         115071.14
                4.        2.069e-003    1.6954919e-003         119229.33
               4.5        2.143e-003     1.786296e-003         122928.92
                5.         2.21e-003    1.8679434e-003         126254.03
               5.5         2.27e-003    1.9419853e-003         129268.08
                6.        2.324e-003    2.0096191e-003         132020.05
               6.5        2.374e-003     2.071787e-003         134548.47
... ...
              260.        4.353e-003    4.4064139e-003         222851.18
             260.5        4.354e-003    4.4074081e-003         222877.67
              261.        4.355e-003    4.4084005e-003         222904.09
......
            1387.5        5.536e-003    5.5095858e-003         236000.72
             1388.        5.536e-003    5.5099509e-003         236001.48
......
            1762.5        5.784e-003    5.7785795e-003         236368.09
             1763.        5.785e-003    5.7789335e-003         236368.38
            1763.5        5.786e-003    5.7792874e-003         236368.68
             1764.        5.784e-003    5.7796414e-003         236368.98
......
             2000.        5.932e-003    5.9458837e-003          236475.6
            2000.5        5.934e-003    5.9462345e-003         236475.77
             2001.        5.934e-003    5.9465853e-003         236475.93
            2001.5        5.933e-003     5.946936e-003          236476.1
......
            2397.5         6.19e-003     6.223588e-003         236561.02
             2398.         6.19e-003    6.2239362e-003         236561.08
            2398.5         6.19e-003    6.2242845e-003         236561.15
             2399.        6.191e-003    6.2246327e-003         236561.21
            2399.5        6.192e-003     6.224981e-003         236561.27
             2400.        6.192e-003    6.2253292e-003         236561.34

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2022-3-24 18:26:44 | 显示全部楼层 来自 北京
1stOpt好像也能算
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2026-1-3 09:19 , Processed in 0.037392 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表