Multi valued function graph in matlab - 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).

Related

Merge sort in scilab

I implemented merge sort in scilab with the following code:
function x = mergesortre (x)
n = length (x);
if ( n > 1 ) then
m = floor (n/2);
p = n-m;
x1 = mergesortre ( x(1:m) );
x2 = mergesortre ( x(m+1:n) );
x = merge ( x1 , x2 );
end
endfunction
function [x] = merge ( x1 , x2 )
n1 = length (x1);
n2 = length (x2);
n = n1 + n2;
x = [];
i = 1
j = 1
k = 1
while(j<=n1 && k<=n2)
if x1(j)>=x2(k)
x(i)=x2(k);
k=k+1;
i=i+1;
elseif x1(j)<x2(k)
x(i)=x1(j);
j=j+1;
i=i+1;
end
end
if (j > n1) then
x(i+1:n) = x2(k:n2);
else
x(i+1:n) = x1(j:n1);
end
endfunction
a=[5,4,3,2,1];
x=mergesortre(a);
disp x;
However in when i try to see the sorted array using the terminal window its showing only the first element,for example if my array is [5,4,3,2,1] its only giving output as 1. I need help understanding what i did wrong.
Your error is in the merge function. As i is already incremented at the end of the loop you have to concatenate starting at i:
if (j > n1) then
x(i:n) = x2(k:n2);
else
x(i:n) = x1(j:n1);
end
A recursive algorithm needs a termination condition. There is no such condition in your function mergesortre. It's likely because the declaration of your function does not used the input argument x. Try to change it like this:
function [a] = mergesortre ( a )
I guess you wanted to use a as an input and output argument.

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

vectorizing function in octave / matlab

I have a function that I was wondering if it was possible to vectorize it and not have to use a for loop. The code is below.
a=1:2:8
for jj=1:length(a)
b(jj)=rtfib(a(jj)); %fibbonacci function
end
b
output below:
a =
1 3 5 7
>>>b =
1 3 8 21
I was trying to do it this way
t = 0:.01:10;
y = sin(t);
but doing the code below doesn't work any suggestions?
ps: I'm trying to keep the function rtfib because of it's speed and I need to use very large Fibonacci numbers. I'm using octave 3.8.1
a=1:2:8
b=rtfib(a)
Here's the rtfib code below as requested
function f = rtfib(n)
if (n == 0)
f = 0;
elseif (n==1)
f=1;
elseif (n == 2)
f = 2;
else
fOld = 2;
fOlder = 1;
for i = 3 : n
f = fOld + fOlder;
fOlder = fOld;
fOld = f;
end
end
end
You can see that your function rtfib actually computes every Fibonacci number up to n.
You can modify it so that is stores and returns all these number, so that you only have to call the function once with the maximum number you need:
function f = rtfib(n)
f=zeros(1,n+1);
if (n >= 0)
f(1) = 0;
end
if (n>=1)
f(2)=1;
end
if (n >= 2)
f(3) = 2;
end
if n>2
fOld = 2;
fOlder = 1;
for i = 3 : n
f(i+1) = fOld + fOlder;
fOlder = fOld;
fOld = f(i+1);
end
end
end
(It will return fibonnaci(n) in f(n+1), if you don't need the 0 you could change it so that it returns fibonnaci(n) in f(n) if you prefer)
Then you only need to call
>>f=rtfib(max(a));
>>b=f(a+1)
b =
1 3 8 21
If you don't want to store everything you could modify the function rtfib a little more, so that it takes the the array a as input, compute the Fibonacci numbers up to max(a) but only stores the one needed, and it would directly return b.
Both solutions will slow down rtfib itself but it will be a lot faster than calculating the Fibonacci numbers from 0 each time.

Combining functions with boundaries in 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) ...

MATLAB: Losing points near singularities?

I am trying to plot some bump function supported on the interval (0,3). I've defined the function piecewise so that it is zero outside the interval. Here is the function:
function d = bump2(t)
region1 = (t > 0) & (t < 3);
d(region1) = exp(1./(t(region1).^2 - 3*t(region1)));
region2 = (t <= 0) & (t >= 3);
d(region2) = 0;
end
If I set x = -1:.01:4 and try to run plot(x,bump2(x)) I get an error telling me that my vectors aren't the same length. This is indeed true since length(x) = 501 and length(bump2(x)) = 400 However, when I set x = .01:.01:2.99, then everything checks out fine and the lengths of the vectors are equal.
Also, strangely, I have another, similar function
function b = bump(t)
region1 = abs(t) < 1;
b(region1) = exp(-1./(1 - ((t(region1)).^2)));
region2 = abs(t) >= 1;
b(region2) = 0;
end
with which I've never had this problem. Why are these two functions different? And why does the first function work when I exclude the points 0 and 3, even though I've defined the function to avoid possible singularities there?
This is because the b(region1) is trimming off the ends of your vector x so that it is not the same size.
Consider if you set x = -1:3 and then run the code plot(x, bump3(x)); with:
function d = bump3 (t)
region1 = (t > 0) & (t < 3);
d(region1) = t(region1);
end
Then you get the same problem. The issue is that inside bump3 you have
K>> region1
region1 =
0 0 1 1 0
Now this is the trick. This region1 is of data type logical so MATLAB interprets the next line
d(region1) = t(region1);
as
d(find(region1)) = t(find(region1));
But if you wrote
d = [];
d(5) = 1;
Then you would get a bunch of zeros at the zero, so you do here.
You might consider modifying to say d = t(region1); to get only the good values, but then you still have a sizing problem. A solution is to return the indices you used with the new value as an additional return value in bump like this:
Execute:
x = -1:3;
[y region1] = bump4(x);
plot(x(region1), y);
Where you modify your bump function like this:
function [d region1] = bump4 (t)
region1 = (t > 0) & (t < 3);
d = t(region1);
end
EDIT:
If you really do want those extra zeros on the left and right you can also fix this problem by initializing d before using it in your code like this:
function d = bump2(t)
region1 = (t > 0) & (t < 3);
d = zeros(size(t));
d(region1) = exp(1./(t(region1).^2 - 3*t(region1)));
region2 = (t <= 0) & (t >= 3);
d(region2) = 0;
end
Because I set d = zeros(...) then you have zeros outside the region and your bump function within it. Another way of looking at the problem is that MATLAB is padding on the left side but not on the right because you never set a blank value out there. This fixes that problem by telling MATLAB how big d should be.