boost::compute stream compaction - boost

How to do stream compaction with boost::compute?
E.g. if you want to perform heavy operation only on certain elements in the array. First you generate mask array with ones corresponding to elements for which you want to perform operation:
mask = [0 0 0 1 1 0 1 0 1]
Then perform exclusive scan (prefix sum) of mask array to get:
scan = [0 0 0 0 1 2 2 3 3]
Then compact this array with:
if (mask[i])
inds[scan[i]] = i;
To get final array of compacted indices (inds):
[3 4 6 8]
Size of the final array is scan.last() + mask.last()

#include <boost/compute/algorithm/copy_if.hpp>
using namespace boost::compute;
detail::copy_index_if(mask.begin(), mask.end(), inds.begin(), _1 == 1, queue);

Related

Slice appending not working as intended when generating a binary sequence

I have this piece of code that generate all binary sequences of length n.
so:
allBitsSeqs(2) gives a 1-by-n int slice [[1 1][0 0] [1 0] [0 1]]
Here's the code:
func allBitSeqs(n int) [][]int {
seq := [][]int{{1}, {0}}
for floor := 1; floor < n; floor++ {
remember := [][]int{}
for i := 0; i < len(seq); i++ {
one := append(seq[i], 1)
remember = append(remember, one)
zero := append(seq[i], 0)
remember = append(remember, zero)
}
seq = remember
}
return seq
}
playground link: https://play.golang.org/p/s40RS7qEKfL
problem is, when n = 4 or more, I get:
[[1 1 1 0] [1 1 1 0] [1 1 0 0] [1 1 0 0] [1 0 1 0] [1 0 1 0] [1 0 0 0] [1 0 0 0] [0 1 1 0] [0 1 1 0] [0 1 0 0] [0 1 0 0] [0 0 1 0] [0 0 1 0] [0 0 0 0] [0 0 0 0]]
Notice how they are repeating in pairs.
I have tried some debugging and I think it has something to do with how Go copy its slices when it needs to allocate more space.
A slice is a view of an underlying array. If you have multiple slices working with the same underlying array, you may get unexpected results if you don't know how slices work.
one := append(seq[i], 1)
Say, one is a slice pointing to an array that has the capacity to hold the added element. Something like the following:
[ 1 1 . . . ]
The array capacity is 5, with first two elements set to 1 (slice len=2). When you add another 1, it becomes:
[ 1 1 1 . .]
Then you do the following:
remember = append(remember, one)
With this, you added a slice pointing to the above array, with len=3 and capacity=5.
Then:
zero := append(seq[i], 0)
Remember that seq[i] is still pointing to the same array. Further, seq[i] has len=2. So the array becomes:
[ 1 1 0 . . ]
That is your zero. However, when you add that 0, you also changed the slice one. You end up with both zero and one pointing to [1 1 0 . .].
Long story short: when you assign a slice to a variable, you assign the view to an array. If you modify the contents of the underlying array, the contents of the view also change.
To fix: create a new slice, copy data, and store that copy.

Octave model matrix

