Using Strong Wolfe Condition to find learning rate - matlab

I'm trying to optimize a function with gradient decent code that I wrote but I want to use another function file related to Strong Wolfe Condition to find a good alpha.
Both of my codes are working with an equation and same time I get -inf for another equation.
-inf occures in con1 and con3 in Strong Wolfe Condition function.
I have no idea why with the second equation I can't find the Alpha. please help me with this.
My codes are wroten in Matlab.
This is my gradient descent code:
% Clear the space
clear all;
clc;
% Define the equation
syms x1 x2;
% f(x1, x2) = (-x1 ^ 3) * exp(x2 - (x1 ^ 2) - (10 * ((x1 - x2) ^ 2))); % First equation
f(x1, x2) = -cos(x1) * (cos(x2) * (exp((x1-pi)^2+(x2-pi)^2))); % Second equation
% plot the contour plot
fcontour(f, 'Fill', 'on');
% To show the color bar next to the plot
colorbar
% For 3d plot //// I just coment it because it doesn't look good
% fsurf(f);
% To hold the plot so we can show the update of point on it
hold on
% The diviation of equation
gx = gradient(f);
% Initial point given by homework
% x = [0.75, -1.25];
x = [2.1, 2.1];
% Learing Rate (alpha)
% learningRate = LR(x, f);
learningRate = LR(x, f);
% First compute of gradient with initial points
xResult = double(subs(gx(x(1, 1), x(1, 2)),{x1,x2},{x(1,1),x(1,2)}));
% Two empty list to save the points during the update
x1List = [x(1, 1)];
x2List = [x(1, 2)];
% for loop for update the points
for i = 1:1000
% with GD formula update the points
x(1, 1) = x(1,1) - (learningRate * xResult(1, 1));
x(1, 2) = x(1,2) - (learningRate * xResult(2, 1));
% Save the points inside the empty list for further use
x1List = [x1List x(1, 1)]; %#ok
x2List = [x2List x(1, 2)]; %#ok
% With new points compute the gradient
xResult = double(subs(gx(x(1, 1), x(1, 2)),{x1,x2},{x(1,1),x(1,2)}));
% Plot the point on contour
% plot(x(1, 1), x(1, 2), 'r-*');
% title('Iteration = ', i )
% pause(0.1)
% Break the iteration
% Check if the points don't change more than 10e-4 and if so break
errorAmountx1 = x1List(1, i) - x(1, 1);
errorAmountx2 = x2List(1, i) - x(1, 2);
if (errorAmountx1 < 10e-4 && errorAmountx2 < 10e-4)
break
end
% if (mod(i, 5) == 0)
% learningRate = LR_2(x, f);
% end
end
% After finding the min point print out the results
disp('Iteration = ');
disp(i);
disp('The Min Point = ');
disp(x);
disp('Final x in equation : ')
fResult = double(subs(f(x(1,1), x(1,2)),{x1,x2},{x(1,1),x(1,2)}));
disp(fResult);
plot(x1List, x2List, 'r-*');
This is my Strong Wolfe Condition code:
function [learningRate] = LR(x, f)
syms x1 x2;
f(x1, x2) = f;
lr = 0.00001:0.001:1;
c1 = rand();
c2 = c1 + rand() * (1 - c1);
gradi = double(subs(gradient(f, [x1, x2]),{x1,x2},{x(1,1),x(1,2)}));
p = -gradi;
for i = 1:length(lr)
disp(i);
xap = x + lr(i) * transpose(p);
con1 = double(subs(f(xap(1,1), xap(1,2)),{x1,x2},{xap(1,1), xap(1,2)}));
con2 = double(subs(f(x(1,1), x(1,2)),{x1,x2},{x(1,1),x(1,2)})) + (c1 * (lr(i) * transpose(gradi)) * p);
con3 = abs(transpose(double(subs(gradient(f, [x1, x2]),{x1,x2},{xap(1,1),xap(1,2)}))) * p);
con4 = c2 * abs(transpose(gradi) * p);
if (con1 <= con2 && con3 <= con4)
learningRate = lr(i);
break
end
end
end

Related

filter Kalman in Matlab

