EIGEN : Sparse matrix multiplication not producing a pruned result - visual-studio-2013

I'm using EIGEN for the sparse matrix optimizations and functions. Everything is "working" fine, except in some case and I can't figure this case out.
Here is the thing :
Matrix A
2 0 0
0 2 0
0 0 2
Matrix B
6 3
0 1
2 8
Result
12 6
0 2
4 16
As you can see, this is the right result, and I'm always having the right result.
The problem is about the values considered as "Non Zero". In this case :
SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = A*B;
result.pruned();
cout << result.nonZeros();
The result of nonZeros() is 5, which is the "normal" case, since Result got only 5 non Zero values.
Now, let's consider this code :
SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = (A*B).pruned();
cout << result.nonZeros();
The result of nonZeros() is 6. I do not understand why, this is the syntax available on the documentation.
And now the strangest part is that on very large matrix result = A*B; result.pruned() is sometimes ALSO saving 0 as nonZero, but less than if I used (A*B).pruned();
I got three questions :
Why are result = (A*B).pruned() and result=A*B;result.pruned(); giving different results concerning nonZero values (and not effective result, which is right in both case)?
Why are 0 values from a product sometimes not considered as Zero Values?
Are you having the same result than me?
I'm using Visual Studio Professional 2013 and Eigen 3.3.2, using DEBUG mode and targeting WIN32.
Thanks for your help.
EDIT : Benchmark of sparse multiplication with VS2013, DEBUG/Release mode for W32 (With or without SSE2 instruction set, same results in both case); the result is always the right one so i'm not pasting it here, it's not bringing any information. With :
1 = SparseMatrix<int, RowMajor> resultA = A*B;
2 = SparseMatrix<int, RowMajor> resultB = (A*B);resultB.pruned();
3 = SparseMatrix<int, RowMajor> resultC = (A*B).pruned();
Case 1
Matrix A
2 0 0
0 2 0
0 0 2
Matrix B
5 3
0 1
2 8
Expected value = 5
1 = 5
2 = 5
3 = 6
Case 2
Matrix are too large, here is the file
Expected value = 0
1 = 1444
2 = 1444
3 = 0
As you can see, depending both on the input and the way I'm calling functions, the result is optimized or not, and none of 1, 2 or 3 are working in every case.
EDIT² : Problem fixed by ggael solution (thanks).

My previous answer (below) was wrong. Problem fixed there.
This is because you are targeting win32 and thus you are hitting
classical issues with the extended precision of the FPU registers. By
default, pruned remove entries that are strictly equal to 0, but
with the FPU, it could be that a non zero becomes zero only after
being copied from its register to memory. Update your compiler flags
to either target SSE2 instruction set, or to kill the extra FPU
precision.

Related

Decomposing uint32s into uint8s in a large matrix

For a project I am working on, I am loading in large image files, which Matlab inputs as LxWx3 arrays of uint8s. I have a function which concatenates these component-wise into a LxWx1 array of uint32s, but I can't find a way to do the reverse without using nested for loops, which is far too slow for the matrices I am working with.
Could anyone recommend a way to accomplish this effuciently? Basically, given a LxW Matrix of uint32s, I want to return a LxWx3 matrix of uint8s, where the (x, y,1:3) components are the three most significant bytes in the corresponding uint32.
You can do that with typecast:
A = uint32([2^16 2^30; 256 513]);
B = permute(reshape(typecast(A(:), 'uint8'), [], size(A,1), size(A,2)), [2 3 1]);
B = flipdim(B, 3); %// flip 3rd dim to bring MSB first, if needed (depends on computer)
B = B(:,:,2:4);
Example: for A = uint32([2^16 2^30; 256 513]);
A =
65536 1073741824
256 513
the result is
B(:,:,1) =
1 0
0 0
B(:,:,2) =
0 0
1 2
B(:,:,3) =
0 0
0 1

Fast matrix Exponentiation computation in Galois field

I am looking for a fast way to compute power of matrix A in galois field 2 (GF(2)). A is a double matrix and its exponentiation of x denoted by
A^x = A * A * A * ... * A (x times)
The simple way is that converts A to GF(2) (because given matrix A is double matrix) and then peform exponentiation operation.
Matlab code
A1 = gf(A, 2) % // convert to galois field
A_pow_x_first = A1^x; % // Perform A^x
However, this way takes long time to converts matrix A to GF(2). I am looking for a fast way without GF(2) converting. That is, I using mod operation
A_pow_x_second = mod(A^x, 2)
However, the problem is that the result of first way and second way are not similar. The problem is that overflow of number. Some member suggested to me convert matrix A to int64. However, I think it is not good way to handle with my problem. Could you suggest to me a fast way to do it in matlab? Thanks in advance
This is simple example
>> A = [1 0 1
0 1 1
1 1 1]
First way,
>> A_pow_x_first = gf(A, 2)^50
Result:
0 1 0
1 0 0
0 0 1
Second way
>> A_pow_x_second = mod(A^50, 2)
A_pow_x_second =
0 0 0
0 0 0
0 0 0
How to fast compute A^x without convert to GF(2) that has similar result in first way?

Converting a number into a special base system

