We denote a(n) as the number of sequence of n values of 0,1 and 2 where the value 0 can't be next to another 0 in the sequence.
For example, we can have (0,1,0,2), but not (0,0,2,1)
Prove by direct proof that a(n) = 2a(n-1) + 2a(n-2) for n ≥ 3
You can construct any such sequence of length n (for n>2) uniquely in one of these four ways:
s(n-1), 1
s(n-1), 2
s(n-2), 1, 0
s(n-2), 2, 0
Where s(n-1) is any such sequence of length n-1 and s(n-2) is any such sequence of length n-2.
Or to put it in words; a sequence of length n (for n>2) can be any sequence of length n-1 followed by a 1 or a 2, or any sequence of length n-2 followed by 1, 0 or 2, 0.
If a(n) is the number of such sequences of length n, this observation immediately gives that a(n) = 2a(n-1) + 2a(n-2) as required.
And for completeness, a(1) = 3 and a(2) = 8.
Related
I have 3 sequences in a cell-array :
S= {'ABC','ACB','AB'}
S{1}='ABC' means A<B<C and have the weights : A:3, B:2, C:1
S{2}='ACB' means A<C<B and have the weights : A:3, C:2, B:1
S{3}='AB' means A<B and have the weights : A:3, B:2
I want to convert each of the strings in the Input_cell into a matrix M[i,j] which has to satisfy those conditions :
M[i,i] =1
M[i,j] = 1/M[j,i]
If S{1}(i)<S{1}(j) then M[i,j]=weight(S{1}(i))/weight(S{1}(j))
For example:
In S{1}= 'ABC' , and weights will be A:3, B:2, C:1
If A<B then M[A,B]=3/2 and M[B,A]=2/3
If B<C then M[B,C]=2/1 and M[C,B]=1/2 ....etc
So the expected matrix for S{1} would be:
A B C
A [1 3/2 3
B 2/3 1 2
C 1/3 1/2 1]
In S{2}='ACB', the weights of ACB will be A:3, C:2, B:1. So the expected matrix of S{2} would be:
A B C
A [1 3 3/2
B 1/3 1 1/2
C 2/3 2 1]
In S{3}='AB', the weights of AB will be A:3, B:2, C:unknown. If there is an unknown value, we will put 1 in the matrix. Such as M[A,C]=M[C,A]=M[B,C]=M[C,B]=1. So the expected matrix of S{3} would be:
A B C
A [1 3/2 1
B 2/3 1 1
C 1 1 1]
How can I input the cell array of strings and convert them into matrices as above ?
This task has 2 parts (for each element of cell array):
1) Get numbers from strings. For example, ACB sequence is transformed to [3, 1, 2], because strength of the first column will be 3, the second 1, the third 2.
2) Create matrix from that array.
1) Check which letter is first and put 3 on the correct place. Then check which is second, put 2. Third, put 1. If there is no number, put nan (= initialize array by nan). If you can have arbitrarily many letters thing works the same, just first figure out how big array you need. But then your 3rd case will cease to work, as it will assume you only have 2 elements and will make 2x2 matrix.
The second part goes like this:
seq=[3,1,2];
M = seq' * (1./seq);
M(isnan(M)) = 1; % all the numbers with nan become 1.
Note that this will have doubles - M=1.5 and 0.3333, not fractions (1/3, 3/2). To represent it as fractions, you will require a bit more work to do it in general. For each element of the matrix, find gcd of the nominator and denominator and divide by it. In this simple case of 3 elements, you simply put nominator and denominator in the matrix with 1 on the diagonal - there are no common divisors.
denominator = repmat(seq, 3, 1);
Given (rectangular) adjacency matrix m, how to construct adjacency list in q language?
In QIdioms wiki I've found solution in the k language which when run through q console with k) command gives me 'vs error:
m:(1 0 1;1 0 1)
k) (^m)_vs &,/m
'vs
Result should be:
0 0 1 1
0 2 0 2
This is what I was able to replicate in q:
k) &,/m
0 2 3 5
q) where raze m
0 2 3 5
k's^ a.k.a. shape verb is missing in q so I just did:
k) (^m)
000b
000b
q) 2 3#0b
000b
000b
Now, since:
q) parse "vs"
k) {x\:y}
I tried unsuccessfully both:
q) (2 3#0b) _vs where raze m
'
q) (2 3#0b) _\: where raze m
'type
Note that QIdioms wiki has q solution for inverse problem: from adj.list to adj.matrix.
You've got errors because original Q idioms are written in k2 - an old version of k which modern kdb+ version don't support. A current version of k is k4 and it's not backwards-compatible with k2.
For instance, X _vs Y where X and Y are integer atoms or lists in old k2 behaved like X vs Y will behave in kdb+ starting from 3.4t 2015.12.13: http://code.kx.com/q/ref/lists/#vs:
Since 3.4t 2015.12.13: For integer types, computes the base representation of Y in the radices X.
Another example. Indeed ^ in k2 was a shape operator, but it is not any longer. In k2 ^m would have returned 2 3 for a matrix m from your example whereas current implementation behaves like q's not null as far as I understand.
Now, back to your original question, "how to construct adjacency list in q language". One way to do it is this:
q)lm:{flip raze(til count x),''where each x}
or
k)lm:{+,/(!#x),''&:'x}
UPDATE: Here's how it works. If we were to build an adjacency list using any "verbose" language we would do something like this:
for i = 0 to <number of rows> - 1 <---- (1)
for j = 0 to <number of columns> - 1 <---- (2)
if M[i;j] <> 0 <---- (3)
print i, j
In an array language like q (1) can be "translated" into til count M because count will return the number of elements at top level, i.e. the number of rows. (2) and (3) combined can be represented by where each M. Indeed, for every row we return positions of non-zero elements. Given an original matrix m we will get:
til count m -> 0 1
where each m -> (0 2; 0 2)
All we need to do is join row and column indexes. We can't use just ,' because it will join 0 with the first 0 2 and 1 with the second 0 2 resulting in (0 0 2; 1 0 2). We need to go one level deeper, joining every element from the left with every element of every element of a nested list (0 2; 0 2) from the right, hence double apostrophes in ,''.
I hope it makes sense now.
Personally, I would not use flip (or + in k), I can't read an adjacency matrix in this form:
0 0 1 1
0 2 0 2
I think this is much more readable:
0 0
0 2
1 0
1 2
But it's up to you of course.
I have a matrix A with integer elements from 0 to N-1.
What I need to get is vector V of length N which for each position "i" will contain number of elements equal to "i" in matrix A.
For example:
N = 6
A:
0 0 1
1 2 3
3 5 0
V:
3 2 1 2 0 1 0
What is the efficient way to do this?
My real matrix is about 10K x 10K elements and N is about 100.
Use v = histc(A(:), 0:(N-1)). To get exactly your result, perform v = v'.
You want to use histc (after reshape to convert to a vector)
n = histc(x,edges) counts the number of values in vector x that fall
between the elements in the edges vector (which must contain
monotonically nondecreasing values). n is a length(edges) vector
containing these counts.
V = histc(reshape(A,1,[]), 0:(N-1) );
I am trying to write a MatLab function to compute Fibonacci numbers. below is what I have but it comes up with an error about F(0).
??? Attempted to access F(0); index must be a positive integer or logical.
Error in ==> fibonacci at 11
F(0) = 0;
How do I tell matlab that the first two values in the array are 0 and 1??
function F = fibonacci( n )
%A fibonacci sequence is where the next term in the series is given by the
%sum of the pervious two terms
%Only valid if n is greater than or equal to 2
if n >= 2 ;
%Make an array with n terms
F = zeros (1,n);
%run a for loop from 2 to n
for i = 2:n;
F(0) = 0;
F(1) = 1;
F(i) = F(i-1) + F(i-2)
end
end
end
Your formatting is a bit off, but it seems like you are assigning a value to the zero-index of an array. As far as I know MatLab uses 1 as the index of the first item in an array.
If you change your if n>=2 to if >=3 and set the 1 and 2 index items instead of the 0 and 1 items you should be well on your way.
See also Is zero based indexing available in MATLAB
MATLAB uses 1-based indexing, which means you should rewrite indices to reflect this shift, by replacing your n variables with n+1. This starts the fibonacci at 0, but indexed to 1, 1 at 2, 1 at 3, 2 at 4, 3 at 5, and so on to your "n"th term, now be indexed at n+1.
A matrix has m rows and n columns (n being a number not exceeding 10), and the nth column contains either 1 or 0 (binary). I want to use this binary as a decision to take out the associated row (if 1, or otherwise if 0). I understand that this can be done through iteration with the use of the IF conditional.
However, this may become impractical with matrices whose number of rows m gets into the hundreds (up to 1000). What other procedures are available?
You can use logical datatypes for indexing. For example,
M =
1 2 0
4 5 1
7 8 0
M = [1 2 0;4 5 1;7 8 0];
v = (M(:,n) == 1);
M(v,2) = 1;
M =
1 2 0
4 1 1
7 8 0
Now you have set all the elements in column 2 to 1 if the corresponding element in column n is true.
Note that the v = (M(:,n) == 1) converts the nth column to a logical vector. You can accomplish the same with v = logical(M(:,n));
I would recommend this blog entry for a detailed look at logical indexing.
Update:
If you want to erase rows, then use:
M(v,:) = [];