How does this recursion work? Can you explain how they got the output? - matlab

function fnum = fib(n)
if (n == 1) || (n == 2)
fnum = 1;
else
fnum = fib(n-1) + fib(n-2);
end
Can you explain how does each step outputs for the given input. For example inputting 7 gives me 13, 5 gives me 5, but I am not able to track how. I would highly appreciate your reply.

Recursion basically means that the function calls itself.
If we follow your function for fib(3), you will see that what it does is call fib(2)+fib(1). The values of these are defined, and are 1, so it will return 2.
If you call it with fib(4), it will go and compute fib(3)+fib(2). You already know what fib(3) does (see previous paragraph), and we already mentioned that fib(2) returns 1.
If you call it with fib(5) it will go and compute fib(4)+fib(3). See previous paragraph.
This is a very useful way of programming as it is a very simple function to compute something that is arguably more complicated. The most important thing is that you make sure that any recursive function has strong stopping criteria, else it can go forever!

Do you know how Fibonacci series is defined? This function implements that recursively.
Longer answer
Fibonacci series is defined as
n(1) = 1
n(2) = 1
n(k+1) = n(k) + n(k-1)
So when you put 5 as argument, the expansion becomes
n(4+1) = n(4)+n(3)
= n(3)+n(2)+n(2)+n(1)
= n(2)+n(1)+1+1+1
= 1+1+1+1+1
= 5
A much easier back of envelop method is to start from first index and add last two terms to arrive at the next.
1, 1, 2 <- (1+1), 3 <- (2+1), 5 <- (3+2), ...

The Fibonnacci series is defined as f(1) = 1, f(2) = 1 and for all n > 2, f(n) = f(n-1) + f(n-2)
So when you call fib(1) it returns 1 same for fib(2). But when you call fib(3) it returns fib(3-1) + fib(3-2) which is fib(2) + fib(1) = 2. And then when you call fib(4)it returns fib(3) + fib(2) = (fib(2) + fib(1)) + fib(1) = 3. And recursively the fibonnaci series is equal to 1, 1, 3, 5, 8, 13, 21, ...
For the code when n is different than 1 or 2 it call the function fib recursively. And when is equals to 1 or 2 it returns 1.

Related

jruby concurrent pool threads mixing up when combined for result

