Not getting the right output

Here I'm trying to find the minimum of my function using "gradient method with step splitting". Here my output is not correct. And also code has some warnings and graph isn't correctly plotting.
So my function is : 10*(x)^2 - 4*x*y + 7*(y)^2 - 4*sqrt(5)*(5*x+y) - 16
and the right point of min should be : ( sqrt5 , 0 )
and the min of the function should be -66.
Hope for a little help.
Thanks.
clc;
close all;
clear;
hold on;
Funct = @(vect) 10*vect(1).^2 - 4*vect(1)*vect(2) + 7*vect(2).^2 + 4*sqrt(5)*(5*vect(1)-vect(2)) - 16;
vect= [0 10];
gradientx = @(x,y) 20.*x - 4.*y - 20*sqrt(5);
gradienty = @(x,y) (-4).*x + 14.*y + 4*sqrt(5);
Grad = [gradientx(vect(1),vect(2)) gradienty(vect(1),vect(2))];
e = 0.01;
kappa = 10;
fn=Funct(vect);
abs_grad = norm(Grad);
n = 3;
i = 0;
Fnew=0;
massiv= [vect(1) ;vect(2)];
while(kappa > e)
newvect = vect - kappa*(Grad./abs_grad);
Fnew=Funct(newvect);
if fn - Fnew<0.5*kappa*(abs_grad)
kappa = kappa/2;
else
fn = Fnew;
fimplicit(@(x,y) 10*(x)^2 - 4*x*y + 7*(y)^2 - 4*sqrt(5)*(5*x+y) - 16-fn, 'Color','r')
vect=newvect;
Grad = [gradientx(vect(1),vect(2)) gradienty(vect(1),vect(2))];
abs_grad = norm(Grad);
n=n+2;
i = i + 1;
massiv = [massiv [vect(1);vect(2)]];
end
n = n + 1;
end
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
grid on;
box on;
title e=0.01;
xlabel('X');
ylabel('Y');
plot(massiv(1,:),massiv(2,:),'b-*');
result = Funct(massiv(:,end));
fprintf('Precision parameter %.4f\n',e);
Precision parameter 0.0100
fprintf('Point of minimum [%.4f ,%.4f]\n', vect(1),vect(2));
Point of minimum [1.9062 ,6.2237]
fprintf('Min: %10.4f \n', result);
Min: 273.6048
fprintf('Iterations: %d \n',i );
Iterations: 9
fprintf('Number of calculated objective function values: %d\n\n',n );
Number of calculated objective function values: 40

7 Comments

Funct = @(vect) 10*vect(1).^2 - 4*vect(1)*vect(2) + 7*vect(2).^2 + 4*sqrt(5)*(5*vect(1)-vect(2)) - 16;
or
@(x,y) 10*(x)^2 - 4*x*y + 7*(y)^2 - 4*sqrt(5)*(5*x+y) - 16
Which function is correct ?
After you decided which one you want to use, check also the gradient.
I changed it to this. But there are still errors. (
clc;
clear;
hold on;
Funct = @(x) 10*x(1).^2 - 4*x(1)*x(2) + 7*x(2).^2 - 4*sqrt(5)*(5*x(1)-x(2)) - 16;
x= [0 10];
gradientx = @(x) 20*x - 4*y - 20*sqrt(5);
gradienty = @(x) (-4)*x + 14*y + 4*sqrt(5);
Grad = [gradientx(x(1),x(2)) gradienty(x(1),x(2))];
e = 0.01;
kappa = 10;
fn=Funct(x);
abs_grad = norm(Grad);
n = 3;
i = 0;
Fnew=0;
massiv= [x(1) ;x(2)];
while(kappa > e)
newvect = x - kappa*(Grad./abs_grad);
Fnew=Funct(newvect);
if fn - Fnew<0.5*kappa*(abs_grad)
kappa = kappa/2;
else
fn = Fnew;
fimplicit(@(x) 10*x(1).^2 - 4*x(1)*x(2) + 7*x(2).^2 - 4*sqrt(5)*(5*x(1)-x(2)) - 16 - fn, 'Color','r')
x=newvect;
Grad = [gradientx(x(1),x(2)) gradienty(x(1),x(2))];
abs_grad = norm(Grad);
n=n+2;
i = i + 1;
massiv = [massiv [x(1);x(2)]];
end
n = n + 1;
end
grid on;
box on;
title e=0.01;
xlabel('X');
ylabel('Y');
plot(massiv(1,:),massiv(2,:),'b-*');
result = Funct(massiv(:,end));
fprintf('Precision parameter %.4f\n',e);
fprintf('Point of minimum [%.4f ,%.4f]\n', x(1),x(2));
fprintf('Min: %10.4f \n', result);
fprintf('Iterations: %d \n',i );
fprintf('Number of calculated objective function values: %d\n\n',n );
Torsten
Torsten on 7 Jan 2023
Edited: Torsten on 7 Jan 2023
gradient_x and gradient_y are still wrong.
They have x and y as inputs, and the calculated formulae for them are also not correct.
Further the function you apply fimplicit to should accept array input. Look at how I defined it in your previous question.
ahh yes yes I made a typo error. There is - 4*sqrt(5)*(5*x(1)-x(2)). not + 4*sqrt(5)*(5*x(1)-x(2)).
So the gradients will be like this..? When I put it like this there will be " too many arguments error ".
Funct = @(x) 10*x(1).^2 - 4*x(1)*x(2) + 7*x(2).^2 - 4*sqrt(5)*(5*x(1)-x(2)) - 16;
x= [0 10];
gradientx = @(x) 20*x(1) - 4*x(2) - 20*sqrt(5);
gradienty = @(x) (-4)*x(1) + 14*x(2) + 4*sqrt(5);
and the fimplicit should be like this? In the previous question you answered, there was a (x,y) inputs. and here I used x(1) and x(2). So Im confused that should I put it like @(x) or @(x(1),x(2)) ?
fimplicit(@(x) Funct (x) - fn, 'Color','r')
If you want to call your gradients now with one input argument,
gradientx = @(x) 20*x(1) - 4*x(2) - 20*sqrt(5);
gradienty = @(x) (-4)*x(1) + 14*x(2) + 4*sqrt(5);
it's ok. But then you will also change the computational calls:
Grad = [gradientx(x(1),x(2)) gradienty(x(1),x(2))];
fimplicit only accepts functions of the form f(x,y). Thus you have to change
fimplicit(@(x) Funct (x) - fn, 'Color','r')
accordingly.
And take care that Funct is vectorized.
@(x,y) 10*(x)^2 - 4*x*y + 7*(y)^2 - 4*sqrt(5)*(5*x+y) - 16-fn
is not vectorized.
I wonder why you change all these things in the previous code that worked. Do you like the challenge of mastering errors ?
Understood! Sorry I'm dumb when it comes to coding. Now the code is working!!
Thank you very much for the help!! Appreciate!)

Sign in to comment.

Answers (0)

Products

Release

R2021b

Asked:

on 6 Jan 2023

Commented:

on 7 Jan 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!