Merge sort in scilab - mergesort

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.

Related

How can I measure length of signal in simulink?

I have model with "matlab function block" in which I have recursive least square method. Recursive algorithm needs to know length of incoming signal in order to work correctly. But when I use command N=length(y) it returns me length N= 1. But I think it should give me higher length.
Simulink model
Matlab function block code "rls_iden6"
function [P,N] = fcn(u,y)
%%
N = length(y);
sigma=1;
C = sigma*eye(2); %p
P = ones(2,1);
z= [y; u];
lamda=1;
for n=1:N
sample_out = y(n);
C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
P = P + (C*z* (sample_out - (z'*P)));
end
My final code should look like it's shown below, because it works in matlab workspace. Simulink should give me 5 parameters instead of just 2.
load data_cela.mat
u=U; %input
y=Y; %output
%%
input = 3;
output = 2;
system = input + output;
N = length(y);
%initial conditions
sigma = 1;
C = sigma*eye(system);
P = ones(system,1);
lamda = 1; %forgetting factor
for n=3:N
for i=1:2
W(i) = y(n-i); %output
end
for i=1:3
V(i) = u(n-i+1); %input
end
z = [V';W'];
sample_out = y(n);
pom(n)= z' * P;
error(n) = y(n) - pom(n);
C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
P = P + (C*z* (sample_out - (z'*P) ) );
change(1:system,n) = P;
end
f_param = [P(1:3);-P(4:5)];
num = [P(1:3,1)];
den = [1;-P(4:5,1)];
num1 = num(3,1);
trasferfunction = tf(num1,den',1)
Result:
0.002879
----------------------
z^2 - 1.883 z + 0.8873
You will need to add a buffer before signal to convert the scalar to matrix. Then after the buffer has been added set the buffer size to the amount of data you want, i.e. by setting it to 2 will make 2 rows and 1 column. This will help you to get the data however, for setting delay properly you will require to set buffer overlap to 1.
Hope this helps.

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

Error in using a function with more that one argument

Here is the code of the functions I'm using.
function max = find_max( matrix )
a = -1;
for i = 1:numel( matrix ),
if ( matrix(i) > a),
a = matrix(i);
end
end
max = a;
end
function maxs = find_maxs( matrix, count )
maxs = [];
while (count > 0),
a = -1;
for i = 1:numel( matrix ),
if ( matrix(i) > a && ~is_present(maxs, matrix(i))),
a = matrix(i);
end
end
maxs = [maxs a];
count = count - 1;
end
end
function present = is_present( vector, element )
for i = 1:numel( vector ),
if ( vector(i) == element),
present = TRUE;
return;
end
end
end
When I try to call:
m = [1 2 3 4];
disp(is_present(m, 1));
Or the function find_maxs, I get this error.
??? Undefined function or method 'is_present' for input arguments of type 'double'.
I'm new to matlab and I don't understand why I'm getting this error. The name of the file is find_max.m, the same name of the first function (which works fine).
Just to expand on eigenchris's comment (I'd put it as a comment but I don't have the privilege yet),
Each function should have it's own m file, and the m file should have the same name as the function.
Ex:
function max = find_max( matrix )
should be in a file named 'find_max.m'

Have to convert Integer to binary

I'm writing a user-defined function to convert integers to binary. The largest number that could be converted with the function should be a binary number with
16 1 s. If a larger number is entered as d, the function should display an error
message. With my code, I'm trying to add the numbers 0 or 1 to my vector x based on the remainder, then I want to reverse my final vector to display a number in binary. Here's what I have:
function [b] = bina(d)
% Bina is a function that converts integers to binary
x = [];
y = 2;
in = d/2;
if d >=(2^16 -1)
fprintf('This number is too big')
else
while in > 1
if in >= 1
r = rem(in,y);
x = [x r]
end
end
end
end
As you insist on a loop:
x = [];
y = 2;
in = d;
if d >=(2^16 -1)
fprintf('This number is too big')
else
ii = 1;
while in > 0
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1);
ii = ii+1;
end
end
b = x;
You had the right ideas, but you need to update the variables in your while-loop with every iteration. This is mainly in, where you need to subtract the remainder. And just store the binary remainders in your variable x.
You can check your result with
x = double( dec2bin(d, 16) ) - 48
You could also use a for loop, by pre-calculating the number of iterations with
find( d < 2.^(1:16),1)
and then
if d >=(2^16 -1)
fprintf('This number is too big')
else
for ii = 1:find( d < 2.^(1:16),1)
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1)
end
end

lapack - addressing for fully packed rectangular format

I would like to use the LAPACK routines for factorisation and inversion of matrices using the fully packed rectangular format, as this requires only n(n+1)/2 elements to be stored for a symmetric nxn matrix. So far, I am setting up the matrix in 'packed' format and transform it calling routine DTPTTF. However, this requires a second array. I would like to build my matrix directly in fully packed rectangular format (to save on space) - is there an 'addressing' function which will give me the position of the i,j-th element? or could somebody point me to the relevant formula?
to partly answer my own question: inspecting the source code of DTPTTF and the example given therein, I've worked out the adress for one of the four possible constellations (the only one I need), namely uplo ='L' and trans ='N'. below is my fortran function:
! ==================================== ! returns address for RFP format
integer function ijfprf( ii, jj, n ) ! for row jj and column ii
! ==================================== ! for UPLO = 'L' and TRANSR = 'N' only!
implicit none
integer, intent(in) :: ii, jj, n
integer :: i, j, k, n1, k1
if( ii <= jj ) then
i = ii; j = jj
else
i = jj; j = ii
end if
k = n/2
if( mod(n,2) == 0 ) then ! n even
n1 = n + 1
if( i <= k ) then
ijfprf = 1 + (i - 1) * n1 + j
else
ijfprf = ( j - k - 1 ) * n1 + i - k
end if
else ! n odd
k1 = k + 1
if( i > k1 ) then
ijfprf = ( j - k1 ) * n + i - k1
else
ijfprf = ( i - 1 ) * n + j
end if
end if
return
end function ijfprf