Is there a simple (non for loop) way to create a model matrix in Octave. In R i use model.matrix() to do this.
I have this array:
array = [1;2;3;2]
and i need (for regression reasons)
*(model = [1 0 0 0; 0 1 0 1; 0 0 1 0])* EDIT on my side
result is this model (colum 1 is for 1, column 2 for the two's etc.:
model = [1 0 0 ; 0 1 0 ; 0 0 1 ; 0 1 0]
I can do this with a for loop:
model = zeros(4,3);
for i=1:4
model(i,array(i)) = 1;
end
but it would be nice to do this in one step something like:
model = model.matrix(array)
i can than include it in a formula straight away
You need to turn your values into linear indices like so:
octave:1> array = [1 2 3 2];
octave:2> model = zeros ([numel(array) max(array)]);
octave:3> model(sub2ind (size (model), 1:numel(array), array)) = 1
model =
1 0 0
0 1 0
0 0 1
0 1 0
Because your matrix will be very sparse, a possible optimization is to create a sparse matrix instead.
octave:4> sp = sparse (1:numel(array), array, 1, numel (array), max (array))
sp =
Compressed Column Sparse (rows = 4, cols = 3, nnz = 4 [33%])
(1, 1) -> 1
(2, 2) -> 1
(4, 2) -> 1
(3, 3) -> 1
octave:5> full (sp)
ans =
1 0 0
0 1 0
0 0 1
0 1 0
This will take a lot less memory but many functions will be unable to handle them and convert them to a full matrix anyway. So whether this is worth is dependent on what you want to do next.

Coming with a procedure to generate an array with special properties

I have an array of size n. Each element can hold any integer as long as the following properties holds:
1) All elements are non-negative
2) sum(array[0,i+1])<i for 0<=i<n
3) sum(array)=n-1
Let's call such an array a bucket.
I need to come up with a procedure that will generate the next bucket.
We can assume the first bucket is {0,0,0...n-1}
Example: For n=5, some possible combinations are
[0 0 0 0 4]
[0 0 0 1 3]
[0 0 0 2 2]
[0 0 0 3 1]
[0 0 1 2 1]
[0 0 2 1 1]
[0 1 1 1 1]
[0 1 0 0 3]
[0 1 1 0 2]
I'm having trouble coming up with a procedure that hits all the possible combinations. Any hints/tips? (Note I want to generate the next bucket. I'm not looking to print out all possible buckets at once)
You can use a simple backtracking procedure. The idea is to keep track of the current sum and the current index i. This would allow you to express the required constrains.
n = 5
a = [0] * n
def backtrack(i, sum):
if i > 0 and sum > i-1:
return
if i == n:
if sum == n-1:
print(a)
return
for e in range(n-sum):
a[i] = e
backtrack(i + 1, sum+e)
backtrack(0, 0)
test run

Counting subrows in each row of a matrix in Matlab?

