Labfans是一个针对大学生、工程师和科研工作者的技术社区。 | 论坛首页 | 联系我们(Contact Us) |
![]() |
![]() |
#1 | |||||
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]()
为了实现在t 在 [400,414] [900,910] 区间
常数Q 为0 t在其余情况 Q都为5.3*10^(-6) Q设初始值也设为 5.3*10^(-6); t=0:0.1:2000 写了下面一段程序 引用:
结果中间elseif语句完全没有效果, 在t= [900,910] 区间中 Q仍然=5.3*10^(-6) 而 在t = [400, 414]区间中 Q是=0的 但是我改到 t= [700, 710] 区间中, Q在这时候却可以变成 0了 这时候 t 在 两个区间[400, 414] [700, 710] 中 Q值都变成了0 引用:
我还试过下面这些 始终都是同样问题,900-910 就不行,700-710就可以 引用:
引用:
引用:
|
|||||
![]() |
![]() |
![]() |
#2 |
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]()
为什么 完全相同的程序,900-910 elseif 语句就没作用 换成700-710 却可以了?
这是什么毛病啊, |
![]() |
![]() |
![]() |
#3 |
高级会员
注册日期: 2007-12-02
年龄: 44
帖子: 303
声望力: 31 ![]() ![]() ![]() ![]() |
![]()
请把调用的命令都发上来,看下. 你现在的这些程序,我运行了下,没有问题.
我调用的命令是: t=905; if((t >= 400) && (t <= 414)) Q = 0; elseif ((t >=900) && (t <= 910)) Q = 0; else Q = 5.3*10^(-6); end 程序输出中 Q=0 |
![]() |
![]() |
![]() |
#4 | |
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]()
程序一共有两个.m 文件,一个是主程序scriptEx5.m 另外一个是调用的 EquationEx5.m
EquationEx5.m 是需要求解的函数方程式部分, if, elseif 语句也在这部分程序里 下面是程序原件,可以直接分别拷贝为scriptEx5.m 和EquationEx5.m 运行 运行主程序scriptEx5, 会有图显示出来,在Q=0的时候,曲线会有突起,表示温度有升高 400-414 部分始终正常,900-910 就没变化, 但是将EquationEx5.m 中900-910 改成 700-710 就可以了,这时候可以观察到400-414 和700-710 两个突起 手动将常数Q 改为0 可以在任何位置观察到温度升高的现象, 但用elseif 语句却只有700-710 部分比较正常 下面是主程序 ScriptEx5.m 中的代码 引用:
|
|
![]() |
![]() |
![]() |
#5 | |
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]()
主程序ScriptEx5.m 调用的EquationEx5.m (ode15s函数中调用) 如下
引用:
|
|
![]() |
![]() |
![]() |
#6 |
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]()
发现是什么毛病了,
因为ode15s 这个solver不精确, 根本没有运行 t在 900-910 之间的数据,直接跳过去了 汗啊 ode45 精度会相对高些, 但其实也同样可能出现类似问题, 虽然设了 t = [0: 0.1: 2000]; 但实际上t值跨度可能达到几十甚至上百。 看来matlab 这软件还需要完善啊 |
![]() |
![]() |
![]() |
#7 |
高级会员
注册日期: 2007-12-02
年龄: 44
帖子: 303
声望力: 31 ![]() ![]() ![]() ![]() |
![]()
正在思考中,确实很奇怪哦
这个是刚性微分方程的求解,对于那par 28个参数是个什么东东,程序里好象没有全用 不防把你要求解的微分方程附上来,大家一起看下? 如何 |
![]() |
![]() |
![]() |
#8 |
高级会员
注册日期: 2007-12-02
年龄: 44
帖子: 303
声望力: 31 ![]() ![]() ![]() ![]() |
![]()
哈哈,经过你的提醒,我明白了, 调整下" 相对误差容许上限" 就可以了
原程序中"ode45"命令前面先进行求解参数的修改,使得求解保证足够的精度 插入的命令如下: options=odeset('RelTol',1e-7)%默认是0.001,现在改为10^(-7) [time1,State1] = ode45(@EquationEx5,t,state0,options,Parameters); |
![]() |
![]() |
![]() |
#9 | |
初级会员
注册日期: 2008-01-11
年龄: 44
帖子: 6
声望力: 0 ![]() |
![]() 引用:
hehe 多谢阿 以前没注意这个问题 t=[0:0.1:2000] 本来以为可以设置 取t值间隔0.1 结果根本没效果 看了一下matlab的帮助文件,这个RelTol 还有 AbsTol 指的 似乎都是相对于函数值来说的 在函数值相对平缓的区域, 计算的过程中,自变量取值跨度会相当的大,不知道有什么 办法才可以直接控制自变量的精度 看帮助文件里面写可以直接设置 t = [t1,t2,...,tf], 在中间直接指定要计算的自变量值 但我试了一下,发现不行 如果我指定 t = [0,401,405,414,901,905,909,1500] 整个函数竟然变成直的了,全乱套了 |
|
![]() |
![]() |
![]() |
#10 | |
高级会员
注册日期: 2007-12-02
年龄: 44
帖子: 303
声望力: 31 ![]() ![]() ![]() ![]() |
![]() 引用:
AbsTol 为一个向量,其分量表示每个状态变量容许的绝对误差,其默认值为10^(-6).当然可以自由设置其值,以改变求解精度 MaxStep 为求解方程最大容许的步长 这些都可以由options来更改,方法同上面的那个程序. 微分方程的求解,你上面用的都是数值逼近的方法,每个方法各有优缺点,建议你参阅下相关书籍. 总的来说求解过程要注意三个方面 1.选择适当的步长. 如果步长太大,误差很大,你上面出现的问题主要是由于步长过大导致的.但是如果步长太小,又会产生较大的累积误差. 2. 改进近似算法精度.比较成功的方法有RUNGE-KUTTA法,Adams法等,ode45就是综合了这两种方法. 3.采用变步长的方法. 前面说的"适当"地选择步长,这本身就是个模糊的概念,如果适当地选择步长取决于经验.事实上,很多种方法都容许变步长的求解,如果误差较小时,可自动地增加步长,而误差较大时再自动减小步长,从而精确,有效地求解给出的常微分方程的初值问题. 以上言论摘自 "高等应用数学的MALTAB求解" 一书,作者 薛定宇 陈阳泉 我手上没有这本书的电子版,如果有谁有的话,不妨分享下. 我觉得买一本更好,这本书应该说是matlab方面的经典书籍了. |
|
![]() |
![]() |