How convert symbolic equation to solve in ode45? - matlab

I'm trying to solve a differential equation like below:
%% Parameters Initialization
C = 0.01;
gfi = 0.2308;
gso = 0.769;
Efi = 17.333;
Eso = 0;
km = 0.842;
v12m = 5.85;
kn = 4.4;
v12n = 9.667;
tauni = 3;
%% defining Functions
syms v n;
n_v_e = 1 / (1+exp((v12n-v)/kn));
m_v = 1 / (1+exp((v12m-v)/km));
gfi_v = gfi * m_v;
Dn = tauno*(n_v_e-n);
Ifi = gfi_v*(v-Efi);
Iso = gso*n*(v-Eso);
Dv = -1/C * (Ifi + Iso);
%% Solving ODE
v0 = -10;
n0 = 0.1;
te = 2000;
Dv = subs(Dv,'v','y(1)');
Dv = subs(Dv,'n','y(2)');
Dn = subs(Dn,'v','y(1)');
Dn = subs(Dn,'n','y(2)');
[t,V] = ode45(#(t,y)[Dv;Dn],[0 te],[v0;n0]);
the problem occurs right here at ode45 saying "Inputs must be floats, namely single or double."
I know the problem is due to symbols (n and v) but I don't know how to get rid of them!
I don't also want to write a seperate function and use it instead of [Dv;Dn].
Thank you for your help

Related

Solving coupled ODE eigenvalue problem using Chebfun

I am solving a coupled eigenvalue problem using Chebfun but I am getting some error. I am attaching my code here
%% Problem setup.
chi= 1;
m = 1495/1000;
L = 1;
th =-chi^(-1/m)*(-1 + chi^(1/m));
gm = 1500/1000;
kx = 1;
kz = 1;
kh = sqrt(kx^2 + kz^2);
g = 10;
Le = 0.001;
Omg= 25000;
VA = Le*2*Omg*L;
mu = 1;
B0 = VA*sqrt(mu);
omgC = 2*Omg*kz/kh;
omgM = VA*kx;
omge = 0.01*omgM;
kappa = 1e-5;
cp = 1;
dom = [0,1];
op = chebop(#(y,u,b,s) [-g*kh^2*(1+y*th)^(-m)*omgM^2.*s./(omgC^2*omge)...
+kh^2*u+(m*th^2.*u./(1+y*th).^2)-(m^2*th^2*u./(1+y*th).^2)...
+1j*kh^2*kx*m*th*(1+y*th)^(-m)*omgM^2.*u./(kh*kz*omgC*omge*(1+y*th))...
+kh^2*(1+y*th).^(-2*m)*omgM^4.*u./(omgC^2*omge^2)...
-2*m*th*diff(u,1)./(1+y*th)-1j*kh^3*(1+y*th)^(-m)*omgM^2.*diff(u,1)/(kh*kz*omgC*omge)...
+1j*kh*kx*(1+y*th)^(-m)*omgM^2.*diff(u,1)/(kz*omgC*omge)...
+1j*kh*kz*(1+y*th)^(-m)*omgM^2.*diff(u,1)/(kx*omgC*omge)-diff(u,2);...
omge*b+1j*B0*kx*u+omge*diff(b,2)/kh^2;-u./(1+y*th)+...
kappa*(-kh*2.*s+1j*(1+m)*th.*s./(1+y*th)+diff(s,2))], dom);
oplam = chebop(#(y,u,b,s) [-1j*kh^2*(1+y*th)^(-2*m)*omgM^4.*b/(B0*kx*omgC^2*omge^2)...
-kh^2*u/omge;b;s], dom);
op.bc = #(y,u,b,s) [u(0),b(0),s(0),u(1),b(1),s(1)];
%% Solve the eigenvalue problem.
[V, D] = eigs(op, oplam);
D = diag(D);
The error I am getting is
Dimensions of matrices being concatenated are not consistent.
I am not sure what mistake I am making. Should I convert the equations into first order and then input them? or is it somewhere in the syntax? Please help.
Thank you.

Numerical Analysis help in MatLab