I need an algorithm in Matlab which counts how many adjacent and non-overlapping (1,1) I have in each row of a matrix A mx(n*2) without using loops. E.g.
A=[1 1 1 0 1 1 0 0 0 1; 1 0 1 1 1 1 0 0 1 1] %m=2, n=5
Then I want
B=[2;3] %mx1
Specific case
Assuming A to have ones and zeros only, this could be one way -
B = sum(reshape(sum(reshape(A',2,[]))==2,size(A,2)/2,[]))
General case
If you are looking for a general approach that must work for all integers and a case where you can specify the pattern of numbers, you may use this -
patt = [0 1] %%// pattern to be found out
B = sum(reshape(ismember(reshape(A',2,[])',patt,'rows'),[],2))
Output
With patt = [1 1], B = [2 3]
With patt = [0 1], B = [1 0]
you can use transpose then reshape so each consecutive values will now be in a row, then compare the top and bottom row (boolean compare or compare the sum of each row to 2), then sum the result of the comparison and reshape the result to your liking.
in code, it would look like:
A=[1 1 1 0 1 1 0 0 0 1; 1 0 1 1 1 1 0 0 1 1] ;
m = size(A,1) ;
n = size(A,2)/2 ;
Atemp = reshape(A.' , 2 , [] , m ) ;
B = squeeze(sum(sum(Atemp)==2))
You could pack everything in one line of code if you want, but several lines is usually easier for comprehension. For clarity, the Atemp matrix looks like that:
Atemp(:,:,1) =
1 1 1 0 0
1 0 1 0 1
Atemp(:,:,2) =
1 1 1 0 1
0 1 1 0 1
You'll notice that each row of the original A matrix has been broken down in 2 rows element-wise. The second line will simply compare the sum of each row with 2, then sum the valid result of the comparisons.
The squeeze command is only to remove the singleton dimensions not necessary anymore.
you can use imresize , for example
imresize(A,[size(A,1),size(A,2)/2])>0.8
ans =
1 0 1 0 0
0 1 1 0 1
this places 1 where you have [1 1] pairs... then you can just use sum
For any pair type [x y] you can :
x=0; y=1;
R(size(A,1),size(A,2)/2)=0; % prealocarting memory
for n=1:size(A,1)
b=[A(n,1:2:end)' A(n,2:2:end)']
try
R(n,find(b(:,1)==x & b(:,2)==y))=1;
end
end
R =
0 0 0 0 1
0 0 0 0 0
With diff (to detect start and end of each run of ones) and accumarray (to group runs of the same row; each run contributes half its length rounded down):
B = diff([zeros(1,size(A,1)); A.'; zeros(1,size(A,1))]); %'// columnwise is easier
[is js] = find(B==1); %// rows and columns of starts of runs of ones
[ie je] = find(B==-1); %// rows and columns of ends of runs of ones
result = accumarray(js, floor((ie-is)/2)); %// sum values for each row of A

Best data structure for search?

I have a list with items where each have number of properties (A, B, C, D) which I would like to filter using template containing same attributes (A, B, C, D). When I use a template I would like to filter all items matching this template. The match is assumed if item is equal to template or is smaller subsequence of it (0 match any item).
Example data
A B C D
1 0 1 0
2 0 0 0
0 0 2 3
2 0 2 1
2 0 2 0
0 0 0 0
Example templates
[2 0 0 0] will filter {[0 0 0 0], [2 0 0 0]}
[2 0 2 0] will filter {[0 0 0 0], [2 0 0 0], [2 0 2 0]}
[2 0 2 1] will filter {[0 0 0 0], [2 0 2 1]}
[3 4 5 6] will filter {[0 0 0 0]}
[0 0 2 0] will filter {[0 0 0 0], [0 0 2 3], [2 0 2 1], [2 0 2 0]}
The problem is that number of comparisons can easily reach 300k and can get slow sometimes. What tricks or structure I could use to make things quicker? Any ideas?
Assuming 4 properties, let's place all the items into 16 buckets.
First bucket is where there are no zero-values for the properties. Selecting from here - simple lookup based on key ABCD.
Second bucket is where the property A == 0. Selecting from here is a lookup on the template with value of BCD.
Third bucket is where B == 0. Selecting from here is a lookup on the template with value of ACD.
Fourth is where A == 0 and B == 0. Selecting from here is a lookup on the template with value of CD.
....
Fifteenth is where A,B,C == 0. the lookup is on D.
Sixteenth is where A,B,C,D == 0. This can be a boolean variable ;-)
Since all of the 16 buckets are 'exact match' - you can use methods like hash tables for the search inside them.
(this proposal is based on the assumption from the example that it's 0 in the prop value that counts as 'match any' and not in the template.) - because the 2000 selected only one value in your exaample. it will obviously be incorrect if the semantics is 'any' in both places.
--
update: corollary: you can have no more than 2^Nproperties matches.
Example:
Let's suppose we have 3 properties A,B,C and the following four items:
itemX[A=1, B=0, C=1] ---> B is a wildcard, so bucketAC[11] = itemX
itemY[A=2, B=0, C=0] ---> B and C are wildcards, so bucketA[2] = itemY
itemZ[A=2, B=1, C=0] ---> C is a wildcard, so bucketAB[21] = itemZ
now, the lookup for a key 'abc' would be as follows (I also include to the right the
contents of the buckets for ease of reading, and '<<' means 'accumulate' in this context)
1.results << bucketA[a] | '2' => itemY[A=2, B=0, C=0]
2.results << bucketB[b]
3.results << bucketAB[ab] | '21' => itemZ[A=2, B=1, C=0]
4.results << bucketC[c]
5.results << bucketAC[ac] | '11' => itemX[A=1, B=0, C=1]
6.results << bucketBC[bc]
7.results << bucketABC[abc]
8.results << bucket_item_all_wildcards
So if we use template [2 0 0], we get the results from key being A=2 in bucketA only.
If we use template [2 1 0], then we get the results from key being A=2 in bucketA,
and from key being AB=21 in bucketAB - two results.
NB: Of course, the above notation for keys is rather frivolous, it merely assumes "hashtable-like access with the concatenation of the said properties being the key".
If you are allowed to have items with the same properties multiple times, then you will need to have multiple elements in some slots - and then, obviously, you can have more
than 2^Nproperties search results, nonetheless you can track the maximum number of duplicates and hence always predict the worst-case maximum number of items.
Notably, if the number of properties grows, the total possible number of buckets will quickly blow up (e.g. 32 properties would mean maximum more than 4 billion buckets),
so this idea will no longer be applicable directly, and would need further
optimizations around the bucket traversal/allocation.
What about nested hash maps? For example, an item "it" will be stored as:
map(it.A)(it.B)(it.C).(it.D) = it
So [2 0 2 0] could be searched as:
map(2).keys.(2).keys

Categories

Resources