ode45 Not Enough Initial Conditions - matlab

I have defined a function using matlabFunction. Here is the code:
matlabFunction([a16;-((1+x16^2)/(2*x16))*a16],'vars',{x16,[a16]},'file','DE_19')
which seemed to work. However, when I try to use ode45 to solve the differential equation defined by matlabFunction, I get an error. Here is the code:
[x,y] = ode45(#(x16,Y) DE_19(x16,Y),[1,11],[2,7,5]);
The error I get is
Error using odearguments (line 93)
#(X16,Y)DE_19(X16,Y) returns a vector
of length 6, but the length of
initial conditions vector is 3. The
vector returned by
#(X16,Y)DE_19(X16,Y) and the initial
conditions vector must have the same
number of elements.
Error in ode45 (line 114)
[neq, tspan, ntspan, next, t0,
tfinal, tdir, y0, f0, odeArgs,
odeFcn, ...
So, I tried changing my initial conditions from [2,7,5] to [2,7,5,8,9,4]. When I did this, I got the same message, but instead of saying that the vector returned is length 6, and that the length of my initial condition vector was 3, it said that the vector returned was of length 12, and that the length of my initial condition vector was 6.
Why is it doing this? This seems strange that the length of the vector returned would vary as I vary the length of the initial condition vector.

Have you looked at the contents of DE_19.m? You should provide the code you used before calling matlabFunction, but here's a runnable version that might be something like what you used:
syms a16 x16;
DE_19 = matlabFunction([a16;-((1+x16^2)/(2*x16))*a16],'vars',{x16,[a16]})
This returns:
DE_19 =
#(x16,a16)[a16;(a16.*(x16.^2+1.0).*(-1.0./2.0))./x16]
As you can see, if you pass in a scalar state (the second argument, a16, is the state and the first, x16 is the independent variable – this is true for all ODE solvers: t then y), the output will always two elements. And indeed the output will always be twice as long as the input state. Maybe a16 and x16 should be switched? Look at the help and documentation for matlabFunction as they provide an example that does exactly this.
By the way, there's no real need to create a file. You can use the anonymous function returned by matlabFunction like this (you'll need to figure out which variable is which and what is missing to still get it to work):
DE_19 = matlabFunction([...],'vars',{...})
[x,y] = ode45(DE_19,[1,11],[2,7,5]);

Related

Polyval issues after using polyint

Im trying to calculate the area of randomly generated graph, which is created from randomly generated x and y values and drawn using polyfit.
clear
clc
for i=1:8
x(i)= round((12+5).*rand - 5,0)
y(i)= round((7+6).*rand -6,0)
end
p=polyfit(x,y,5);
x1=-5:0.1:12;
y1=polyval(p,x1);
plot(x,y,'o')
hold on
plot(x1,y1)
y2=(x1)*0-5
plot(x1,y2)
hold off
syms x
S1=int(x.*0-5,x,-2,7)
pp=polyint(p,x)
S2=polyval(pp,-2)-polyval(pp,7)
S=S1+S2
However, I am getting this weird error that doesnt make any sense to me.
Undefined function 'filter' for input arguments of type 'sym'.
Error in polyval (line 56)
y = filter(1,[1 -x],p);
Why doesnt it allow me to use polyval after using polyint ? Its still a polynomial..
In other words. How could I change the end of the code to calculate the definite integral of the newly formed polynomial, which is always different

nlinfit Dimension Error

I am using nonlinearfit tool in matlab.
I keep getting the following error:
Error using nlinfit (line 210)
MODELFUN must be a function that returns a vector of fitted values the same size as Y (1-by-100). The model function you provided returned a result that was 1-by-2.
One common reason for a size mismatch is using matrix operators (, /, ^) in your function instead of the corresponding element-wise operators (., ./, .^).
I found this question very similar to mine, but still I get the same error. I have tried calculating myfun on the console while using a vector as an input, which gives me output of correct dimension. It will be ton of help if anybody can point out the mistake.
% Defining the function
myfun = #(t,b)exp(t.*b(1)+b(2));
[y_a] = arrayfun(myfun,x_a);
% Using nonlinear least square minimization
beta0 = [1 1];
nlinfit(x,y,myfun, beta0)
Thanks in advance...:)
Edit: Found this to be working.
g = fittype('exp(k*x + a)');
[fit1,gof,fitinfo] = fit(x',y',g,'StartPoint',[1 1]);
The function used in nlinfit takes the parameter vector as its first argument, then the independent data vector. You want,
myfun = #(b,t)exp(t.*b(1)+b(2));
Note that you could just use * rather than .* in this instance too.

fminsearch multiple parameters matlab