There is an array with indices [[0, n_0], [1, n_1], ..., [n, n_n]]. For each n_i a function is called. It is necessary to reorder the result from the threads by first component after every thread has terminated. As far as I could find a way to do this, I organized that the index is hard-coded by asking if the index is e.g. 0 and then starting the code separately for the hard-coded index 0. So far this a possible way to do it (even though the code looks as if someone didn't understand what a loop is for).
rest = []
tpl.each do |idx, vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ', res]
rest += [[0, res]]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ', res]
rest += [[1, res]]
end#pool.post
end;end
But now there is a strange behaviour:
Index 0 and 1 are calculated accurately, but when the result of 1 is added one line later, the result of the former function is added (again).
["idx 1: ", [4]]
["idx 0: ", [16900]]
rest: [[0, [16900]], [1, [16900], ...]
This is not always the case, so it depends on the order of the appearance of the results.
If e.g. the calculation of index 0 is finished after the calculation of index 1, then idx 1 is missing, or wrong. But other cases of confused results also appear: idx 0 before idx 1, but result of idx 0 is the result of idx 1.
?
It looks like if the threads are not really separated. Can that be enforced, or is there a smarter way of keeping indeces?
One option, I found out, is to synchronize the threads, but that would make the algorithm slower again, so a better solution is:
The results don't get mixed up, if the rest-tuple already has the structure to differentiate the results coming in:
rest = [[], []]
tpl.each do |idx, vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ', res]
rest[0] << [0, res]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ', res]
rest[1] << [1, res]
end#pool.post
end;end

How can I sum up functions that are made of elements of the imported dataset?

See the code and error. I have already tried Do, For,...and it is not working.
CODE + Error from Mathematica:
Import of survival probabilities _{k}p_x and _{k}p_y (calculated in excel)
px = Import["C:\Users\Eva\Desktop\kpx.xlsx"];
px = Flatten[Take[px, All], 1];
NOTE: The probability _{k}p_x can be found on the position px[[k+2, x -16]
i = 0.04;
v = 1/(1 + i);
JointLifeIndep[x_, y_, n_] = Sum[v^k*px[[k + 2, x - 16]]*py[[k + 2, y - 16]], {k , 0, n - 1}]
Part::pkspec1: The expression 2+k cannot be used as a part specification.
Part::pkspec1: The expression 2+k cannot be used as a part specification.
Part::pkspec1: The expression 2+k cannot be used as a part specification.
General::stop: Further output of Part::pkspec1 will be suppressed during this calculation.
Part of dataset (left corner of the dataset):
k\x 18 19 20
0 1 1 1
1 0.999478086278185 0.999363078716059 0.99927911905056
2 0.998841497412202 0.998642656911039 0.99858030519133
3 0.998121451605207 0.99794428814123 0.99788275311401
4 0.997423447323642 0.997247180349674 0.997174407432264
5 0.996726703362208 0.996539285828369 0.996437857252448
6 0.996019178300768 0.995803204773039 0.99563600297737
7 0.995283481416241 0.995001861216016 0.994823584922968
8 0.994482556091416 0.994189960607964 0.99405569519175
9 0.993671079225432 0.99342255996206 0.993339856748282
10 0.992904079096455 0.992707177451333 0.992611817294026
11 0.992189069953677 0.9919796017009 0.991832027835091
Without having the exact same data files to work with it is often easy for each of us to make mistakes that the other cannot reproduce or understand.
From your snapshot of your data set I used Export in Mathematica to try to reproduce your .xlsx file. Then I tried the following
px = Import["kpx.xlsx"];
px = Flatten[Take[px, All], 1];
py = px; (* fake some py data *)
i = 0.04;
v = 1/(1 + i);
JointLifeIndep[x_, y_, n_] := Sum[v^k*px[[k+2,x-16]]*py[[k+2,y-16]], {k,0,n-1}];
JointLifeIndep[17, 17, 12]
and it displays 362.402
Notice I used := instead of = in my definition of JointLifeIndep. := and = do different things in Mathematica. = will immediately evaluate the right hand side of that definition. This is possibly the reason that you are getting the error that you do.
You should also be careful with your subscript values and make sure that every subscript is between 1 and the number of rows (or columns) in your matrix.
So see if you can try this example with an Excel sheet containing only the snapshot of data that you showed and see if you get the same result that I do.
Hopefully that will be enough for you to make progress.

Merging two sorted lists, one with additional 0s

Consider the following problem:
We are given two arrays A and B such that A and B are sorted
except A has B.length additional 0s appended to its end. For instance, A and B could be the following:
A = [2, 4, 6, 7, 0, 0, 0]
B = [1, 7, 9]
Our goal is to create one sorted list by inserting each entry of B
into A in place. For instance, running the algorithm on the above
example would leave
A = [1, 2, 4, 6, 7, 7, 9]
Is there a clever way to do this in better than O(n^2) time? The only way I could think of is to insert each element of B into A by scanning linearly and performing the appropriate number of shifts, but this leads to the O(n^2) solution.
Some pseudo-code (sorta C-ish), assuming array indexing is 0-based:
pA = A + len(A) - 1;
pC = pA; // last element in A
while (! *pA) --pA; // find the last non-zero entry in A
pB = B + len(B) - 1;
while (pA >= A) && (pB >= B)
if *pA > *pB
*pC = *pA; --pA;
else
*pC = *pB; --pB;
--pC
while (pB >= B) // still some bits in B to copy over
*pC = *pB; --pB; --pC;
Not really tested, and just written off the top of my head, but it should give you the idea... May not have the termination and boundary conditions exactly right.
You can do it in O(n).
Work from the end, moving the largest element towards the end of A. This way you avoid a lot of trouble to do with where to keep the elements while iterating. This is pretty easy to implement:
int indexA = A.Length - B.Length - 1;
int indexB = B.Length - 1;
int insertAt = A.Length;
while (indexA > 0 || indexB > 0)
{
insertAt--;
A[insertAt] = max(B[indexB], A[indexA]);
if (A[indexA] <= B[indexB])
indexB--;
else
indexA--;
}

Creating a for-loop that stores values in a new variable

I'm quite new to Matlab so excuse me for the basic question.
I need to make a for-loop that repeats it's self 384 times.
So :
for i=1:384
I now need the for loop to check if 2 certain variables have the value 1 through 10, and then let them store this in a new variable with that value.
So:
if x==1
somevariable = 1
elseif x== 2
saomevariable = 2
..
..
..
elseif y = 1
someothervariable = 1
etc etc.
Is there a way to write this more efficient?
Thank you!
The first think you can do is:
if(x >= 1 && x <= 10)
somevariable=x;
end
if(y >= 1 && y <= 10)
someohtervariable=y;
end
If you could post more information about "x" and "y", perhaps your script can be further "improved".
Hope this helps.

Matlab function calling basic

I'm new to Matlab and now learning the basic grammar.
I've written the file GetBin.m:
function res = GetBin(num_bin, bin, val)
if val >= bin(num_bin - 1)
res = num_bin;
else
for i = (num_bin - 1) : 1
if val < bin(i)
res = i;
end
end
end
and I call it with:
num_bin = 5;
bin = [48.4,96.8,145.2,193.6]; % bin stands for the intermediate borders, so there are 5 bins
fea_val = GetBin(num_bin,bin,fea(1,1)) % fea is a pre-defined 280x4096 matrix
It returns error:
Error in GetBin (line 2)
if val >= bin(num_bin - 1)
Output argument "res" (and maybe others) not assigned during call to
"/Users/mac/Documents/MATLAB/GetBin.m>GetBin".
Could anybody tell me what's wrong here? Thanks.
You need to ensure that every possible path through your code assigns a value to res.
In your case, it looks like that's not the case, because you have a loop:
for i = (num_bins-1) : 1
...
end
That loop will never iterate (so it will never assign a value to res). You need to explicitly specify that it's a decrementing loop:
for i = (num_bins-1) : -1 : 1
...
end
For more info, see the documentation on the colon operator.
for i = (num_bin - 1) : -1 : 1