I am in a numerical analysis class, and I am working on a homework question. This comes Timothy Sauer's Numerical Analysis, and is in the second suggested activity section. I have been talking with my professor about this code, and it seems the error and the approximation are wrong, but neither one of us are able to figure out why. The following code is what I am using, and this is in MatLab. Anyone know enough about Euler Bernoulli beams, and Matlab who can help out?
function ebbeamerror %This is for part three
disp(['tabe of errors at x=L for each n'])
disp([' n ',' Aprox ',' Actual value',' Error'])
disp(['======================================================='])
format bank
for k = 1:11
n = 10*(2^k);
D = sparse(1:n,1:n,6*ones(1,n),n,n);
G = sparse(2:n,1:n-1,-4*ones(1,n-1),n,n);
F = sparse(3:n,1:n-2,ones(1,n-2),n,n);
S = G+D+F+G'+F';
S(1,1) = 16;
S(1,2) = -9;
S(1,3) = 8/3;
S(1,4) = -1/4;
S(2,1) = -4;
S(2,2) = 6;
S(2,3) = -4;
S(2,4) = 1;
S(n-1,n-3)=16/17;
S(n-1,n-2)=-60/17;
S(n-1,n-1)=72/17;
S(n-1,n)=-28/17;
S(n,n-3)=-12/17;
S(n,n-2)=96/17;
S(n,n-1)=-156/17;
S(n,n)=72/17;
E = 1.3e10;
w = 0.3;
d = 0.03;
I = w*d^3/12;
g = -9.81;
f = 480*d*g*w;
h = 2/10;
L = 2;
x = (h^4)*f/(E*I);
x1 = ones(n ,1);
b = x*x1;
size (S);
size(b);
pause
y = S\b;
x=2;
a = (f/(24*E*I))*(x^2)*(x^2-4*L*x+6*L^2);
disp([n y(n) a abs(y(n)-a)])
end
end

Why is this function producing a value of 'Inf'?

I have the following function below which I need to translate into MATLAB code, I'm pretty sure I've got the function translated properly. However I've got a small issue with the code.
Function to translate:
When I attempt to run this function the value of phi comes out as being inf I'm really not sure why this is happening?
Also, can someone tell me if I'm doing the right thing with the sum part of this function? In my mind this is telling me to apply this function to every value and then take that value and add it to phi, but I'm not sure if that's what I'm actually doing.
function [exists] = detectHaarWatermark(watermarkedCoefs, watermark)
coefsSize = size(watermarkedCoefs,1);
phi = 0;
numeratorTotal = 0;
denomanatorTotal = 0;
for i = 1 : coefsSize
for j = 1 : coefsSize
y = watermarkedCoefs(i,j) %Watermarked coefficient
w = watermark(i,j) %Watermark
% val = ((w * sign(y))^2) / (w^2)
numerator = (w * sign(y))
numeratorTotal = numeratorTotal + numerator;
numeratorTotal = numeratorTotal^2;
denomanator = (w^2)
denomanatorTotal = denomanatorTotal + denomanator;
val = numeratorTotal / denomanatorTotal;
phi = val;
end
end
phi
stdDev = std2(watermarkedCoefs)
if phi > (10*stdDev)
exists = true;
else
exists = false;
end
end %end function
Edit:
numerator = (sum(sum(watermark.*(sign(watermarkedCoefs)))));
numerator = power(numerator, 2);
denomanator = sum(sum(watermark.^2));
phi = numerator / denomanator

Matlab ODE to solve 2DOF vibrational systems

