Output argument not assigned during call (MATLAB) - matlab

I'm having a bit of difficulty with this function in MATLAB and I can't figure out what the issue is. The error is,
Output argument "x" (and maybe others) not assigned during call to "SDLS".
Error in NO_wk4_Q3c (line 7)
x = SDLS( A, x0, b, 1e-3 );
So as far as I know, it's something to do with the output for 'x', yet I have assigned 'x' in the function file. Is it something to do with the 'while' loop?
Below is the function file:
function [ x, k ] = SDLS( A, x0, b, tol )
% Steepest descent with exact line search.
% A is the input matrix, x0 is the initial guess, b is a vector, tol is the
% tolerence level for convergence.
if nargin < 4
tol=eps;
end
g = A*x0+b; % Derivative of Q(x)=(1/2)x'Ax+b'x+c;
p = zeros(1,1);
k = 0;
x=zeros(1,1);
while norm(g,2)>=1e-3
g = A*x0 + b;
p = -g; % direction vector
alpha = -(transpose(g)*p)/(transpose(p)*A*p); % step length
x = x0 + alpha*p; % updates approximation
x0 = x;
k = k+1;
end
end
The script file that calls the function is as follows:
clear all;
A = [4 2; 2 3]; % Matrix
x0 = [ -1; -1]; % Initial guess
b = [ 3; 1];
[ x, k] = SDLS( A, x0, b, 1e-3 );
Any advice would be great :-)

Related

How can I find the value of a matrix that minimize a least square cost function in MATLAB?