I'm trying to use fminsearch with multiple parameters but I can't seem to even get it working with two. I've also tried using optimization tool in matlab but then I get:
Optimization running.
Error running optimization.
Not enough input arguments.
What i do:
fval = fminsearch(#g,[1 1])
The function g looks like this:
function r=g(x,y)
r=x.^3+3*x*y.^2+12*x*y;
end
but i get this:
Error using g (line 2)
Not enough input arguments.
Error in fminsearch (line 190)
fv(:,1) = funfcn(x,varargin{:});
Your function g takes two inputs, x and y, however you supply fminsearch one input, the vector [1 1]. You need to rewrite it so that fminsearch only needs a single vector as input, but then that vector is split into two numbers to input into g.
fminsearch(#(v) g(v(1),v(2)),[1 1])
This makes an anonymous function that takes a vector as input (v) and then uses the first element (v(1)) as the first input to g, and the second element as the second input.

Matlab fitting data to a function, where the function is a summation and periodic, syntax

I am attempting to fit temperature data over the last 50 years for the US using the lsqcurvefit, but I am concerned that my fitting function has bad syntax.
The fitting function itself is of the form:
∑(ai+bi*t+ci*t^2)*(cos(vt+p))
Summing from i=1 to N. I would like t to correspond to the time vector called TIME. Ideally the fitting should return values for a, b, c, v, and p which describe the temperature data
I am attempting to fit daily maximum temperatures, a vector called TMAX.
So far I have:
lsqcurvefit(fitFn(1,2,TIME),5,TIME,TMAX)
Where fitFn is defined in a script as
function f = fitFn(i,N,t)
f=0;
for i=1:N
f =#(i,N,a,b,c,v,p,t) f + (a+b*t+c*t^2)*(cos(v*t+p));
end
However whenever I run lsqcurvefit I get the error
Error using
fitFn>#(i,N,a,b,c,v,p,t)f+(a+b*t+c*t^2)*(cos(v*t+p)) (line
4)
Not enough input arguments.
Error in lsqcurvefit (line 199)
initVals.F =
feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial user-supplied objective function
evaluation. LSQCURVEFIT cannot continue.
I am sure I'm making a simple error but I'm somewhat at a loss. I'm new to MatLab and don't quite understand how to use anonymous functions. Any help would be greatly appreciated.
Thanks for reading
Your fitFn is very wrong. I think this is what you want:
f = #(x,t) (x(1)+x(2)*t+x(3)*t.^2)*cos(x(4)*t+x(5))
lsqcurvefit(f,zeros(1,5),TIME,TMAX)

Matrix dimension error while calling mldivide in MATLAB

I am getting this error while running my code:
Error using ==> mldivide Matrix dimensions must agree.
Here is my code :
%make the plots of phase and group velocity vs discreteness of the grid
c=1;
a=input('Please enter the ratio cdt/dx : ')
figure(1)
R=2:40;
plot(R,phase_vel(R,a)/c)
xlabel('R=l/dx')
ylabel('u_phase/c')
%figure(2)
%plot(group_vel(R,a),R,0,40)
%xlabel('R=l/dx')
%ylabel('u_group/c')
and here are my functions :
function phase_velocity = phase_vel(R,a)
%numerical phase velocity of the discrete wave
c=1;
phase_velocity=(2*pi*c)/(R*knum(R,a));
end
function group_velocity =group_vel(R,a )
%numerical group velocity of the discrete wave
c=1;
group_velocity=(a*sin(knum(R,a)))/(sin(2*pi*a/R))
end
function knumber = knum(R,a)
%This is the k wave number
knumber=acos((1/a)^2*(cos(2*pi*a/R)-1)+1);
end
How can I resolve this error?
EDIT: I used . operator in every equation and i changed the limits of R=4:40
If your goal is to apply your formulas to each individual value in the vector R then you should be performing all of your computations using the element-wise arithmetic operators .*, ./, and .^ instead of the matrix operators *, /, and ^.
Your error is probably occurring in the first call to your function knum, specifically when you try to compute 2*pi*a/R. Since 2*pi*a is a single scalar value, you get an error when trying to perform matrix right division / using the row vector R. The really weird thing is the error message:
??? Error using ==> mldivide
Matrix dimensions must agree.
which implies you are using the matrix left division operator \, which you clearly aren't. I tested this in MATLAB R2010b and I get the same incorrect function name appearing in my message. I think this may just be a typo in the error message, and I've dropped a note to the MATLAB folks to take a look at it and clear it up.
I don't have the Symbolic Math Toolbox, but your problem seems to be that you are using plot, a function which can deal with arrays of numbers, and feeding it the result of a symbolic calculation. Have a look at the Matlab Help, where the Topic Creating Plots of Symbolic Functions suggests using ezplot(). Alternatively you need to evaluate your symbolic expression for certain input values to create an array of numbers that plot can deal with - but you can't use double() for that since it wouldn't know what numbers to plug into your variables.