Matlab bvp4c报错:BCFUN需返回长度为5的列向量原因解析
解决Matlab bvp4c边界条件长度错误的问题
问题重现
用户编写的Matlab边值问题求解代码如下:
function Y6 solinit = bvpinit(linspace(0,1),[0;3;1;1],2); sol = bvp4c(@ode, @bc, solinit); y = sol.y; time = sol.parameters*sol.x; ut = -y(4,:); figure(1); plot(time,y([1 2],:)','-'); hold on; plot(time, ut, 'k:'); axis([0 time(1,end) -1.5 3]); text(1.3,2.5,'x_1(t)'); text(1.3,.9,'x_2(t)'); text(1.3,-.5,'u(t)'); xlabel('time'); ylabel('states'); title('Numerical solution'); hold off; % ------------------------------------------------------------------------- % ODE's of augmented states function dydt = ode(t,y,T) dydt = T*[2*y(2);4*y(4);0;-2*y(3)]; % ------------------------------------------------------------------------- % boundary conditions: x1(0)=11;p2(0)=2; x2(tf)=3; 3*p1(tf)+p2(2)^2=0 function res = bc(ya,yb,T) res = [ ya(1) - 11; ya(4); yb(2) - 3; 3*yb(3)+yb(4)^2];
运行后报错:
'The boundary condition function BCFUN should return a column vector of length 5'
错误原因
Matlab的bvp4c函数对边界条件的数量有严格要求:
当边值问题包含n个状态变量 + m个未知参数时,边界条件函数必须返回长度为
n + m的列向量。
你的代码里:
- 状态变量共4个(
y(1)到y(4)) - 传入了1个未知参数
T(对应终端时间tf,通过time = sol.parameters*sol.x实现时间区间缩放)
因此,边界条件总数量需要是4 + 1 = 5,但你的bc函数只返回了4个元素的向量,不满足要求,触发报错。
另外,你注释里标注的边界条件p2(0)=2,原代码里写成了ya(4),漏掉了-2,这也是一个逻辑错误。
修正方法
你需要补充1个边界条件,结合代码的时间缩放逻辑,这通常是最优控制问题中自由终端时间的横截条件(比如终端时刻哈密顿函数为0)。同时修正漏写的边界条件项,示例如下:
function res = bc(ya,yb,T) % 修正原边界条件中的遗漏项 cond1 = ya(1) - 11; % x1(0)=11 cond2 = ya(4) - 2; % p2(0)=2(原代码漏写-2) cond3 = yb(2) - 3; % x2(tf)=3 cond4 = 3*yb(3)+yb(4)^2; % 3*p1(tf)+p2(tf)^2=0 % 补充第5个边界条件:终端时刻哈密顿函数为0(根据你的问题逻辑调整) cond5 = 2*yb(2)*yb(3) + 4*yb(4)*(-yb(4)); % 组合为长度5的列向量 res = [cond1; cond2; cond3; cond4; cond5];
关键知识点
bvpinit的第三个参数是未知参数的初始猜测,这里对应终端时间tf的初始值- 时间缩放
time = T*sol.x是因为bvp4c默认求解区间为[0,1],通过缩放得到实际时间区间[0, tf] - 带未知参数的边值问题,边界条件总数必须等于状态变量数 + 未知参数数
内容的提问来源于stack exchange,提问作者Nguyễn Minh Tú
相关产品推荐
相关产品推荐