Given the value of S1 which is a vector of size (1,K), I want to find the value of matrix B of size (N,M) that can minimize the following least square cost function:
sum(S2 - S1).^2
Subject to:
S2(i)>=S1(i) \forall i \in {1, .., K}
Where S2 is a vector of size (1,K) and is a function of matrix B.
S2 can be calculated after optimizing matrix B using the following system parameters and equations:
clc;
clear;
% Given system parameters:
N = 2;
K = 4;
M = 2;
C_l = 4;
H = [0.1185 0.2811; 0.3550 0.8224; 0.3260 0.9644; 0.5333 0.6083]; % 4*2 matrix
A = [-2 1; -1 1]; % 2*2 matrix
C = [7 -3; 7 -3; -2 1; -2 1]; % 4*2 matrix
P = [25000000 0; 0 25000000]; % 4*4 matrix
S1 = [3.1683 3.1686 1.8716 1.8898]; % 1*4 vector
S2 = zeros(1,K); % intial value
B = zeros(N,M); % intial value
% How can we optimize the value of the B matrix to achieve our goal?
%calculate S2 from B and the other given inputs
for j=1:1:N
d(j) = (B(j,:)*P*B(j,:)')/((2^(2*C_l))-(norm(A(:,j))^2));
end
D_d = diag(d);
for i=1:1:K
V_d(i)=C(i,:)*P*B'*H(i,:)'*inv(1+H(i,:)*(A'*D_d*A+B*P*B')*H(i,:)');
sigma_d(i)=norm((V_d(i)*H(i,:)*B-C(i,:))*(P^(1/2)))^2+(V_d(i)^2)*(1+H(i,:)*A'*D_d*A*H(i,:)');
S2(i)=0.5*log2((P(1,1))/sigma_d(:,i));
end

Falsi method algorithm

I wrote a falsi method code and I got problem with fa function. My general function is in interval [a,b]=[2,12], as I defined in main script:
a=2;
b=12;
%Function
syms x real;
f=1.2*sin(x)+2*log(x+2)-5;
I wonder how to correctly pass argument a to the function fa and, in general, to falsi method function . I guess, it cannot be just '2', it must be dynamic somehow. Thanks for tips ! :)
function [ x ] = task1_falsi( f, x, a)
% Defining functions
a=2;
fa=feval(f,a);
f=inline(f);
fa=inline(fa);
err=1;
% Falsi's loop.
% Stops when error is negligible or number of iterations becomes prohibitive
it=0;
while (it<1000) && (err>10e-5)
% Falsi's algorithm
x1=x-feval(f,x)*(x-a)/fa;
% Calculating error
err=abs(x1-x);
% New zero is previous value
x=x1;
it=it+1;
%Showing steps
fprintf('%d\t%f \n',it, x);
end
disp('Root:');
disp(x);
disp('Iterations:');
disp(it);
end
%Task 1
% Falsi's method algorithm
function [ x ] = task1_falsi( f, x)
err=1;
y = 7; % Starting point
z = 8;
f=inline(f);
% Ending point
maxIteration = 1000; % Maximum number of iterations
epsilon = 0.001; % Accuracy
it=0; % Vector with number of iterations
xold = z; % Variable used for calculations
solutionRegulaFalsix=zeros(10,1); % Error vector
for j=0:20
while (it <= maxIteration)
x1 = y - ((feval(f,y)*(z-y))/(feval(f,z)-feval(f,y))); % Calculating the root
it= it+ 1;
if (abs(x1-xold)<epsilon*abs(x1)) % Accuracy condition
break;
else
xold = x1;
if feval(f,y)*feval(f,z) > 0
y = x1; % Starting point is being changed
else
z = x1; % Ending point is being changed
end
end
end
err = abs(x1-x); % Calculating the error
% epsilon = epsilon/10;
%Showing steps
fprintf('%d\t%f \n',it, x);
y=2;
z=3;
disp('Root:');
disp(x1);
disp('Iterations:');
disp(it);
end
end

Matlab can't solve the collocation equations. Encountered a singular jacobian

function bvp()
solinit = bvpinit(linspace(0,1,10),[0, 0.3, 0, 0.5]);
sol = bvp4c(#myprojec,#mybounds, solinit);
plot(sol.x,sol.y(1,:),'.');
%Hold on can be used to suspend the graph so as to plot another graph on
%the same axis with different parameters
xlabel('\c');
ylabel('\theta');
function dydx = myprojec(x,y)
% enter the parameter
% x represents c
% y(i) represents f,theta
% f = y(1), f' = y(2), theta = y(4), theta' = y(5)
% star (*) replaced by 0
% infinity =5
% Max infinity = 10
% B = input('input the value of Beta:');
B = 5;
% M = input('input the value of M:');
M = 1;
% Km = input('input the value of Km:');
Km = 1.5;
% Br = input ('input the value of Br:');
Br = 12;
dydx=[ y(2);(B^2-M)*y(1)-Km;y(4);Br*((M- B^2)*y(1)-y(2)^2)];
% Now d bcs
function res = mybounds(ya,yb)
% where to denote initial values of y at zero(0)
% finf denotes initial vlue of y at infinity (5 or 10)
% n = input('input the value of n:');
res = [ya(1)
yb(1)-1
ya(4)
yb(4)-(1)];
The error I got is that Matlab cannot solve the collocation equations. A singular Jacobian encountered. I would appreciate your suggestions.

Get row of functions from a matrix of functions

Before overwhelming you with examples where I try to encapsulate every aspect of my issue I'll try to just state the problem as simply as possible:
If f11 , ... , fnm is n*m real valued funtions that I wish to evaluate m at a time in n steps, through some higher order function b i.e.
v = []
f1 = #(x) [f11(x) f12(x) ... f1m(x)]
v = [v b(f1)]
f2 = #(x) [f21(x) f22(x) ... f2m(x)]
v = [v b(f2)]
How would I solve this through iteration? i.e. something like this:
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v b(f(i,:)) ]
end
Here's an example of what I have (it grew in order to not miss out any details of my actual real-world problem but I have tried to make it as small as possible):
% 4 functions that take a 1x2 real valued vector as argument
% and return a real value
f11 = #(x) x(1) + x(2);
f12 = #(x) x(1) - x(2);
f21 = #(x) x(2) - x(1);
f22 = #(x) x(1) * x(2);
% we'll run function b for 2 steps, then 4 steps
steps = [2 4];
% start value
x = [1 2];
% vector to hold results
v = []
% get the result of passing the 1:st 2 functions to b with steps(1)
f1 = #(x) [f11(x) f12(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd 2 functions to b with steps(2)
f2 = #(x) [f21(x) f22(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
Where b is a function defined as follows:
function [ X ] = b( x, f, n )
% #param:
% x = an 1x2 real valued vector
% f = a real valued function returning
% a 1x2 real valued vector
% n = an integer defining the rows of return matrix
%
% #return:
% X = an nx2 real valued matrix defined as below
X = zeros(n,2);
for i=1:n
% apply the functions on x
a = f(x+1);
b = f(x+2);
% update x
x = a+b
% add x to return matrix
X(i,:) = x;
end
end
The above code could be generalized as:
% n*m functions that take a 1xm real valued vector as argument
% and return a real value
f11 = #(x) ... ;
f12 = #(x) ... ;
.
.
.
fnm = #(x) ... ;
% we'll run function b for a1 steps, then a2 steps, ... , then an steps
steps = [a1 a2 ... an];
% start value
x = [1 2 ... m];
% vector to hold results
v = []
% get the result of passing the 1:st m functions to b with steps(1)
f1 = #(x) [f11(x) ... f1m(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd m functions to b with steps(2)
f2 = #(x) [f21(x) ... f2m(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
.
.
.
% add the result of passing the n:ed m functions to b with steps(n)
fn = #(x) [fn1(x) ... fnm(x)];
v = [v ;b(x, fn, steps(n))];
% update x
x = v(end,:)
Where b is any function that returns an steps(i) x m matrix.
I wonder if both the small concrete example and the general example should be solvable through a general iteration, something like this:
% let f hold all the functions as a matrix
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v ; b(x, f(i,:), steps(i)) ]
end
So the trick is in defining your functions as a cell matrix and then using some vectorization to solve the problem. This is the code that I came up with:
%First define your functions in a cell matrix
fn_mat = {#(x) x(1) + x(2), #(x) x(1) - x(2); ...
#(x) x(2) - x(1), #(x) x(1) * x(2)};
%Store the sixe of this matrix in two variables
[n, m] = size(fn_mat);
%Number of steps
steps = [2, 4];
% start value
x = [1 2];
% vector to hold results
v = [];
%This will run the required code for n iterations
for ii = 1:n
%This is the tricky part. What I have done is used arrayfun to run over
%all the functions in the row defined by ii and pass x as an argument
%each time. The rest is same as before
fn = #(x) arrayfun(#(a, b) fn_mat{ii, a}(b{:}), 1:m, repmat({x}, 1, m));
v = [v; b(x, fn, steps(ii))];
x = v(ii, :);
end
For the current values, the output is:
v =
12 -2
26 28
-28 -13
30 610
1160 38525
74730 89497060
The for loop is general enough to accommodate any size of fn_mat.

Using MATLAB to write a function that implements Newton's method in two dimensions

I am trying to write a function that implements Newton's method in two dimensions and whilst I have done this, I have to now adjust my script so that the input parameters of my function must be f(x) in a column vector, the Jacobian matrix of f(x), the initial guess x0 and the tolerance where the function f(x) and its Jacobian matrix are in separate .m files.
As an example of a script I wrote that implements Newton's method, I have:
n=0; %initialize iteration counter
eps=1; %initialize error
x=[1;1]; %set starting value
%Computation loop
while eps>1e-10&n<100
g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)]; %g(x)
eps=abs(g(1))+abs(g(2)); %error
Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)]; %Jacobian
y=x-Jg\g; %iterate
x=y; %update x
n=n+1; %counter+1
end
n,x,eps %display end values
So with this script, I had implemented the function and the Jacobian matrix into the actual script and I am struggling to work out how I can actually create a script with the input parameters required.
Thanks!
If you don't mind, I'd like to restructure your code so that it is more dynamic and more user friendly to read.
Let's start with some preliminaries. If you want to make your script truly dynamic, then I would recommend that you use the Symbolic Math Toolbox. This way, you can use MATLAB to tackle derivatives of functions for you. You first need to use the syms command, followed by any variable you want. This tells MATLAB that you are now going to treat this variable as "symbolic" (i.e. not a constant). Let's start with some basics:
syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x. Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
% This should give 2*(3^2) + 6*3 + 3 = 39
Because this is 2D, we're going to need 2D functions... so let's define x and y as variables. The way you call the subs command will be slightly different:
syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
% Should give 56
One more thing... we can place equations into vectors or matrices and use subs to simultaneously substitute all values of x and y into each equation.
syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
We can do the same thing for matrices, but for brevity I won't show you how to do that. I will defer to the code and you can see it then.
Now that we have that established, let's tackle your code one piece at a time to truly make this dynamic. Your function requires the initial guess x0, the function f(x) as a column vector, the Jacobian matrix as a 2 x 2 matrix and the tolerance tol.
Before you run your script, you will need to generate your parameters:
syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector
% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];
% Initial vector
x0 = [1; 1];
% Tolerance:
tol = 1e-10;
Now, make your script into a function:
% To run in MATLAB, do:
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);
function [n, xout, tol] = Jacobian2D(f, J, x0, tol)
% Just to be sure...
syms x, y;
% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB
% Initialize counter
n = 0;
% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';
% Computation loop
while ep > tol && n < 100
g = subs(f, {x,y}, xout); %g(x)
ep = abs(g(1)) + abs(g(2)); %error
Jg = subs(J, {x,y}, xout); %Jacobian
yout = xout - Jg\g; %iterate
xout = yout; %update x
n = n + 1; %counter+1
end
% Transpose and convert back to number representation
xout = double(xout');
I should probably tell you that when you're doing computation using the Symbolic Math Toolbox, the data type of the numbers as you're calculating them are a sym object. You probably want to convert these back into real numbers and so you can use double to cast them back. However, if you leave them in the sym format, it displays your numbers as neat fractions if that's what you're looking for. Cast to double if you want the decimal point representation.
Now when you run this function, it should give you what you're looking for. I have not tested this code, but I'm pretty sure this will work.
Happy to answer any more questions you may have. Hope this helps.
Cheers!