I want to convert a number in base 10 into a special base form like this:
A*2^2 + B*3^1 + C*2^0
A can take on values of [0,1]
B can take on values of [0,1,2]
C can take on values of [0,1]
For example, the number 8 would be
1*2^2 + 1*3 + 1.
It is guaranteed that the given number can be converted to this specialized base system.
I know how to convert from this base system back to base-10, but I do not know how to convert from base-10 to this specialized base system.
In short words, treat every base number (2^2, 3^1, 2^0 in your example) as weight of an item, and the whole number as the capacity of a bag. This problem wants us to find a combination of these items which they fill the bag exactly.
In the first place this problem is NP-complete. It is identical to the subset sum problem, which can also be seen as a derivative problem of the knapsack problem.
Despite this fact, this problem can however be solved by a pseudo-polynomial time algorithm using dynamic programming in O(nW) time, which n is the number of bases, and W is the number to decompose. The details can be find in this wikipedia page: http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming and this SO page: What's it called when I want to choose items to fill container as full as possible - and what algorithm should I use?.
Simplifying your "special base":
X = A * 4 + B * 3 + C
A E {0,1}
B E {0,1,2}
C E {0,1}
Obviously the largest number that can be represented is 4 + 2 * 3 + 1 = 11
To figure out how to get the values of A, B, C you can do one of two things:
There are only 12 possible inputs: create a lookup table. Ugly, but quick.
Use some algorithm. A bit trickier.
Let's look at (1) first:
A B C X
0 0 0 0
0 0 1 1
0 1 0 3
0 1 1 4
0 2 0 6
0 2 1 7
1 0 0 4
1 0 1 5
1 1 0 7
1 1 1 8
1 2 0 10
1 2 1 11
Notice that 2 and 9 cannot be expressed in this system, while 4 and 7 occur twice. The fact that you have multiple possible solutions for a given input is a hint that there isn't a really robust algorithm (other than a look up table) to achieve what you want. So your table might look like this:
int A[] = {0,0,-1,0,0,1,0,1,1,-1,1,1};
int B[] = {0,0,-1,1,1,0,2,1,1,-1,2,2};
int C[] = {0,1,-1,0,2,1,0,1,1,-1,0,1};
Then look up A, B, C. If A < 0, there is no solution.

fortran library for sparse matrix multiplication

I have a large matrix which I have stored in the following format, given the matrix A;
A =
1 0 3
5 1 -2
0 0 7
3 vectors;
NVPN = [1 3 4 7] - I arbitrarily put a 1 in the first column, then from the second onwards it is a cumulatively summing the number of non-zero elements per column.
NNVI = [1 2 2 1 2 3] - row index of each non-zero element.
CONT = [1 5 1 3 -2 7] - value of each non-zero element.
I now need to perform matrix*matrix multiplication and matrix*vector multiplication. Does anyone know if the are any FORTRAN libraries, which I can amend to fit my problem, to do this above?
Thanks in advance
The MATMUL function allows you to perform matrix products, which is defined in the section 13.7.70 of the FORTRAN 90 standard. See also: GCC reference.
There is already a topic on sparse matrix libraries here.

Form a Matrix From a Large Text File Quickly

Hi I am struggling with reading data from a file quickly enough. ( Currently left for 4hrs, then crashed) must be a simpler way.
The text file looks similar like this:
From To
1 5
3 2
2 1
4 3
From this I want to form a matrix so that there is a 1 in the according [m,n]
The current code is:
function [z] = reed (A)
[m,n]=size(A);
i=1;
while (i <= n)
z(A(1,i),A(2,i))=1;
i=i+1;
end
Which output the following matrix, z:
z =
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
My actual file has 280,000,000 links to and from, this code is too slow for this size file. Does anybody know a much faster was to do this in matlab?
thanks
You can do something along the lines of the following:
>> A = zeros(4,5);
>> B = importdata('testcase.txt');
>> A(sub2ind(size(A),B.data(:,1),B.data(:,2))) = 1;
My test case, 'testcase.txt' contains your sample data:
From To
1 5
3 2
2 1
4 3
The result would be:
>> A
A =
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
EDIT - 1
After taking a look at your data, it seems that even if you modify this code appropriately, you may not have enough memory to execute it as the matrix A would become too large.
As such, you can use sparse matrices to achieve the same as given below:
>> B = importdata('web-Stanford.txt');
>> A = sparse(B.data(:,1),B.data(:,2),1,max(max(B.data)),max(max(B.data)));
This would be the approach I'd recommend as your A matrix will have a size of [281903,281903] which would usually be too large to handle due to memory constraints. A sparse matrix on the other hand, maintains only those matrix entries which are non-zero, thus saving on a lot of space. In most cases, you can use sparse matrices more-or-less as you use normal matrices.
More information about the sparse command is given here.
EDIT - 2
I'm not sure why it isn't working for you. Here's a screenshot of how I did it in case that helps:
EDIT - 3
It seems that you're getting a double matrix in B while I'm getting a struct. I'm not sure why this is happening; I can only speculate that you deleted the header lines from the input file before you used importdata.
Basically it's just that my B.data is the same as your B. As such, you should be able to use the following instead:
>> A = sparse(B(:,1),B(:,2),1,max(max(B)),max(max(B)));

Resources