Undefined function or variable 'x' - matlab

I am trying to evaluate two matrixes which I defined outside of the function MetNewtonSist using subs and I get the error Undefined function or variable 'x' whenever I try to run the code.
[edit] I added the code for the GaussPivTot function which determines the solution of a liniear system.
syms x y
f1 = x^2 + y^2 -4;
f2 = (x^2)/8 - y;
J = jacobian( [ f1, f2 ], [x, y]);
F = [f1; f2];
subs(J, {x,y}, {1, 1})
eps = 10^(-6);
[ x_aprox,y_aprox, N ] = MetNewtonSist( F, J, 1, 1, eps )
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, eps)
k = 1;
x_v(1) = x0;
y_v(1) = y0;
while true
k = k + 1;
z = GaussPivTot(subs(J, {x, y}, {x_v(k-1), y_v(k-1)}),-subs(F,{x, y}, {x_v(k-1), y_v(k-1)}));
x_v(k) = z(1) + x_v(k-1);
y_v(k) = z(1) + y_v(k-1);
if norm(z)/norm([x_v(k-1), y_v(k-1)]) < eps
return
end
end
N = k;
x_aprox = x_v(k);
y_aprox = y_v(k);
end
function [x] = GaussPivTot(A,b)
n = length(b);
A = [A,b];
index = 1:n;
for k = 1:n-1
max = 0;
for i = k:n
for j = k:n
if A(i,j) > max
max = A(i,j);
p = i;
m = j;
end
end
end
if A(p,m) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
if p ~= k
aux_line = A(p,:);
A(p,:) = A(k, :);
A(k,:) = aux_line;
end
if m ~= k
aux_col = A(:,m);
A(:,m) = A(:,k);
A(:,k) = aux_col;
aux_index = index(m);
index(m) = index(k);
index(k) = aux_index;
end
for l = k+1:n
M(l,k) = A(l,k)/A(k,k);
aux_line = A(l,:);
A(l,:) = aux_line - M(l,k)*A(k,:);
end
end
if A(n,n) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
y = SubsDesc(A, A(:,n+1));
for i = 1:n
x(index(i)) = y(i);
end
end

By default, eps is defined as 2.2204e-16 in MATLAB. So do not overwrite it with your variable and name it any word else.
epsilon = 1e-6;
Coming to your actual issue, pass x and y as input arguments to the MetNewtonSist function. i.e. define MetNewtonSist as:
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, epsilon, x, y)
%added x and y and renamed eps to epsilon
and then call it with:
[x_aprox, y_aprox, N] = MetNewtonSist(F, J, 1, 1, epsilon, x, y);

Related

Steepest Descent using Armijo rule