I'm currently learning Matlab's ODE-functions to solve simple vibration-problems.
For instance mx''+cx'+kx=F*sin(wt) can be solved using
function dx = fun(t,x)
m=0.02; % Mass - kg
k=25.0; % Stiffness - N/m
c=0.0125; % System damping - Ns/m
f=10; % Frequency
F=5;
dx= [x(2); (F*sin(2*pi*f*t)-c*x(2)-k*x(1))/m]
And then calling the ode45 function to get displacement and velocity
[t,x]=ode45(#fun,[0 10],[0.0;0.0])
My question, which I have not fully understood searching the web, is if it is possible to use ODE-function for a multiple degree of freedom system? For instance, if we have two masses, springs and dampers, which we excite att mass 1, we get the following equations:
m1*x1''+c1*x1'-c2*x2'+(k1+k2)*x1-k2*x2 = f1(t)
m2*x2''-c2*x1'+(c1+c2)*x2'-k2*x1+k2*x2 = 0
Here, the displacements x1 & x2 depend on each other, my question is how one should go about to solve these ODE's in Matlab?
There is no restriction that the inputs to the function solved by ODE45 be scalar. Just pass in an input matrix and expect out an output matrix. For example here is a function that solves the position of a 6 bar mechanism.
function zdot = cp_solve(t,z)
%% Constants
g = -9.81;
L1 = .2;
m0 = 0;
I0 = 0;
m1 = 1;
I1 = (1/3) * m1 * L1^2;
%% Inputs
q = z(1:6);
qdot = z(7:12);
%% Mass Matrix
M = zeros(6,6);
M(1,1) = m0;
M(2,2) = m0;
M(3,3) = I0;
M(4,4) = m1;
M(5,5) = m1;
M(6,6) = I1;
%% Constraint Matrix
Phiq = zeros(5,6);
Phiq(1,1) = 1;
Phiq(2,2) = 1;
Phiq(3,3) = 1;
Phiq(4,1) = 1;
Phiq(4,4) = -1;
Phiq(4,6) = (-L1/2)*sin(q(6));
Phiq(5,2) = 1;
Phiq(5,5) = -1;
Phiq(5,6) = (L1/2)*cos(q(6));
%% Generalized Forces
Q = zeros(6,1);
Q(5) = m1 * g;
%% Right Side Vector
rs = zeros(5,1);
rs(4) = (L1/2) * cos(q(6)) * qdot(6)^2;
rs(5) = (L1/2) * sin(q(6)) * qdot(6)^2;
%% Coefficient Matrix
C = [M Phiq'; Phiq zeros(5,5)];
R = [Q; rs];
%% Solution
Sol = C \ R;
zdot = [qdot; Sol(1:6)];
end
The inputs are the positions and velocities of the members. The outputs are the new positions and velocities.
You use it the same way you would any ODE45 problem. Setup the initial conditions, define a time and solve the problem.
%% Constants
L1 = .2;
C1 = L1/2;
theta1 = 30*pi/180;
theta_dot1 = 0;
tspan = 0:.001:2;
%% Initial Conditions
q = zeros(6,1);
q(6) = theta1;
q(4) = C1 * cos(q(6));
q(5) = C1 * sin(q(6));
qdot = zeros(6,1);
qdot(6) = theta_dot1;
z0 = [q; qdot];
%% Solve the problem
options = odeset('RelTol', 1.0e-9, 'AbsTol', 1.0e-6);
[Tout, Zout] = ode45(#cp_solve, tspan, z0, options);
In your case you have 2 equations and 2 unknowns. Set the problem up as a matrix problem and solve it simultaneously in your function. I would recommend the modal approach for your case.

Has fminsearch too many parameters?

I run this code in matlab to minimize the parameters of my function real_egarchpartial with fminsearch:
data = xlsread('return_cc_in.xlsx');
SPY = data(:,25);
dailyrange = xlsread('DR_in.xlsx');
drSPY= dailyrange(:,28);
startingVals = [mean(SPY); 0.041246; 0.70121; 0.05; 0.04; 0.45068; -0.1799; 1.0375; 0.06781; 0.070518];
T = size(SPY,1);
options = optimset('fminsearch');
options.Display = 'iter';
estimates = fminsearch(#real_egarchpartial, startingVals, options, SPY, drSPY);
[ll, lls, u]=real_egarchpartial(estimates, SPY, drSPY);
And I get this message:
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
I put the original starting values. So I assumed they are corrects. I used fminsearch and not fmincon because my function hasn't constraints and with fminunc my function gets a lot of red messages.
the real_egarchpartial function is the following:
function [ll,lls,lh] = real_egarchpartial(parameters, data, x_rk)
mu = parameters(1);
omega = parameters(2);
beta = parameters(3);
tau1 = parameters(4);
tau2 = parameters(5);
gamma = parameters(6);
csi = parameters(7);
phi = parameters(8);
delta1 = parameters(9);
delta2 = parameters(10);
%Data and h are T by 1 vectors
T = size(data,1);
eps = data-mu;
lh = zeros(T,1);
h = zeros(T,1);
u = zeros(T,1);
%Must use a back Cast to start the algorithm
h(1)=var(data);
lh(1) = log(h(1));
z= eps/sqrt(h(1));
u(1) = rand(1);
lxRK = log(x_rk);
for t = 2:T;
lh(t) = omega + beta*lh(t-1) + tau1*z(t-1) + tau2*((z(t-1).^2)-1)+ gamma*u(t-1);
h(t)=exp(lh(t));
z = eps/sqrt(h(t));
end
for t = 2:T
u(t)= lxRK(t) - csi - phi*h(t) - delta1*z(t) - delta2*((z(t).^2)-1);
end
lls = 0.5*(log(2*pi) + lh + eps.^2./h);
ll = sum(lls);
Could someone explain what is wrong? Is there another function more efficient for my estimation? Any help will be appreciated! Thank you.