There is a error that I can't solve, here is the code in matlab:
% Define the system matrices A, C, and the initial state
A = [1 1
0 1]; % state transition matrix
C = [1 0]; % measurement matrix
x0 = [1 0]; % initial state
% Define the number of time steps and the noise covariance matrices
N = 50; % number of time steps
Q_values = 0.1; % values of Q to consider
R_values = 0.25; % values of R to consider
% Pre-allocate memory for the states and estimated states
x = zeros(2, N); % real state
xhat = zeros(2, N); % state estimate
xpred = zeros(2, N); % prediction state
% Loop over each value of Q and R
for i = 1:length(Q_values)
for j = 1:length(R_values)
Q = Q_values(i) * eye(2); % covariance of process noise
R = R_values(j) * eye(2); % covariance of measurement noise
% Initialize the state estimate and its covariance
xhat(:, 1) = x0;
P = eye(2); % initial covariance of state estimate
% Generate the real state and measurements with noise
for k = 1:N
w = sqrt(Q) * randn(2, 1); % process noise
v = sqrt(R) * randn(1, 1); % measurement noise
x(:, k+1) = A * x(:, k) + w; % real state
yk = C * x(:, k) + v; % measurement
% Predict the state and covariance at time k
xpred(:, k+1) = A * xhat(:, k); % state prediction
P_pred = A * P * A' + Q; % covariance prediction
% Compute the Kalman gain
K = P_pred * C' / (C * P_pred * C');
% Update the state estimate and covariance
xhat(:, k+1) = A * xpred(:, k+1) + K .* (yk - C .* xpred(:, k+1));
P = (eye(2) - K * C) * P_pred;
end
end
error is here:
Unable to perform assignment because the size of the left side is 2-by-1 and the size of the right side
is 2-by-2.
Error in Untitled (line 42)
xhat(:, k+1) = A * xpred(:, k+1) + K .* (yk - C .* xpred(:, k+1));
Do you guys have some ideas how to change my code?

Airfoil plot issue

