The best I could handle was using accelerated loop logic. Combined with the ability to use the Non-Zero approach as described by themis, you can answer your question by checking out less than 2% of the N ^ 2 problem.
Below is the code that gives time for numbers from 80% to 99%. When numbers go around 88% of zero, using themis switches is “better” (however, it was not encoded in the example below).
This is not a very theoretical solution, but it is practical.
OK, here is some “theory” of the problem space:
In principle, each bit for X (output) is the sum of the OR bits on the diagonal of the grid constructed using bits A along the top (from MSB to LSB from left to right) and bits B along (from MSB to LSB from top to bottom). Since bit X is 1, if any of the diagonal is 1, you can perform an early exit to bypass the cell.
The code below shows that even for numbers equal ~ 87% zero, you only need to check ~ 2% of the cells. For more dense (more than 1) numbers, this percentage drops even more.
In other words, I would not worry about complex algorithms and just conduct an effective logic check. I think the trick is to look at the bits of your output as a diagonal of the grid, and not at bits A shift-OR with bits B. The most difficult thing in this case is tracking the bits you can see at at and B and how index bits correctly.
Hope this makes sense. Let me know if I need to explain this a bit more (or if you have any problems with this approach).
NOTE. If we knew your problem space a little better, we could optimize the algorithm accordingly. If your numbers are mostly non-zero, then this approach is better than themis, as the result is more computation and the required storage space (sizeof (int) * NNZ).
NOTE 2: This assumes that the data is mostly bits, and I use the .NET BitArray to store and access the data. I do not think that this can cause serious headaches when translated into other languages. The basic idea is still being applied.
using System; using System.Collections; namespace BigIntegerOr { class Program { private static Random r = new Random(); private static BitArray WeightedToZeroes(int size, double pctZero, out int nnz) { nnz = 0; BitArray ba = new BitArray(size); for (int i = 0; i < size; i++) { ba[i] = (r.NextDouble() < pctZero) ? false : true; if (ba[i]) nnz++; } return ba; } static void Main(string[] args) {