PDA

View Full Version : Splitting bitarrays into smaller bitarrays


Rorschach
02-11-2010, 12:26 PM
Does anyone have a fast function for splitting a bitarray into x sized smaller bitarrays?

eg:
A=#{1,3,7,10..15,18,20,25,56,58,60,70..80}

splitting 'A' into 10's would generate something like

#{1,3,7,10..15,18,20}
#{25,56,58,60..67}
#{68..70,80}

Speed is of the essence here..

Thanks,

HornBerger
02-11-2010, 01:01 PM
here's my attempt, hopefully there's an easier way to do this :blush:. any how, the splitbitray function takes 2 params, a bit array a and an integer x and splits the bit array at x intervals
fn splitbitray a x =
(
st = timestamp()
b = #()
k = 1
initj = 0
maxcount = a.count
for i = x to maxcount by x do
(
if (finditem a i)!=0 do
(
b[k] = #{}
for j = initj to (initj+x) do
(
if (finditem a j)!=0 do
(
append b[k] j
)
)
initj = i
k+=1
)
)
for l=1 to b.count do
print b[l]
et = timestamp()
format "took % miliseconds\n" (et-st)
)
a=#{1,3,7,10..15,18,20,22,25,50,56,58,60,70..80}

splitbitray a 10


cheers! :)

SyncViewS
02-11-2010, 01:58 PM
Hi, here is my version, it should be a little faster. Takes as input the bitarray and the dimension of new chunks.

function splitBitArray baInput iSpan =
(
local baChunk = #{}
local iCount = 0
local abaOutput = #()

for iIndex in baInput do
(
baChunk[iIndex] = true
iCount += 1

if (iCount == iSpan) do
(
append abaOutput baChunk
baChunk = #{}
iCount = 0
)
)

if (not baChunk.isEmpty) do
append abaOutput baChunk

return abaOutput
)
- Enrico

Rorschach
02-11-2010, 02:17 PM
thanks guys, extremely helpful

Hornbergers was slightly faster on some giant bitarrays I tried, but duplicates bits between arrays, ie:

#(#{1..10}, #{10..20}, #{20..30}, #{30..40}, #{40..50}

Whereas SyncViewS gives the correct:
#(#{1..10}, #{11..20}, #{21..30}, #{31..40}, #{41..50}

SyncViewS
02-11-2010, 02:24 PM
If you have to deal with huge BitArray, there is another handy optimization to play: rather then appending small BitArrays to a single Array, which can become quite slow when it grows, there can be a cap to appending say 10 bitArrays to an Array, then other 10 to another one and so on, and perform as last passage the join of all Arrays containing BitArrays chunks. I hope this is clear. If I have a bunch of minutes, I'll give it a try.

- Enrico

HornBerger
02-11-2010, 03:03 PM
sorry had a misconception ;) before here's the corrected code
fn splitbitray a x =
(
st = timestamp()
a = a as array
k = 1
b = #()
for i = 1 to (a.count) by x do
(
b[k] = #{}
nextj = i+x-1
if nextj> a.count do
nextj = a.count
for j = i to (nextj) do
(
append b[k] a[j]
)
if (b[k].count>1) do
k+=1
)
for l=1 to b.count do
format "%" b[l]
et = timestamp()
format "\ntook % miliseconds\n" (et-st)
)
a=#{1,3,7,10..15,18,20,25,56,58,60,70..80}

splitbitray a 10

cheers! :)

CGTalk Moderation
02-11-2010, 03:03 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.