How to find the row rank of matrix in Galois fields? - matlab

Matlab has a built-in function for calculating rank of a matrix with decimal numbers as well as finite field numbers. However if I am not wrong they calculate only the lowest rank (least of row rank and column rank). I would like to calculate only the row rank, i.e. find the number of independent rows of a matrix (finite field in my case). Is there a function or way to do this?

In linear algebra the column rank and the row rank are always equal (see proof), so just use rank
(if you're computing the the rank of a matrix over Galois fields, consider using gfrank instead, like #DanBecker suggested in his comment):
Example:
>> A = [1 2 3; 4 5 6]
A =
1 2 3
4 5 6
>> rank(A)
ans =
2
Perhaps all three columns seem to be linearly independent, but they are dependent:
[1 2; 4 5] \ [3; 6]
ans =
-1
2
meaning that -1 * [1; 4] + 2 * [2; 5] = [3; 6]

Schwartz,
Two comments:
You state in a comment "The rank function works just fine in Galois fields as well!" I don't think this is correct. Consider the example given on the documentation page for gfrank:
A = [1 0 1;
2 1 0;
0 1 1];
gfrank(A,3) % gives answer 2
rank(A) % gives answer 3
But it is possible I am misunderstanding things!
You also said "How to check if the rows of a matrix are linearly independent? Does the solution I posted above seem legit to you i.e. taking each row and finding its rank with all the other rows one by one?"
I don't know why you say "find its rank with all the other rows one by one". It is possible to have a set of vectors which are pairwise linearly independent, yet linearly dependent taken as a group. Just consider the vectors [0 1], [1 0], [1 1]. No vector is a multiple of any other, yet the set is not linearly independent.
Your problem appears to be that you have a set of vector that you know are linearly independent. You add a vector to that set, and want to know whether the new set is still linearly independent. As #EitanT said, all you need to do is combine the (row) vectors into a matrix and check whether its rank (or gfrank) is equal to the number of rows. No need to do anything "one-by-one".
Since you know that the "old" set is linearly independent, perhaps there is a nice fast algorithm to check whether the new vector makes thing linearly dependent. Maybe at each step you orthogonalize the set, and perhaps that would make the process of checking for linear independence given the new vector faster. That might make an interesting question somewhere like mathoverflow.

Related

Is there anyway to generate two vectors whose correlation are very different in Matlab?

if I have vectorA = [1 1 -1]; and vectorB = [-1 -1 1], and vectorC = [1 1 -1]
Correlation means the similarity of two vectors.
So Correlation(vectorA,vectorB) = vectorA*vectorB = -3
Correlation(vectorA,vectorC) = 3;
That means vectorA and vectorC are similar because the correlation is high enough.
and correlation of vectorA and vectorB are more different because the correlation is low enough.
My trouble is How can I generate SIX vectors and their correlation is low enough?That means I want these two vectors so different in every element of vector.
Is there any wise way to generate or somehow? Thanks everyone.
PS: elements in vector are all +1 or -1.
If you define correlation as the Dot Product between 2 vectors then the definition is equivalent to Orthogonality of the Vectors.
In your case, your space is R ^ 3, which means you can not find more than 3 vectors which are Orthogonal to each other (Namely, has no correlation).
If you need 6 which has the lowest correlation, well it is all about their direction.
Since the direction is the issue, let's assume all of them are normalized of have a norm of 1.
Then think about the Unit Circle and just divide it into 6 direction which the angle between them is equal, just like you'd slice a Pizza.

Need alternative to randsample for probability vectors with 0s in MATLAB

I have a question similar to this one:
Weighted random numbers in MATLAB
At this point, I use randsample in my program as follows:
T = [0 .5 .5; .5 0 .5; .5 .5 0]
choices = 1:3
for i = 1:3
t(i) = transpose(randsample(choices,1,true,T(i,:)));
end
Thus t(i) describes for each person which neighbor they will select.
My T matrix, when read rowwise describes the probability of a person to select their neighbor. For example, the first row says the 1st person will select node 2 or 3 with 50% probability each. They cannot select his own node 1. As I scale up my model, they will always have equal probability of selecting a neighbor, 1/number of neighbors. I have hardcoded the T matrix here for brevity's sake.
I tried to use histc as suggested in the linked topic, but since there is always a 0 in each row of my T matrix, I don't think the cumulative sum accurately sets up bins for rows with a 0 in the middle (here the second row of T).
I also tried to use bsxfun, and I was able to get sensical output when looking at each row of my T matrix individually, but I failed to put it in a loop. I feel the solution may be here, but I'm not sure I fully understand how this function is operating in my context.
So, does anybody have any ideas of how I can speed up my randsample function? At the moment, I iterate it 10000x, and so it is a major bottleneck in my program. It works as I need it to, it's just far too slow.
So you want, for each person, to pick a neighbour among all other persons, with uniform probability.
I would do it this way. It should be pretty fast.
n = 7; %// number of persons
t = ceil((n-1)*rand(1,n)); %// step 1
t = t + (t>=(1:n)); %// step 2
For each k, the generated t(k) is randomly picked from the set {1, 2, ..., k-1, k+1, ..., n} with uniform distribution. To achieve this, two steps are used:
A random value is picked from {1, ..., n-1};
If this value is greater than or equal to k it is incremented by 1.

Is there overhead of accessing elements in a sparse matrix

Let's say I have a sparse matrix A. I want to do heavy calculations on it. The calculations do not modify A, only accessing its elements e.g. take a row of A then multiply with something. I wonder whether I should convert A to a full matrix before doing any calculation, or just do it directly?
In other words, is accessing elements in a sparse matrix slower than a full matrix?
Slicing sparse matrices across columns is much faster than slicing across rows in MATLAB. So you should prefer accessing M(:,i) over M(i,:).
Internally MATLAB uses the Compressed Sparse Column (CSC) storage:
the non-zero elements are stored in a 1-D double array of length nzmax arranged in column-major order (pr for real part and pi for imaginary part if matrix is complex)
ir an array of integers with corresponding row indices
jc an integer array of length n+1 (where n is the number of columns) containing column index information. By definition, the last value of jc contains nnz (number of non-zeros stored).
As an example, take the following sparse matrix:
>> M = sparse([1 3 5 3 4 1 5], [1 1 1 2 2 4 4], [1 7 5 3 4 2 6], 5, 4);
This is what it looks like stored in memory (I'm using 0-based indices for ir and jc):
1 . . 2
. . . .
7 3 . .
. 4 . .
5 . . 6
pr = 1 7 5 3 4 2 6
ir = 0 2 4 2 3 0 4
jc = 0 3 5 5 7
nzmax = at least 7
nnz = 7
m = 5
n = 4
To retrieve the i-th column of the sparse matrix M(:,i), it suffices to do: pr(jc(i):jc(i+1)-1) (to keep it simple, I'm not paying attention to 0- vs 1-based indexing). On the other hand, accessing a matrix row involves more calculations and array traversals (it is no longer spatial-locality friendly).
Here are some links to the MATLAB documentation for more info: Sparse Matrices, Manipulating Sparse Matrices
It's worth checking out the original paper by John R. Gilbert, Cleve Moler, and Robert Schreiber: "Sparse Matrices In Matlab: Design and Implementation", (SIAM Journal on Matrix Analysis and Applications , 13:1, 333–356 (1992)).
Here are some quotes from the above paper to answer your question about the overhead of sparse storage:
The computational complexity of simple array operations should be
proportional to nnz, and perhaps also depend linearly on m or n,
but be independent of the product m*n. The complexity of more
complicated operations involves such factors as ordering and fill-in,
but an objective of a good sparse matrix algorithm should be:
The time required for a sparse matrix operation should be proportional
to number of arithmetic operations on nonzero quantities.
We call this the "time is proportional to flops" rule; it is a
fundamental tenet of our design.
and
This (column-oriented sparse matrix) scheme is not efficient
for manipulating matrices on element at a time: access to a single
element takes time at least proportional to the logarithm of the
length of its column; inserting or removing a nonzero may require
extensive data movement. However, element-by-element manipulation is
rare in MATLAB (and is expensive even in full MATLAB). Its most common
application would be to create a sparse matrix, but this is more
efficiently done by building a list [i,j,s] of matrix elements in
arbitrary order and then using sparse(i,j,s) to create the matrix.
The sparse data structure is allowed to have unused elements after the
end of the last column of the matrix. Thus an algorithm that builds up
a matrix one column at a time can be implemented efficiently by
allocating enough space for all the expected nonzeros at the outset.
Also section 3.1.4 "asymptotic complexity analysis" should be of interest (it's too long to quote here).

Finding proportional columns in matrix

I have a big matrix (1,000 rows and 50,000 columns). I know some columns are correlated (the rank is only 100) and I suspect some columns are even proportional. How can I find such proportional columns? (one way would be looping corr(M(:,j),M(:,k))), but is there anything more efficient?
If I am understanding your problem correctly, you wish to determine those columns in your matrix that are linearly dependent, which means that one column is proportional or a scalar multiple of another. There's a very basic algorithm based on QR Decomposition. For QR decomposition, you can take any matrix and decompose it into a product of two matrices: Q and R. In other words:
A = Q*R
Q is an orthogonal matrix with each column as being a unit vector, such that multiplying Q by its transpose gives you the identity matrix (Q^{T}*Q = I). R is a right-triangular or upper-triangular matrix. One very useful theory by Golub and Van Loan in their 1996 book: Matrix Computations is that a matrix is considered full rank if all of the values of diagonal elements of R are non-zero. Because of the floating point precision on computers, we will have to threshold and check for any values in the diagonal of R that are greater than this tolerance. If it is, then this corresponding column is an independent column. We can simply find the absolute value of all of the diagonals, then check to see if they're greater than some tolerance.
We can slightly modify this so that we would search for values that are less than the tolerance which would mean that the column is not independent. The way you would call up the QR factorization is in this way:
[Q,R] = qr(A, 0);
Q and R are what I just talked about, and you specify the matrix A as input. The second parameter 0 stands for producing an economy-size version of Q and R, where if this matrix was rectangular (like in your case), this would return a square matrix where the dimensions are the largest of the two sizes. In other words, if I had a matrix like 5 x 8, producing an economy-size matrix will give you an output of 5 x 8, where as not specifying the 0 will give you an 8 x 8 matrix.
Now, what we actually need is this style of invocation:
[Q,R,E] = qr(A, 0);
In this case, E would be a permutation vector, such that:
A(:,E) = Q*R;
The reason why this is useful is because it orders the columns of Q and R in such a way that the first column of the re-ordered version is the most probable column that is independent, followed by those columns in decreasing order of "strength". As such, E would tell you how likely each column is linearly independent and those "strengths" are in decreasing order. This "strength" is exactly captured in the diagonals of R corresponding to this re-ordering. In fact, the strength is proportional to this first element. What you should do is check to see what diagonals of R in the re-arranged version are greater than this first coefficient scaled by the tolerance and you use these to determine which of the corresponding columns are linearly independent.
However, I'm going to flip this around and determine the point in the R diagonals where the last possible independent columns are located. Anything after this point would be considered linearly dependent. This is essentially the same as checking to see if any diagonals are less than the threshold, but we are using the re-ordering of the matrix to our advantage.
In any case, putting what I have mentioned in code, this is what you should do, assuming your matrix is stored in A:
%// Step #1 - Define tolerance
tol = 1e-10;
%// Step #2 - Do QR Factorization
[Q, R, E] = qr(A,0);
diag_R = abs(diag(R)); %// Extract diagonals of R
%// Step #3 -
%// Find the LAST column in the re-arranged result that
%// satisfies the linearly independent property
r = find(diag_R >= tol*diag_R(1), 1, 'last');
%// Step #4
%// Anything after r means that the columns are
%// linearly dependent, so let's output those columns to the
%// user
idx = sort(E(r+1:end));
Note that E will be a permutation vector, and I'm assuming you want these to be sorted so that's why we sort them after the point where the vectors fail to become linearly independent anymore. Let's test out this theory. Suppose I have this matrix:
A =
1 1 2 0
2 2 4 9
3 3 6 7
4 4 8 3
You can see that the first two columns are the same, and the third column is a multiple of the first or second. You would just have to multiply either one by 2 to get the result. If we run through the above code, this is what I get:
idx =
1 2
If you also take a look at E, this is what I get:
E =
4 3 2 1
This means that column 4 was the "best" linearly independent column, followed by column 3. Because we returned [1,2] as the linearly dependent columns, this means that columns 1 and 2 that both have [1,2,3,4] as their columns are a scalar multiple of some other column. In this case, this would be column 3 as columns 1 and 2 are half of column 3.
Hope this helps!
Alternative Method
If you don't want to do any QR factorization, then I can suggest reducing your matrix into its row-reduced Echelon form, and you can determine the basis vectors that make up the column space of your matrix A. Essentially, the column space gives you the minimum set of columns that can generate all possible linear combinations of output vectors if you were to apply this matrix using matrix-vector multiplication. You can determine which columns form the column space by using the rref command. You would provide a second output to rref that gives you a vector of elements that tell you which columns are linearly independent or form a basis of the column space for that matrix. As such:
[B,RB] = rref(A);
RB would give you the locations of which columns for the column space and B would be the row-reduced echelon form of the matrix A. Because you want to find those columns that are linearly dependent, you would want to return a set of elements that don't contain these locations. As such, define a linearly increasing vector from 1 to as many columns as you have, then use RB to remove these entries in this vector and the result would be those linearly dependent columns you are seeking. In other words:
[B,RB] = rref(A);
idx = 1 : size(A,2);
idx(RB) = [];
By using the above code, this is what we get:
idx =
2 3
Bear in mind that we identified columns 2 and 3 to be linearly dependent, which makes sense as both are multiples of column 1. The identification of which columns are linearly dependent are different in comparison to the QR factorization method, as QR orders the columns based on how likely that particular column is linearly independent. Because columns 1 to 3 are related to each other, it shouldn't matter which column you return. One of these forms the basis of the other two.
I haven't tested the efficiency of using rref in comparison to the QR method. I suspect that rref does Gaussian row eliminations, where the complexity is worse compared to doing QR factorization as that algorithm is highly optimized and efficient. Because your matrix is rather large, I would stick to the QR method, but use rref anyway and see what you get!
If you normalize each column by dividing by its maximum, proportionality becomes equality. This makes the problem easier.
Now, to test for equality you can use a single (outer) loop over columns; the inner loop is easily vectorized with bsxfun. For greater speed, compare each column only with the columns to its right.
Also to save some time, the result matrix is preallocated to an approximate size (you should set that). If the approximate size is wrong, the only penalty will be a little slower speed, but the code works.
As usual, tests for equality between floating-point values should include a tolerance.
The result is given as a 2-column matrix (S), where each row contains the indices of two rows that are proportional.
A = [1 5 2 6 3 1
2 5 4 7 6 1
3 5 6 8 9 1]; %// example data matrix
tol = 1e-6; %// relative tolerance
A = bsxfun(#rdivide, A, max(A,[],1)); %// normalize A
C = size(A,2);
S = NaN(round(C^1.5),2); %// preallocate result to *approximate* size
used = 0; %// number of rows of S already used
for c = 1:C
ind = c+find(all(abs(bsxfun(#rdivide, A(:,c), A(:,c+1:end))-1)<tol));
u = numel(ind); %// number of columns proportional to column c
S(used+1:used+u,1) = c; %// fill in result
S(used+1:used+u,2) = ind; %// fill in result
used = used + u; %// update number of results
end
S = S(1:used,:); %// remove unused rows of S
In this example, the result is
S =
1 3
1 5
2 6
3 5
meaning column 1 is proportional to column 3; column 1 is proportional to column 5 etc.
If the determinant of a matrix is zero, then the columns are proportional.
There are 50,000 Columns, or 2 times 25,000 Columns.
It is easiest to solve the determinant of a 2 by 2 matrix.
Hence: to Find the proportional matrix, the longest time solution is to
define the big-matrix on a spreadsheet.
Apply the determinant formula to a square beginning from 1st square on the left.
Copy it for every row & column to arrive at the answer in the next spreadsheet.
Find the Columns with Determinants Zero.
This is Quite basic,not very time consuming and should be result oriented.
Manual or Excel SpreadSheet(Efficient)

Calculating standard deviation using data points and count vector in Matlab

I want to use Matlab to calculate the standard deviation of a population I have compiled.
The matlab function takes as input one large population vector and outputs the standard dev.
However, for optimisation purposes, instead of one large vector, I have a set of individual data points, and the number of times each point is used.
I could use a loop and create a huge population vector, but it's not ideal.
How could I go about this?
Very easy from the definition of standard deviation: just introduce weights to account for the number of repetitions of each data point:
data = [1 3 4 2 4]; %// data values
count = [4 5 4 5 8]; %// number of times for each value
mu = sum(data.*count)./(sum(count));
dev = sqrt(sum((data-mu).^2.*count)./(sum(count)-1)); %// or ./sum(count)