I am trying to find the fib sequence using recursion but my function keeps giving me an error.
function y = r_nFib(seq, n)
y = zeros(1,n);
for m = 1:n
y(m) = r_nFib(m);
end
if seq == 0
y = [0 y];
else
y = [seq, seq, y];
function y = r_nFib(seq, n)
if n<3
y(1:n) = 1;
else
y(n) = r_nFib(n-2) + r_nFib(n-1);
end
y = y(n);
end
end
n is the length of the fib sequence and seq is the starting number. If seq is 0 then this is how the sequence is going to start
y = [0 1 1 2 3 5 8] % first two number will be the 0 and 1
if seq is any thing other than 0, then
if seq = 2;
y = [2 2 4 6 10] % first two number will be the seq
How do I correct my function to give me the right answer. I have never used recursion and I am new to it. Any help would be really appreciated.
y = r_nFib(4,10)
y = [4 4 8 12 20 32 52 84 136 220];
Thank you.
function y = r_nFib(seq, n)
if length(seq) == 1
if seq == 0
seq = [0, 1];
else
seq = [seq, seq];
end
end
if length(seq) >= n
y = seq;
else
y = r_nFib([seq (seq(end - 1) + seq(end))], n);
end
Here is a solution that I typed up for matlab, explaining recursion:
A recursive method works by breaking a larger problem into smaller problems each time the method is called. This allows you to break what would be a difficult problem; a factorial summation, into a series of smaller problems.
Each recursive function has 2 parts:
1) The base case: The lowest value that we care about evaluating. Usually this goes to zero or one.
if (num == 1)
out = 1;
end
2) The general case: The general case is what we are going to call until we reach the base case. We call the function again, but this time with 1 less than the previous function started with. This allows us to work our way towards the base case.
out = num + factorial(num-1);
This statement means that we are going to firstly call the function with 1 less than what this function with; we started with three, the next call starts with two, the call after that starts with 1 (Which triggers our base case!)
Once our base case is reached, the methods "recurse-out". This means they bounce backwards, back into the function that called it, bringing all the data from the functions below it!It is at this point that our summation actually occurs.
Once the original function is reached, we have our final summation.
For example, let's say you want the summation of the first 3 integers.
The first recursive call is passed the number 3.
function [out] = factorial(num)
%//Base case
if (num == 1)
out = 1;
end
%//General case
out = num + factorial(num-1);
Walking through the function calls:
factorial(3); //Initial function call
//Becomes..
factorial(1) + factorial(2) + factorial(3) = returned value
This gives us a result of 6!
matlab - Clearer explanation of recursion
Related
This is my first stab at machine learning, and I can implement the code anyway that I want. I have Matlab access, which I think will be simpler than Python, and I have pseudo code for implementing a PLA. The last part of the code, however, absolutely baffles me, though it is simpler than the code I have seen on here thus far. It seems to be calling for the use of variables not declared. Here's what I have. I'll point out the number line at which I get stuck.
1) w <- (n + 1) X m (matrix of small random nums)
2) I <- I augmented with col. of 1s
3) for 1 = 1 to 1000
4) delta_W = (N + 1) X m (matrix of zeros) // weight changes
5) for each pattern 1 <= j <= p
6) Oj = (Ij * w) > 0 // j's are subscript/vector matrix product w/ threshold
7) Dj = = Tj - Oj // diff. between target and actual
8) w = w + Ij(transpose)*Dj // the learning rule
Lines 1 thru 4 are coded.
My questions are on line 5: What does "for each pattern mean" (i.e., how does one say it in code). Also, which j are they interested in, I have a j in the observation matrix and a j in the target matrix. Also, where did "p" come from (I have i's, j's, m's and n's but no p's)? Any thoughts would be appreciated.
"for each pattern" refers to the inputs. All they are saying is to run that loop where Ij is the input to the perceptron.
To write this in MATLAB, it really depends on how your data is oriented. I would store your inputs as a mXn matrix, where m is the number of inputs and n is the size of each input.
Say our inputs look like :
input = [1 5 -1;
2 3 2;
4 5 6;
... ]
First 'augment' this with a column of ones for the bias input:
[r c] = size(input);
input = [input ones(r,1)];
Then, your for loop will simply be:
for inputNumber = 1:r
pattern = input(inputNumber,:);
and you can continue from there.
I am trying to implement a recursive function to add the odd numbers in a vector v.
So far this is my attempt
function result = sumOdd(v)
%sum of odd numbers in a vector v
%sumOdd(v)
n = 1;
odds = [];
if length(v) > 0
if mod(v(n),2) == 1
odds(n) = v(n);
v(n) = [];
n = n + 1;
sumOdd(v)
elseif mod(v(n),2) == 0
v(n) = [];
n = n + 1;
sumOdd(v)
end
else
disp(sum(odds))
end
end
This does not work and returns a value of zero. I am new to programming and recursion and would like to know what I'm doing wrong.
Thank you.
There is a better way to solve this in MATLAB:
function result=summOdd(v)
odd_numbers=v(mod(v,2)); % Use logical indexing to get all odd numbers
result=sum(odd_numbers); % Summ all numbers.
end
To give a recursive solution:
When implementing a recursive function, there is a pattern you should always follow. First start with the trivial case, where the recursion stops. In this case, the sum of an empty list is 0:
function result = sumOdd(v)
%sum of odd numbers in a vector v
%sumOdd(v)
if length(v) == 0
result=0;
else
%TBD
end
end
I always start this way to avoid infinite recursions when trying my code. Where the %TBD is placed you have to put your actual recursion. In this case your idea was to process the first element and put all remaining into the recursion. First write a variable s which contains 0 if the first element is even and the first element itself when it is odd. This way you can calculate the result using result=s+sumOdd(v)
function result = sumOdd(v)
%sum of odd numbers in a vector v
%sumOdd(v)
if length(v) == 0
result=0;
else
if mod(v(1),2) == 1
s=v(1);
else
s=0;
end
v(1) = [];
result=s+sumOdd(v);
end
end
Now having your code finished, read the yellow warning the editor gives to you, it tells you to replace length(v) == 0 with isempty(v).
Instead of keeping 'n', you can always delete the first element of v. Also, you need to pass 'odds' as an argument, as you're initializing it as an empty array at each time you call the function (hence the zero output).
The following example seems to do the job:
function result = sumOdd(v,odds)
%sum of odd numbers in a vector v
%sumOdd(v)
if ~isempty(v)
if mod(v(1),2) == 1
odds = [odds;v(1)];
v(1) = [];
sumOdd(v,odds)
elseif mod(v(1),2) == 0
v(1) = [];
sumOdd(v,odds)
end
else
disp(sum(odds))
end
end
I've written a simple function that takes a vector vec, iterates through it, performing an operation whose result is stored in another vector vecRes of same size at same index, and returns vecRes upon completing the loop. Below is function code:
function [ vecRes ] = squareTerms( vec )
vecSize = size(vec);
vecRes = zeros(vecSize);
for i = 1:vecSize
vecRes(i) = vec(i)^2;
end
end
Problem is that it seems to exit too early, after only one iteration in fact as the output appears as:
vecRes = 1 0 0 0 0 0 0 0 0 0
For input:
vec = 1 2 3 4 5 6 7 8 9 10
I can't figure out why it does so. Any help is greatly appreciated.
Size returns 2 values, rows and columns. Probably you are a having a 1xN vector. So size returns [1 N] and your loop runs 1 time.
>>> size ([1 2 3])
>
> ans =
>
> 1 3
>
>>> 1:size ([1 2 3])
>
> ans =
>
> 1
Others have pointed out the problem. My preferred solution in this sort of case is to use numel, i.e.
vecRes = zeros(size(vec));
for i = 1:numel(vec)
vecRes(i) = vec(i) ^ 2;
end
Of course, in this case, vectorisation is better still:
vecRes = vec .^ 2;
Replace
for i = 1:vecSize
with
for i = 1:vecSize(2)
vecSize is an array of numbers, not just a single value. For example, if vec is a 1 by 8 vector, then size(vec) will return [1, 8].
Therefore, your for-loop-statement,
for i = 1:vecSize
, is actually equivalent to something like:
for i = 1:[1, 8]
This doesn't make much sense. There are a number of ways to fix the problem. You could write:
for i = 1:length(vec)
or
for i = 1:numel(vec) % "numel" stands for "number of elements"
If the vector is 1xn instead of nx1, you can write:
for i = 1:size(vec, 2)
Yet another alternative is:
for i = 1:max(vecSize)
However, the most sensible option is not to write the squareTerms function at all and simply write
vecRes = vec.^2;
Note the dot before the caret. vec^2 and vec . ^2 are not the same thing.
If you put a dot before an operator sign, the operation will be performed element-wise. For example,
C = A * B
performs matrix multiplication, but
C = A .* B
will cause the first element of A to by multiplied by the first element of B, and the result will be assigned to the first element of C. Then, the product of the second elements of A and B will be taken, and the result will be stuck in the second element of C, and so on.
vecRes = vec.^2;
So I am very new to Matlab and I have been tasked with implementing LU factorization. I have to do it recursively because we are not allowed to use for loops in our code, and recursion will give us optimal marks. I have written this code. The code works for the first step, and does what it is supposed to, but for the next two steps, the matrix is not modified at all. I have this code:
function[L, U] = myLU(A,B, pos)
%A = Mtrix that becomes U
%B = Matrix that becomes L
tmp_L = B;
[x,y] = size(A);
if pos > x
L = B;
U = A;
return
else
pos %<-- just to see if it iterates through everything
[tmp_U,tmp_L] = elimMat(A,pos);
myLU(tmp_U,tmp_L, pos+1);
end
L = tmp_L;
U = tmp_U;
end
I where elimMat(A, pos) returns the elimination matrix for column pos. as well as another matrix, which will end up being the matrix of multipliers. What i tried doing is then finding the LU factorization of this matrix A. since elimMat returns L and U(this works, if i do it manually it works), i had to make a function that allows me to do it automatically without using a for loop. I thought i would do it recursively. What i ended up doing is adding another variable B to the function so that i can store intermediate values of my matrix obtained in each step and put it all together later.
So here is my question. Am i implementing the recursion wrong? and if i am how can i fix it? The other thing i wanted to ask is how can i implement this so i do not need variable B as an additional imput, and only use the existing variables, or variables previously defined, to find the solution? I would really like only two inputs in my function: The matrix name and the starting index.
here is elimMat if if helps:
function [M,L] = elimMat(A,k)
%find the size of the matrix
[x,y] = size(A);
tmp_mat = zeros(x,y);
%M = The current matrix we are working on for Elimination -> going to
%become U.
%L = The L part of the matrix we are working on. Contains all the
%multipliers. This is going to be our L matrix.
for i = 1:x
mult = A(i,k)/A(k,k);
if i > k
tmp_mat(i,k) = mult;
P = A(k,:)*mult;
A(i,:) = A(i,:)-P;
elseif i == k
tmp_mat(k,k) = 1;
end
end
M = A;
L = tmp_mat;
end
thanks for any feedback you can provide.
Here is the output: WHAT I GET VS what it should be:
[U = VS [U =
1 2 2 1 2 2
0 -4 -6 0 -4 -6
0 -2 -4] 0 0 2
L = VS [L=
1 0 0 1 0 0
4 0 0 4 1 0
4 0 0] 4 0.5 1
As you can see only the first column is changed
You forgot to catch the output of your recursive call:
[tmp_L, tmp_U] = myLU(tmp_U,tmp_L, pos+1);
Matlab passes variables by value, so a function cannot change its input variable itself (ok, it can, but it's tricky and unsafe).
Your original version didn't return the updated matrices, so the outermost function call encountered the myLU() call, let the recursion unfold and finish, and then went on to use tmp_L and tmp_U as returned from the very first call to elimMAT(A,1).
Note that you might want to standardize your functions such that they return U and L in the same order to avoid confusion.
Okay, so I have a script that will produce my vector of repeated integers of a certain interval, but now theres a particular instance where I need to make sure that once it is shuffled, the numbers do not repeat. So for example, I produced a vector of repeating 1-5, 36 times, shuffled. How do I ensure that there are no repeated numbers after shuffling? And to make things even more complex, I need to produce two such vectors that do not ever have the same value at the same index. For example, lets say 1:5 was repeated twice for these vectors, so then this would be what I'm looking for:
v1 v2
4 2
2 4
3 2
5 3
4 5
1 4
5 1
1 5
3 1
2 3
I made that right now by taking an example of 1 vector and just shifting it off by 1 to create another vector that will satisfy the requirements, but in my situation, that wont actually work because I can't have them be systematically dependent like that.
So I tried a recursive technique to make the script start over if the vectors did not make the cut and as expected, that did not go over so well. I hit my maximum recursive iterations and I've realized this is clearly not the way to go. Is there some other alternative?
EDIT:
So I found a way to satisfy some of the conditions I needed above in the following code:
a = nchoosek(1:5,2);
b = horzcat(a(:,2),a(:,1));
c = vertcat(a,b);
cols = repmat(c,9,1);
cols = cols(randperm(180),:);
I just need to find a way to shuffle cols that will also enforce no repeating numbers in columns, such that cols(i,1) ~= cols(i+1,1) and cols(i,2) ~= cols(i+1,2)
This works, but it probably is not very efficient for a large array:
a = nchoosek(1:5, 2);
while (any(a(1: end - 1, 1) == a(2: end, 1)) ...
|| any(a(1: end - 1, 2) == a(2: end, 2)))
random_indices = randperm(size(a, 1));
a = a(random_indices, :);
end
a
If you want something faster, the trick is to logically insert each row in a place where your conditions are satisfied, rather than randomly re-shuffling. For example:
n1 = 5;
n2 = 9;
a = nchoosek(1:n1, 2);
b = horzcat(a(:,2), a(:,1));
c = vertcat(a, b);
d = repmat(c, n2, 1);
d = d(randperm(n1 * n2), :);
% Perform an "insertion shuffle"
for k = 2: n1 * n2
% Grab row k from array d. Walk down the rows until a position is
% found where row k does not repeat with its upstairs or downstairs
% neighbors.
m = 1;
while (any(d(k,:) == d(m,:)) || any(d(k,:) == d(m+1,:)))
m = m + 1;
end
% Insert row k in the proper position.
if (m < k)
ind = [ 1: m k m+1: k-1 k+1: n1 * n2 ];
else
ind = [ 1: k-1 k+1: m k m+1: n1 * n2 ];
end
d = d(ind,:);
end
d
One way to solve this problem is to think both vectors as being created as follows:
For every row of arrays v1 and v2
Shuffle the array [1 2 3 4 5]
Set the values of v1 and v2 at the current row with the first and second value of the shuffle. Both values will always be different.
Code:
s = [1 2 3 4 5];
Nrows = 36;
solution = zeros(Nrows,2);
for k=1:Nrows
% obtain indexes j for shuffling array s
[x,j] = sort(rand(1,5));
%row k takes the first two values of shuffled array s
solution(k,1:2) = s(j(1:2));
end
v1 = solution(:,1);
v2 = solution(:,2);
Main edit: random => rand,
With this method there is no time wasted in re-rolling repeated numbers because the first and second value of shuffling [1 2 3 4 5] will always be different.
Should you need more than two arrays with different numbers the changes are simple.