extended algorithm implementation in matlab - matlab

i have found following pseudo-code for extended euclidean algorithm
i implemented following algorithm
function [x1,y1,d1]=extend_eucledian(a,b)
if b==0
x1=1;
y1=0;
d1=a;
return;
end
[x1,y1,d1]=extend_eucledian(b,mod(a,b));
x1=y1;
y1=x1-floor(a/b)*y1;
d1=d1;
end
when i run following this program, i got following result
[x1,y1,d1]=extend_eucledian(23,20)
x1 =
0
y1 =
0
d1 =
1
i guess that [x1,y1,d1] are not changing their values during the iteration, for instance , i have tried following code
function [x1,y1,d1]=extend_eucledian(a,b)
if b==0
x1=1;
y1=0;
d1=a;
return;
else
x1=y1;
y1=x1-floor(a/b)*y1;
d1=d1;
end
[x1,y1,d1]=extend_eucledian(b,mod(a,b));
end
but i got
>> [x1,y1,d1]=extend_eucledian(23,20)
Undefined function or variable 'y1'.
Error in extend_eucledian (line 8)
x1=y1;
how can i fix this problem? where i am making mistake?

The problem can be solved by introducing intermediate working variables, that will store the result of the recursive call:
function [x,y,d]=extended_euclid(a,b)
if b==0
x=1;
y=0;
d=a;
return;
end
[x1,y1,d1]=extended_euclid(b,mod(a,b));
x=y1;
y=x1-floor(a/b)*y1;
d=d1;
end
This function works as expected:
>> [x, y, d] = extended_euclid(23,20)
x =
7
y =
-8
d =
1
>> [x, y, d] = extended_euclid(25,20)
x =
1
y =
-1
d =
5

The error in the question is that x1, y1, d1 are used simultaneously as working and output variables. The code can be rewritten using a new tern [x, y d] for the output values:
function [x y d]=eucledian_pairs(a,b)
%a>0,b>0
%d=gcd(a,b) a*x+y*b=d
[x1,y1,d1]=extend_eucledian(a,b);
x=y1;
y=x1-floor(a/b)*y1;
d=d1;
function [x1,y1,d1]=extend_eucledian(a,b)
if b==0
x1=1;
y1=0;
d1=a;
return;
end
[x1,y1,d1]=extend_eucledian(b,mod(a,b));
end
end
Executing this code gives the desired result.
>> [x y d]=eucledian_pairs(20,25)
x =
0
y =
1
d =
5

Related

Issue with storing error at each iteration on Matlab - "unrecognized variable"

I've written a modified Newton's method code, and I'm looking to plot the error at each iteration vs the iteration, but after my code runs Matlab does not recognize my error function or the iterations.
function[x,k,e] = mynewton(x0,tol)
f = #(x) (x-1).^5*exp(x);
df = #(x) 5*(x-1).^4*exp(x)+(x-1).^5*exp(x);
kMax = 200;
format long
x=x0;
y=f(x);
e = [];
k = 0;
disp(' k x error')
while abs(y) > tol && k < kMax
k=k+1;
x = x - f(x)/df(x);
y = f(x);
e_k = abs(x-1);
e(k) = e_k;
disp([k x e_k])
end
end
The output will be 3 columns showing k, x, and e_k at each step, but it won't store these values properly into a vector. Instead, it shows
>> k
Unrecognized function or variable 'k'.
What am I doing wrong?
Any suggestions are very appreciated!!
You need to call your function as:
[x, k, e] = mynewton( x0, tol);
After this call, you can enter k at command window and see its value.

Evaluate a vector in a piecewise function

