I have an optimization problem which I have to solve using Lagrange multipliers.
I have the following code:
clear all
clc
p = #(r,sig) (r./sig.^2) .* exp(-r.^2/2*(sig.^2));
sig = 1;
Pa = 1;
Pc = 20;
a = 0.5;
b = 1;
phi = #(h_AB,h_AC,h_CB) abs(h_AB).^2 +((b .* a.^2*abs(h_AC).^2 .* abs(h_CB).^2)
.* Pc ./ (1 + b * a .^2 .* abs(h_CB) .^2 * Pc));
f1 = #(h_AB,h_AC,h_CB) .5*log((1+phi(h_AB,h_AC,h_CB)*Pa)/(1+abs(h_AC).^2*Pa));
f2 = #(h_AB,h_AC,h_CB) f1(h_AB,h_AC,h_CB) .* p(h_AB,sig) .* p(h_AC,sig).* (h_CB,sig);
q = integral3(f2,-inf,inf,-inf,inf,-inf,inf);
The constant b that I have defined should be a variable (q be a function of b), so that I would find e = jacobian(q,[b]); in the next step.
The problem is that I can't define b as symbolic while other functions are not symbolic and when I define all the functions in symbolic form, I get out of memory solving e = jacobian(q,[b]);
Related
I need to solve two differential equations, where I have two boundary conditions for every equation. Because of that I choose Matlab method bvp4c to solve this system:
p1' = -32 * beta * m1 / (R ^ 4 * p1)
p2' = - ( - 8 * p1' / R - p1' * p2 - 32 * beta * m2 / R ^ 4 ) / p1
I have function file bvpfcn.m where I defined two differential equations:
function dpdz = bvpfcn(z,p)
beta = 1;
m1 = 1;
m2 = 0.1;
ri = 0.7;
z = linspace(0,1,1001);
R = ri - z .* (ri - 1);
dpdz = zeros(2,1001);
dpdz = [- 32 .* beta .* m0 ./ (R .^ 4 .* p(1));
-( - 8 .* dpdz(1) ./ R - dpdz(1) .* p(2) - 32 .* beta .* m1 ./ R .^ 4 ) ./ p(1);
];
end
Then in function file bcfcn.m I defined boundary conditions. My boundary conditions are:
p(1)|(z=0) = 8
p(1)|(z=1) = 1
p(2)|(z=0) = 0
p(2)|(z=1) = 0
And file bcfcn.m is:
function res = bcfcn(pa,pb)
res = [pa(1)-8;
pa(2);
pb(1)-1;
pb(2)];
end
My solution need to be of shape:
shape of expected solution
Because of that shape I am making guess function of cosine type:
function g = guess(z)
g = [0.65.*cos(z)
0.65.*cos(z)];
end
When I execute everything with:
beta = 1;
m1 = 1;
m2 = 0.1;
ri = 0.7;
xmesh = linspace(0,1,1001);
solinit = bvpinit(xmesh, #guess);
sol = bvp4c(#bvpfcn, #bcfcn, solinit);
I got error:
Error using bvparguments (line 111)
Error in calling BVP4C(ODEFUN,BCFUN,SOLINIT):
The boundary condition function BCFUN should return a column vector of length 2.
Error in bvp4c (line 130)
bvparguments(solver_name,ode,bc,solinit,options,varargin);
How can I make column vector when I have 4 boundary conditions? Are my assumpsions ok?
Your column vector from bvpfcn and bcfcn should have same dimensions. Since you have two first order ODEs, you should give only two boundary conditions. You have two extra boundary conditions, these extra conditions will be dependent on other two. You have to find out the independent boundary conditions
I'm trying to apply the Karhunen Loeve procedure to a translation-invariant data set. I understand the KL procedure, and how to create a mask to smooth out missing data. However, I'm having a hard time creating a program to model my Translation invariant data set.
The data set that I need to plot in matlab is:
Translation-Invariant Data Set
And here's the matlab code that I tried to use to model it:
function [fmu] = kLProcedure(N, P, M)
for k = 1:N;
for m = 1:M;
for n = 1:P;
x(m) = ((m-1)*2.*(pi))/M;
t(n) = ((n - 1)*2.*(pi))/P;
k = 1:3;
fmu(x(m),t(n)) = (1/N).*symsum((1/k).*sin(k(x(m)-t(n))),k);
end
end
end
With N=3, P=64, M=64;
I'm trying to use a nested for-loop to calculate each iteration of m, n, and t. and keep getting the error:
Error using /
Matrix dimensions must agree.
Error in kLProcedure (line 28)
fmu(x(m),t(n)) = (1/N).*symsum((1/k).*sin(k(x(m)-t(n))),k);
And advice would be greatly appreciated. Thank you.
Honestly, I don't have an in-depth knowledge of the algorithms you are using, but looking at the formulation of the one you are trying to reproduce, I think the following code is what you are looking for:
fmu = kLProcedure(3,64,64);
plot(fmu);
function [fmu] = kLProcedure(N,M,P)
k = 1:N;
ki = 1 ./ k;
Ni = 1 / N;
m = 1:M;
x = ((m - 1) .* 2 .* pi()) ./ M;
n = 1:P;
t = ((n - 1) .* 2 .* pi()) ./ P;
fmu = zeros(M,P);
for i = m
for j = n
fmu(i,j) = Ni .* sum(ki .* sin(ki .* (x(i) - t(j))));
end
end
end
Output:
Translational-Invariant Data
function [fmu] = kLProcedure(N,M,P)
m = 1:M;
x = ((m - 1) .* 2 .* pi()) ./ M;
n = 1:P;
t = ((n - 1) .* 2 .* pi()) ./ P;
fmu = zeros(M,P);
for i = m
for j = n
fmu(i,j) = 0;
for k = 1:3
fmu(i,j) = fmu(i,j) + (1/3).*sum((1/k).*(sin((k) .* (x(i) - t(j)))));
end
end
end
What would be the best way to simplify a function by getting rid of a loop?
function Q = gs(f, a, b)
X(4) = sqrt((3+2*sqrt(6/5))/7);
X(3) = sqrt((3-2*sqrt(6/5))/7);
X(2) = -sqrt((3-2*sqrt(6/5))/7);
X(1) = -sqrt((3+2*sqrt(6/5))/7);
W(4) = (18-sqrt(30))/36;
W(3) = (18+sqrt(30))/36;
W(2) = (18+sqrt(30))/36;
W(1) = (18-sqrt(30))/36;
Q = 0;
for i = 1:4
W(i) = (W(i)*(b-a))/2;
X(i) = ((b-a)*X(i)+(b+a))/2;
Q = Q + W(i) * f(X(i));
end
end
Is there any way to use any vector-like solution instead of a for loop?
sum is your best friend here. Also, declaring some constants and creating vectors is useful:
function Q = gs(f, a, b)
c = sqrt((3+2*sqrt(6/5))/7);
d = sqrt((3-2*sqrt(6/5))/7);
e = (18-sqrt(30))/36;
g = (18+sqrt(30))/36;
X = [-c -d d c];
W = [e g g e];
W = ((b - a) / 2) * W;
X = ((b - a)*X + (b + a)) / 2;
Q = sum(W .* f(X));
end
Note that MATLAB loves to handle element-wise operations, so the key is to replace the for loop at the end with scaling all of the elements in W and X with those scaling factors seen in your loop. In addition, using the element-wise multiplication (.*) is key. This of course assumes that f can handle things in an element-wise fashion. If it doesn't, then there's no way to avoid the for loop.
I would highly recommend you consult the MATLAB tutorial on element-wise operations before you venture onwards on your MATLAB journey: https://www.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html
Introduction
I am using Matlab to simulate some dynamic systems through numerically solving systems of Second Order Ordinary Differential Equations using ODE45. I found a great tutorial from Mathworks (link for tutorial at end) on how to do this.
In the tutorial the system of equations is explicit in x and y as shown below:
x''=-D(y) * x' * sqrt(x'^2 + y'^2)
y''=-D(y) * y' * sqrt(x'^2 + y'^2) + g(y)
Both equations above have form y'' = f(x, x', y, y')
Question
However, I am coming across systems of equations where the variables can not be solved for explicitly as shown in the example. For example one of the systems has the following set of 3 second order ordinary differential equations:
y double prime equation
y'' - .5*L*(x''*sin(x) + x'^2*cos(x) + (k/m)*y - g = 0
x double prime equation
.33*L^2*x'' - .5*L*y''sin(x) - .33*L^2*C*cos(x) + .5*g*L*sin(x) = 0
A single prime is first derivative
A double prime is second derivative
L, g, m, k, and C are given parameters.
How can Matlab be used to numerically solve a set of second order ordinary differential equations where second order can not be explicitly solved for?
Thanks!
Your second system has the form
a11*x'' + a12*y'' = f1(x,y,x',y')
a21*x'' + a22*y'' = f2(x,y,x',y')
which you can solve as a linear system
[x'', y''] = A\f
or in this case explicitly using Cramer's rule
x'' = ( a22*f1 - a12*f2 ) / (a11*a22 - a12*a21)
y'' accordingly.
I would strongly recommend leaving the intermediate variables in the code to reduce chances for typing errors and avoid multiple computation of the same expressions.
Code could look like this (untested)
function dz = odefunc(t,z)
x=z(1); dx=z(2); y=z(3); dy=z(4);
A = [ [-.5*L*sin(x), 1] ; [.33*L^2, -0.5*L*sin(x)] ]
b = [ [dx^2*cos(x) + (k/m)*y-g]; [-.33*L^2*C*cos(x) + .5*g*L*sin(x)] ]
d2 = A\b
dz = [ dx, d2(1), dy, d2(2) ]
end
Yes your method is correct!
I post the following code below:
%Rotating Pendulum Sym Main
clc
clear all;
%Define parameters
global M K L g C;
M = 1;
K = 25.6;
L = 1;
C = 1;
g = 9.8;
% define initial values for theta, thetad, del, deld
e_0 = 1;
ed_0 = 0;
theta_0 = 0;
thetad_0 = .5;
initialValues = [e_0, ed_0, theta_0, thetad_0];
% Set a timespan
t_initial = 0;
t_final = 36;
dt = .01;
N = (t_final - t_initial)/dt;
timeSpan = linspace(t_final, t_initial, N);
% Run ode45 to get z (theta, thetad, del, deld)
[t, z] = ode45(#RotSpngHndl, timeSpan, initialValues);
%initialize variables
e = zeros(N,1);
ed = zeros(N,1);
theta = zeros(N,1);
thetad = zeros(N,1);
T = zeros(N,1);
V = zeros(N,1);
x = zeros(N,1);
y = zeros(N,1);
for i = 1:N
e(i) = z(i, 1);
ed(i) = z(i, 2);
theta(i) = z(i, 3);
thetad(i) = z(i, 4);
T(i) = .5*M*(ed(i)^2 + (1/3)*L^2*C*sin(theta(i)) + (1/3)*L^2*thetad(i)^2 - L*ed(i)*thetad(i)*sin(theta(i)));
V(i) = -M*g*(e(i) + .5*L*cos(theta(i)));
E(i) = T(i) + V(i);
end
figure(1)
plot(t, T,'r');
hold on;
plot(t, V,'b');
plot(t,E,'y');
title('Energy');
xlabel('time(sec)');
legend('Kinetic Energy', 'Potential Energy', 'Total Energy');
Here is function handle file for ode45:
function dz = RotSpngHndl(~, z)
% Define Global Parameters
global M K L g C
A = [1, -.5*L*sin(z(3));
-.5*L*sin(z(3)), (1/3)*L^2];
b = [.5*L*z(4)^2*cos(z(3)) - (K/M)*z(1) + g;
(1/3)*L^2*C*cos(z(3)) + .5*g*L*sin(z(3))];
X = A\b;
% return column vector [ed; edd; ed; edd]
dz = [z(2);
X(1);
z(4);
X(2)];
I have two first order ODEs that I got from a second order ODE:
y(0)=1
y'(0)=-1/3
u1'=u2
u2=u/9-(pi*u1*e^(x/3)*(2u2*sin(pi*x)+pi*u1cos(pi*x))
u1(0)=y(0)=1
u2(0)=y'(0)=-1/3
My question is how to set up forward Euler? I have that:
n=[0:0.01:2];
h=2./n;
Our equations are:
u1' = u2
u2' = u1/9 - \pi u1 exp(x/3)(2u2 sin(\pi x) + \pi u1 cos(\pi x))
Now the Euler Method for solving an y' = f(x,y) is:
y_{n+1} = y_{n} + h * f(x_n, y_n)
As MATLAB code, we could write this as:
h = 0.01; % Choose a step size
x = [0:h:2]; % Set up x
u = zeros(length(x),2);
u(1,:) = [1; -1/3]; % Initial Conditions for y
for ii = 2:length(x)
u(ii,:) = u(ii-1,:) + h * CalculateDeriv(x(ii-1),u(ii-1,:)); % Update u at each step
end
function deriv = CalculateDerivative(x,u)
deriv = zeros(2,1);
deriv(1) = u(2);
deriv(2) = u(1)/9 - pi*u(1)*exp(x/9)*(2*u(2)*sin(pi*x) + pi*u(1)*cos(pi*x))
end