Reputation: 655
I'm trying to create a program that quickly generates a certain sequence.
The sequence is given through iteration, and goes as follows:
new = old + 1 + (-1*(old reversed))
Example:
old = [1]
new = [1]+[1]+[-1] = [1, 1, -1]
old = [1, 1, -1]
new = [1, 1, -1] + [1] + [1, -1, -1] = [1, 1, -1, 1, 1, -1, -1]
I want this to go as fast as possible, and i figured that since the sequence will only contain -1 or 1, I can use bitwise operations, and let every bit represent true
or false
, which I can then map to -1
or 1
.
Then I end up with a sequence of bits which I can manipulate using bitwise operations. I have a custom class that creates a long[]
, and chunks up the bits in 64 bit pieces.
Everything is working, and I'm getting the correct answer, but this solution is a lot slower than just using a byte[]
array and looping trough.
The most time-consuming function is the one that reverses the order of the bits, and inverts every bit.
Right now it looks like:
//this function is inside the custom class I defined
public void set(int n, int d) { //set bit n as the inverse value of bit d
storage[n/64] ^= ~(storage[ind/64] & (1L << ind)) << (n-ind);
}
//sequence is an instance of my custom class
//the length of the sequence is sequenceLength
for (int i = 1; i < sequenceLength; i++) {
sequence.set(sequenceLength+i, sequenceLength-i);
}
Is there any way to improve performance here? I'm quite new to bitwise operations.
EDIT: Here is the custom class with all relevant methods.
public class Dragon3 {
private FastStorage dragon;
private short[] xpos;
private short[] ypos;
public Dragon3(int n) {
dragon = new FastStorage((int)Math.pow(2,n+1)-1);
dragon.setSize(1);
for (int i = 0; i < n; i++) {
iterate(dragon);
}
}
public class FastStorage {
private long[] storage;
private int size;
public FastStorage(int n) {
storage = new long[(n-1)/64+1];
size = n;
}
public int getSize() {
return size;
}
public void setSize(int n) {
size = n;
}
public void set(int n, int ind) {
storage[n/64] ^= (~storage[ind/64] & (1L << ind)) << (n-ind);
}
public long getInv(int n) {
return ~(storage[n/64]) & (1L << n);
}
public void iterate(FastStorage drag) {
int dragLength = drag.getSize();
drag.setSize(2*dragLength+1);
//drag.toggle(dragLength);
for (int i = 1; i < dragLength+1; i++) {
drag.set2(dragLength+i, dragLength-i);
//drag.set(dragLength+i, drag.getInv(dragLength-i));
}
}
public static void main(String[] args) {
Dragon3 instance = new Dragon3(Integer.valueOf(args[0]));
}
}
Upvotes: 1
Views: 449
Reputation: 1377
You didn't ask for it, but there is a direct formula for your sequence:
public static void main(String[] args) {
for( int n=1 ; n<=15 ; n++ ){
int fold = 1 - ((n/(n&-n))&2);
System.out.print(" " + fold);
}
System.out.println();
}
Upvotes: 2
Reputation: 186
You could try a BitSet though it normally keeps track of the bits that are set so you might need to keep track of the number of bits you are interested in:
public static void main(String[] args) {
BitSet bitSet = new BitSet();
bitSet.set(0,true);
bitSet.set(1, true);
bitSet.set(2, false);
final int length = 3;
printBitSet(bitSet, length);
BitSet newBitSet = new BitSet(length * 2 + 1);
for (int i = 0; i <length; i++) {
newBitSet.set(i, bitSet.get(i));
}
newBitSet.set(length, true);
for (int i = 0; i < length; i++) {
newBitSet.set(length + i + 1, !bitSet.get(length - i - 1));
}
printBitSet(newBitSet, 2*length +1);
}
private static void printBitSet(BitSet bitSet, int length) {
for (int i = 0; i < length; i++) {
System.out.print(" " +( bitSet.get(i) ? "1" : "-1"));
}
System.out.println();
}
Upvotes: 0