I want to evaluate the vector xdata in a piecewise function like this:
dat=load('k2.txt');
xdata = dat(:,1);
ydata = dat(:,2);
n=length(xdata);
p0=[0.0821 6.6 0.4];
y(p0,xdata)
function y_hat = y(p,t)
P=4.885;
T0 = 134.27426;
omega=2*pi/P;
gamma1=0.3539 ;gamma2=0.2851;
c1=0;c2=gamma1+2*gamma2;c3=0;c4=-gamma2;
c0=1-c1-c2-c3-c4;
z= p(2).*((sin(omega.*(t-T0))).^2+((p(3)/p(2)).*cos(omega.*(t-T0))).^2).^(1/2);
lambda1= 0;
lambda3=p(1).^2;
if ((1-p(1)<z) & (z<1+p(1)))
k1 = acos((1-p(1).^2 + z.^2)./(2*z));
k0 = acos(((p(1)).^2+z.^2-1)./(2.*z.*p(1)));
y_hat = 1-1./pi*(p(1).^2.*k0+k1-sqrt((4*z.^2-(1+z.^2-p(1).^2).^2)/4));
end
if (1+p(1)<=z)
y_hat=1-lambda1;
end
if (z<=1-p(1))
y_hat=1-lambda3;
end
end
The problem is that the code doesn't enter none of the if loops and returns nothing. Maybe the reason is that the function tries to fulfill the conditions for all the vector at once? How should I proceed so that y(p0,xdata) returns something?
By the way, I need this because I have to fit a model to data like this:
[theta] = lsqcurvefit(#y, p0, xdata, ydata);
Your code doesn't work, because when you write something like this:
if [1 3 -1] > 0
%code
end
Then "%code" won't be evaluated because it's checking, if the condition holds for every value in the vector.
Let's say you want to define the Heaviside function and evaluate a vector of it. Then, what you do is using a for loop:
x_vals = [-1 1 5];
heav(x_vals)
function y = heav(x)
y = zeros(size(x));
for i = 1:length(x)
if x(i) >= 0
y(i) = 1;
else
y(i) = 0;
end
end
end

I've written a matlab code for simpson 1/3 rule. I made a function for it and then i'm calling it in program

Here's the simpson function
%Simpsons 1/3 rule
function y = simpson(f,x1,x2,n)
global h
%global x1
%global x2
%h = (x2-x1)/n;
x(1) = x1;
sum = f(x1);
for i=2:n+1
x(i)=x(i-1)+h;
if mod(i,2)==0
sum=sum+4*f(x(i));
else
sum=sum+2*f(x(i));
end
end
sum = sum + f(x2);
int = sum*h/3;
disp(int);
end
here's the code in which i'm caliing:
CAo = 0.0625;
x1=0;
x2=0.8;
h=0.2;
n=(x2-x1)/h;
ep=2;
f=inline('(1+2*x)/((1-x)*0.0625)');
y = simpson(f,x1,x1,n);
disp(y)
On running the code, it's giving this error:
In an assignment A(I) = B, the number
of elements in B and I must be the
same.
Error in simpson (line 12)
x(i)=x(i-1)+h;
Error in tut_4_1 (line 8)
y = simpson(f,x1,x1,n);
i tried debugging, it showed my h is of 0 and my x(i-1) is 1X1. How to solve this. ?
The problem is the following line of code:
global h;
This deals with the scope of h. The global keyword only affects the variable h during the lifetime of the function. If you set h in the command window, then try to run Simpson's rule, the scope of h is different than what is seen in the function itself. In fact, the variable h in file is NOT the same as what is seen in the command window.
You also have a mistake in your function. You are returning y, but the output is stored in int. You need to change this to y.
As such, there are two ways for you to fix this:
Place the actual code for calling Simpson's rule inside a function, and the Simpson's rule code as a nested function itself. You would need to remove the call to global h and place it outside of the Simpson's rule code. Something like this:
function [] = test_simpsons()
global h;
function y = simpson(f,x1,x2,n)
x(1) = x1;
sum = f(x1);
for i=2:n+1
x(i)=x(i-1)+h;
if mod(i,2)==0
sum=sum+4*f(x(i));
else
sum=sum+2*f(x(i));
end
end
sum = sum + f(x2);
y = sum*h/3;
end
CAo = 0.0625;
x1=0;
x2=0.8;
h=0.2;
n=(x2-x1)/h;
ep=2;
f=inline('(1+2*x)/((1-x)*0.0625)');
y = simpson(f,x1,x1,n);
disp(y);
end
You would then call test_simpsons.
This is the approach I recommend. Simply make h an input parameter to your Simpson's rule code:
%Simpsons 1/3 rule
function y = simpson(f,x1,x2,n,h)
x(1) = x1;
sum = f(x1);
for i=2:n+1
x(i)=x(i-1)+h;
if mod(i,2)==0
sum=sum+4*f(x(i));
else
sum=sum+2*f(x(i));
end
end
sum = sum + f(x2);
y = sum*h/3;
end
The way you'd call your testing code is now:
CAo = 0.0625;
x1=0;
x2=0.8;
h=0.2;
n=(x2-x1)/h;
ep=2;
f=inline('(1+2*x)/((1-x)*0.0625)');
y = simpson(f,x1,x1,n,h);
disp(y)

Calculate the derivative of the sum of a mathematical function-MATLAB

In Matlab I want to create the partial derivative of a cost function called J(theta_0, theta_1) (in order to do the calculations necessary to do gradient descent).
The function J(theta_0, theta_1) is defined as:
Lets say h_theta(x) = theta_1 + theta_2*x. Also: alpha is fixed, the starting values of theta_1 and theta_2 are given. Let's say in this example: alpha = 0.1 theta_1 = 0, theta_2 = 1. Also I have all the values for x and y in two different vectors.
VectorOfX =
5
5
6
VectorOfX =
6
6
10
Steps I took to try to solve this in Matlab: I have no clue how to solve this problem in matlab. So I started off with trying to define a function in Matlab and tried this:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*x;
This worked, but is not what I really wanted. I wanted to get x^(i), which is in a vector. The next thing I tried was:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*vectorOfX(1);
This gives the following error:
Error using sym/subsindex (line 672)
Invalid indexing or function definition. When defining a
function, ensure that the body of the function is a SYM
object. When indexing, the input must be numeric, logical or
':'.
Error in prog1>gradientDescent (line 46)
h_theta(x) = theta_1 + theta_2*vectorOfX(x);
I looked up this error and don't know how to solve it for this particular example. I have the feeling that I make matlab work against me instead of using it in my favor.
When I have to perform symbolic computations I prefer to use Mathematica. In that environment this is the code to get the partial derivatives you are looking for.
J[th1_, th2_, m_] := Sum[(th1 + th2*Subscript[x, i] - Subscript[y, i])^2, {i, 1, m}]/(2*m)
D[J[th1, th2, m], th1]
D[J[th1, th2, m], th2]
and gives
Coming back to MATLAB we can solve this problem with the following code
%// Constants.
alpha = 0.1;
theta_1 = 0;
theta_2 = 1;
X = [5 ; 5 ; 6];
Y = [6 ; 6 ; 10];
%// Number of points.
m = length(X);
%// Partial derivatives.
Dtheta1 = #(theta_1, theta_2) sum(2*(theta_1+theta_2*X-Y))/2/m;
Dtheta2 = #(theta_1, theta_2) sum(2*X.*(theta_1+theta_2*X-Y))/2/m;
%// Loop initialization.
toll = 1e-5;
maxIter = 100;
it = 0;
err = 1;
theta_1_Last = theta_1;
theta_2_Last = theta_2;
%// Iterations.
while err>toll && it<maxIter
theta_1 = theta_1 - alpha*Dtheta1(theta_1, theta_2);
theta_2 = theta_2 - alpha*Dtheta2(theta_1, theta_2);
it = it + 1;
err = norm([theta_1-theta_1_Last ; theta_2-theta_2_Last]);
theta_1_Last = theta_1;
theta_2_Last = theta_2;
end
Unfortunately for this case the iterations does not converge.
MATLAB is not very flexible for symbolic computations, however a way to get those partial derivatives is the following
m = 10;
syms th1 th2
x = sym('x', [m 1]);
y = sym('y', [m 1]);
J = #(th1, th2) sum((th1+th2.*x-y).^2)/2/m;
diff(J, th1)
diff(J, th2)

variable in solving the equation

I want to solve equations in matlab, eg.
100+a/2=173*cos(b)
sqrt(3)*a/2=173*sin(b)
and the code would be:
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
However, if I want to take 100 as a variable, like
for k=1:100
[a,b]=solve('k+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
There would be an error, how to make it?
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
for i=451:550
for j=451:550
alpha=(1145-i)*degree;
beta=(1145-j)*degree;
x_2=p/cos(alpha)*tan(beta);
y_2=0;
z_2=p*tan(alpha);
syms x y z x_1 x_2 y_1 y_2 z_1 z_2 a b
eq = [(x-x_1)*(y2-y_1)-(x_2-x_1)*(y-y_1),(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1), b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y, eq(3),z);
sol.x
sol.y
sol.z
end
end
I got the expression value, how do I get the numeric value of x,y,z?
[['x(1)=';'x(2)='],num2str(double(sol.x))]
not work ,shows
??? Error using ==> mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in ==> sym.sym>sym.double at 927
Xstr = mupadmex('mllib::double', S.s, 0);
Error in ==> f2 at 38
[['x(1)=';'x(2)='],num2str(double(sol.x))]
If you have access to the Symbolic Toolkit then you do the following:
syms a b k
eq = [k+a/2-173*cos(b), sqrt(3)*a/2-173*sin(b)];
sol = solve(eq(1),a,eq(2),b);
sol.a = simplify(sol.a);
sol.b = simplify(sol.b);
% There are two solutions for 'a' and 'b'
% check residuals for example k=20
subs(subs(eq,{a,b},{sol.a(1),sol.b(1)}),k,20)
% ans = 0.2e-13
subs(subs(eq,{a,b},{sol.a(2),sol.b(2)}),k,20)
% ans = 0.2e-13
Edit 1
Based on new code by OP the matlab script to solve this is:
clear all
clc
syms alpha beta
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
x_2 = p/cos(alpha)*tan(beta);
y_2 = 0;
z_2 = p*tan(alpha);
syms x y z
eq = [(x-x_1)*(y_2-y_1)-(x_2-x_1)*(y-y_1);...
(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1); ...
b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y,eq(3),z);
sol.x = simplify(sol.x);
sol.y = simplify(sol.y);
sol.z = simplify(sol.z);
pt_1 = [sol.x(1);sol.y(1);sol.z(1)] % First Solution Point
pt_2 = [sol.x(2);sol.y(2);sol.z(2)] % Second Solution Point
x = zeros(100,100);
y = zeros(100,100);
z = zeros(100,100);
for i=451:550
disp(['i=',num2str(i)])
for j=451:550
res = double(subs(pt_1,{alpha,beta},{(1145-i)*degree,(1145-j)*degree}));
x(i-450, j-450) = res(1);
y(i-450, j-450) = res(2);
z(i-450, j-450) = res(3);
end
end
disp('x=');
disp(x);
disp('y=');
disp(x);
disp('z=');
disp(x);
I would try
for i=1:100
k=num2str(i)
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
and then solve the equation