Function value and YDATA sizes are incommensurate
Show older comments
I'm working on a project that requires fitting data to ODEs. I'm using lsqcurvefit and ode113 (I used ode45 before but it would take too long and sometimes eventually give me "unable to meet integration tolerances without reducing" errors). I keep getting "Function value and YDATA sizes are incommensurate" and I have no idea which of the arrays are giving me this problem, because I have another script that is very similar to this one, but with less parameters, and it works just fine.
Here are my codes:
function tryfit()
close all;
clear all;
tData = [1970 1980 1990 2000 2010 2014];
xDataW = [.974 .83 .7 .62 .66 .54]; % English Speakers
xDataE = [.026 .13 .3 .38 .34 .38]; % Bilingual Speakers
% bilinguals are just 1-welsh-english
popData = [xDataW; xDataE];
b(1) = rand(1); % initial value for s_English
b(2) = rand(1)+1; % initial value on a_English
b(3) = %rand(1); % initial value for k
lb = [0; 1; 0]; % lowerbound: s,a,k
ub = [1; 2; 1];
options = optimset('PrecondBandWidth', 0);
v = lsqcurvefit(@MiraModelOde, b.', tData, popData.', lb, ub, options)
function xdot = diffeq(t, x)
xdot = zeros(2,1);
xdot(1) = ((1-x(1)).*(1-v(3)).*v(1).*(1-x(2)).^v(2))-(x(1).*(1-v(1)).*(1-x(1)).^v(2));
xdot(2) = ((1-x(2)).*(1-v(3)).*(1-v(1)).*(1-x(1)).^v(2))-(x(1).*v(2).*(1-x(2)).^v(2));
dx = xdot;
end
tData_pred = [tData 2020 2030 2040];
[t,x] = ode113(@diffeq, tData_pred, (popData(:, 1)).');
x(:, 3) = ones(length(x),1) - x(:,2) - x(:,1);
plot(t,x(:,1), 'b')
plot(t,x(:,2), 'r')
plot(t,x(:,3), 'g')
end
and here's MiraModelOde.m
function s = MiraModelOde(v,t)
% codes system of differential equations describing language competition
% dxa/dt = s(1-xa-xb)(1-xb)^a - (1-s)xa(xb)^a
% dxb/dt = (1-s)(1-xa-xb)(1-xa)^a - s(xa)^axb
% xab = 1-xa-xb; (no need xab bc can be derived from xa and xb
% with variables
% x(1) = xa
% x(2) = xb
% parameters:
% v(1) = s
% v(2) = a
% v(3) = k
x0 = [.974 .026]; % initial conditions for population of xa and xb
% first one is English, second is bilingual
% function for ode45
function dx = diffeq(t,x)
xdot = zeros(2,1);
xdot(1) = ((1-x(1)).*(1-v(3)).*v(1).*(1-x(2)).^v(2))-(x(1).*(1-v(1)).*(1-x(1)).^v(2));
xdot(2) = ((1-x(2)).*(1-v(3)).*(1-v(1)).*(1-x(1)).^v(2))-(x(1).*v(2).*(1-x(2)).^v(2));
dx = xdot;
end
[T, Sv] = ode113(@diffeq, t, x0);
s = Sv;
end
I'm sorry if the code is not very readable.
5 Comments
Star Strider
on 2 Nov 2017
Note that you have three variables (not parameters) and three initial conditions in a second-order system.
Therein lies the problem.
You need to revisit your differential equations to see how to reconcile that, and reconcile it with the dependent data you want to fit having two columns. Fitting only two outputs of your differential equation system is not the problem. The problem is defining your system of differential equations correctly, so that you can integrate them.
Cho113578
on 6 Nov 2017
Star Strider
on 6 Nov 2017
Not a stupid question at all. In the system you posted in your most recent Comment, you have two variables, ‘xa’ and ‘xb’, with the others apparently being parameters. Originally, you had three variables in a two-equation system, and that confused both me and the ODE solver.
So integrate your system with respect to ‘xa’ and ‘xb’, and treat the others as parameters to be optimised in the nonlinear regression.
Cho113578
on 7 Nov 2017
Star Strider
on 7 Nov 2017
In your posted code the syntax is wrong because you still have ‘v(3)’ and only ‘v(1)=xa’ and ‘v(2)=xb’ are appropriate to your differential equation system. Whatever ‘v(3)’ is (perhaps ‘sa’?) should be a parameter to be estimated, instead, along with the exponent ‘a’.
Answers (0)
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!