I want to determine the Steepest descent of the Rosenbruck function using Armijo steplength where x = [-1.2, 1]' (the initial column vector).
The problem is, that the code has been running for a long time. I think there will be an infinite loop created here. But I could not understand where the problem was.
Could anyone help me?
n=input('enter the number of variables n ');
% Armijo stepsize rule parameters
x = [-1.2 1]';
s = 10;
m = 0;
sigma = .1;
beta = .5;
obj=func(x);
g=grad(x);
k_max = 10^5;
k=0; % k = # iterations
nf=1; % nf = # function eval.
x_new = zeros([],1) ; % empty vector which can be filled if length is not known ;
[X,Y]=meshgrid(-2:0.5:2);
fx = 100*(X.^2 - Y).^2 + (X-1).^2;
contour(X, Y, fx, 20)
while (norm(g)>10^(-3)) && (k<k_max)
d = -g./abs(g); % steepest descent direction
s = 1;
newobj = func(x + beta.^m*s*d);
m = m+1;
if obj > newobj - (sigma*beta.^m*s*g'*d)
t = beta^m *s;
x = x + t*d;
m_new = m;
newobj = func(x + t*d);
nf = nf+1;
else
m = m+1;
end
obj=newobj;
g=grad(x);
k = k + 1;
x_new = [x_new, x];
end
% Output x and k
x_new, k, nf
fprintf('Optimal Solution x = [%f, %f]\n', x(1), x(2))
plot(x_new)
function y = func(x)
y = 100*(x(1)^2 - x(2))^2 + (x(1)-1)^2;
end
function y = grad(x)
y(1) = 100*(2*(x(1)^2-x(2))*2*x(1)) + 2*(x(1)-1);
end

Compute a matrix inverse by repeatedly solving n linear systems

I am trying to solve this problem. But I keep getting an error.
This is my First Code.
% Program 3.3
function [L, U, P] = lufact(A)
[N, N] = size(A);
X = zeros(N, 1);
Y = zeros(N, 1);
C = zeros(1, N);
R = 1:N;
for p = 1: N-1
[max1, j] = max(abs(A(p:N, p)));
C = A(p,:);
A(p,:) = A(j + p - 1,:);
A(j + p -1, :) = C;
d = R(p);
R(p) = R(j + p -1);
R(j + p - 1) = d;
if A(p,p) == 0
'A is Singular. No unique Solution'
break
end
for k = p + 1:N
mult = A(k,p)/A(p,p);
A(k,p) = mult;
A(k,p + 1:N) = A(k, p + 1:N) - mult *A(p, p + 1:N);
end
I=(1:N)'*ones(1,N,1); J=I';
L = (I>J).*A + eye(N);
U = (J>=I).*A;
P = zeros(N);
for k=1:N
P(k,R(k))=1;
end
end
X(N) = Y(N)/A(N,N);
for k = N-1: -1: 1
X(k) = (Y(k) - A(k, k+1:N)*X(k+1:N))/A(k,k);
end
And This is my 2nd Code which I'm using to solve this problem.
function B = Ques3(A)
% Computes the inverse of a matrix A
[L,U,P] = lufact(A);
N = max(size(A));
I = eye(N);
B = zeros(N);
for j = 1:N
Y = forsub(L,P*I(:,j));
B(:,j) = backsub(U,Y);
end
But I keep getting an error in MATLAB,
>> Ques3(A)
Unrecognized function or variable 'forsub'.
Error in Ques3 (line 12)
Y = forsub(L,P*I(:,j));

How to display a function with double values instead of symbolic?

I want the function P to look like this:
-1 + 0.6366*(x+pi/2) + (-0.000)*(x + pi/2)*(x)
and right now it looks like this
(5734161139222659*x)/9007199254740992 + (5734161139222659*pi)/18014398509481984 - (8131029572207409*x*(x + pi/2))/324518553658426726783156020576256 - 1.
How to convert S array so that the values are not symbolic?
syms P x
f = sin(x);
f = matlabFunction(f);
X = [-pi/2, 0, pi/2];
Y = f(sym(X));
P = MetN(X,Y,x)
P = matlabFunction(P);
function [P] = MetN(X,Y,x)
n = length(X);
for i = 1:n
A(i,1) = 1;
end
for i = 2:n
for j = 2: n
if i >= j
produs = 1;
for k =1:j-1
produs = produs * (X(i) - X(k));
end
A(i,j) = produs;
end
end
end
S = SubsAsc(A, Y);
S = double(S);
disp(S);
sym produs
P = double(sym(S(1)));
for i = 2:n
produs = 1;
for j = 1:i-1
produs = produs * (x - sym(X(j)));
end
disp(produs);
P = P + double(S(i))*produs;
end
end
function [x] = SubsAsc(A,b)
n = length(b);
x(1) = (1/A(1,1))*b(1);
for k = 2:n
s = 0;
for j = 1:k-1
s = s + A(k,j)*x(j);
end
x(k) = (1/A(k,k))*(b(k)-s);
end
end
The output you currently have is because symbolic uses exact arithmetic, so it outputs it as a rational number (hence the ugly fraction).
To have it output P using decimals, use vpa(). For instance output P using decimals to 5 significant digits
>> vpa(P, 5)
ans =
0.63662*x - 2.5056e-17*x*(x + 1.5708)
This will, however, also round pi, so you can't really have the best of both worlds here.

how to find newton iteration for each of initial points

function p = newton_hw(p0,tol,Nmax)
%NEWTON'S METHOD: Enter f(x), f'(x), x0, tol, Nmax
f = #(x) x*cos(x)-((sin(x))^2);
fp= #(x) -x*sin(x)+ cos(x)-2*sin(x)*cos(x);
p = p0 - (f(p0)/fp(p0));
y1=f(p);
fprintf('y1=%f',y1)
i = 1;
while (abs(p - p0) >= tol)
p0 = p;
p = p0 - f(p0)/fp(p0);
i = i + 1;
if (i >= Nmax)
fprintf('Fail after %d iterations\n',Nmax);
break
end
y=f(p);
fprintf('a=%f,y=%f,\n',p,y);
end
end
This is my question:
How to iterate for each of p0 = 0,.1,.2,...,49,5.
Iterating using user's step can be done this way:
for i = 0:0.1:5
Also any indexing can be done the same way: x = [0:2:50].
If your function works correctly (I suppose so), we can go this way:
k = 1;
for i = 0:0.1:5
res(k) = newton_hw(i,0.001,1000);
k = k+1;
end
But also we can do it at one line - style:
res = arrayfun( #(x) newton_hw(x, 0.001, 1000), I)

Matlab: how to calculate the Pseudo Zernike moments?

The code below is defined as algorithm 1 that computes the Pseudo Zernike Radial polynomials:
function R = pseudo_zernike_radial_polynomials(n,r)
if any( r>1 | r<0 | n<0)
error(':zernike_radial_polynomials either r is less than or greater thatn 1, r must be between 0 and 1 or n is less than 0.')
end
if n==0;
R =ones(n +1, length(r));
return;
end
R =ones(n +1, length(r));
rSQRT= sqrt(r);
r0 = ~logical(rSQRT.^(2*n+1)) ; % if any low r exist, and high n, then treat as 0
if any(r0)
m = n:-1:mod(n,2); ss=1:sum(r0);
R0(m +1, ss)=0;
R0(0 +1, ss)=1;
R(:,r0)=R0;
end
if any(~r0)
rSQRT= rSQRT(~r0);
R1 = zernike_radial_polynomials(2*n+1, rSQRT );
m = 2:2: 2*n+1 +1;
R1=R1(m,:);
for m=1:size(R1,1)
R1(m,:) = R1(m,:)./rSQRT';
end
R(:,~r0)=R1;
end
Then, this is algorithm 2 that calculates the moments:
and I translate into the code as follow:
clear all
%input : 2D image f, Nmax = order.
f = rgb2gray(imread('Oval_45.png'));
prompt = ('Input PZM order Nmax:');
Nmax = input(prompt);
Pzm =0;
l = size(f,1);
for x = 1:l;
for y =x;
for n = 0:Nmax;
[X,Y] = meshgrid(x,y);
R = sqrt((2.*X-l-1).^2+(2.*Y-l-1).^2)/l;
theta = atan2((l-1-2.*Y+2),(2.*X-l+1-2));
R = (R<=1).*R;
rad = pseudo_zernike_radial_polynomials(n, R);
for m = 0:n;
%find psi
if mod(m,2)==0
%m is even
newd1 = f(x,y)+f(x,y);
newd2 = f(y,x)+f(y,x);
newd3 = f(x,y)+f(x,y);
newd4 = f(y,x)+f(y,x);
x1 = newd1;
y1 = (-1)^m/2*newd2;
x2 = newd3;
y2 = (-1)^m/2*newd4;
psi = cos(m*theta)*(x1+y1+x2+y2)-(1i)*sin(m*theta)*(x1+y1-x2-y2);
else
newd1 = f(x,y)-f(x,y);
newd2 = f(y,x)-f(y,x);
newd3 = f(x,y)-f(x,y);
newd4 = f(y,x)-f(y,x);
x1 = newd1;
y1 = (-1)^m/2*newd2;
x2 = newd3;
y2 = (-1)^m/2*newd4;
psi = cos(m*theta)*(x1+x2)+sin(m*theta)*(y1-y2)+(1i)*(cos(m*theta)*(y1+y2)-sin(m*theta)*(x1-x2));
end
Pzm = Pzm+rad*psi;
end
end
end
end
However its give me error :
Error using *
Integers can only be combined with integers of the same class, or scalar doubles.
Error in main_pzm (line 44)
Pzm = Pzm+rad*psi;
The detail of the calculation can be seen here