I am having an issue with plotting my airfoil on matlab. It appears that there are some abberations with only one or two values. I have checked again and again with the formulas so they should be good. I have not converted to degrees so that's not the issue.
%% setup
clc
clear all
%type of airfoil
typeNACA = '2312';
%extract values of airfoil type
M = str2double(typeNACA(1)); % max camber %chord
P = str2double(typeNACA(2)); % chordwise position
Thmax = str2double(typeNACA(3:4));
M=M/100;
P=P/100
Thmax=Thmax/100;
% gridpoints
gridpoints = 1000;
% Airfoil grid
x = linspace(0,1,gridpoints);
%camber equations
%yc1(x) = (M/P^2)*(2*P*x-x^2);
%yc(x) = (M/(1-P)^2*(1-2*P+2*Px-x^2); % (for P =< x <1)
%dyc1 = (2*M/P^2)*(P-x)
%dyc2 = (2*M)/(1-P^2)*(P-x)
%Camber and gradient
yc = ones(gridpoints,1);
dyc= ones(gridpoints,1);
theta=ones(gridpoints,1);
for i=1:gridpoints
if (x(i) >= 0 && x(i) < P)
yc(i) = (M/P^2)*(2*P*x(i)-x(i)^2); % (for 0 =< x < P)
dyc(i)= ((2*M)/P^2)*(P - x(i)); %dyc/dx
elseif (x(i) >= P && x(i) <= 1) % (for P =< x <1)
yc(i)=(M/(1-P)^2)*(1-2*P+2*P*x(i)-x(i)^2);
dyc(i) = (2*M)/((1-P)^2*(P-x(i)));
end
theta(i) = atan(dyc(i)); %angle theta
end
% thickness coefficients
a0 = 0.2969;
a1 = -0.126;
a2 = -0.3516;
a3 = 0.2843;
a4 = -0.1036; % -0.1015 for open TE -0.1036 for closed TE
%thickness distribution
yt = ones(gridpoints,1);
for i=1:1:gridpoints
yt(i) = (Thmax/0.2)*(a0*x(i)^0.5 + a1*x(i) + a2*x(i)^2 + a3*x(i)^3 + a4*x(i)^4);
end
% Upper surface points
xu = ones(gridpoints,1);
yu = ones(gridpoints,1);
for i= 1:gridpoints
xu(i) = x(i) - yt(i)*sin(theta(i));
yu(i) = yc(i) + yt(i)*cos(theta(i));
end
% Lower surface points
xl = ones(gridpoints,1);
yl = ones(gridpoints,1);
for i=1:1:gridpoints
xl(i) = x(i) + yt(i)*sin(theta(i));
yl(i) = yc(i) - yt(i)*cos(theta(i));
end
%PLOT
f1 = figure(1);
hold on; grid on;
axis equal
plot(xu,yu,'r';
plot(xl,yl,'b');
well! The first problem is you've forgotten the closing parenthesis in the second line from the end. But if you want me to check your code, I need to have your typeNACA() function .m file to revise it. Or u can post its code here.
%PLOT
f1 = figure(1);
hold on; grid on;
axis equal
plot(xu,yu,'r';
plot(xl,yl,'b');

Unrecognized function or variable 'f' error

I am new to Matlab and I am trying to implement Hough transform without using Matlab builtin function; hence I am learning possible ways to do so. I found a function written in a book that seems to be correct. I got an error and cannot figure it out.
I want to implement hough transform function and later apply it on to a grayscale image
% This functions makes use of sparse matrices
function [h, theta, rho] = HT(f, dtheta, drho)
% [H, THETA, RHO] = HOUGH(F, DTHETA, DRHO) computes the hough
% transform of the image F. DTHETA specifies the spacing (in degrees) of
% the the hough transform bins along the theta axis.
% DRHO specifies the spacing of the hough transform bins along the rho
% axis. H is the Hough transform matrix. It is NRHO-by-NTHETA, where
% NRHO = 2*ceil(norm(size(F))/DRHO) - 1, and NTHETA = 2*ceil(90/DTHETA).
if nargin < 3
drho = 1;
end
if nargin < 2
dtheta = 1;
end
f = double(f);
[M,N] = size(f);
theta = linspace(-90, 0, ceil(90/dtheta) + 1);
theta = [theta -fliplr(theta(2:end - 1))];
ntheta = length(theta);
D = sqrt((M - 1)^2 + (N - 1)^2);
q = ceil(D/drho);
nrho = 2*q - 1;
rho = linspace(-q*drho, q*drho, nrho);
[x, y, val] = find(f);
x = x - 1; y = y-1;
%Initialize output.
h = zeros(nrho, length(theta));
% To avoid excessive memory usage, process 1000 nonzero pixel
% values at a time.
for k = 1:ceil(length(val)/1000)
first = (k-1)*1000 + 1;
last = min(first+999, length(x));
x_matrix = repmat(x(first:last), 1, ntheta);
y_matrix = repmat(y(first:last), 1, ntheta);
val_matrix = repmat(val(first:last), 1, ntheta);
theta_matrix = repmat(theta, size(x_matrix, 1), 1)*pi/180;
rho_matrix = x_matrix.*cos(theta_matrix) + ...
y_matrix.*sin(theta_matrix);
slope = (nrho - 1)/(rho(end) - rho(1));
rho_bin_index = round(slope*(rho_matrix - rho(1)) + 1);
theta_bin_index = repmat(1:ntheta, size(x_matrix, 1), 1);
h = h + full(sparse(rho_bin_index(:), theta_bin_index(:), ...
val_matrix(:), nrho, ntheta));
end
%Illustration of Hough transform on a simple binary image
f = zeros(101, 101);
f(1, 1) = 1; f(101, 1) = 1; f(1, 101) = 1;
f(101, 101) = 1; f(51, 51) = 1;
% Compute & display the hough
H = HT(f);
imshow(H, [])
%Label the axis
[H, theta, rho] = HT(f);
imshow(theta, rho, H, [ ], 'notruesize')
axis on, axis normal
xlabel('\theta', ylabel('\rho'))
I expect the hough transform to be displayed using imshow but I get this error
HT(f, dtheta, drho)
Unrecognized function or variable 'f'.
What you have here is a combination of script and functions in a single .m file. This is allowed starting from Matlab R2016b, but the rule is to have the function definitions after the script is finished.
So your code should look like this:
%Illustration of Hough transform on a simple binary image
f = zeros(101, 101);
f(1, 1) = 1; f(101, 1) = 1; f(1, 101) = 1;
f(101, 101) = 1; f(51, 51) = 1;
% Compute & display the hough
H = HT(f);
imshow(H, [])
%Label the axis
[H, theta, rho] = HT(f);
imshow(theta, rho, H, [ ], 'notruesize')
axis on, axis normal
xlabel('\theta', ylabel('\rho'))
function [h, theta, rho] = HT(f, dtheta, drho)
if nargin < 3
drho = 1;
end
if nargin < 2
dtheta = 1;
end
%.... the rest of the function
end

How to plot pendulum motion for Elastic Pendulum with Spring in Matlab

I have a code that creates the correct xy plot for elastic pendulum with spring. I would like to show an animation of the elastic spring pendulum on an xy plot as the system marches forward in time. How can this be done?
Here is my simulation code:
clc
clear all;
%Define parameters
global M K L g;
M = 1;
K = 25.6;
L = 1;
g = 9.8;
% define initial values for theta, thetad, del, deld
theta_0 = 0;
thetad_0 = .5;
del_0 = 1;
deld_0 = 0;
initialValues = [theta_0, thetad_0, del_0, deld_0];
% Set a timespan
t_initial = 0;
t_final = 36;
dt = .1;
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(#OdeFunHndlSpngPdlmSym, timeSpan, initialValues);
% initialize empty column vectors for theta, thetad, del, deld
M_loop = zeros(N, 1);
L_loop = zeros(N, 1);
theta = zeros(N, 1);
thetad = zeros(N, 1);
del = zeros(N, 1);
deld = zeros(N, 1);
T = zeros(N, 1);
x = zeros(N, 1);
y = zeros(N, 1);
% Assign values for variables (theta, thetad, del, deld)
for i = 1:N
M_loop(i) = M;
L_loop(i) = L;
theta(i) = z(i, 1);
thetad(i) = z(i, 2);
del(i) = z(i, 3);
deld(i) = z(i, 4);
T(i) = (M*(thetad(i)^2*(L + del(i))^2 + deld(i)^2))/2;
V(i) = (K*del(i)^2)/2 + M*g*(L - cos(theta(i))*(L + del(i)));
E(i) = T(i) + V(i);
x(i) = (L + del(i))*sin(theta(i));
y(i) = -(L + del(i))*cos(theta(i));
end
figure(1)
plot(x, y,'r');
title('XY Plot');
xlabel('x position');
ylabel('y position');
Here is my function code:
function dz = OdeFunHndlSpngPdlmSym(~, z)
% Define Global Parameters
global M K L g
% Take output from SymDevFElSpringPdlm.m file for fy1 and fy2 and
% substitute into z2 and z4 respectively
%fy1=thetadd=z(2)= -(M*g*sin(z1)*(L + z3) + M*z2*z4*(2*L + 2*z3))/(M*(L + z3)^2)
%fy2=deldd=z(4)=((M*(2*L + 2*z3)*z2^2)/2 - K*z3 + M*g*cos(z1))/M
% return column vector [thetad; thetadd; deld; deldd]
dz = [z(2);
-(M*g*sin(z(1))*(L + z(3)) + M*z(2)*z(4)*(2*L + 2*z(3)))/(M*(L + z(3))^2);
z(4);
((M*(2*L + 2*z(3))*z(2)^2)/2 - K*z(3) + M*g*cos(z(1)))/M];
You can "simulate" animation in a plot with a continous updating FOR loop and assignig graphic object to variables.
Something like (I assume only to use x,y as arrays function of time array t)
%In order to block the axis and preventing continuous zoom, choose proper axes limit
x_lim = 100; %these values depends on you, these are examples
y_lim = 100;
axis equal
axis([-x_lim x_lim -y_lim y_lim]); %now x and y axes are fixed from -100 to 100
ax = gca;
for i=1:length(t)
if i > 1
delete(P);
delete(L);
end
P = plot(x(i),y(i)); %draw the point
hold on
L = quiver(0,0,x(i),y(i)); %draw a vector from 0,0 to the point
hold on
%other drawings
drawnow
pause(0.1) %pause in seconds needed to simulate animaton.
end
"Hold on" instruction after every plot instruction.
This is only a basic animation, of course.

Optim-nonlinear equation in matlab code

I updated the question to clarify it more. Here is a graph:
For the curve in the attached photo, I hope to draw the curve. I have its equation and it is after simplification will be like this one
% Eq-2
(b*Y* cos(v) + c - k*X*sin(v))^2 + ...
sqrt(k*X*(cos(v) + 1.0) + b*Y*sin(v))^2) - d = 0.0
Where:
v = atan((2.0*Y)/X) + c
and b, c, d and k are constants.
from the attached graph,
The curve is identified in two points:
p1 # (x=0)
p2 # (y=0)
I a new on coding so accept my apologize if my question is not clear.
Thanks
So, after your edit, it is a bit more clear what you want.
I insist that your equation needs work -- the original equation (before your edit) simplified to what I have below. The curve for that looks like your plot, except the X and Y intercepts are at different locations, and funky stuff happens near X = 0 because you have numerical problems with the tangent (you might want to reformulate the problem).
But, after checking your equation, the following code should be helpful:
function solve_for_F()
% graininess of alpha
N = 100;
% Find solutions for all alphae
X = zeros(1,N);
options = optimset('Display', 'off');
alpha = linspace(0, pi/2, N);
x0 = linspace(6, 0, N);
for ii = 1:numel(alpha)
X(ii) = fzero(#(x)F(x, alpha(ii)), x0(ii), options);
end
% Convert and make an X-Y plot
Y = X .* tan(alpha);
plot(X, Y,...
'linewidth', 2,...
'color', [1 0.65 0]);
end
function fval = F(X, alpha)
Y = X*tan(alpha);
% Please, SIMPLIFY in the future
A = 1247745517111813/562949953421312;
B = 4243112111277797/4503599627370496;
V = atan2(2*Y,X) + A;
eq2 = sqrt( (5/33*( Y*sin(V) + X/2*(cos(V) + 1) ))^2 + ...
(5/33*( Y*cos(V) - X/2* sin(V) ))^2 ) - B;
fval = eq2;
end
Results:
So, I was having fun with this (thanks for that)!
Different question, different answer.
The solution below first searches for the constants causing the X and Y intercepts you were looking for (p1 and p2). For those constants that best fit the problem, it makes a plot, taking into account numerical issues.
In fact, you don't need eq. 1, because that's true always for any curve -- it's just there to confuse you, and problematic to use.
So, here it is:
function C = solve_for_F()
% Points of interest
px = 6;
py = 4.2;
% Wrapper function; search for those constants
% causing the correct X,Y intercepts (at px, py)
G = #(C) abs(F( 0, px, C)) + ... % X intercept at px
abs(F(py, 0, C)); % Y intercept at py
% Initial estimate, based on your original equation
C0 = [5/33
1247745517111813/562949953421312
4243112111277797/4503599627370496
5/66];
% Minimize the error in G by optimizing those constants
C = fminsearch(G, C0);
% Plot the solutions
plot_XY(px, py, C);
end
function plot_XY(xmax,ymax, C)
% graininess of X
N = 100;
% Find solutions for all alphae
Y = zeros(1,N);
X = linspace(0, xmax, N);
y0 = linspace(ymax, 0, N);
options = optimset('Display', 'off',...,...
'TolX' , 1e-10);
% Solve the nonlinear equation for each X
for ii = 1:numel(X)
% Wrapper function for fzero()
fcn1 = #(y)F(y, X(ii), C);
% fzero() is probably the fastest and most intuitive
% solver for this problem
[Y(ii),~,flag] = fzero(fcn1, y0(ii), options);
% However, it uses an algorithm that easily diverges
% when the function slope is large. For those cases,
% solve with fminsearch()
if flag ~= 1
% In this case, the minimum of the absolute value
% is searched for (which should be zero)
fcn2 = #(y) abs(fcn1(y));
Y(ii) = fminsearch(fcn2, y0(ii), options);
end
end
% Now plot the X,Y solutions
plot(X, Y,...
'linewidth', 2,...
'color', [1 0.65 0]);
xlabel('X'), ylabel('Y')
axis([0 xmax+.1 0 ymax+.1])
end
function fval = F(Y, X, C)
% Unpack constants
b = C(1); d = C(3);
c = C(2); k = C(4);
% pre-work
V = atan2(2*Y, X) + c;
% Eq. 2
fval = sqrt( (b*Y*sin(V) + k*X*(cos(V) + 1))^2 + ...
(b*Y*cos(V) - k*X* sin(V) )^2 ) - d;
end