| 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方面的经典书籍了.  | 
|
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 |