Combining functions with boundaries in matlab - matlab

I have a function like this:
f(x) = { x if 0 < x < n
{ n-x if n < x < 2*n
How to enter this function in MATLAB?

Best way is to put this in a sub-function or nested function, or in a separate m-file:
function y = f(x)
n = 4; %// Or whatever your N is
if x <= 0 || x >= 2*n
y = 0;
elseif x < n
y = x;
else
y = n-x;
end
end
or, more generally, when x is a vector/matrix,
function y = f(x)
y = x;
y(x >= n) = n-x(x >= n);
y(x <= 0 | x >= 2*n) = 0;
end
Alternatively, you can of course pass the n as an argument:
function y = f(x, n)
...
end
Alternatively, you can use this anonymous function:
f = #(x) (x>0 & x<n).*x + (x>=n & x<=2*n).*(n-x);
again, optionally, pass the n:
f = #(x,n) ...

Related

Code Horner’s Method for Polynomial Evaluation

I am trying to code Horner’s Method for Polynomial Evaluation but for some reason its not working for me and I'm not sure where I am getting it wrong.
These are the data I have:
nodes = [-2, -1, 1]
x = 2
c (coefficients) = [-3, 3, -1]
The code I have so far is:
function y = horner(x, nodes, c)
n = length(c);
y = c(1);
for i = 2:n
y = y * ((x - nodes(i - 1)) + c(i));
end
end
I am supposed to end up with a polynomial such as (−1)·(x+2)(x+1)+3·(x+2)−3·1 and if x =2 then I am supposed to get -3. But for some reason I don't know where I am going wrong.
Edit:
So I changed my code. I think it works but I am not sure:
function y = horner(x, nodes, c)
n = length(c);
y = c(n);
for k = n-1:-1:1
y = c(k) + y * (x - nodes((n - k) + 1));
end
end
This works:
function y = horner(x, nodes, c)
n = length(c);
y = 0;
for i = 1:n % We iterate over `c`
tmp = c(i);
for j = 1:i-1 % We iterate over the relevant elements of `nodes`
tmp *= x - nodes(j); % We multiply `c(i) * (x - nodes(1)) * (x -nodes(2)) * (x- nodes(3)) * ... * (x - nodes(i -1))
end
y += tmp; % We added each product to y
end
% Here `y` is as following:
% c(1) + c(2) * (x - nodes(1)) + c(3) * (x - nodes(1)) * (x - nodes(2)) + ... + c(n) * (x - nodes(1)) * ... * (x - nodes(n - 1))
end
(I'm sorry this isn't python but I don't know python)
In the case where we didn't have nodes, horner's method works like this:
p = c[n]
for i=n-1 .. 1
p = x*p + c[i]
for example for a quadratic (with coeffs a,b,c) this is
p = x*(x*a+b)+c
Note that if your language supports fma
fma(x,y,x) = x*y+z
then horner's method can be written
p = c[n]
for i=n-1 .. 1
p = fma( x, p, c[i])
When you do have nodes, the change is simple:
p = c[n]
for i=n-1 .. 1
p = (x-nodes[i])*p + c[i]
Or, using fma
p = c[n]
for i=n-1 .. 1
p = fma( (x-nodes[i]), p, c[i])
For the quadratic above this leads to
p = (x-nodes[1]*((x-nodes[2])*a+b)+c

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.

Undefined function or variable 'x'

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);

Time Complexity Analysis Of A Recursion

The following code is calculating the determinant using recursion.
For the "for" loop with have O(n) then we call the function again with n-1 elements so we have to multiply each time we call the function?
something like O(n)O(n-1)...*O(1)?
function y = detm(A)
n = length(A);
y = 0;
if n == 1
y = A(1,1);
elseif n == 2
y = A(1,1).*A(2,2)-A(1,2).*A(2,1);
elseif n > 2
for i = 1:n
temp = A(2:end,:);
temp(:,i) = [];
if mod(i,2) == 0
y = y - A(1,i)*detm(temp);
else
y = y + A(1,i)*detm(temp);
end
end
end
end

Multi valued function graph in matlab

This is my first script in matlab. ( I cannot use functions)
Let's say I have a vector of time instants
t = [0:999]*1e-5; %vector of time instants
And my function is m
This is the part where it is implemented:
if (t >= 0)
if t <= to/3
m = 1;
elseif (t <= 2*to/3)
m = -2;
end
else
m = 0;
end
As I realised, m has only one value equal to 1.
How is this possible to have a 1x1000 value here? Where for values of t from 0 to to/3 -> m = 1, to/3 to 2*to/3 -> m = -2and else m=0
You can apply a function on each element of an array using arrayfun like the following:
arrayfun(#(x) m(x), t)
%or
arrayfun(#m, t)
You can find the details here. Also, you can implement your function like the following:
function result = m(t)
result = t;
result(t >= 0 && t <= to/3) = 1;
result(t > to/3 && t <= 2*to/3) = -2;
result(t < 0) = 0;
then call the function m on t such as m(t).